All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Moisey <adrian@changeover.za.net>
To: netfilter-devel@vger.kernel.org
Cc: Adrian Moisey <adrian@changeover.za.net>
Subject: [PATCH nft] netlink_linearize: size nat register allocation by address expression
Date: Thu,  6 Aug 2026 20:50:20 +0200	[thread overview]
Message-ID: <20260806185020.95154-1-adrian@changeover.za.net> (raw)

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


             reply	other threads:[~2026-08-06 18:50 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06 18:50 Adrian Moisey [this message]
2026-08-20 11:15 ` [PATCH nft] netlink_linearize: size nat register allocation by address expression Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260806185020.95154-1-adrian@changeover.za.net \
    --to=adrian@changeover.za.net \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.