diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-01-02 21:54:01 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-01-15 18:11:22 +0100 |
commit | 345d9260f7fe8ba62fd1700489a1d78cd533f59d (patch) | |
tree | e68f0773c3b04e389eb7bdf202fb68dc6d1497d4 /src/expression.c | |
parent | 1542082e259b4a9270e0726904796730a5c310d6 (diff) |
optimize: merge several selectors with different verdict into verdict map
Transform:
ip saddr 1.1.1.1 ip daddr 2.2.2.2 accept
ip saddr 2.2.2.2 ip daddr 3.3.3.3 drop
into:
ip saddr . ip daddr vmap { 1.1.1.1 . 2.2.2.2 : accept, 2.2.2.2 . 3.3.3.3 : drop }
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/expression.c')
-rw-r--r-- | src/expression.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/expression.c b/src/expression.c index 34e0880b..ea999f2e 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1185,14 +1185,40 @@ struct expr *mapping_expr_alloc(const struct location *loc, return expr; } +static bool __set_expr_is_vmap(const struct expr *mappings) +{ + const struct expr *mapping; + + if (list_empty(&mappings->expressions)) + return false; + + mapping = list_first_entry(&mappings->expressions, struct expr, list); + if (mapping->etype == EXPR_MAPPING && + mapping->right->etype == EXPR_VERDICT) + return true; + + return false; +} + +static bool set_expr_is_vmap(const struct expr *expr) +{ + + if (expr->mappings->etype == EXPR_SET) + return __set_expr_is_vmap(expr->mappings); + + return false; +} + static void map_expr_print(const struct expr *expr, struct output_ctx *octx) { expr_print(expr->map, octx); - if (expr->mappings->etype == EXPR_SET_REF && - expr->mappings->set->data->dtype->type == TYPE_VERDICT) + if ((expr->mappings->etype == EXPR_SET_REF && + expr->mappings->set->data->dtype->type == TYPE_VERDICT) || + set_expr_is_vmap(expr)) nft_print(octx, " vmap "); else nft_print(octx, " map "); + expr_print(expr->mappings, octx); } |