diff mbox series

[nft] payload: restore is_raw flag for th expressions parsed from udata

Message ID 20260825191048.95426-1-adrian@changeover.za.net
State New
Headers show
Series [nft] payload: restore is_raw flag for th expressions parsed from udata | expand

Commit Message

Adrian Moisey Aug. 25, 2026, 7:10 p.m. UTC
payload_expr_parse_udata() restores the pseudo transport header (th)
proto desc from set userdata, but not payload.is_raw. The bison and
json parsers both set is_raw for raw th expressions, which makes
evaluation skip the transport protocol conflict check. Without it,
re-evaluating a map declared with 'typeof ... th dport ...' from a
later transaction fails with a bogus

  conflicting transport layer protocols specified: tcp vs. th

Set is_raw when the restored desc is proto_th, just like the parsers
do.

Signed-off-by: Adrian Moisey <adrian@changeover.za.net>
---
 src/payload.c                                 |  3 ++
 .../testcases/maps/typeof_maps_restore_0      | 28 +++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100755 tests/shell/testcases/maps/typeof_maps_restore_0
diff mbox series

Patch

diff --git a/src/payload.c b/src/payload.c
index 162367eb..4f1834a0 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -239,6 +239,9 @@  static struct expr *payload_expr_parse_udata(const struct nftnl_udata *attr)
 
 	expr = payload_expr_alloc(&internal_location, desc, type);
 
+	if (desc == &proto_th)
+		expr->payload.is_raw = true;
+
 	if (len)
 		expr->len = len;
 
diff --git a/tests/shell/testcases/maps/typeof_maps_restore_0 b/tests/shell/testcases/maps/typeof_maps_restore_0
new file mode 100755
index 00000000..417e1c3c
--- /dev/null
+++ b/tests/shell/testcases/maps/typeof_maps_restore_0
@@ -0,0 +1,28 @@ 
+#!/bin/bash
+
+# 'th dport' in a typeof map is restored from set userdata. A later
+# transaction re-evaluating it must not fail with a bogus
+# "conflicting transport layer protocols specified: tcp vs. th".
+
+set -e
+
+$NFT -f - <<EOF
+table ip t {
+	map m {
+		typeof ip saddr : ip daddr . th dport
+		elements = { 10.1.1.1 : 10.2.3.4 . 4242 }
+	}
+
+	chain c {
+		type nat hook prerouting priority dstnat; policy accept;
+		meta l4proto tcp dnat ip to ip saddr map @m
+	}
+
+	chain d {
+		type nat hook prerouting priority dstnat; policy accept;
+	}
+}
+EOF
+
+# separate transaction
+$NFT add rule 'ip t d meta l4proto tcp dnat ip addr . port to ip saddr map @m'