]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
optimize: only merge OP_IMPLICIT and OP_EQ relational
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 17 Jun 2022 16:17:49 +0000 (18:17 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 23 Jun 2022 17:00:02 +0000 (19:00 +0200)
Add test to cover this case.

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

index e3d4bc785226640ed2f5215bf8de66061ab2218c..e4508fa5116a96f61ec55de0e32674027b15c404 100644 (file)
@@ -164,6 +164,11 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
                expr_a = stmt_a->expr;
                expr_b = stmt_b->expr;
 
+               if (expr_a->op != expr_b->op)
+                       return false;
+               if (expr_a->op != OP_IMPLICIT && expr_a->op != OP_EQ)
+                       return false;
+
                if (fully_compare) {
                        if (!stmt_expr_supported(expr_a) ||
                            !stmt_expr_supported(expr_b))
@@ -351,6 +356,11 @@ static int rule_collect_stmts(struct optimize_ctx *ctx, struct rule *rule)
                clone = stmt_alloc(&internal_location, stmt->ops);
                switch (stmt->ops->type) {
                case STMT_EXPRESSION:
+                       if (stmt->expr->op != OP_IMPLICIT &&
+                           stmt->expr->op != OP_EQ) {
+                               clone->ops = &unsupported_stmt_ops;
+                               break;
+                       }
                case STMT_VERDICT:
                        clone->expr = expr_get(stmt->expr);
                        break;
diff --git a/tests/shell/testcases/optimizations/dumps/skip_non_eq.nft b/tests/shell/testcases/optimizations/dumps/skip_non_eq.nft
new file mode 100644 (file)
index 0000000..6df3865
--- /dev/null
@@ -0,0 +1,6 @@
+table inet x {
+       chain y {
+               iifname "eth0" oifname != "eth0" counter packets 0 bytes 0 accept
+               iifname "eth0" oifname "eth0" counter packets 0 bytes 0 accept
+       }
+}
diff --git a/tests/shell/testcases/optimizations/skip_non_eq b/tests/shell/testcases/optimizations/skip_non_eq
new file mode 100755 (executable)
index 0000000..431ed0a
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet x {
+       chain y {
+               iifname "eth0" oifname != "eth0" counter packets 0 bytes 0 accept
+               iifname "eth0" oifname "eth0" counter packets 0 bytes 0 accept
+       }
+}"
+
+$NFT -o -f - <<< $RULESET