]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
optimize: select merge criteria based on candidates rules
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 6 Feb 2023 13:18:10 +0000 (14:18 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 6 Feb 2023 16:52:39 +0000 (17:52 +0100)
Select the merge criteria based on the statements that are used
in the candidate rules, instead of using the list of statements
in the given chain.

Update tests to include a rule with a verdict, which triggers
the bug described in the bugzilla ticket.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1657
Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/optimize.c
tests/shell/testcases/optimizations/dumps/merge_nat.nft
tests/shell/testcases/optimizations/merge_nat

index 5f6e3a64fdd3c4541bd467922d90bca076d87a73..ff4f26278a6d4f1b97d019df10dc0b14ae97c6ea 100644 (file)
@@ -985,21 +985,21 @@ static void rule_optimize_print(struct output_ctx *octx,
        fprintf(octx->error_fp, "%s\n", line);
 }
 
-static enum stmt_types merge_stmt_type(const struct optimize_ctx *ctx)
+static enum stmt_types merge_stmt_type(const struct optimize_ctx *ctx,
+                                      uint32_t from, uint32_t to)
 {
-       uint32_t i;
+       uint32_t i, j;
 
-       for (i = 0; i < ctx->num_stmts; i++) {
-               switch (ctx->stmt[i]->ops->type) {
-               case STMT_VERDICT:
-               case STMT_NAT:
-                       return ctx->stmt[i]->ops->type;
-               default:
-                       continue;
+       for (i = from; i <= to; i++) {
+               for (j = 0; j < ctx->num_stmts; j++) {
+                       if (!ctx->stmt_matrix[i][j])
+                               continue;
+                       if (ctx->stmt_matrix[i][j]->ops->type == STMT_NAT)
+                               return STMT_NAT;
                }
        }
 
-       /* actually no verdict, this assumes rules have the same verdict. */
+       /* merge by verdict, even if no verdict is specified. */
        return STMT_VERDICT;
 }
 
@@ -1012,7 +1012,7 @@ static void merge_rules(const struct optimize_ctx *ctx,
        bool same_verdict;
        uint32_t i;
 
-       stmt_type = merge_stmt_type(ctx);
+       stmt_type = merge_stmt_type(ctx, from, to);
 
        switch (stmt_type) {
        case STMT_VERDICT:
index 7a6ecb76a9346abad930c1bf542795e8df22029d..32423b220ed17ce1f8c1ebcb2f5bd57904b2b73b 100644 (file)
@@ -1,20 +1,24 @@
 table ip test1 {
        chain y {
+               oif "lo" accept
                dnat to ip saddr map { 4.4.4.4 : 1.1.1.1, 5.5.5.5 : 2.2.2.2 }
        }
 }
 table ip test2 {
        chain y {
+               oif "lo" accept
                dnat ip to tcp dport map { 80 : 1.1.1.1 . 8001, 81 : 2.2.2.2 . 9001 }
        }
 }
 table ip test3 {
        chain y {
+               oif "lo" accept
                snat to ip saddr . tcp sport map { 1.1.1.1 . 1024-65535 : 3.3.3.3, 2.2.2.2 . 1024-65535 : 4.4.4.4 }
        }
 }
 table ip test4 {
        chain y {
+               oif "lo" accept
                dnat ip to ip daddr . tcp dport map { 1.1.1.1 . 80 : 4.4.4.4 . 8000, 2.2.2.2 . 81 : 3.3.3.3 . 9000 }
        }
 }
index 290cfcfebe2e04122e156f3becdd962314592019..ec9b239c6f487a5f96cdb1620d2aa893323bf3e0 100755 (executable)
@@ -4,6 +4,7 @@ set -e
 
 RULESET="table ip test1 {
         chain y {
+                oif lo accept
                 ip saddr 4.4.4.4 dnat to 1.1.1.1
                 ip saddr 5.5.5.5 dnat to 2.2.2.2
         }
@@ -13,6 +14,7 @@ $NFT -o -f - <<< $RULESET
 
 RULESET="table ip test2 {
         chain y {
+                oif lo accept
                 tcp dport 80 dnat to 1.1.1.1:8001
                 tcp dport 81 dnat to 2.2.2.2:9001
         }
@@ -22,6 +24,7 @@ $NFT -o -f - <<< $RULESET
 
 RULESET="table ip test3 {
         chain y {
+                oif lo accept
                 ip saddr 1.1.1.1 tcp sport 1024-65535 snat to 3.3.3.3
                 ip saddr 2.2.2.2 tcp sport 1024-65535 snat to 4.4.4.4
         }
@@ -31,6 +34,7 @@ $NFT -o -f - <<< $RULESET
 
 RULESET="table ip test4 {
         chain y {
+                oif lo accept
                 ip daddr 1.1.1.1 tcp dport 80 dnat to 4.4.4.4:8000
                 ip daddr 2.2.2.2 tcp dport 81 dnat to 3.3.3.3:9000
         }