* [PATCH nft] netlink_linearize: size nat register allocation by address expression
@ 2026-08-06 18:50 Adrian Moisey
2026-08-20 11:15 ` Pablo Neira Ayuso
0 siblings, 1 reply; 2+ messages in thread
From: Adrian Moisey @ 2026-08-06 18:50 UTC (permalink / raw)
To: netfilter-devel; +Cc: Adrian Moisey
nat statements with a literal concatenation of address and port, e.g.
dnat ip6 addr . port to fd00:10:244::4 . 6443
allocated a fixed 128-bit register block for the address, but the ip6
address . port concatenation is 144 bits (5 registers), so
netlink_gen_concat overran into unallocated registers and hit the
assertion 'dreg < ctx->reg_low' in netlink_gen_expr. IPv4 escaped by
luck since its 48-bit concatenation fits into the padded block.
Allocate the register based on the address expression instead, which
sizes by expr->len for concatenations, and add the matching
release_register() call. Extend the nat_addr_port test with literal
concatenation rules for ip and ip6.
Signed-off-by: Adrian Moisey <adrian@changeover.za.net>
---
src/netlink_linearize.c | 6 ++-
.../maps/dumps/nat_addr_port.json-nft | 54 +++++++++++++++++++
.../testcases/maps/dumps/nat_addr_port.nft | 2 +
tests/shell/testcases/maps/nat_addr_port | 2 +
4 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index ac0eaff9..dfa841c6 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -1292,8 +1292,7 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
nftnl_expr_set_u32(nle, nftnl_flag_attr, stmt->nat.flags);
if (stmt->nat.addr) {
- amin_reg = get_register(ctx, NULL);
- registers++;
+ amin_reg = get_register(ctx, stmt->nat.addr);
if (stmt->nat.addr->etype == EXPR_RANGE) {
amax_reg = get_register(ctx, NULL);
@@ -1374,6 +1373,9 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
registers--;
}
+ if (stmt->nat.addr)
+ release_register(ctx, stmt->nat.addr);
+
nft_rule_add_expr(ctx, nle, &stmt->location);
}
diff --git a/tests/shell/testcases/maps/dumps/nat_addr_port.json-nft b/tests/shell/testcases/maps/dumps/nat_addr_port.json-nft
index 38b01e69..09052c43 100644
--- a/tests/shell/testcases/maps/dumps/nat_addr_port.json-nft
+++ b/tests/shell/testcases/maps/dumps/nat_addr_port.json-nft
@@ -320,6 +320,33 @@
]
}
},
+ {
+ "rule": {
+ "family": "ip",
+ "table": "ipfoo",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "meta": {
+ "key": "l4proto"
+ }
+ },
+ "right": "tcp"
+ }
+ },
+ {
+ "dnat": {
+ "addr": "10.2.3.4",
+ "port": 4242
+ }
+ }
+ ]
+ }
+ },
{
"rule": {
"family": "ip",
@@ -670,6 +697,33 @@
]
}
},
+ {
+ "rule": {
+ "family": "ip6",
+ "table": "ip6foo",
+ "chain": "c",
+ "handle": 0,
+ "expr": [
+ {
+ "match": {
+ "op": "==",
+ "left": {
+ "meta": {
+ "key": "l4proto"
+ }
+ },
+ "right": "tcp"
+ }
+ },
+ {
+ "dnat": {
+ "addr": "fd00:10:244::4",
+ "port": 6443
+ }
+ }
+ ]
+ }
+ },
{
"rule": {
"family": "ip6",
diff --git a/tests/shell/testcases/maps/dumps/nat_addr_port.nft b/tests/shell/testcases/maps/dumps/nat_addr_port.nft
index c8493b3a..fb1c190a 100644
--- a/tests/shell/testcases/maps/dumps/nat_addr_port.nft
+++ b/tests/shell/testcases/maps/dumps/nat_addr_port.nft
@@ -29,6 +29,7 @@ table ip ipfoo {
ip saddr 10.1.1.2 tcp dport 42 dnat to 10.2.3.4:4242
meta l4proto tcp dnat ip to ip saddr map @y
dnat ip to ip saddr . tcp dport map @z
+ meta l4proto tcp dnat to 10.2.3.4:4242
dnat to numgen inc mod 2 map @t1
meta l4proto tcp dnat ip to numgen inc mod 2 map @t2
}
@@ -62,6 +63,7 @@ table ip6 ip6foo {
ip6 saddr dead::2 tcp dport 42 dnat to [c0::1a]:4242
meta l4proto tcp dnat ip6 to ip6 saddr map @y
dnat ip6 to ip6 saddr . tcp dport map @z
+ meta l4proto tcp dnat to [fd00:10:244::4]:6443
dnat to numgen inc mod 2 map @t1
meta l4proto tcp dnat ip6 to numgen inc mod 2 map @t2
}
diff --git a/tests/shell/testcases/maps/nat_addr_port b/tests/shell/testcases/maps/nat_addr_port
index 703a2ad9..5f6ff1c4 100755
--- a/tests/shell/testcases/maps/nat_addr_port
+++ b/tests/shell/testcases/maps/nat_addr_port
@@ -31,6 +31,7 @@ table ip ipfoo {
ip saddr 10.1.1.2 tcp dport 42 dnat to 10.2.3.4:4242
meta l4proto tcp dnat ip addr . port to ip saddr map @y
meta l4proto tcp dnat ip addr . port to ip saddr . tcp dport map @z
+ meta l4proto tcp dnat ip addr . port to 10.2.3.4 . 4242
dnat ip to numgen inc mod 2 map @t1
meta l4proto tcp dnat ip addr . port to numgen inc mod 2 map @t2
}
@@ -72,6 +73,7 @@ table ip6 ip6foo {
ip6 saddr dead::2 tcp dport 42 dnat to [c0::1a]:4242
meta l4proto tcp dnat ip6 addr . port to ip6 saddr map @y
meta l4proto tcp dnat ip6 addr . port to ip6 saddr . tcp dport map @z
+ meta l4proto tcp dnat ip6 addr . port to fd00:10:244::4 . 6443
dnat ip6 to numgen inc mod 2 map @t1
meta l4proto tcp dnat ip6 addr . port to numgen inc mod 2 map @t2
}
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH nft] netlink_linearize: size nat register allocation by address expression
2026-08-06 18:50 [PATCH nft] netlink_linearize: size nat register allocation by address expression Adrian Moisey
@ 2026-08-20 11:15 ` Pablo Neira Ayuso
0 siblings, 0 replies; 2+ messages in thread
From: Pablo Neira Ayuso @ 2026-08-20 11:15 UTC (permalink / raw)
To: Adrian Moisey; +Cc: netfilter-devel
On Thu, Aug 06, 2026 at 08:50:20PM +0200, Adrian Moisey wrote:
> nat statements with a literal concatenation of address and port, e.g.
>
> dnat ip6 addr . port to fd00:10:244::4 . 6443
>
> allocated a fixed 128-bit register block for the address, but the ip6
> address . port concatenation is 144 bits (5 registers), so
> netlink_gen_concat overran into unallocated registers and hit the
> assertion 'dreg < ctx->reg_low' in netlink_gen_expr. IPv4 escaped by
> luck since its 48-bit concatenation fits into the padded block.
>
> Allocate the register based on the address expression instead, which
> sizes by expr->len for concatenations, and add the matching
> release_register() call. Extend the nat_addr_port test with literal
> concatenation rules for ip and ip6.
Applied, thanks
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-20 11:16 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06 18:50 [PATCH nft] netlink_linearize: size nat register allocation by address expression Adrian Moisey
2026-08-20 11:15 ` Pablo Neira Ayuso
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.