summaryrefslogtreecommitdiffstats
path: root/src/expression.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2022-01-02 21:54:01 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2022-01-15 18:11:22 +0100
commit345d9260f7fe8ba62fd1700489a1d78cd533f59d (patch)
treee68f0773c3b04e389eb7bdf202fb68dc6d1497d4 /src/expression.c
parent1542082e259b4a9270e0726904796730a5c310d6 (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.c30
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);
}