]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: simplify map statement
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 24 Aug 2018 07:52:17 +0000 (09:52 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 24 Aug 2018 07:52:17 +0000 (09:52 +0200)
Instead of using the map expression, store dynamic key and data
separately since they need special handling than constant maps.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/statement.h
src/evaluate.c
src/netlink_delinearize.c
src/netlink_linearize.c
src/parser_bison.y
src/statement.c

index 7840e9d261dae7b9be841d8d4186384018f0982f..6c583a918eb9371c06600aa072a1bdd794d422af 100644 (file)
@@ -193,7 +193,8 @@ extern struct stmt *set_stmt_alloc(const struct location *loc);
 
 struct map_stmt {
        struct expr             *set;
-       struct expr             *map;
+       struct expr             *key;
+       struct expr             *data;
        enum nft_dynset_ops     op;
 };
 
index 3f15b322d503817570ec5fc4c02ed6346fde28a5..9bc67d8f71f1fd375f05eea08e2dae22c0be5c2c 100644 (file)
@@ -2714,8 +2714,31 @@ static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt)
 
 static int stmt_evaluate_map(struct eval_ctx *ctx, struct stmt *stmt)
 {
-       if (expr_evaluate(ctx, &stmt->map.map->map) < 0)
+       expr_set_context(&ctx->ectx, NULL, 0);
+       if (expr_evaluate(ctx, &stmt->map.set) < 0)
                return -1;
+       if (stmt->map.set->ops->type != EXPR_SET_REF)
+               return expr_error(ctx->msgs, stmt->map.set,
+                                 "Expression does not refer to a set");
+
+       if (stmt_evaluate_arg(ctx, stmt,
+                             stmt->map.set->set->key->dtype,
+                             stmt->map.set->set->key->len,
+                             stmt->map.set->set->key->byteorder,
+                             &stmt->map.key) < 0)
+               return -1;
+       if (expr_is_constant(stmt->map.key))
+               return expr_error(ctx->msgs, stmt->map.key,
+                                 "Key expression can not be constant");
+       if (stmt->map.key->comment != NULL)
+               return expr_error(ctx->msgs, stmt->map.key,
+                                 "Key expression comments are not supported");
+       if (expr_is_constant(stmt->map.data))
+               return expr_error(ctx->msgs, stmt->map.data,
+                                 "Data expression can not be constant");
+       if (stmt->map.data->comment != NULL)
+               return expr_error(ctx->msgs, stmt->map.data,
+                                 "Data expression comments are not supported");
 
        return 0;
 }
index dbf1f6186a3d57e519a36bc0aacace3ea3413b2d..898c737f9b288462064226fe51bf913b97a45b69 100644 (file)
@@ -1321,7 +1321,8 @@ static void netlink_parse_dynset(struct netlink_parse_ctx *ctx,
        } else if (expr_data != NULL) {
                stmt = map_stmt_alloc(loc);
                stmt->map.set   = set_ref_expr_alloc(loc, set);
-               stmt->map.map   = map_expr_alloc(loc, expr, expr_data);
+               stmt->map.key   = expr;
+               stmt->map.data  = expr_data;
                stmt->map.op    = nftnl_expr_get_u32(nle, NFTNL_EXPR_DYNSET_OP);
        } else {
                stmt = set_stmt_alloc(loc);
@@ -2508,6 +2509,10 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
                case STMT_SET:
                        expr_postprocess(&rctx, &stmt->set.key);
                        break;
+               case STMT_MAP:
+                       expr_postprocess(&rctx, &stmt->map.key);
+                       expr_postprocess(&rctx, &stmt->map.data);
+                       break;
                case STMT_DUP:
                        if (stmt->dup.to != NULL)
                                expr_postprocess(&rctx, &stmt->dup.to);
index 442c5a940bc3f7c485a945520a46f7582fb0632b..821fcd0a6377a7d222c6edb0c7b7de55d9c86878 100644 (file)
@@ -1274,26 +1274,27 @@ static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
 static void netlink_gen_map_stmt(struct netlink_linearize_ctx *ctx,
                                 const struct stmt *stmt)
 {
-       struct nftnl_expr *nle;
-       enum nft_registers sreg_key;
+       struct set *set = stmt->map.set->set;
        enum nft_registers sreg_data;
+       enum nft_registers sreg_key;
+       struct nftnl_expr *nle;
 
-       sreg_key = get_register(ctx, stmt->map.map->map->key);
-       netlink_gen_expr(ctx, stmt->map.map->map->key, sreg_key);
+       sreg_key = get_register(ctx, stmt->map.key);
+       netlink_gen_expr(ctx, stmt->map.key, sreg_key);
 
-       sreg_data = get_register(ctx, stmt->map.map->mappings);
-       netlink_gen_expr(ctx, stmt->map.map->mappings, sreg_data);
+       sreg_data = get_register(ctx, stmt->map.data);
+       netlink_gen_expr(ctx, stmt->map.data, sreg_data);
 
-       release_register(ctx, stmt->map.map->map->key);
-       release_register(ctx, stmt->map.map->mappings);
+       release_register(ctx, stmt->map.key);
+       release_register(ctx, stmt->map.data);
 
        nle = alloc_nft_expr("dynset");
        netlink_put_register(nle, NFTNL_EXPR_DYNSET_SREG_KEY, sreg_key);
        netlink_put_register(nle, NFTNL_EXPR_DYNSET_SREG_DATA, sreg_data);
 
        nftnl_expr_set_u32(nle, NFTNL_EXPR_DYNSET_OP, stmt->map.op);
-       nftnl_expr_set_str(nle, NFTNL_EXPR_DYNSET_SET_NAME, stmt->map.set->identifier);
-       nftnl_expr_set_u32(nle, NFTNL_EXPR_DYNSET_SET_ID, stmt->map.set->set->handle.set_id);
+       nftnl_expr_set_str(nle, NFTNL_EXPR_DYNSET_SET_NAME, set->handle.set.name);
+       nftnl_expr_set_u32(nle, NFTNL_EXPR_DYNSET_SET_ID, set->handle.set_id);
 
        nftnl_rule_add_expr(ctx->nlr, nle);
 }
index bc6f72779dd70a3b8758f5b11565d531eb8203a6..199ef13d8c1d03faf3af06879795f4fe796038e3 100644 (file)
@@ -2872,7 +2872,8 @@ map_stmt          :       set_stmt_op     symbol_expr '{' set_elem_expr_stmt      COLON   set_elem_expr_s
                        {
                                $$ = map_stmt_alloc(&@$);
                                $$->map.op  = $1;
-                               $$->map.map = map_expr_alloc(&@$, $4, $6);
+                               $$->map.key = $4;
+                               $$->map.data = $6;
                                $$->map.set = $2;
                        }
                        ;
index cec83c19e52900f59782ac5404403105e269b5ee..039ca943e92c41335fb7a0678265e941f3ebf00f 100644 (file)
@@ -657,15 +657,16 @@ static void map_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
        nft_print(octx, "%s ", set_stmt_op_names[stmt->map.op]);
        expr_print(stmt->map.set, octx);
        nft_print(octx, " { ");
-       expr_print(stmt->map.map->map->key, octx);
+       expr_print(stmt->map.key, octx);
        nft_print(octx, " : ");
-       expr_print(stmt->map.map->mappings, octx);
+       expr_print(stmt->map.data, octx);
        nft_print(octx, " }");
 }
 
 static void map_stmt_destroy(struct stmt *stmt)
 {
-       expr_free(stmt->map.map);
+       expr_free(stmt->map.key);
+       expr_free(stmt->map.data);
        expr_free(stmt->map.set);
 }