netfilter.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* some questions on nft
@ 2025-09-23  1:18 Christoph Anton Mitterer
  2025-09-24 12:17 ` Florian Westphal
  0 siblings, 1 reply; 3+ messages in thread
From: Christoph Anton Mitterer @ 2025-09-23  1:18 UTC (permalink / raw)
  To: netfilter

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.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: some questions on nft
  2025-09-23  1:18 some questions on nft Christoph Anton Mitterer
@ 2025-09-24 12:17 ` Florian Westphal
  2025-09-24 21:45   ` Christoph Anton Mitterer
  0 siblings, 1 reply; 3+ messages in thread
From: Florian Westphal @ 2025-09-24 12:17 UTC (permalink / raw)
  To: Christoph Anton Mitterer; +Cc: netfilter

Christoph Anton Mitterer <calestyo@scientia.org> 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).

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: some questions on nft
  2025-09-24 12:17 ` Florian Westphal
@ 2025-09-24 21:45   ` Christoph Anton Mitterer
  0 siblings, 0 replies; 3+ messages in thread
From: Christoph Anton Mitterer @ 2025-09-24 21:45 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter

Hey Florian.

Thanks for taking your time on this :-)

On Wed, 2025-09-24 at 14:17 +0200, Florian Westphal wrote:
> Christoph Anton Mitterer <calestyo@scientia.org> 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.

So you if mean either establishes, or related or both are set, right?

I assume it works always like this with "," and any bitfields?

My nft doesn't seem to recognise --netlink=debug. Do you mean
--debug=netlink? :-)


> >    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.

I see. , good to know.


> 
> > 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.

Such documentation would actually be quite helpful, cause I've seen
e.g. that "redefining" (or better updating) a table with that syntax
won't cause e.g. its comment to be updated.
But the policy of a chain will be overridden by a later one.


> >    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 :)

Well from the documentation, both form seemed to be considered "equal",
so it's not necessarily obvious whether or not it's just stupid or
missing some docs ;-)


> 
> > 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.

And I assume this is really hardwired?

I.e. even if on would hack the system to bring up lo after e.g. eth0...
or if one would remove lo and bring it back?
Not sure whether this is even still possible.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n12926
seems to indicate that not.


> >    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?

Not that I want... but just to catch any stuff that co-admins might do
;-)


> > 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).

True. But I though more about the poor-man's way, where any referred
named set would have simply been resolved when being added.


Thanks... your answers were quite helpful. :-)


Cheers,
Chris.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-09-24 21:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-23  1:18 some questions on nft Christoph Anton Mitterer
2025-09-24 12:17 ` Florian Westphal
2025-09-24 21:45   ` Christoph Anton Mitterer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).