diff mbox series

[nft] segtree: Fix add and delete of element in same batch

Message ID 20191121104124.23345-1-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show
Series [nft] segtree: Fix add and delete of element in same batch | expand

Commit Message

Phil Sutter Nov. 21, 2019, 10:41 a.m. UTC
The commit this fixes accidentally broke a rather exotic use-case which
is but used in set-simple.t of tests/monitor:

| # nft 'add element t s { 22-25 }; delete element t s { 22-25 }'

Since ranges are now checked for existence in userspace before delete
command is submitted to kernel, the second command above was rejected
because the range in question wasn't present in cache yet. Fix this by
adding new interval set elements to cache after creating the batch job
for them.

Fixes; decc12ec2dc31 ("segtree: Check ranges when deleting elements")

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 src/rule.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Pablo Neira Ayuso Dec. 2, 2019, 5:59 p.m. UTC | #1
On Thu, Nov 21, 2019 at 11:41:24AM +0100, Phil Sutter wrote:
> The commit this fixes accidentally broke a rather exotic use-case which
> is but used in set-simple.t of tests/monitor:
> 
> | # nft 'add element t s { 22-25 }; delete element t s { 22-25 }'
> 
> Since ranges are now checked for existence in userspace before delete
> command is submitted to kernel, the second command above was rejected
> because the range in question wasn't present in cache yet. Fix this by
> adding new interval set elements to cache after creating the batch job
> for them.

Applied, with minor glitch:

        if (set->init != NULL &&
            set->flags & NFT_SET_INTERVAL)

Just in case the set definition is empty.

Thanks Phil.
diff mbox series

Patch

diff --git a/src/rule.c b/src/rule.c
index 4abc13c993b89..c7b58529a80da 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1511,6 +1511,13 @@  static int __do_add_setelems(struct netlink_ctx *ctx, struct set *set,
 	if (mnl_nft_setelem_add(ctx, set, expr, flags) < 0)
 		return -1;
 
+	if (set->flags & NFT_SET_INTERVAL) {
+		interval_map_decompose(expr);
+		list_splice_tail_init(&expr->expressions, &set->init->expressions);
+		set->init->size += expr->size;
+		expr->size = 0;
+	}
+
 	return 0;
 }