Signed-off-by: Christoph Anton Mitterer --- doc/nft.txt | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/doc/nft.txt b/doc/nft.txt index 2ca601b1..4cd3fa8e 100644 --- a/doc/nft.txt +++ b/doc/nft.txt @@ -572,6 +572,107 @@ table inet filter { nft delete rule inet filter input handle 5 ------------------------- +OVERALL EVALUATION OF THE RULESET +--------------------------------- +This is a summary of how the ruleset is evaluated. + +* Even if a packet is accepted by the ruleset (and thus by netfilter), it may + still get discarded by other means, for example Linux generally ignores + various ICMP types and there are sysctl options like + `net.ipv{4,6}.conf.*.forwarding` or `net.ipv4.conf.*.rp_filter`. +* Tables are merely a concept of nftables to structure the ruleset and not known + to netfilter itself. + They are thus irrelevant with respect to netfilter’s evaluation of the + ruleset. +* Packets traverse the network stack and at various hooks (see + <> above for lists of hooks per address family) they’re + evaluated by any base chains attached to these hooks. +* Base chains may call regular chains and regular chains may call other regular + chains (via *jump* and *goto* verdicts), in which case evaluation continues in + the called chain. + Base chains themsevlves cannot be called and only chains of the same table can + be called. +* For each hook, the attached chains are evaluated in order of their priorities. + Chains with lower priority values are evaluated before those with higher ones. + The order of chains with the same priority value is undefined. +* An *accept* verdict (including an implict one via the base chain’s policy) + ends the evaluation of the current base chain (and any regular chains called + from that). + It accepts the packet only with respect to the current base chain. Any other + base chain (or regular chain called by such) with a higher priority of the + same hook as well as any other base chain (or regular chain called by such) of + any later hook may however still ultimately *drop* (which might also be done + via verdict-like statements that imply *drop*, like *reject*) the packet with + an according verdict (with consequences as described below for *drop*). + Thus and merely from netfilter’s point of view, a packet is only ultimately + accepted if none of the chains of the relevant hooks issues a *drop* verdict + (be it explicitly or implicitly by policy or via a verdict-like statement that + implies *drop*, for example *reject*), which already means that there has to + be at least one *accept* verdict (be it explicitly or implicitly by policy). + All this applies analogously to verdict-like statements that imply *accept*, + for example the NAT statements. +* A *drop* verdict (including an implict one via the base chain’s policy) + immediately ends the evaluation of the whole ruleset and ultimately drops the + packet. + Unlike with an *accept* verdict, no further chains of any hook and regardless + of their table get evaluated and it’s therefore not possible to have a *drop* + verdict changed to an *accept* in a later chain. + Thus, if any base chain uses drop as its policy, the same base chain (or any + regular chain directly or indirectly called by it) must accept a packet or it + is ensured to be ultimately dropped by it. + All this applies analogously to verdict-like statements that imply *drop*, + for example *reject*. +* Given the semantics of *accept*/*drop* and only with respect to the utlimate + decision of whether a packet is accepted or dropped, the ordering of the + various base chains per hook via their priorities matters only in so far, as + any of them modifies the packet or its meta data and that has an influence on + the verdicts issued by the chains – other than that, the ordering shouldn’t + matter (except for performance and other side effects). + It also means that short-circuiting the ultimate decision is only possible via + *drop* verdicts (respectively verdict-like statements that imply *drop*, for + example *reject*). +* A *jump* verdict causes the current position to be stored in the call stack of + chains and evaluation to continue at the beginning of the called regular + chain. + Called chains must be from the same table and cannot be base chains. + When the end of the called chain is reached, an implicit *return* verdict is + issued. + Other verdicts (respectively verdict-like statements) are processed as + described above and below. +* A *goto* verdict is equal to *jump* except that the current position is not + stored in the call stack of chains. +* A *return* verdict ends the evaluation of the current chain, pops the most + recently added position from the call stack of chains and causes evaluation to + continue after that position. + When there’s no position to pop (which is the case when the current chain is + either the base chain or a regular chain that was reached solely via *goto* + verdicts) it ends the evaluation of the current base chain (and any regular + chains called from it) using the base chain’s policy as implicit verdict. +* Examples for *jump*/*goto*/*return*: + * 'base' {*jump*}→ 'regular-1' {*jump*}→ 'regular-2' + At the end of 'regular-2' or when a *return* is issued in that, evaluation + continues after the *jump* position in 'regular-1'. + At the end of 'regular-1' or when a *return* is issued in that, evaluation + continues after the *jump* position in 'base'. + * 'base' {*jump*}→ 'regular-1' {*goto*}→ 'regular-2' + At the end of 'regular-2' or when a *return* is issued in that, evaluation + continues after the *jump* position in 'base'. + * 'base' {*jump*}→ 'regular-1' {*jump*}→ 'regular-2' {*goto*}→ 'regular-3' + At the end of 'regular-3' or when a *return* is issued in that, evaluation + continues after the *jump* position in 'regular-1'. + At the end of 'regular-1' or when a *return* is issued in that, evaluation + continues after the *jump* position in 'base'. + * 'base' {*jump*}→ 'regular-1' {*goto*}→ 'regular-2' {*goto*}→ 'regular-3' + At the end of 'regular-3' or when a *return* is issued in that, evaluation + continues after the *jump* position in 'base'. +* Verdicts (that is: *accept*, *drop*, *jump*, *goto*, *return*, *continue* and + *queue*) as well as statements that imply a verdict (like *reject* or the NAT + statements) also end the evaluation of any later statements in their + respective rules (respectively cause an error when loading such rules). + For example in `… counter accept` the `counter` statement is processed, but in + `… accept counter` it is not. + This does not apply to the `comment` statement, which is always evaluated. + SETS ---- nftables offers two kinds of set concepts. Anonymous sets are sets that have no -- 2.51.0