]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
expression: tolerate named set protocol dependency
authorFlorian Westphal <fw@strlen.de>
Thu, 20 Mar 2025 08:34:45 +0000 (09:34 +0100)
committerFlorian Westphal <fw@strlen.de>
Thu, 20 Mar 2025 10:42:45 +0000 (11:42 +0100)
Included test will fail with:
/dev/stdin:8:38-52: Error: Transparent proxy support requires transport protocol match
   meta l4proto @protos tproxy to :1088
                        ^^^^^^^^^^^^^^^
Tolerate a set reference too.  Because the set can be empty (or there
can be removals later), add a fake 0-rhs value.

This will make pctx_update assign proto_unknown as the transport protocol
in use, Thats enough to avoid 'requires transport protocol' error.

v2: restrict it to meta lhs for now (Pablo Neira Ayuso)

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1686
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/expression.c
tests/shell/testcases/nft-f/dumps/named_set_as_protocol_dep.json-nft [new file with mode: 0644]
tests/shell/testcases/nft-f/dumps/named_set_as_protocol_dep.nft [new file with mode: 0644]
tests/shell/testcases/nft-f/named_set_as_protocol_dep [new file with mode: 0755]

index 413f446772bbbfa2f8af04e53db1f039f09cd088..156a66eb37f01fb120029b2cbd90c37151899184 100644 (file)
@@ -945,6 +945,17 @@ void relational_expr_pctx_update(struct proto_ctx *ctx,
                                    i->key->etype == EXPR_VALUE)
                                        ops->pctx_update(ctx, &expr->location, left, i->key);
                        }
+               } else if (ops == &meta_expr_ops &&
+                          right->etype == EXPR_SET_REF) {
+                       const struct expr *key = right->set->key;
+                       struct expr *tmp;
+
+                       tmp = constant_expr_alloc(&expr->location, key->dtype,
+                                                 key->byteorder, key->len,
+                                                 NULL);
+
+                       ops->pctx_update(ctx, &expr->location, left, tmp);
+                       expr_free(tmp);
                }
        }
 }
diff --git a/tests/shell/testcases/nft-f/dumps/named_set_as_protocol_dep.json-nft b/tests/shell/testcases/nft-f/dumps/named_set_as_protocol_dep.json-nft
new file mode 100644 (file)
index 0000000..4bc24aa
--- /dev/null
@@ -0,0 +1,75 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "inet",
+        "name": "test",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "inet",
+        "table": "test",
+        "name": "prerouting",
+        "handle": 0,
+        "type": "filter",
+        "hook": "prerouting",
+        "prio": -150,
+        "policy": "accept"
+      }
+    },
+    {
+      "set": {
+        "family": "inet",
+        "name": "protos",
+        "table": "test",
+        "type": {
+          "typeof": {
+            "meta": {
+              "key": "l4proto"
+            }
+          }
+        },
+        "handle": 0,
+        "elem": [
+          "tcp",
+          "udp"
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "test",
+        "chain": "prerouting",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "@protos"
+            }
+          },
+          {
+            "tproxy": {
+              "port": 1088
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/nft-f/dumps/named_set_as_protocol_dep.nft b/tests/shell/testcases/nft-f/dumps/named_set_as_protocol_dep.nft
new file mode 100644 (file)
index 0000000..2bc0c2a
--- /dev/null
@@ -0,0 +1,11 @@
+table inet test {
+       set protos {
+               typeof meta l4proto
+               elements = { tcp, udp }
+       }
+
+       chain prerouting {
+               type filter hook prerouting priority mangle; policy accept;
+               meta l4proto @protos tproxy to :1088
+       }
+}
diff --git a/tests/shell/testcases/nft-f/named_set_as_protocol_dep b/tests/shell/testcases/nft-f/named_set_as_protocol_dep
new file mode 100755 (executable)
index 0000000..5c516e4
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+dumpfile=$(dirname $0)/dumps/$(basename $0).nft
+
+$NFT -f "$dumpfile" || exit 1