]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: remove EXPR_VALUE from expr_value()
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 5 Feb 2026 02:41:21 +0000 (03:41 +0100)
committerFlorian Westphal <fw@strlen.de>
Tue, 10 Feb 2026 17:22:01 +0000 (18:22 +0100)
Rework the following commit:

 7e6be917987c ("segtree: fix decomposition of unclosed intervals containing address prefixes")

this allows to add an assert(expr->etype == EXPR_SET_ELEM), in order to
normalize the input.

The closed flag tells us if this interval is represented with two
element or only one (as an open interval).

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
src/segtree.c

index 5e03122ebfb7d716bab219f342bd5fdfc7c438cc..95cab41668f05fa915f7cd8c811fc50bae2becb7 100644 (file)
@@ -114,17 +114,12 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
 
 static struct expr *expr_value(struct expr *expr)
 {
-       switch (expr->etype) {
-       case EXPR_SET_ELEM:
-               if (expr->key->etype == EXPR_MAPPING)
-                       return expr->key->left;
+       assert(expr->etype == EXPR_SET_ELEM);
 
-               return expr->key;
-       case EXPR_VALUE:
-               return expr;
-       default:
-               BUG("invalid expression type %s", expr_name(expr));
-       }
+       if (expr->key->etype == EXPR_MAPPING)
+               return expr->key->left;
+
+       return expr->key;
 }
 
 static struct expr *get_set_interval_find(const struct set *cache_set,
@@ -528,7 +523,7 @@ static struct expr *interval_to_range(struct expr *low, struct expr *i, mpz_t ra
 }
 
 static void
-add_interval(struct expr *set, struct expr *low, struct expr *i)
+add_interval(struct expr *set, struct expr *low, struct expr *i, bool closed)
 {
        struct expr *expr;
        mpz_t range, p;
@@ -537,7 +532,7 @@ add_interval(struct expr *set, struct expr *low, struct expr *i)
        mpz_init(p);
 
        mpz_sub(range, expr_value(i)->value, expr_value(low)->value);
-       if (i->etype != EXPR_VALUE)
+       if (closed)
                mpz_sub_ui(range, range, 1);
 
        mpz_and(p, expr_value(low)->value, range);
@@ -633,7 +628,7 @@ void interval_map_decompose(struct expr *set)
                        }
                }
 
-               add_interval(set, low, i);
+               add_interval(set, low, i, true);
 
                if (i->key->flags & EXPR_F_INTERVAL_END) {
                        expr_free(low);
@@ -648,11 +643,12 @@ void interval_map_decompose(struct expr *set)
        i = constant_expr_alloc(&low->location, low->dtype,
                                low->byteorder, expr_value(low)->len, NULL);
        mpz_bitmask(i->value, i->len);
+       i = set_elem_expr_alloc(&low->location, i);
 
-       if (!mpz_cmp(i->value, expr_value(low)->value)) {
+       if (!mpz_cmp(i->key->value, expr_value(low)->value)) {
                set_expr_add(set, low);
        } else {
-               add_interval(set, low, i);
+               add_interval(set, low, i, false);
                expr_free(low);
        }