set location of internal elements (already in the kernel) to the one that partial or fully deletes it. Otherwise, error reporting refers to internal location. Before this patch: # nft delete element x y { 1.1.1.3 } Error: Could not process rule: Too many open files in system delete element x y { 1.1.1.3 } ^^^^^^^ After this patch: # nft delete element x y { 1.1.1.3 } Error: Could not process rule: Too many open files in system delete element x y { 1.1.1.3 } ^^^^^^^ This occurs after splitting an existing interval in two: remove: [1010100-10101ff] add: [1010100-1010102] add: [1010104-10101ff] which results in two additions after removing the existing interval that is split. Fixes: 81e36530fcac ("src: replace interval segment tree overlap and automerge") Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- src/intervals.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/intervals.c b/src/intervals.c index ff202be9375b..a58ec5b26397 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -86,6 +86,7 @@ static void remove_overlapping_range(struct set_automerge_ctx *ctx, struct expr *prev, struct expr *i) { if (i->flags & EXPR_F_KERNEL) { + i->location = prev->location; purge_elem(ctx, i); return; } @@ -104,12 +105,14 @@ static bool merge_ranges(struct set_automerge_ctx *ctx, struct range *prev_range, struct range *range) { if (prev->flags & EXPR_F_KERNEL) { + prev->location = i->location; purge_elem(ctx, prev); expr_free(i->key->left); i->key->left = expr_get(prev->key->left); mpz_set(prev_range->high, range->high); return true; } else if (i->flags & EXPR_F_KERNEL) { + i->location = prev->location; purge_elem(ctx, i); expr_free(prev->key->right); prev->key->right = expr_get(i->key->right); @@ -304,6 +307,7 @@ static void __adjust_elem_left(struct set *set, struct expr *prev, struct expr * static void adjust_elem_left(struct set *set, struct expr *prev, struct expr *i, struct expr *purge) { + prev->location = i->location; remove_elem(prev, set, purge); __adjust_elem_left(set, prev, i); @@ -323,6 +327,7 @@ static void __adjust_elem_right(struct set *set, struct expr *prev, struct expr static void adjust_elem_right(struct set *set, struct expr *prev, struct expr *i, struct expr *purge) { + prev->location = i->location; remove_elem(prev, set, purge); __adjust_elem_right(set, prev, i); @@ -335,6 +340,8 @@ static void split_range(struct set *set, struct expr *prev, struct expr *i, { struct expr *clone; + prev->location = i->location; + if (prev->flags & EXPR_F_KERNEL) { clone = expr_clone(prev); list_move_tail(&clone->list, &purge->expressions); @@ -422,8 +429,10 @@ static int setelem_delete(struct list_head *msgs, struct set *set, if (mpz_cmp(prev_range.low, range.low) == 0 && mpz_cmp(prev_range.high, range.high) == 0) { if (elem->flags & EXPR_F_REMOVE) { - if (prev->flags & EXPR_F_KERNEL) + if (prev->flags & EXPR_F_KERNEL) { + prev->location = elem->location; list_move_tail(&prev->list, &purge->expressions); + } list_del(&elem->list); expr_free(elem); -- 2.30.2