Support nested map lookups combined with vmap lookup as shown in the example below. This syntax enables flexibility to use the values of a map as keys for looking up vmap when users have two distinct maps for different purposes and do not want to alter any packet-related objects (e.g., packet mark, ct mark, ip fields) to store the value returned from the first map lookup for the final vmap lookup. Command: add rule ip table-a ip saddr map @map1 vmap @map2 Output: chain table-a { ip saddr map @map1 vmap @map2 } It also supports multiple map lookups prior to vmap if users need to use multiple maps for the same query, such as chain table-a { ip saddr map @map1 map @map2 vmap @map3 } Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1736 Signed-off-by: Son Dinh <dinhtrason@xxxxxxxxx> --- src/evaluate.c | 2 +- src/netlink_delinearize.c | 12 +++++++----- src/parser_bison.y | 8 ++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git src/evaluate.c src/evaluate.c index 1682ba58..07c26d16 100644 --- src/evaluate.c +++ src/evaluate.c @@ -2052,7 +2052,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) expr_set_context(&ctx->ectx, NULL, 0); if (expr_evaluate(ctx, &map->map) < 0) return -1; - if (expr_is_constant(map->map)) + if (map->map->etype != EXPR_MAP && expr_is_constant(map->map)) return expr_error(ctx->msgs, map->map, "Map expression can not be constant"); diff --git src/netlink_delinearize.c src/netlink_delinearize.c index da9f7a91..f8968a25 100644 --- src/netlink_delinearize.c +++ src/netlink_delinearize.c @@ -428,11 +428,13 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx, return netlink_error(ctx, loc, "Lookup expression has no left hand side"); - if (left->len < set->key->len) { - expr_free(left); - left = netlink_parse_concat_expr(ctx, loc, sreg, set->key->len); - if (left == NULL) - return; + if (left->etype != EXPR_MAP) { + if (left->len < set->key->len) { + expr_free(left); + left = netlink_parse_concat_expr(ctx, loc, sreg, set->key->len); + if (left == NULL) + return; + } } right = set_ref_expr_alloc(loc, set); diff --git src/parser_bison.y src/parser_bison.y index 61bed761..26b5a50a 100644 --- src/parser_bison.y +++ src/parser_bison.y @@ -3254,6 +3254,10 @@ verdict_stmt : verdict_expr ; verdict_map_stmt : concat_expr VMAP verdict_map_expr + { + $$ = map_expr_alloc(&@$, $1, $3); + } + | map_expr VMAP verdict_map_expr { $$ = map_expr_alloc(&@$, $1, $3); } @@ -4579,6 +4583,10 @@ multiton_rhs_expr : prefix_rhs_expr ; map_expr : concat_expr MAP rhs_expr + { + $$ = map_expr_alloc(&@$, $1, $3); + } + | map_expr MAP rhs_expr { $$ = map_expr_alloc(&@$, $1, $3); } -- 2.44.0.windows.1