From bd51f04f73bd585f6e3f9ed82a5db7d9640198b8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 16 Jun 2021 19:00:50 +0200 Subject: 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 --- src/evaluate.c | 26 +++++++++++++++++++------- 1 file 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; } } -- cgit v1.2.3