It is not clear to me from the manual if this commands are equal in their function:
meta skuid == "root" counter accept
skuid 0 counter accept
also
ct state == { established, related } counter accept
ct state established,related counter accept
My questions about syntax is:
- can I skip word
meta
(seems it must be skipped when item used inlog flags
)? - can I add == sign in any command that match something (for readability)?
- can I write list (set of items) as
item1,item2
and not{ item1, item2 }
or it's only forct
command?
To verify two rules are identical even beyond being displayed the same (in rare cases involving multiple protocol layers, rules can display the same, be functionally equivalent but not be exactly the same at the bytecode level, that's almost a reproducibility bug), use the option
--debug=netlink
which will also display bytecode sent to the kernel. If the bytecode is identical, the rules are identical.Here's an interactive example (using nftables 1.0.9. Results can slightly change depending on version):
As can be seen the 2 first rules are the same. Indeed
"root"
is resolved as usual to the uid 0 by userspace, and themeta
keyword is optional (at least with the version here).The two last rules, even if functionally equivalent, aren't identical. On case uses an anonymous set of two values. But these two values are meant to be combined in a bitwise manner (ie: all possible symbols have different exponent of 2 as value), that's what is doing the last rule instead where the
,
takes a different role. At a glance, I'd tell the 2ndct
rule is more optimized than the first: no need to involve a set lookup.Still use of the first case exist: when using
vmap
(a verdict map rather than a simple set) to call different verdicts depending on the conntrack state in a single rule.Whatever you choose, for a given nftables version, it will always be displayed back in one way:
That should probably be what to use, or that might anyway end up being used, just because when handled manually rather than by tools it's often practical to dump the ruleset, edit it, and reload it.
The case in
ct
cannot be generalized at all: the 2nd variant can be done (if specific syntax support is implemented anyway) only where power of two values are involved so they can be combined in bitwise operations:An obvious example is the use of the TCP flags with nftables:
So just like
ct
:The two last rules (note the use of
|
for a bitwise OR operation instead of,
for the built-in syntax) are exactly the same. But first rule uses an anonymous set just like in the previous case. In all cases in this example, one matching TCP flag among multiple is enough to match: functionally equivalent. Had there been the need to match two flags at once, only the 2nd case would have been usable.Typically the rule below, that requires the presence of two flags at once, cannot be implemented with an anonymous set:
Note: it doesn't make sense to combine in this manner flags with
ct
because contrary to TCP flags, only one flag at once is supposed to exist (a given packet can not have multiple conntrack states at once).