]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
optimize: more robust statement merge with vmap
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 3 Mar 2022 12:06:59 +0000 (13:06 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 3 Mar 2022 14:54:27 +0000 (15:54 +0100)
Check expressions that are expected on the rhs rather than using a
catch-all default case.

Actually, lists and sets need to be their own routine, because this
needs the set element key expression to be merged.

This is a follow up to 99eb46969f3d ("optimize: fix vmap with anonymous
sets").

Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/optimize.c
tests/shell/testcases/optimizations/dumps/merge_stmts_vmap.nft
tests/shell/testcases/optimizations/merge_stmts_vmap

index 64c0a4dbe76431378508cf30c0ce6284ce4b213c..af075da437f93ad65a25d6905ff097e745ae02e4 100644 (file)
@@ -437,7 +437,6 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict, struct ex
 
        switch (expr->etype) {
        case EXPR_LIST:
-       case EXPR_SET:
                list_for_each_entry(item, &expr->expressions, list) {
                        elem = set_elem_expr_alloc(&internal_location, expr_get(item));
                        mapping = mapping_expr_alloc(&internal_location, elem,
@@ -445,12 +444,27 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict, struct ex
                        compound_expr_add(set, mapping);
                }
                break;
-       default:
+       case EXPR_SET:
+               list_for_each_entry(item, &expr->expressions, list) {
+                       elem = set_elem_expr_alloc(&internal_location, expr_get(item->key));
+                       mapping = mapping_expr_alloc(&internal_location, elem,
+                                                    expr_get(verdict->expr));
+                       compound_expr_add(set, mapping);
+               }
+               break;
+       case EXPR_PREFIX:
+       case EXPR_RANGE:
+       case EXPR_VALUE:
+       case EXPR_SYMBOL:
+       case EXPR_CONCAT:
                elem = set_elem_expr_alloc(&internal_location, expr_get(expr));
                mapping = mapping_expr_alloc(&internal_location, elem,
                                             expr_get(verdict->expr));
                compound_expr_add(set, mapping);
                break;
+       default:
+               assert(0);
+               break;
        }
 }
 
index 427572954a18c8f3eb963486066d59863698dbaa..5a9b3006743b327a2844dbe528cadd552b8e60df 100644 (file)
@@ -4,6 +4,6 @@ table ip x {
        }
 
        chain z {
-               tcp dport vmap { 1 : accept, 2-3 : drop }
+               tcp dport vmap { 1 : accept, 2-3 : drop, 4 : accept }
        }
 }
index 6511c7b20cb60cbdd0021287330cd1d5a0e95cd0..79350076d6c64daf56127170239479e9f2b12ce6 100755 (executable)
@@ -10,6 +10,7 @@ RULESET="table ip x {
        chain z {
                tcp dport { 1 } accept
                tcp dport 2-3 drop
+               tcp dport 4 accept
        }
 }"