[PATCH nft 3/7] src: assert on EXPR_SET only contains EXPR_SET_ELEM in the expressions list

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

 



Normalize the representation so the expressions list in EXPR_SET always
contains EXPR_SET_ELEM. Add assert() to validate this.

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 src/evaluate.c            | 23 +++++++++--------------
 src/expression.c          | 16 ++++++++++++----
 src/intervals.c           | 14 ++++++++++++++
 src/json.c                | 10 ++++++++--
 src/netlink.c             |  2 ++
 src/netlink_delinearize.c |  9 ++++++---
 src/optimize.c            |  3 +++
 src/segtree.c             |  6 ++++++
 8 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index b0a3e990e476..0b7508a18ede 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2069,6 +2069,8 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr)
 			struct expr *new, *j;
 
 			list_for_each_entry(j, &expr_set(i->key->left)->expressions, list) {
+				assert(j->etype == EXPR_SET_ELEM);
+
 				new = mapping_expr_alloc(&i->location,
 							 expr_get(j->key),
 							 expr_get(i->key->right));
@@ -2770,9 +2772,9 @@ static void optimize_singleton_set(struct expr *rel, struct expr **expr)
 	struct expr *set = rel->right, *i;
 
 	i = list_first_entry(&expr_set(set)->expressions, struct expr, list);
-	if (i->etype == EXPR_SET_ELEM &&
-	    list_empty(&i->stmt_list)) {
+	assert (i->etype == EXPR_SET_ELEM);
 
+	if (list_empty(&i->stmt_list)) {
 		switch (i->key->etype) {
 		case EXPR_PREFIX:
 		case EXPR_RANGE:
@@ -5476,19 +5478,12 @@ static struct expr *expr_set_to_list(struct eval_ctx *ctx, struct expr *dev_expr
 	LIST_HEAD(tmp);
 
 	list_for_each_entry_safe(expr, next, &expr_set(dev_expr)->expressions, list) {
-		list_del(&expr->list);
-
-		switch (expr->etype) {
-		case EXPR_SET_ELEM:
-			key = expr_clone(expr->key);
-			expr_free(expr);
-			expr = key;
-			break;
-		default:
-			BUG("invalid expression type %s\n", expr_name(expr));
-			break;
-		}
+		assert(expr->etype == EXPR_SET_ELEM);
 
+		list_del(&expr->list);
+		key = expr_clone(expr->key);
+		expr_free(expr);
+		expr = key;
 		list_add(&expr->list, &tmp);
 	}
 
diff --git a/src/expression.c b/src/expression.c
index 8b54b6a38ae5..68e2fec192b2 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -941,8 +941,9 @@ void relational_expr_pctx_update(struct proto_ctx *ctx,
 			ops->pctx_update(ctx, &expr->location, left, right);
 		else if (right->etype == EXPR_SET) {
 			list_for_each_entry(i, &expr_set(right)->expressions, list) {
-				if (i->etype == EXPR_SET_ELEM &&
-				    i->key->etype == EXPR_VALUE)
+				assert(i->etype == EXPR_SET_ELEM);
+
+				if (i->key->etype == EXPR_VALUE)
 					ops->pctx_update(ctx, &expr->location, left, i->key);
 			}
 		} else if (ops == &meta_expr_ops &&
@@ -1378,6 +1379,8 @@ static void set_expr_print(const struct expr *expr, struct output_ctx *octx)
 	nft_print(octx, "{ ");
 
 	list_for_each_entry(i, &expr_set(expr)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		nft_print(octx, "%s", d);
 		expr_print(i, octx);
 		count++;
@@ -1400,8 +1403,10 @@ static void set_expr_destroy(struct expr *expr)
 {
 	struct expr *i, *next;
 
-	list_for_each_entry_safe(i, next, &expr_set(expr)->expressions, list)
+	list_for_each_entry_safe(i, next, &expr_set(expr)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
 		expr_free(i);
+	}
 }
 
 static void set_expr_set_type(const struct expr *expr,
@@ -1410,8 +1415,11 @@ static void set_expr_set_type(const struct expr *expr,
 {
 	struct expr *i;
 
-	list_for_each_entry(i, &expr_set(expr)->expressions, list)
+	list_for_each_entry(i, &expr_set(expr)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		expr_set_type(i, dtype, byteorder);
+	}
 }
 
 static const struct expr_ops set_expr_ops = {
diff --git a/src/intervals.c b/src/intervals.c
index 7df5ce2ab4db..3ac45cf29abd 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -183,6 +183,8 @@ static void setelem_automerge(struct set_automerge_ctx *ctx)
 	mpz_init(rop);
 
 	list_for_each_entry_safe(i, next, &expr_set(ctx->init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		if (expr_type_catchall(i->key))
 			continue;
 
@@ -243,6 +245,8 @@ static void set_to_range(struct expr *init)
 	struct expr *i, *elem;
 
 	list_for_each_entry(i, &expr_set(init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		elem = interval_expr_key(i);
 		setelem_expr_to_range(elem);
 	}
@@ -274,6 +278,8 @@ int set_automerge(struct list_head *msgs, struct cmd *cmd, struct set *set,
 	setelem_automerge(&ctx);
 
 	list_for_each_entry_safe(i, next, &expr_set(init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		if (i->flags & EXPR_F_KERNEL) {
 			list_move_tail(&i->list, &expr_set(existing_set->init)->expressions);
 		} else if (existing_set) {
@@ -413,6 +419,8 @@ static int setelem_delete(struct list_head *msgs, struct set *set,
 	mpz_init(rop);
 
 	list_for_each_entry_safe(elem, next, &expr_set(elems)->expressions, list) {
+		assert(elem->etype == EXPR_SET_ELEM);
+
 		i = interval_expr_key(elem);
 
 		if (expr_type_catchall(i->key)) {
@@ -585,6 +593,8 @@ static int setelem_overlap(struct list_head *msgs, struct set *set,
 	mpz_init(rop);
 
 	list_for_each_entry_safe(elem, next, &expr_set(init)->expressions, list) {
+		assert(elem->etype == EXPR_SET_ELEM);
+
 		i = interval_expr_key(elem);
 
 		if (expr_type_catchall(i->key))
@@ -654,6 +664,8 @@ int set_overlap(struct list_head *msgs, struct set *set, struct expr *init)
 	err = setelem_overlap(msgs, set, init);
 
 	list_for_each_entry_safe(i, n, &expr_set(init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		if (i->flags & EXPR_F_KERNEL)
 			list_move_tail(&i->list, &expr_set(existing_set->init)->expressions);
 		else if (existing_set) {
@@ -711,6 +723,8 @@ int set_to_intervals(const struct set *set, struct expr *init, bool add)
 	mpz_t p;
 
 	list_for_each_entry_safe(i, n, &expr_set(init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		elem = interval_expr_key(i);
 
 		if (expr_type_catchall(elem->key))
diff --git a/src/json.c b/src/json.c
index 36c03e581b4a..612e8e6999eb 100644
--- a/src/json.c
+++ b/src/json.c
@@ -232,8 +232,11 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
 		json_t *array = json_array();
 		const struct expr *i;
 
-		list_for_each_entry(i, &expr_set(set->init)->expressions, list)
+		list_for_each_entry(i, &expr_set(set->init)->expressions, list) {
+			assert(i->etype == EXPR_SET_ELEM);
+
 			json_array_append_new(array, expr_print_json(i, octx));
+		}
 
 		json_object_set_new(root, "elem", array);
 	}
@@ -763,8 +766,11 @@ json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx)
 	json_t *array = json_array();
 	const struct expr *i;
 
-	list_for_each_entry(i, &expr_set(expr)->expressions, list)
+	list_for_each_entry(i, &expr_set(expr)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		json_array_append_new(array, expr_print_json(i, octx));
+	}
 
 	return nft_json_pack("{s:o}", "set", array);
 }
diff --git a/src/netlink.c b/src/netlink.c
index 10817e5cfb53..7a17f394c69f 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1219,6 +1219,8 @@ void alloc_setelem_cache(const struct expr *set, struct nftnl_set *nls)
 	const struct expr *expr;
 
 	list_for_each_entry(expr, &expr_set(set)->expressions, list) {
+		assert(expr->etype == EXPR_SET_ELEM);
+
 		nlse = alloc_nftnl_setelem(set, expr);
 		nftnl_set_elem_add(nls, nlse);
 	}
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index f4ebdfcbf2f3..3db5502910ad 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2206,9 +2206,9 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
 				struct expr *elem;
 
 				elem = list_first_entry(&expr_set(set->init)->expressions, struct expr, list);
+				assert(elem->etype == EXPR_SET_ELEM);
 
-				if (elem->etype == EXPR_SET_ELEM &&
-				    elem->key->etype == EXPR_VALUE)
+				if (elem->key->etype == EXPR_VALUE)
 					payload_icmp_check(ctx, payload, elem->key);
 			}
 		}
@@ -2882,8 +2882,11 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 		expr_postprocess(ctx, &expr->right);
 		break;
 	case EXPR_SET:
-		list_for_each_entry(i, &expr_set(expr)->expressions, list)
+		list_for_each_entry(i, &expr_set(expr)->expressions, list) {
+			assert(i->etype == EXPR_SET);
+
 			expr_postprocess(ctx, &i);
+		}
 		break;
 	case EXPR_CONCAT:
 		expr_postprocess_concat(ctx, exprp);
diff --git a/src/optimize.c b/src/optimize.c
index 422990d1ca6f..e537f48adf58 100644
--- a/src/optimize.c
+++ b/src/optimize.c
@@ -589,6 +589,7 @@ static void merge_vmap(const struct optimize_ctx *ctx,
 
 	mappings = stmt_b->expr->mappings;
 	list_for_each_entry(expr, &expr_set(mappings)->expressions, list) {
+		assert(expr->etype == EXPR_SET_ELEM);
 		mapping = expr_clone(expr);
 		set_expr_add(stmt_a->expr->mappings, mapping);
 	}
@@ -655,6 +656,7 @@ static void __merge_concat(const struct optimize_ctx *ctx, uint32_t i,
 			switch (stmt_a->expr->right->etype) {
 			case EXPR_SET:
 				list_for_each_entry(expr, &expr_set(stmt_a->expr->right)->expressions, list) {
+					assert(expr->etype == EXPR_SET_ELEM);
 					concat_clone = expr_clone(concat);
 					clone = expr_clone(expr->key);
 					concat_expr_add(concat_clone, clone);
@@ -766,6 +768,7 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict,
 		break;
 	case EXPR_SET:
 		list_for_each_entry(item, &expr_set(expr)->expressions, list) {
+			assert(item->etype == EXPR_SET_ELEM);
 			mapping = mapping_expr_alloc(&internal_location, expr_get(item->key),
 						     expr_get(verdict->expr));
 
diff --git a/src/segtree.c b/src/segtree.c
index b5be0005d1ea..f95a7ce1c8a8 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -80,6 +80,8 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
 	new_init = set_expr_alloc(&internal_location, NULL);
 
 	list_for_each_entry(i, &expr_set(init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		switch (i->key->etype) {
 		case EXPR_VALUE:
 			set_elem_add(set, new_init, i->key->value,
@@ -137,6 +139,8 @@ static struct expr *get_set_interval_find(const struct set *cache_set,
 	mpz_init2(val, set->key->len);
 
 	list_for_each_entry(i, &expr_set(set->init)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		key = expr_value(i);
 		switch (key->etype) {
 		case EXPR_VALUE:
@@ -357,6 +361,8 @@ void concat_range_aggregate(struct expr *set)
 	mpz_t range, p;
 
 	list_for_each_entry_safe(i, next, &expr_set(set)->expressions, list) {
+		assert(i->etype == EXPR_SET_ELEM);
+
 		if (!start) {
 			start = i;
 			continue;
-- 
2.30.2





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux