some questions on nft
Christoph Anton Mitterer <[email protected]> Tue, 23 Sep 2025 03:18:25 +0200
| Newsgroups | gmane.comp.security.firewalls.netfilter.general |
|---|---|
| Message-ID | <[email protected]> |
Hey.
I'd have some questions, where I couldn't find the answer in the wiki
nor the manpage:
1) I there any difference between e.g
ct state established,related accept
and
ct state {established,related} accept
I mean the later is obviously a set, the former syntax doesn't even
seem to be documented but is used even by official tools (e.g.
-translate).
In particular, is any of them faster?
Same for others like dport.
2) When using the *inet* family (which btw. is really nice)... quite
some of the examples in the wiki and other 3rd party places use
e.g.:
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?
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?
In particular.e.g
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
?
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?
It seems that something like:
table inet filter {
chain input {
type filter hook input priority filter
ct state {established,related} accept
}
}
include "x.nft"
with that x.nft being e.g.:
table inet filter {
chain input {
type filter hook input priority filter
ip daddr 1.1.1.1 accept
}
}
would actually merge (but e.g. things like table comment aren't
overwritten.
But no idea how his would be done with sets, etc.?
Or is this simply a: don't do such 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?
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?)
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
7) Also not possible, AFAICS, but was it ever considered to allow
using sets within (v)maps or even other sets?
Like:
set http_ports {
typeof tcp dport
elements = { 80, 443, 8080 }
}
map whitelist {
type ipv4_addr . inet_service : verdict
}
add element filter whitelist { 1.2.3.4 . @http_ports : accept}
add element filter whitelist { 4.4.4.4 . @foo_ports : accept}
Thanks,
Chris.