diff options
author | Jeremy Sowden <jeremy@azazel.net> | 2024-04-29 20:27:53 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2024-05-20 13:37:54 +0200 |
commit | c6127ff0c4480ccefc5c29548409898fb315a2ca (patch) | |
tree | d1c13d8ac36a6013a26dfd80a93608766fefce26 /src/evaluate.c | |
parent | 52a7af9bec15a4fb4bfea86e40b70f96098f7dfd (diff) |
evaluate: add support for variables in map expressions
It is possible to use a variable to initialize a map, which is then used
in a map statement:
define dst_map = { ::1234 : 5678 }
table ip6 nat {
map dst_map {
typeof ip6 daddr : tcp dport;
elements = $dst_map
}
chain prerouting {
ip6 nexthdr tcp redirect to ip6 daddr map @dst_map
}
}
However, if one tries to use the variable directly in the statement:
define dst_map = { ::1234 : 5678 }
table ip6 nat {
chain prerouting {
ip6 nexthdr tcp redirect to ip6 daddr map $dst_map
}
}
nft rejects it:
/space/azazel/tmp/ruleset.1067161.nft:5:47-54: Error: invalid mapping expression variable
ip6 nexthdr tcp redirect to ip6 daddr map $dst_map
~~~~~~~~~ ^^^^^^^^
It also rejects variables in stateful object statements:
define quota_map = { 192.168.10.123 : "user123", 192.168.10.124 : "user124" }
table ip nat {
quota user123 { over 20 mbytes }
quota user124 { over 20 mbytes }
chain prerouting {
quota name ip saddr map $quota_map
}
}
thus:
/space/azazel/tmp/ruleset.1067161.nft:15:29-38: Error: invalid mapping expression variable
quota name ip saddr map $quota_map
~~~~~~~~ ^^^^^^^^^^
Add support for these uses together with some test-cases.
Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1067161
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index f28ef2aa..f26bc7f9 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -2061,6 +2061,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) mappings->set_flags |= NFT_SET_MAP; switch (map->mappings->etype) { + case EXPR_VARIABLE: case EXPR_SET: if (ctx->ectx.key && ctx->ectx.key->etype == EXPR_CONCAT) { key = expr_clone(ctx->ectx.key); @@ -2104,6 +2105,11 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) if (expr_evaluate(ctx, &map->mappings->set->init) < 0) return -1; + if (map->mappings->set->init->etype != EXPR_SET) { + return expr_error(ctx->msgs, map->mappings->set->init, + "Expression is not a map"); + } + if (set_is_interval(map->mappings->set->init->set_flags) && !(map->mappings->set->init->set_flags & NFT_SET_CONCAT) && interval_set_eval(ctx, ctx->set, map->mappings->set->init) < 0) @@ -4576,6 +4582,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) mappings->set_flags |= NFT_SET_OBJECT; switch (map->mappings->etype) { + case EXPR_VARIABLE: case EXPR_SET: key = constant_expr_alloc(&stmt->location, ctx->ectx.dtype, @@ -4595,6 +4602,11 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) if (expr_evaluate(ctx, &map->mappings->set->init) < 0) return -1; + if (map->mappings->set->init->etype != EXPR_SET) { + return expr_error(ctx->msgs, map->mappings->set->init, + "Expression is not a map"); + } + if (set_is_interval(map->mappings->set->init->set_flags) && !(map->mappings->set->init->set_flags & NFT_SET_CONCAT) && interval_set_eval(ctx, ctx->set, map->mappings->set->init) < 0) |