From: Florian Westphal <fw@strlen.de>
To: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
Cc: netfilter-devel@vger.kernel.org, Pablo Neira Ayuso <pablo@netfilter.org>
Subject: Re: [PATCH 4/7] doc: add overall description of the ruleset evaluation
Date: Tue, 30 Sep 2025 13:50:35 +0200 [thread overview]
Message-ID: <aNvECxpxlsYS7Noy@strlen.de> (raw)
In-Reply-To: <20250926021136.757769-5-mail@christoph.anton.mitterer.name>
Christoph Anton Mitterer <mail@christoph.anton.mitterer.name> wrote:
> +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 are sysctl options lik
Minor typo, 'like'.
> + `net.ipv{4,6}.conf.*.forwarding` or `net.ipv4.conf.*.rp_filter`.
> +* With respect to the evaluation tables don’t matter at all and are not known by
> + netfilter.
> + They’re merely used to structure the ruleset.
'evaluation ordering'? Tables do matter in the sense that you can't
have any chains without them.
> +* Packets traverse the network stack and at various hooks they’re evaluated by
> + any base chains attached to these hooks.
Maybe add the hook names here? (preouting, input, and so on).
Or a reference to this topic.
> +* For each hook, the attached chains are evaluated in order of their priorities
> + (with chains with lower priority values being evaluated before those with
> + higher values and the order of chains with the same value being undefined).
It took me a sec to parse this, maybe:
... higher values. The order of chains with identical priorities is
undefined.
(or similar).
> +* An *accept* verdict (including an implict one via the base chain’s policy,
> + even if caused in certain cases by a *return* verdict) 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, which does
> + not mean that the packet is ultimately accepted.
Maybe: 'It accepts the packet only with respect to the current base
chain.' The rest is already made clear by your next sentence:
> + 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 still utlimately *deny*/*reject* the packet with
~~~~~~~ ultimately, but i'd just
remove this word.
please avoid 'deny' and use 'drop' everywhere. In this case,
.. may still drop the packet.
... is enough.
> + Thus and merely from netfilter’s point of view, a packet is only accepted if
> + none of the chains (regardless of their tables) that are attached to any of
> + the respectively relevant hooks issues a *deny*/*reject* verdict (be it
> + explicitly or implicitly by policy) and if there’s at least on *accept*
> + verdict (be it explicitly or implicitly by policy).
I'm not sure if the last part is needed as there is no such thing as a
base chain without a policy, so i would simplify this to:
Thus a packet is only accepted if no chain or rule issues a drop
verdict, including chain policies.
> + In that, the ordering of the various base chains per hook via their priorities
> + matters (with respect to the packets utlimate fate) only in so far, if any of
> + then would modify the packet or its meta data and that has an influence on the
> + verdicts – if not, the ordering shouldn’t matter (except for performance).
I'm not sure about this paragraph. While its correct, base chains and
their priorities still have effects, e.g. if ip defragmentation has
taken place or not. I think the previous paragraph is clear enough wrt.
packet acceptance.
> +* A *drop*/*reject* verdict (including an implict one via the base chain’s
> + policy even if caused in certain cases by a *return* verdict) immediately ends
> + the evaluation of the whole ruleset and ultimately drops/rejects 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 an
> + *drop*/*reject* verdict overturned.
As noted elsewhere, reject is just a more fancy drop, it should not be
mentioned here.
> + Thus, if any base chain uses drop as it’s 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.
Can that be reduced to something like:
Thus, base chains that use 'policy drop' must contain at least one accept rule or
must call another chain with an accept rule to avoid blocking all traffic.
> +* A *jump* verdict causes evaluation to continue at the first rule of the
> + regular chain it calls. Called chains must be of the same table and cannot be
> + base chains.
'must reside in same table'?
> + If no other verdict is issued in the called chain and if all rules of that
.. chain... ?
> + have been evaluated, evaluation will continue with the next rule after the
> + calling rule of the calling chain.
> + That is, reaching the end of the called chain causes a “jump back to the
> + calling chain” respectively an implicit *return* verdict.
Yes, this is why there is sometimes a reference to the call stack / or
chain stack.
'jump' makes a 'where am I' note, 'goto' doesn't.
> +* A *goto* verdict causes evaluation to continue at the first rule of the
> + regular chain it calls. Called chains must be of the same table and cannot be
> + base chains.
> + If no other verdict is issued in the called chain and if all rules of that
> + have been evaluated, evaluation of the current base chain and the regular
> + chains called by it end with an implicit verdict of the base chain’s policy.
> + That is, unlike with *jump*, reaching the end of the called chain does not
> + cause a “jump back to the calling chain”.
I think we should try to simplify this.
jump and goto are almost the same, the only difference is that goto
doesn't make a 'where am I' note, so the evaluation of the *called*
chain behaves as if those rules were part of the chain that contains the
'goto' statement.
> +* A *return* verdict’s processing depend upon in which chain it is issued.
Hmm. Not so sure. Its always the same:
End evaluation of this chain and go back to where you came from.
> + In a regular chain that was called via *jump* it ends evaluation of that chain
> + and return to the calling chain as described above.
Right.
> + In a regular chain that was called via *goto* or in a base chain, the *return*
> + verdict is equivalent to the base chain’s policy.
Yes, but thats because the called chain executes in the context of the
calling chain. Since thats a base chain, the return statement causes
a chain-stack-underflow. It has same effect as 'return' in ANY chain:
1. End evaluation of the chain.
2. Go back to where you cam from.
We have nowhere else to go back to.
So all of those are identical:
chain base {
hook ...
...
# no more rules, implicit return -> base chain policy
}
----
chain base {
hook ...
...
return # variant of above with explicit return
}
----
chain user {
return
}
chain base {
hook ...
goto user
}
----
All end up with 'no terminal statement seen and no more rules to check'.
> +* All verdicts described above (that is: *accept*, *drop*, *reject*, *jump*,
> + *goto* and *return*) also end the evaluation of any later statements in their
> + respective rules (or even cause an error when loadin such rules) with the
> + exception of the `comment` statement.
Why mention the comment statement here?
Comment is special, its not a statement from the evaluation
perspective. It tells the kernel to allocate some extra space to
store the comment data, the interpreter doesn't know its there.
> + That is, for example in `… counter accept` the `counter` statement is
> + processed, but in `… accept counter` it is not.
I think this was already mentioned, also, nft should already be
informing the user that the rule has unreachable trailing statements.
next prev parent reply other threads:[~2025-09-30 11:50 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-25 0:07 nft manpage/wiki issues and improvement ideas Christoph Anton Mitterer
2025-09-25 7:35 ` Pablo Neira Ayuso
2025-09-25 20:37 ` Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 0/7] doc: miscellaneois improvements Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 1/7] doc: clarify evaluation of chains Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 2/7] doc: fix/improve documentation of verdicts Christoph Anton Mitterer
2025-09-30 10:50 ` Florian Westphal
2025-10-02 14:50 ` Christoph Anton Mitterer
2025-10-02 15:21 ` Florian Westphal
2025-10-10 23:06 ` Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 3/7] doc: minor improvements with respect to the term “ruleset” Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 4/7] doc: add overall description of the ruleset evaluation Christoph Anton Mitterer
2025-09-30 11:50 ` Florian Westphal [this message]
2025-10-10 23:07 ` Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 5/7] doc: add some more documentation on bitmasks Christoph Anton Mitterer
2025-09-30 11:51 ` Florian Westphal
2025-09-30 11:53 ` Florian Westphal
2025-09-26 1:52 ` [PATCH 6/7] doc: describe include’s collation order to be that of the C locale Christoph Anton Mitterer
2025-09-26 1:52 ` [PATCH 7/7] doc: describe how values match sets Christoph Anton Mitterer
2025-09-26 2:32 ` nft manpage/wiki issues and improvement ideas Christoph Anton Mitterer
2025-10-11 0:23 ` [PATCH v2 0/7] doc: miscellaneous improvements Christoph Anton Mitterer
2025-10-11 0:23 ` [PATCH v2 1/7] doc: clarify evaluation of chains Christoph Anton Mitterer
2025-10-15 11:46 ` Florian Westphal
2025-10-11 0:23 ` [PATCH v2 2/7] doc: fix/improve documentation of verdicts Christoph Anton Mitterer
2025-10-15 11:42 ` Florian Westphal
2025-10-17 2:30 ` Christoph Anton Mitterer
2025-10-18 13:25 ` Florian Westphal
2025-10-19 0:11 ` Christoph Anton Mitterer
2025-10-11 0:23 ` [PATCH v2 3/7] doc: minor improvements with respect to the term “ruleset” Christoph Anton Mitterer
2025-10-15 11:51 ` Florian Westphal
2025-10-11 0:24 ` [PATCH v2 4/7] doc: add overall description of the ruleset evaluation Christoph Anton Mitterer
2025-10-20 9:39 ` Florian Westphal
2025-10-20 23:48 ` Christoph Anton Mitterer
2025-10-11 0:24 ` [PATCH v2 5/7] doc: add some more documentation on bitmasks Christoph Anton Mitterer
2025-10-18 13:32 ` Florian Westphal
2025-10-19 1:31 ` Christoph Anton Mitterer
2025-10-11 0:24 ` [PATCH v2 6/7] doc: describe include’s collation order to be that of the C locale Christoph Anton Mitterer
2025-10-18 13:35 ` Florian Westphal
2025-10-18 22:13 ` Christoph Anton Mitterer
2025-10-11 0:24 ` [PATCH v2 7/7] doc: describe how values match sets Christoph Anton Mitterer
2025-10-18 13:51 ` Florian Westphal
2025-10-19 1:50 ` Christoph Anton Mitterer
2025-10-19 1:38 ` [PATCH v3 0/6] doc: miscellaneous improvements Christoph Anton Mitterer
2025-10-19 1:38 ` [PATCH v3 1/6] doc: fix/improve documentation of verdicts Christoph Anton Mitterer
2025-10-20 9:28 ` Florian Westphal
2025-10-20 22:13 ` Christoph Anton Mitterer
2025-10-19 1:38 ` [PATCH v3 2/6] doc: minor improvements with respect to the term “ruleset” Christoph Anton Mitterer
2025-10-20 9:04 ` Florian Westphal
2025-10-19 1:38 ` [PATCH v3 3/6] doc: add overall description of the ruleset evaluation Christoph Anton Mitterer
2025-10-19 1:38 ` [PATCH v3 4/6] doc: add more documentation on bitmasks and sets Christoph Anton Mitterer
2025-10-20 9:06 ` Florian Westphal
2025-10-20 21:57 ` Christoph Anton Mitterer
2025-10-20 22:18 ` Florian Westphal
2025-10-20 23:51 ` Christoph Anton Mitterer
2025-10-19 1:38 ` [PATCH v3 5/6] doc: describe include’s collation order to be that of the C locale Christoph Anton Mitterer
2025-10-19 1:38 ` [PATCH v3 6/6] doc: minor improvements the `reject` statement Christoph Anton Mitterer
2025-10-20 23:49 ` [PATCH v4 0/5] doc: miscellaneous improvements Christoph Anton Mitterer
2025-10-20 23:49 ` [PATCH v4 1/5] doc: fix/improve documentation of verdicts Christoph Anton Mitterer
2025-10-20 23:49 ` [PATCH v4 2/5] doc: add overall description of the ruleset evaluation Christoph Anton Mitterer
2025-10-20 23:49 ` [PATCH v4 3/5] doc: add more documentation on bitmasks and sets Christoph Anton Mitterer
2025-10-20 23:49 ` [PATCH v4 4/5] doc: describe include’s collation order to be that of the C locale Christoph Anton Mitterer
2025-10-20 23:49 ` [PATCH v4 5/5] doc: minor improvements the `reject` statement Christoph Anton Mitterer
2025-10-22 14:34 ` Florian Westphal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aNvECxpxlsYS7Noy@strlen.de \
--to=fw@strlen.de \
--cc=mail@christoph.anton.mitterer.name \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.