Re: some questions on nft

Florian Westphal <[email protected]> Wed, 24 Sep 2025 14:17:11 +0200
Newsgroups gmane.comp.security.firewalls.netfilter.general
Message-ID <[email protected]>
Christoph Anton Mitterer <[email protected]> wrote:
> 1) I there any difference between e.g
>       ct state established,related accept

You can use nft --netlink=debug, that should explain the difference.
This is a bit-test, matches if either flag is set.

>    and
>       ct state {established,related} accept

matches when established is set but not related and vice versa.
Given established and related are mutually exclusive, both do the
same thing but the former is a bit faster.

>       add rule inet my_table my_input meta l4proto '{ icmp, ipv6-icmp }' accept
>       add rule inet my_table my_input meta l4proto udp ct state new jump my_udp_chain
>       add rule inet filter output meta l4proto tcp
>       add rule filter input meta l4proto { tcp, udp }  th dport 53  counter packets 0 bytes 0  accept  comment \"accept DNS\"
> 
>    Am I correct, that l4proto has to be used in these, simply because
>    the respective protos are matches as a whole, and e.g. the tcp/udp
>    header expression cannot be used because one would need to add
>    something like dport?

'udp dport 53' would not match tcp (it internally adds l4proto udp).

>    But as soon as one does want to do that anyway (e.g. using
>    tcp/udp dport or some icmp icmpv6 type), is there any difference or
>    disadvantage when leaving out the meta l4proto match and just doing
>      tcp ..
>      udp ..
>      icmp
>      icmpv6 ..
>    ?
>    AFAIU, tcp/udp would just work in both v4 and v6 while icmp would
>    only apply to v4 and icmpv6 only to v6 packets automatically.
>    So an obscure ICMPv6 over IPv4 wouldn't be matched, right?

No, would not be matched.  You can check --netlink=debug to reveal
the internal dependencies that nft will insert to prevent false matches
on random packets.

> 3) I've seen examples like:
>       ct state vmap { established : accept, related : accept, invalid : drop } 
>    where a vmap is used, which is a nice way of writing it down.
> 
>    But is this slower (when it internally uses some hash or so) than
>    e.g. two rules:
>        ct state established,related accept
>        ct state invalid accept

Heavily depends on the circumstances, IIRC the set lookup costs are more
expensive than a single rule only doing payload checks. but its faster
when replacing at least 3 rules.

> 4) In principle I prefer the syntax as returned by nft list over the
>    one using single commands, like:
>      add rule ...
>    is there any documentation on how the block based syntax is
>    merged when using include? Or is that even officially supported?

Its expected to work, yes.  Not aware of any documentation.

>    But no idea how his would be done with sets, etc.?
>    Or is this simply a: don't do such stupid things?

Well, its always a good idea to NOT do stupid things :)

> 5) Many examples use:
>      iif lo
>    or
>      iifname lo
> 
>    Now first, if I'd bring down lo and bring it up again (like it may
>    actually happen with eth0/wlan0 and others)... would it get a
>    different id, and thus no longer be matched by iif?

No, lo is always 1.  For other devices, yes, might get different id.

>    In particular for lo, wouldn't it anyway better to use
>      iiftype loopback
>    (which would simply match all loopbacks, regardless of their name)
>    or is there any disadvantage I can't see?)

Hmm, why would anyone add another loopback device?

> 6) Probably not possible, but can one match v4 and v6 addrs in one rule
>    (when being in the inet family)?
>    Like in:
>       ??? daddr @addrs tcp dport 22 accept
>    with @addrs containing v4 and v6

No.

> 7) Also not possible, AFAICS, but was it ever considered to allow
>    using sets within (v)maps or even other sets?

No idea. I don't like it because it slows things down (need to
iterate and then query several sets).