From: Pablo Neira Ayuso Date: Wed, 4 Dec 2024 22:36:05 +0000 (+0100) Subject: intervals: set internal element location with the deletion trigger X-Git-Tag: v1.1.2~113 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=93077e35accccd8cc056b67f70bfb3182c819fd4;p=thirdparty%2Fnftables.git intervals: set internal element location with the deletion trigger 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 --- diff --git a/src/intervals.c b/src/intervals.c index ff202be9..a58ec5b2 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);