[PATCH nftables] evaluate: add support for variables in map expressions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It is possible to use a variable to initialize a map, which is then used in a
map statement:

  define m = { ::1234 : 5678 }

  table ip6 nat {
    map m {
      typeof ip6 daddr : tcp dport;
      elements = $m
    }
    chain prerouting {
      ip6 nexthdr tcp redirect to ip6 daddr map @m
    }
  }

However, if one tries to use the variable directly in the statement:

  define m = { ::1234 : 5678 }

  table ip6 nat {
    chain prerouting {
      ip6 nexthdr tcp redirect to ip6 daddr map $m
    }
  }

nft rejects it:

  /space/azazel/tmp/ruleset.1067161.nft:5:47-48: Error: invalid mapping expression variable
      ip6 nexthdr tcp redirect to ip6 daddr map $m
                                  ~~~~~~~~~     ^^

Extend `expr_evaluate_map` to allow it.

Add a test-case.

Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1067161
Signed-off-by: Jeremy Sowden <jeremy@xxxxxxxxxx>
---
 src/evaluate.c                                |  1 +
 .../shell/testcases/maps/anonymous_snat_map_1 | 16 +++++
 .../maps/dumps/anonymous_snat_map_1.json-nft  | 58 +++++++++++++++++++
 .../maps/dumps/anonymous_snat_map_1.nft       |  5 ++
 4 files changed, 80 insertions(+)
 create mode 100755 tests/shell/testcases/maps/anonymous_snat_map_1
 create mode 100644 tests/shell/testcases/maps/dumps/anonymous_snat_map_1.json-nft
 create mode 100644 tests/shell/testcases/maps/dumps/anonymous_snat_map_1.nft

diff --git a/src/evaluate.c b/src/evaluate.c
index 1682ba58989e..d49213f8d6bd 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2061,6 +2061,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
 	mappings->set_flags |= NFT_SET_MAP;
 
 	switch (map->mappings->etype) {
+	case EXPR_VARIABLE:
 	case EXPR_SET:
 		if (ctx->ectx.key && ctx->ectx.key->etype == EXPR_CONCAT) {
 			key = expr_clone(ctx->ectx.key);
diff --git a/tests/shell/testcases/maps/anonymous_snat_map_1 b/tests/shell/testcases/maps/anonymous_snat_map_1
new file mode 100755
index 000000000000..031de0c1a83f
--- /dev/null
+++ b/tests/shell/testcases/maps/anonymous_snat_map_1
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# Variable containing anonymous map can be added to a snat rule
+
+set -e
+
+RULESET='
+define m = {1.1.1.1 : 2.2.2.2}
+table nat {
+  chain postrouting {
+    snat ip saddr map $m
+  }
+}
+'
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/maps/dumps/anonymous_snat_map_1.json-nft b/tests/shell/testcases/maps/dumps/anonymous_snat_map_1.json-nft
new file mode 100644
index 000000000000..f4c55706787c
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/anonymous_snat_map_1.json-nft
@@ -0,0 +1,58 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "nat",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "nat",
+        "name": "postrouting",
+        "handle": 0
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "nat",
+        "chain": "postrouting",
+        "handle": 0,
+        "expr": [
+          {
+            "snat": {
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "saddr"
+                    }
+                  },
+                  "data": {
+                    "set": [
+                      [
+                        "1.1.1.1",
+                        "2.2.2.2"
+                      ]
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/anonymous_snat_map_1.nft b/tests/shell/testcases/maps/dumps/anonymous_snat_map_1.nft
new file mode 100644
index 000000000000..5009560c9d69
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/anonymous_snat_map_1.nft
@@ -0,0 +1,5 @@
+table ip nat {
+	chain postrouting {
+		snat to ip saddr map { 1.1.1.1 : 2.2.2.2 }
+	}
+}
-- 
2.43.0





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux