diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-06-16 19:00:50 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-06-18 09:40:20 +0200 |
commit | bd51f04f73bd585f6e3f9ed82a5db7d9640198b8 (patch) | |
tree | 04e6a6d2bee131653192f1e6fd88e4b54d33dd93 | |
parent | 623f595e484783e08e292eb54745995e109487f0 (diff) |
evaluate: do not skip mapping elements
Set element keys are of EXPR_SET_ELEM expression type, however, mappings
use the EXPR_MAPPING expression to wrap the EXPR_SET_ELEM key
(mapping->left) and the corresponding data (mapping->right).
This patch adds a wrapper function to fetch the EXPR_SET_ELEM expression
from the key in case of mappings and use it.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | src/evaluate.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index aa7ec9be..d220c8e3 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1414,27 +1414,39 @@ static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr) return 0; } +static const struct expr *expr_set_elem(const struct expr *expr) +{ + if (expr->etype == EXPR_MAPPING) + return expr->left; + + return expr; +} + static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) { struct expr *set = *expr, *i, *next; + const struct expr *elem; list_for_each_entry_safe(i, next, &set->expressions, list) { if (list_member_evaluate(ctx, &i) < 0) return -1; - if (i->etype == EXPR_SET_ELEM && - i->key->etype == EXPR_SET_REF) + elem = expr_set_elem(i); + + if (elem->etype == EXPR_SET_ELEM && + elem->key->etype == EXPR_SET_REF) return expr_error(ctx->msgs, i, "Set reference cannot be part of another set"); - if (i->etype == EXPR_SET_ELEM && - i->key->etype == EXPR_SET) { - struct expr *new = expr_clone(i->key); + if (elem->etype == EXPR_SET_ELEM && + elem->key->etype == EXPR_SET) { + struct expr *new = expr_clone(elem->key); - set->set_flags |= i->key->set_flags; + set->set_flags |= elem->key->set_flags; list_replace(&i->list, &new->list); expr_free(i); i = new; + elem = expr_set_elem(i); } if (!expr_is_constant(i)) @@ -1450,7 +1462,7 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) expr_free(i); } else if (!expr_is_singleton(i)) { set->set_flags |= NFT_SET_INTERVAL; - if (i->key->etype == EXPR_CONCAT) + if (elem->key->etype == EXPR_CONCAT) set->set_flags |= NFT_SET_CONCAT; } } |