[PATCH nft 3/4] src: simplify map statement

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxx>
---
 include/statement.h       |  3 ++-
 src/evaluate.c            | 25 ++++++++++++++++++++++++-
 src/netlink_delinearize.c |  7 ++++++-
 src/netlink_linearize.c   | 21 +++++++++++----------
 src/parser_bison.y        |  3 ++-
 src/statement.c           |  7 ++++---
 6 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/include/statement.h b/include/statement.h
index 7840e9d261da..6c583a918eb9 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -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;
 };
 
diff --git a/src/evaluate.c b/src/evaluate.c
index 3f15b322d503..9bc67d8f71f1 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -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;
 }
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index dbf1f6186a3d..898c737f9b28 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -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);
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 442c5a940bc3..821fcd0a6377 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -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);
 }
diff --git a/src/parser_bison.y b/src/parser_bison.y
index bc6f72779dd7..199ef13d8c1d 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -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;
 			}
 			;
diff --git a/src/statement.c b/src/statement.c
index cec83c19e529..039ca943e92c 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -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);
 }
 
-- 
2.11.0




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux