Rules that are equal need to have at least one mergeable statement. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- src/optimize.c | 28 ++++++++++++++++++- .../optimizations/dumps/not_mergeable.nft | 12 ++++++++ .../testcases/optimizations/not_mergeable | 16 +++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/shell/testcases/optimizations/dumps/not_mergeable.nft create mode 100755 tests/shell/testcases/optimizations/not_mergeable diff --git a/src/optimize.c b/src/optimize.c index 419a37f2bb20..ea067f80bce0 100644 --- a/src/optimize.c +++ b/src/optimize.c @@ -1011,15 +1011,41 @@ static bool stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b) return __stmt_type_eq(stmt_a, stmt_b, true); } +static bool stmt_is_mergeable(const struct stmt *stmt) +{ + if (!stmt) + return false; + + switch (stmt->ops->type) { + case STMT_VERDICT: + if (stmt->expr->etype == EXPR_MAP) + return true; + break; + case STMT_EXPRESSION: + case STMT_NAT: + return true; + default: + break; + } + + return false; +} + static bool rules_eq(const struct optimize_ctx *ctx, int i, int j) { - uint32_t k; + uint32_t k, mergeable = 0; for (k = 0; k < ctx->num_stmts; k++) { + if (stmt_is_mergeable(ctx->stmt_matrix[i][k])) + mergeable++; + if (!stmt_type_eq(ctx->stmt_matrix[i][k], ctx->stmt_matrix[j][k])) return false; } + if (mergeable == 0) + return false; + return true; } diff --git a/tests/shell/testcases/optimizations/dumps/not_mergeable.nft b/tests/shell/testcases/optimizations/dumps/not_mergeable.nft new file mode 100644 index 000000000000..08b2b58f66c3 --- /dev/null +++ b/tests/shell/testcases/optimizations/dumps/not_mergeable.nft @@ -0,0 +1,12 @@ +table ip x { + chain t1 { + } + + chain t2 { + } + + chain y { + counter packets 0 bytes 0 jump t1 + counter packets 0 bytes 0 jump t2 + } +} diff --git a/tests/shell/testcases/optimizations/not_mergeable b/tests/shell/testcases/optimizations/not_mergeable new file mode 100755 index 000000000000..25635cdd653d --- /dev/null +++ b/tests/shell/testcases/optimizations/not_mergeable @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +RULESET="table ip x { + chain t1 { + } + chain t2 { + } + chain y { + counter jump t1 + counter jump t2 + } +}" + +$NFT -o -f - <<< $RULESET -- 2.30.2