]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: add expr_to_intervals()
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 22 Apr 2016 16:02:18 +0000 (18:02 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 27 Apr 2016 10:31:58 +0000 (12:31 +0200)
Refactor code to add the new expr_to_intervals(). This function takes
the list of set element expressions and convert them to a list of
half-closed intervals.

This is useful for different purposes, such as interval overlap
and conflicts detection.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/segtree.c

index f544704b42aa2afaf34691a752a68cf00484e5a6..88bb3a253568dd855ad6b629763e8d651bce69b3 100644 (file)
@@ -299,20 +299,20 @@ static bool interval_conflict(const struct elementary_interval *e1,
                return false;
 }
 
-static int set_to_segtree(struct list_head *msgs, struct expr *set,
-                         struct seg_tree *tree)
+static unsigned int expr_to_intervals(const struct expr *set,
+                                     unsigned int keylen,
+                                     struct elementary_interval **intervals)
 {
-       struct elementary_interval *intervals[set->size];
        struct elementary_interval *ei;
        struct expr *i, *next;
        unsigned int n;
        mpz_t low, high;
 
-       mpz_init2(low, tree->keylen);
-       mpz_init2(high, tree->keylen);
+       mpz_init2(low, keylen);
+       mpz_init2(high, keylen);
 
        /*
-        * Convert elements to intervals and sort by priority.
+        * Convert elements to intervals.
         */
        n = 0;
        list_for_each_entry_safe(i, next, &set->expressions, list) {
@@ -320,10 +320,30 @@ static int set_to_segtree(struct list_head *msgs, struct expr *set,
                range_expr_value_high(high, i);
                ei = ei_alloc(low, high, i, 0);
                intervals[n++] = ei;
+       }
+       mpz_clear(high);
+       mpz_clear(low);
+
+       return n;
+}
+
+static int set_to_segtree(struct list_head *msgs, struct expr *set,
+                         struct seg_tree *tree)
+{
+       struct elementary_interval *intervals[set->size];
+       struct expr *i, *next;
+       unsigned int n;
+
+       n = expr_to_intervals(set, tree->keylen, intervals);
 
+       list_for_each_entry_safe(i, next, &set->expressions, list) {
                list_del(&i->list);
                expr_free(i);
        }
+
+       /*
+        * Sort intervals by priority.
+        */
        qsort(intervals, n, sizeof(intervals[0]), interval_cmp);
 
        /*
@@ -340,8 +360,6 @@ static int set_to_segtree(struct list_head *msgs, struct expr *set,
                ei_insert(tree, intervals[n]);
        }
 
-       mpz_clear(high);
-       mpz_clear(low);
        return 0;
 }