From: Pablo Neira Ayuso Date: Fri, 5 Jul 2024 12:03:33 +0000 (+0200) Subject: optimize: clone counter before insertion into set element X-Git-Tag: v1.0.6.1~195 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d96eee7e3f53a178de21b1f9d44857f11995d653;p=thirdparty%2Fnftables.git optimize: clone counter before insertion into set element commit ac77f3805c71f14c51730a9c5cb726ee67f14159 upstream. The counter statement that is zapped from the rule needs to be cloned before inserting it into each set element. Fixes: 686ab8b6996e ("optimize: do not remove counter in verdict maps") Signed-off-by: Pablo Neira Ayuso --- diff --git a/src/optimize.c b/src/optimize.c index f7546fd1..5aee74b7 100644 --- a/src/optimize.c +++ b/src/optimize.c @@ -691,29 +691,36 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict, struct expr *set, struct stmt *counter) { struct expr *item, *elem, *mapping; + struct stmt *counter_elem; switch (expr->etype) { case EXPR_LIST: list_for_each_entry(item, &expr->expressions, list) { elem = set_elem_expr_alloc(&internal_location, expr_get(item)); - if (counter) - list_add_tail(&counter->list, &elem->stmt_list); + if (counter) { + counter_elem = counter_stmt_alloc(&counter->location); + list_add_tail(&counter_elem->list, &elem->stmt_list); + } mapping = mapping_expr_alloc(&internal_location, elem, expr_get(verdict->expr)); compound_expr_add(set, mapping); } + stmt_free(counter); break; case EXPR_SET: list_for_each_entry(item, &expr->expressions, list) { elem = set_elem_expr_alloc(&internal_location, expr_get(item->key)); - if (counter) - list_add_tail(&counter->list, &elem->stmt_list); + if (counter) { + counter_elem = counter_stmt_alloc(&counter->location); + list_add_tail(&counter_elem->list, &elem->stmt_list); + } mapping = mapping_expr_alloc(&internal_location, elem, expr_get(verdict->expr)); compound_expr_add(set, mapping); } + stmt_free(counter); break; case EXPR_PREFIX: case EXPR_RANGE: @@ -818,8 +825,8 @@ static void __merge_concat_stmts_vmap(const struct optimize_ctx *ctx, struct expr *set, struct stmt *verdict) { struct expr *concat, *next, *elem, *mapping; + struct stmt *counter, *counter_elem; LIST_HEAD(concat_list); - struct stmt *counter; counter = zap_counter(ctx, i); __merge_concat(ctx, i, merge, &concat_list); @@ -827,13 +834,16 @@ static void __merge_concat_stmts_vmap(const struct optimize_ctx *ctx, list_for_each_entry_safe(concat, next, &concat_list, list) { list_del(&concat->list); elem = set_elem_expr_alloc(&internal_location, concat); - if (counter) - list_add_tail(&counter->list, &elem->stmt_list); + if (counter) { + counter_elem = counter_stmt_alloc(&counter->location); + list_add_tail(&counter_elem->list, &elem->stmt_list); + } mapping = mapping_expr_alloc(&internal_location, elem, expr_get(verdict->expr)); compound_expr_add(set, mapping); } + stmt_free(counter); } static void merge_concat_stmts_vmap(const struct optimize_ctx *ctx, diff --git a/tests/shell/testcases/optimizations/dumps/merge_counter.nft b/tests/shell/testcases/optimizations/dumps/merge_counter.nft new file mode 100644 index 00000000..72eed5d0 --- /dev/null +++ b/tests/shell/testcases/optimizations/dumps/merge_counter.nft @@ -0,0 +1,8 @@ +table ip x { + chain y { + type filter hook input priority filter; policy drop; + ct state vmap { invalid counter packets 0 bytes 0 : drop, established counter packets 0 bytes 0 : accept, related counter packets 0 bytes 0 : accept } + tcp dport { 80, 123 } counter packets 0 bytes 0 accept + ip saddr . ip daddr vmap { 1.1.1.1 . 2.2.2.2 counter packets 0 bytes 0 : accept, 1.1.1.2 . 3.3.3.3 counter packets 0 bytes 0 : drop } + } +} diff --git a/tests/shell/testcases/optimizations/merge_counter b/tests/shell/testcases/optimizations/merge_counter new file mode 100755 index 00000000..3b8bbadd --- /dev/null +++ b/tests/shell/testcases/optimizations/merge_counter @@ -0,0 +1,20 @@ +#!/bin/bash + +# NFT_TEST_REQUIRES(NFT_TEST_HAVE_set_expr) + +set -e + +RULESET="table ip x { + chain y { + type filter hook input priority 0; policy drop; + + ct state invalid counter drop + ct state established,related counter accept + tcp dport 80 counter accept + tcp dport 123 counter accept + ip saddr 1.1.1.1 ip daddr 2.2.2.2 counter accept + ip saddr 1.1.1.2 ip daddr 3.3.3.3 counter drop + } +}" + +$NFT -o -f - <<< $RULESET