summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2025-10-22 14:03:37 +0200
committerPhil Sutter <phil@nwl.cc>2025-10-23 22:48:50 +0200
commit695ee5a8b174f86e2e64786530147e56d8d27f19 (patch)
tree4e4996ca303600d42236108b2be66078a98382ed /src
parentaec699af2a006b1dd6580abb95910c402e306fa9 (diff)
optimize: Fix verdict expression comparison
In verdict expression, 'chain' points at a constant expression of verdict_type, not a symbol expression. Therefore 'chain->identifier' points eight bytes (on 64bit systems) into the mpz_t 'value' holding the chain name. This matches the '_mp_d' data pointer, so works by accident. Fix this by copying what verdict_jump_chain_print() does and export chain names before comparing. Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure") Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'src')
-rw-r--r--src/optimize.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/optimize.c b/src/optimize.c
index cdd6913a..ffc06480 100644
--- a/src/optimize.c
+++ b/src/optimize.c
@@ -341,13 +341,18 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
static bool expr_verdict_eq(const struct expr *expr_a, const struct expr *expr_b)
{
+ char chain_a[NFT_CHAIN_MAXNAMELEN];
+ char chain_b[NFT_CHAIN_MAXNAMELEN];
+
if (expr_a->verdict != expr_b->verdict)
return false;
if (expr_a->chain && expr_b->chain) {
- if (expr_a->chain->etype != expr_b->chain->etype)
+ if (expr_a->chain->etype != EXPR_VALUE ||
+ expr_a->chain->etype != expr_b->chain->etype)
return false;
- if (expr_a->chain->etype == EXPR_VALUE &&
- strcmp(expr_a->chain->identifier, expr_b->chain->identifier))
+ expr_chain_export(expr_a->chain, chain_a);
+ expr_chain_export(expr_b->chain, chain_b);
+ if (strcmp(chain_a, chain_b))
return false;
} else if (expr_a->chain || expr_b->chain) {
return false;