diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-07-16 14:36:28 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-07-21 14:20:18 +0200 |
commit | d100e2d811749bf34bb6aeac322052c56661c124 (patch) | |
tree | 4644bbd66ca3056917de47c012c87e9fa1a5c2b0 /src/evaluate.c | |
parent | bde991a2e8fe012c65895a5bac8bd9ccb22ffbc4 (diff) |
src: allow to use variables in flowtable and chain devices
This patch adds support for using variables for devices in the chain and
flowtable definitions, eg.
define if_main = lo
table netdev filter1 {
chain Main_Ingress1 {
type filter hook ingress device $if_main priority -500; policy accept;
}
}
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 67eb5d60..c9601f17 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -3719,6 +3719,69 @@ static bool evaluate_priority(struct eval_ctx *ctx, struct prio_spec *prio, return true; } +static bool evaluate_expr_variable(struct eval_ctx *ctx, struct expr **exprp) +{ + struct expr *expr; + + if (expr_evaluate(ctx, exprp) < 0) + return false; + + expr = *exprp; + if (expr->etype != EXPR_VALUE && + expr->etype != EXPR_SET) { + expr_error(ctx->msgs, expr, "%s is not a valid " + "variable expression", expr_name(expr)); + return false; + } + + return true; +} + +static bool evaluate_device_expr(struct eval_ctx *ctx, struct expr **dev_expr) +{ + struct expr *expr, *next, *key; + LIST_HEAD(tmp); + + if ((*dev_expr)->etype == EXPR_VARIABLE) { + expr_set_context(&ctx->ectx, &ifname_type, + IFNAMSIZ * BITS_PER_BYTE); + if (!evaluate_expr_variable(ctx, dev_expr)) + return false; + } + + if ((*dev_expr)->etype != EXPR_SET && + (*dev_expr)->etype != EXPR_LIST) + return true; + + list_for_each_entry_safe(expr, next, &(*dev_expr)->expressions, list) { + list_del(&expr->list); + + switch (expr->etype) { + case EXPR_VARIABLE: + expr_set_context(&ctx->ectx, &ifname_type, + IFNAMSIZ * BITS_PER_BYTE); + if (!evaluate_expr_variable(ctx, &expr)) + return false; + break; + case EXPR_SET_ELEM: + key = expr_clone(expr->key); + expr_free(expr); + expr = key; + break; + case EXPR_VALUE: + break; + default: + BUG("invalid expresion type %s\n", expr_name(expr)); + break; + } + + list_add(&expr->list, &tmp); + } + list_splice_init(&tmp, &(*dev_expr)->expressions); + + return true; +} + static uint32_t str2hooknum(uint32_t family, const char *hook); static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft) @@ -3740,6 +3803,9 @@ static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft) expr_name(ft->priority.expr)); } + if (ft->dev_expr && !evaluate_device_expr(ctx, &ft->dev_expr)) + return -1; + return 0; } @@ -3965,6 +4031,9 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain) if (!chain->dev_expr) return __stmt_binary_error(ctx, &chain->loc, NULL, "Missing `device' in this chain definition"); + + if (!evaluate_device_expr(ctx, &chain->dev_expr)) + return -1; } else if (chain->dev_expr) { return __stmt_binary_error(ctx, &chain->dev_expr->location, NULL, "This chain type cannot be bound to device"); |