]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
optimize: fix reject statement
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 17 Jun 2022 15:28:00 +0000 (17:28 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 23 Jun 2022 17:00:02 +0000 (19:00 +0200)
Add missing code to the statement collection routine. Compare reject
expressions when available. Add tests/shell.

Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/optimize.c
tests/shell/testcases/optimizations/dumps/merge_reject.nft [new file with mode: 0644]
tests/shell/testcases/optimizations/merge_reject [new file with mode: 0755]

index 94242ee5f490d9aee5801f997a65dfe098b8a550..4276258464843b84e386a2fc236f6674b595268c 100644 (file)
@@ -178,13 +178,19 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
                        return false;
                break;
        case STMT_REJECT:
-               if (stmt_a->reject.expr || stmt_b->reject.expr)
-                       return false;
-
                if (stmt_a->reject.family != stmt_b->reject.family ||
                    stmt_a->reject.type != stmt_b->reject.type ||
                    stmt_a->reject.icmp_code != stmt_b->reject.icmp_code)
                        return false;
+
+               if (!!stmt_a->reject.expr ^ !!stmt_b->reject.expr)
+                       return false;
+
+               if (!stmt_a->reject.expr)
+                       return true;
+
+               if (__expr_cmp(stmt_a->reject.expr, stmt_b->reject.expr))
+                       return false;
                break;
        case STMT_NAT:
                if (stmt_a->nat.type != stmt_b->nat.type ||
@@ -304,6 +310,13 @@ static int rule_collect_stmts(struct optimize_ctx *ctx, struct rule *rule)
                        clone->nat.flags = stmt->nat.flags;
                        clone->nat.type_flags = stmt->nat.type_flags;
                        break;
+               case STMT_REJECT:
+                       if (stmt->reject.expr)
+                               clone->reject.expr = expr_get(stmt->reject.expr);
+                       clone->reject.type = stmt->reject.type;
+                       clone->reject.icmp_code = stmt->reject.icmp_code;
+                       clone->reject.family = stmt->reject.family;
+                       break;
                default:
                        xfree(clone);
                        continue;
diff --git a/tests/shell/testcases/optimizations/dumps/merge_reject.nft b/tests/shell/testcases/optimizations/dumps/merge_reject.nft
new file mode 100644 (file)
index 0000000..9a13e2b
--- /dev/null
@@ -0,0 +1,7 @@
+table ip x {
+       chain y {
+               ip daddr 172.30.33.70 tcp dport 3306 counter packets 0 bytes 0 drop
+               meta l4proto . ip daddr . tcp dport { tcp . 172.30.238.117 . 8080, tcp . 172.30.33.71 . 3306, tcp . 172.30.254.251 . 3306 } counter packets 0 bytes 0 reject
+               ip daddr 172.30.254.252 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
+       }
+}
diff --git a/tests/shell/testcases/optimizations/merge_reject b/tests/shell/testcases/optimizations/merge_reject
new file mode 100755 (executable)
index 0000000..497e8f6
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table ip x {
+       chain y {
+               meta l4proto tcp ip daddr 172.30.33.70 tcp dport 3306 counter packets 0 bytes 0 drop
+               meta l4proto tcp ip daddr 172.30.33.71 tcp dport 3306 counter packets 0 bytes 0 reject
+               meta l4proto tcp ip daddr 172.30.238.117 tcp dport 8080 counter packets 0 bytes 0 reject
+               meta l4proto tcp ip daddr 172.30.254.251 tcp dport 3306 counter packets 0 bytes 0 reject
+               meta l4proto tcp ip daddr 172.30.254.252 tcp dport 3306 counter packets 0 bytes 0 reject with tcp reset
+       }
+}"
+
+$NFT -o -f - <<< $RULESET