summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-06-23 21:37:31 +0200
committerFlorian Westphal <fw@strlen.de>2025-06-26 00:43:24 +0200
commit5335452966c4e5da2f3a5cf617cf431d711b215e (patch)
treec526e0e7c84e715dc55ad7e9cfb78471954ebe5a /src
parentab1139f807f0d0519a25704e75c442ccb71f7a60 (diff)
evaluate: check that set type is identical before merging
Reject maps and sets of the same name: BUG: invalid range expression type catch-all set element nft: src/expression.c:1704: range_expr_value_low: Assertion `0' failed. After: Error: Cannot merge set with existing datamap of same name set z { ^ v2: Pablo points out that we shouldn't merge datamaps (plain value) and objref maps either, catch this too and add another test: nft --check -f invalid_transcation_merge_map_and_objref_map invalid_transcation_merge_map_and_objref_map:9:13-13: Error: Cannot merge map with incompatible existing map of same name We should also make sure that both data (for map case) and set keys are identical, this is added in a followup patch. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 5f46aaf9..fc9d82f7 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -5165,6 +5165,18 @@ static int elems_evaluate(struct eval_ctx *ctx, struct set *set)
return 0;
}
+static bool set_type_compatible(const struct set *set, const struct set *existing_set)
+{
+ if (set_is_datamap(set->flags))
+ return set_is_datamap(existing_set->flags);
+
+ if (set_is_objmap(set->flags))
+ return set_is_objmap(existing_set->flags);
+
+ assert(!set_is_map(set->flags));
+ return !set_is_map(existing_set->flags);
+}
+
static int set_evaluate(struct eval_ctx *ctx, struct set *set)
{
struct set *existing_set = NULL;
@@ -5288,8 +5300,15 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
return 0;
}
- if (existing_set && set_is_interval(set->flags) && !set_is_interval(existing_set->flags))
- return set_error(ctx, set, "existing %s lacks interval flag", type);
+ if (existing_set) {
+ if (set_is_interval(set->flags) && !set_is_interval(existing_set->flags))
+ return set_error(ctx, set,
+ "existing %s lacks interval flag", type);
+ if (!set_type_compatible(set, existing_set))
+ return set_error(ctx, set, "Cannot merge %s with incompatible existing %s of same name",
+ type,
+ set_is_map(existing_set->flags) ? "map" : "set");
+ }
set->existing_set = existing_set;