summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2025-03-06 18:49:21 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2025-06-19 00:01:13 +0200
commit73fe1f4ae4e8925e39922ecdaef7a024ee31254b (patch)
treed1689d308e290eec94e593f7fa3848bd1f47384f
parent4386556d9265dab2eea5e1fce833bbdb4fa1690d (diff)
segtree: incomplete output in get element command with maps
commit 6db28b2d71e7f61c64338787be5d82edfdb62a21 upstream. get element command displays an incomplete range. Using this simple test ruleset: table ip x { map y { typeof ip saddr : meta mark counter flags interval,timeout elements = { 1.1.1.1-1.1.1.10 timeout 10m : 20, 2.2.2.2-2.2.2.5 timeout 10m : 30} } then, invoking the get element command: # nft get element x y { 1.1.1.2 } results in, before (incomplete output): table ip x { map y { type ipv4_addr : mark flags interval,timeout elements = { 1.1.1.1 counter packets 0 bytes 0 timeout 10m expires 1m24s160ms : 0x00000014 } } } Note that it displays 1.1.1.1, instead of 1.1.1.1-1.1.1.10. After this fix: table ip x { map y { type ipv4_addr : mark flags interval,timeout elements = { 1.1.1.1-1.1.1.10 counter packets 0 bytes 0 timeout 10m expires 1m24s160ms : 0x00000014 } } } Fixes: a43cc8d53096 ("src: support for get element command") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/segtree.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/src/segtree.c b/src/segtree.c
index fcc1255b..8ea434b8 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -110,19 +110,34 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
return new_init;
}
+static struct expr *expr_value(struct expr *expr)
+{
+ switch (expr->etype) {
+ case EXPR_MAPPING:
+ return expr->left->key;
+ case EXPR_SET_ELEM:
+ return expr->key;
+ case EXPR_VALUE:
+ return expr;
+ default:
+ BUG("invalid expression type %s\n", expr_name(expr));
+ }
+}
+
static struct expr *get_set_interval_find(const struct set *cache_set,
struct expr *left,
struct expr *right)
{
const struct set *set = cache_set;
struct expr *range = NULL;
- struct expr *i;
+ struct expr *i, *key;
mpz_t val;
mpz_init2(val, set->key->len);
list_for_each_entry(i, &set->init->expressions, list) {
- switch (i->key->etype) {
+ key = expr_value(i);
+ switch (key->etype) {
case EXPR_VALUE:
if (expr_basetype(i->key)->type != TYPE_STRING)
break;
@@ -132,14 +147,14 @@ static struct expr *get_set_interval_find(const struct set *cache_set,
case EXPR_PREFIX:
case EXPR_RANGE:
range_expr_value_low(val, i);
- if (left && mpz_cmp(left->key->value, val))
+ if (left && mpz_cmp(expr_value(left)->value, val))
break;
range_expr_value_high(val, i);
- if (right && mpz_cmp(right->key->value, val))
+ if (right && mpz_cmp(expr_value(right)->value, val))
break;
- range = expr_clone(i->key);
+ range = expr_clone(i);
goto out;
default:
break;
@@ -151,20 +166,6 @@ out:
return range;
}
-static struct expr *expr_value(struct expr *expr)
-{
- switch (expr->etype) {
- case EXPR_MAPPING:
- return expr->left->key;
- case EXPR_SET_ELEM:
- return expr->key;
- case EXPR_VALUE:
- return expr;
- default:
- BUG("invalid expression type %s\n", expr_name(expr));
- }
-}
-
static struct expr *__expr_to_set_elem(struct expr *low, struct expr *expr)
{
struct expr *elem = set_elem_expr_alloc(&low->location, expr);