* Stateless NAT in nftables with maps for performance
@ 2025-09-12 11:28 Juan Carlos Lazcano
2025-09-12 12:05 ` Florian Westphal
0 siblings, 1 reply; 6+ messages in thread
From: Juan Carlos Lazcano @ 2025-09-12 11:28 UTC (permalink / raw)
To: netfilter@vger.kernel.org
Hi netfilter community!
I'm trying to orchestrate the generation and maintenance of thousands of dnat & snat rules in a stateless configuration within the prerouting and forward hooks with chain types of filter, and unfortunately am hitting a big performance barrier as a result. Its fine with a few thousand, but once we get into the tens of thousands of rules, things start slowing down linearly, which is why we would like to switch to maps. However, I cannot figure out 1) if maps are supported in filter chains within prerouting/forward hooks and 2) if it supports the syntax for stateless nat?
For example:
table ip mytable {
map dnat_map {
type ipv4_addr : ipv4_addr
}
chain dnat {
type filter hook prerouting priority raw; policy accept;
}
}
I normally generate stateless dnat's via:
$ nft add rule ip mytable dnat ip daddr 100.101.84.137 counter ip daddr set 10.11.1.32 notrack comment "comment 1"
But, lets say I want to try to replace this rule with a map. If i populate my map with a a key pair like:
$ nft add element ip mytable dnat_map { 100.101.84.137 : 10.11.33.32 }
How can I represent my original rule using a map?
I've tried:
$ sudo nft add rule ip mytable dnat ip daddr @dnat_map ip daddr set @dnat_map
Error: unknown raw payload base
add rule ip inode dns-dnat ip daddr @dnat_map ip daddr set @dnat_map
^^^^^^^^^
and a few other variations, but I cannot figure out if this is even supported.
Any feedback would be great, I'm running nftables v1.1.5 (Commodore Bullmoose #6) & kernel 6.8.0-79-generic x86_64 on ubuntu 24.04
Thanks!
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Stateless NAT in nftables with maps for performance
2025-09-12 11:28 Stateless NAT in nftables with maps for performance Juan Carlos Lazcano
@ 2025-09-12 12:05 ` Florian Westphal
2025-09-12 12:23 ` Florian Westphal
0 siblings, 1 reply; 6+ messages in thread
From: Florian Westphal @ 2025-09-12 12:05 UTC (permalink / raw)
To: Juan Carlos Lazcano; +Cc: netfilter@vger.kernel.org
Juan Carlos Lazcano <juan@placidnetworks.com> wrote:
> Hi netfilter community!
> I'm trying to orchestrate the generation and maintenance of thousands of dnat & snat rules in a stateless configuration within the prerouting and forward hooks with chain types of filter, and unfortunately am hitting a big performance barrier as a result. Its fine with a few thousand, but once we get into the tens of thousands of rules, things start slowing down linearly, which is why we would like to switch to maps. However, I cannot figure out 1) if maps are supported in filter chains within prerouting/forward hooks and 2) if it supports the syntax for stateless nat?
>
> For example:
>
> table ip mytable {
> map dnat_map {
> type ipv4_addr : ipv4_addr
> }
> chain dnat {
> type filter hook prerouting priority raw; policy accept;
> }
> }
>
> I normally generate stateless dnat's via:
>
> $ nft add rule ip mytable dnat ip daddr 100.101.84.137 counter ip daddr set 10.11.1.32 notrack comment "comment 1"
>
> But, lets say I want to try to replace this rule with a map. If i populate my map with a a key pair like:
>
> $ nft add element ip mytable dnat_map { 100.101.84.137 : 10.11.33.32 }
>
> How can I represent my original rule using a map?
ip daddr set ip daddr map @dnat_map
~~~~~~~~ #######
| \ The key to query the map for
|
\ What you want replaced
This rule is:
[ payload load 4b @ network header + 16 => reg 1 ] # loads the key (second ip daddr).
[ lookup reg 1 set dnat_map dreg 1 0x0 ] # queries map
[ payload write reg 1 => 4b @ network header + 16 csum_type 1 csum_off 10 csum_flags 0x1 ]
# Then places the result of the map at the location (first ip daddr).
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Stateless NAT in nftables with maps for performance
2025-09-12 12:05 ` Florian Westphal
@ 2025-09-12 12:23 ` Florian Westphal
2025-09-12 12:47 ` Juan Carlos Lazcano
0 siblings, 1 reply; 6+ messages in thread
From: Florian Westphal @ 2025-09-12 12:23 UTC (permalink / raw)
To: Juan Carlos Lazcano; +Cc: netfilter@vger.kernel.org
Florian Westphal <fw@strlen.de> wrote:
> ip daddr set ip daddr map @dnat_map
Forgot the usual disclaimer: this breaks icmp(v6).
There is a reason for existence of stateful nat after all.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Stateless NAT in nftables with maps for performance
2025-09-12 12:23 ` Florian Westphal
@ 2025-09-12 12:47 ` Juan Carlos Lazcano
2025-09-12 13:37 ` Florian Westphal
0 siblings, 1 reply; 6+ messages in thread
From: Juan Carlos Lazcano @ 2025-09-12 12:47 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter@vger.kernel.org
You all are amazing. Thank you for all that you do!
My echo/reply base icmp functionality for v4 is working atleast at a cursory glance, without further testing I'm not sure what other parts of icmp are not working with this approach.
> On 09/12/2025 8:23 AM Florian Westphal <fw@strlen.de> wrote:
>
>
> Florian Westphal <fw@strlen.de> wrote:
> > ip daddr set ip daddr map @dnat_map
>
> Forgot the usual disclaimer: this breaks icmp(v6).
>
> There is a reason for existence of stateful nat after all.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Stateless NAT in nftables with maps for performance
2025-09-12 12:47 ` Juan Carlos Lazcano
@ 2025-09-12 13:37 ` Florian Westphal
2025-09-15 9:11 ` Pablo Neira Ayuso
0 siblings, 1 reply; 6+ messages in thread
From: Florian Westphal @ 2025-09-12 13:37 UTC (permalink / raw)
To: Juan Carlos Lazcano; +Cc: netfilter@vger.kernel.org
Juan Carlos Lazcano <juan@placidnetworks.com> wrote:
> My echo/reply base icmp functionality for v4 is working atleast at a cursory glance, without further testing I'm not sure what other parts of icmp are not working with this approach.
Internal addresses leak via icmp dst unreach, redirects etc. which contain copies of
the (rewritten or original) addresses.
That in turn breaks path mtu discovery for instance:
Server may see internal address reflected in embedded header.
Client can receive error for source address it doesn't have.
NAT engine also rewrites embedded headers, see e.g. nf_nat_ipv4_fn()
in net/netfilter/nf_nat_proto.c and nf_nat_icmp_reply_translation() to
avoid this.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Stateless NAT in nftables with maps for performance
2025-09-12 13:37 ` Florian Westphal
@ 2025-09-15 9:11 ` Pablo Neira Ayuso
0 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2025-09-15 9:11 UTC (permalink / raw)
To: Florian Westphal; +Cc: Juan Carlos Lazcano, netfilter@vger.kernel.org
On Fri, Sep 12, 2025 at 03:37:36PM +0200, Florian Westphal wrote:
> Juan Carlos Lazcano <juan@placidnetworks.com> wrote:
> > My echo/reply base icmp functionality for v4 is working atleast at a cursory glance, without further testing I'm not sure what other parts of icmp are not working with this approach.
>
> Internal addresses leak via icmp dst unreach, redirects etc. which contain copies of
> the (rewritten or original) addresses.
> That in turn breaks path mtu discovery for instance:
>
> Server may see internal address reflected in embedded header.
> Client can receive error for source address it doesn't have.
>
> NAT engine also rewrites embedded headers, see e.g. nf_nat_ipv4_fn()
> in net/netfilter/nf_nat_proto.c and nf_nat_icmp_reply_translation() to
> avoid this.
I think this can be fixed by extending userspace to mangle the icmp
payload, I would like to reach this at some point.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-09-15 9:11 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-12 11:28 Stateless NAT in nftables with maps for performance Juan Carlos Lazcano
2025-09-12 12:05 ` Florian Westphal
2025-09-12 12:23 ` Florian Westphal
2025-09-12 12:47 ` Juan Carlos Lazcano
2025-09-12 13:37 ` Florian Westphal
2025-09-15 9:11 ` Pablo Neira Ayuso
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).