* Wed Mar 18 2026 Phil Sutter <psutter@redhat.com> [1.0.9-7.el9] - src: fix reset element support for interval set type (Phil Sutter) [RHEL-153461] - src: netlink: fix crash when ops doesn't support udata (Phil Sutter) [RHEL-153461] Resolves: RHEL-153461
131 lines
3.9 KiB
Diff
131 lines
3.9 KiB
Diff
From 0a38b9fcf1841e68088f2db39e3c96b3ad3b0369 Mon Sep 17 00:00:00 2001
|
|
From: Phil Sutter <psutter@redhat.com>
|
|
Date: Wed, 18 Mar 2026 22:17:46 +0100
|
|
Subject: [PATCH] src: fix reset element support for interval set type
|
|
|
|
JIRA: https://issues.redhat.com/browse/https://redhat.atlassian.net/browse/RHEL-153461
|
|
Upstream Status: nftables commit 2b164aec4295d5f4f6d45aa098279494ab44289b
|
|
|
|
commit 2b164aec4295d5f4f6d45aa098279494ab44289b
|
|
Author: Florian Westphal <fw@strlen.de>
|
|
Date: Thu Mar 6 14:23:30 2025 +0100
|
|
|
|
src: fix reset element support for interval set type
|
|
|
|
Running reset command yields on an interval (rbtree) set yields:
|
|
nft reset element inet filter rbtreeset {1.2.3.4}
|
|
BUG: unhandled op 8
|
|
|
|
This is easy to fix, CMD_RESET doesn't add or remove so it should be
|
|
treated like CMD_GET.
|
|
|
|
Unfortunately, this still doesn't work properly:
|
|
|
|
nft get element inet filter rbset {1.2.3.4}
|
|
returns:
|
|
... elements = { 1.2.3.4 }
|
|
|
|
but its expected that "get" and "reset" also return stateful objects
|
|
associated with the element. This works for other set types, but for
|
|
rbtree, the list of statements gets lost during segtree processing.
|
|
|
|
After fix, get/reset returns:
|
|
elements = { 1.2.3.4 counter packets 10 ...
|
|
|
|
A follow up patch will add a test case.
|
|
|
|
Fixes: 83e0f4402fb7 ("Implement 'reset {set,map,element}' commands")
|
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
---
|
|
src/evaluate.c | 1 +
|
|
src/segtree.c | 36 ++++++++++++++++++++++++++++++------
|
|
2 files changed, 31 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
index 2196e92..711990a 100644
|
|
--- a/src/evaluate.c
|
|
+++ b/src/evaluate.c
|
|
@@ -1729,6 +1729,7 @@ static int interval_set_eval(struct eval_ctx *ctx, struct set *set,
|
|
ctx->nft->debug_mask);
|
|
break;
|
|
case CMD_GET:
|
|
+ case CMD_RESET:
|
|
break;
|
|
default:
|
|
BUG("unhandled op %d\n", ctx->cmd->op);
|
|
diff --git a/src/segtree.c b/src/segtree.c
|
|
index 28172b3..c4029f9 100644
|
|
--- a/src/segtree.c
|
|
+++ b/src/segtree.c
|
|
@@ -206,6 +206,27 @@ static struct expr *expr_to_set_elem(struct expr *e)
|
|
return __expr_to_set_elem(e, expr);
|
|
}
|
|
|
|
+static void set_compound_expr_add(struct expr *compound, struct expr *expr, struct expr *orig)
|
|
+{
|
|
+ struct expr *elem;
|
|
+
|
|
+ switch (expr->etype) {
|
|
+ case EXPR_SET_ELEM:
|
|
+ list_splice_init(&orig->stmt_list, &expr->stmt_list);
|
|
+ compound_expr_add(compound, expr);
|
|
+ break;
|
|
+ case EXPR_MAPPING:
|
|
+ list_splice_init(&orig->left->stmt_list, &expr->left->stmt_list);
|
|
+ compound_expr_add(compound, expr);
|
|
+ break;
|
|
+ default:
|
|
+ elem = set_elem_expr_alloc(&orig->location, expr);
|
|
+ list_splice_init(&orig->stmt_list, &elem->stmt_list);
|
|
+ compound_expr_add(compound, elem);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
int get_set_decompose(struct set *cache_set, struct set *set)
|
|
{
|
|
struct expr *i, *next, *range;
|
|
@@ -227,20 +248,23 @@ int get_set_decompose(struct set *cache_set, struct set *set)
|
|
errno = ENOENT;
|
|
return -1;
|
|
}
|
|
+
|
|
+ set_compound_expr_add(new_init, range, left);
|
|
+
|
|
expr_free(left);
|
|
expr_free(i);
|
|
|
|
- compound_expr_add(new_init, range);
|
|
left = NULL;
|
|
} else {
|
|
if (left) {
|
|
range = get_set_interval_find(cache_set,
|
|
left, NULL);
|
|
+
|
|
if (range)
|
|
- compound_expr_add(new_init, range);
|
|
+ set_compound_expr_add(new_init, range, left);
|
|
else
|
|
- compound_expr_add(new_init,
|
|
- expr_to_set_elem(left));
|
|
+ set_compound_expr_add(new_init,
|
|
+ expr_to_set_elem(left), left);
|
|
}
|
|
left = i;
|
|
}
|
|
@@ -248,9 +272,9 @@ int get_set_decompose(struct set *cache_set, struct set *set)
|
|
if (left) {
|
|
range = get_set_interval_find(cache_set, left, NULL);
|
|
if (range)
|
|
- compound_expr_add(new_init, range);
|
|
+ set_compound_expr_add(new_init, range, left);
|
|
else
|
|
- compound_expr_add(new_init, expr_to_set_elem(left));
|
|
+ set_compound_expr_add(new_init, expr_to_set_elem(left), left);
|
|
}
|
|
|
|
expr_free(set->init);
|