This patch extends the ruleset optimization infrastructure to collapse several rules with the same selectors into a concatenation. Transform: meta iifname eth1 ip saddr 1.1.1.1 ip daddr 2.2.2.3 accept meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.2.5 accept meta iifname eth2 ip saddr 1.1.1.3 ip daddr 2.2.2.6 accept into: meta iifname . ip saddr . ip daddr { eth1 . 1.1.1.1 . 2.2.2.6, eth1 . 1.1.1.2 . 2.2.2.5 , eth1 . 1.1.1.3 . 2.2.2.6 } accept Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- src/optimize.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/optimize.c b/src/optimize.c index c30000bd2397..279eabb02152 100644 --- a/src/optimize.c +++ b/src/optimize.c @@ -217,6 +217,47 @@ static void merge_stmts(const struct optimize_ctx *ctx, stmt_a->expr->right = set; } +static void merge_multi_stmts(const struct optimize_ctx *ctx, + uint32_t from, uint32_t to, + const struct merge *merge) +{ + struct expr *concat, *expr, *elem; + struct stmt *stmt, *stmt_a; + uint32_t i, k; + + stmt = ctx->stmt_matrix[from][merge->stmt[0]]; + /* build concatenation of selectors, eg. ifname . ip daddr . tcp dport */ + concat = concat_expr_alloc(&internal_location); + + for (k = 0; k < merge->num_stmts; k++) { + stmt_a = ctx->stmt_matrix[from][merge->stmt[k]]; + compound_expr_add(concat, expr_get(stmt_a->expr->left)); + } + expr_free(stmt->expr->left); + stmt->expr->left = concat; + + /* build set data contenation, eg. { eth0 . 1.1.1.1 . 22 } */ + expr = set_expr_alloc(&internal_location, NULL); + + for (i = from; i <= to; i++) { + concat = concat_expr_alloc(&internal_location); + for (k = 0; k < merge->num_stmts; k++) { + stmt_a = ctx->stmt_matrix[i][merge->stmt[k]]; + compound_expr_add(concat, expr_get(stmt_a->expr->right)); + } + elem = set_elem_expr_alloc(&internal_location, concat); + compound_expr_add(expr, elem); + } + expr_free(stmt->expr->right); + stmt->expr->right = expr; + + for (k = 1; k < merge->num_stmts; k++) { + stmt_a = ctx->stmt_matrix[from][merge->stmt[k]]; + list_del(&stmt_a->list); + stmt_free(stmt_a); + } +} + static void merge_rules(const struct optimize_ctx *ctx, uint32_t from, uint32_t to, const struct merge *merge) @@ -224,7 +265,7 @@ static void merge_rules(const struct optimize_ctx *ctx, uint32_t x; if (merge->num_stmts > 1) { - return; + merge_multi_stmts(ctx, from, to, merge); } else { merge_stmts(ctx, from, to, merge); } -- 2.30.2