]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
optimize: do not merge rules with set reference in rhs
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 17 Jun 2022 15:20:26 +0000 (17:20 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 23 Jun 2022 17:00:02 +0000 (19:00 +0200)
Otherwise set reference ends up included in an anonymous set, as an
element, which is not supported.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/optimize.c
tests/shell/testcases/optimizations/dumps/skip_merge.nft [new file with mode: 0644]
tests/shell/testcases/optimizations/skip_merge [new file with mode: 0755]

index a2a4e587e1253ab35b993cf36b21c748da9153ba..543d3ca5a9c7567241b6cc64a393054059fa8670 100644 (file)
@@ -105,6 +105,12 @@ static bool stmt_expr_supported(const struct expr *expr)
        return false;
 }
 
+static bool expr_symbol_set(const struct expr *expr)
+{
+       return expr->right->etype == EXPR_SYMBOL &&
+              expr->right->symtype == SYMBOL_SET;
+}
+
 static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
                           bool fully_compare)
 {
@@ -122,6 +128,10 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
                        if (!stmt_expr_supported(expr_a) ||
                            !stmt_expr_supported(expr_b))
                                return false;
+
+                       if (expr_symbol_set(expr_a) ||
+                           expr_symbol_set(expr_b))
+                               return false;
                }
 
                return __expr_cmp(expr_a->left, expr_b->left);
diff --git a/tests/shell/testcases/optimizations/dumps/skip_merge.nft b/tests/shell/testcases/optimizations/dumps/skip_merge.nft
new file mode 100644 (file)
index 0000000..9c10b74
--- /dev/null
@@ -0,0 +1,23 @@
+table inet filter {
+       set udp_accepted {
+               type inet_service
+               elements = { 500, 4500 }
+       }
+
+       set tcp_accepted {
+               type inet_service
+               elements = { 80, 443 }
+       }
+
+       chain udp_input {
+               udp dport 1-128 accept
+               udp dport @udp_accepted accept
+               udp dport 53 accept
+       }
+
+       chain tcp_input {
+               tcp dport { 1-128, 8888-9999 } accept
+               tcp dport @tcp_accepted accept
+               tcp dport 1024-65535 accept
+       }
+}
diff --git a/tests/shell/testcases/optimizations/skip_merge b/tests/shell/testcases/optimizations/skip_merge
new file mode 100755 (executable)
index 0000000..8af976c
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet filter {
+    set udp_accepted {
+        type inet_service;
+        elements = {
+            isakmp, ipsec-nat-t
+        }
+    }
+
+    set tcp_accepted {
+        type inet_service;
+        elements = {
+            http, https
+        }
+    }
+
+    chain udp_input {
+        udp dport 1-128 accept
+        udp dport @udp_accepted accept
+        udp dport domain accept
+    }
+
+    chain tcp_input {
+        tcp dport 1-128 accept
+        tcp dport 8888-9999 accept
+        tcp dport @tcp_accepted accept
+        tcp dport 1024-65535 accept
+    }
+}"
+
+$NFT -o -f - <<< $RULESET