]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: only use prefix expressions for ranges for selected datatypes
authorPatrick McHardy <kaber@trash.net>
Thu, 16 Jan 2014 17:11:12 +0000 (17:11 +0000)
committerPatrick McHardy <kaber@trash.net>
Thu, 16 Jan 2014 17:11:12 +0000 (17:11 +0000)
It is uncommon to represent f.i. port number ranges as prefix expressions.

Introduce a datatype DTYPE_F_PREFIX flag to indicate that the preferred
representation of a range is a prefix and use it for segtree decomposition
to decide whether to use a range or prefix expression.

The ipaddr, ip6addr, mark and realm datatypes are changed to include the
DTYPE_F_PREFIX flag.

This fixes completely unreadable output in cases where the ranges are
representable as prefixes, f.i. in case of port number:

{ 0/6 => jump chain1, 0/5 => jump chain2, 0/4 => continue}

becomes:

{ 0-1023 => jump chain1, 1024-2047 => jump chain2, 2048-4095 => continue}

Signed-off-by: Patrick McHardy <kaber@trash.net>
include/datatype.h
src/datatype.c
src/meta.c
src/segtree.c

index 239d5ea5718bcf1540abea45495d6255494f2837..84dcdc8c0af6c5585e4896b4b5a7a4b5eed13c6f 100644 (file)
@@ -83,8 +83,15 @@ enum byteorder {
 
 struct expr;
 
+/**
+ * enum datatype_flags
+ *
+ * @DTYPE_F_ALLOC:             datatype is dynamically allocated
+ * @DTYPE_F_PREFIX:            preferred representation for ranges is a prefix
+ */
 enum datatype_flags {
        DTYPE_F_ALLOC           = (1 << 0),
+       DTYPE_F_PREFIX          = (1 << 1),
 };
 
 /**
index 86ea80e3ce3ff4ed0fd960f6fb7ce5d51ba11d5e..45944907c8a3a48d1563ad1253e4917159346b9d 100644 (file)
@@ -380,6 +380,7 @@ const struct datatype ipaddr_type = {
        .basetype       = &integer_type,
        .print          = ipaddr_type_print,
        .parse          = ipaddr_type_parse,
+       .flags          = DTYPE_F_PREFIX,
 };
 
 static void ip6addr_type_print(const struct expr *expr)
@@ -437,6 +438,7 @@ const struct datatype ip6addr_type = {
        .basetype       = &integer_type,
        .print          = ip6addr_type_print,
        .parse          = ip6addr_type_parse,
+       .flags          = DTYPE_F_PREFIX,
 };
 
 static void inet_protocol_type_print(const struct expr *expr)
@@ -662,6 +664,7 @@ const struct datatype mark_type = {
        .basefmt        = "0x%.8Zx",
        .print          = mark_type_print,
        .parse          = mark_type_parse,
+       .flags          = DTYPE_F_PREFIX,
 };
 
 static void time_type_print(const struct expr *expr)
index f06a2fbd522d8124e68d89de058dc5e8730bb637..849acd1589563a2f70e3281e00b939f686bf1159 100644 (file)
@@ -61,6 +61,7 @@ static const struct datatype realm_type = {
        .basetype       = &integer_type,
        .print          = realm_type_print,
        .parse          = realm_type_parse,
+       .flags          = DTYPE_F_PREFIX,
 };
 
 static void tchandle_type_print(const struct expr *expr)
index 5426e24f196a13bdcac5b6762b42bd2d3501a02c..e3bca4cab6483a7443731daf8ed6d231c4790422 100644 (file)
@@ -552,7 +552,9 @@ void interval_map_decompose(struct expr *set)
 
                if (!mpz_cmp_ui(range, 0))
                        compound_expr_add(set, low);
-               else if (!range_is_prefix(range) || mpz_cmp_ui(p, 0)) {
+               else if ((!range_is_prefix(range) ||
+                         !(i->dtype->flags & DTYPE_F_PREFIX)) ||
+                        mpz_cmp_ui(p, 0)) {
                        struct expr *tmp;
 
                        tmp = constant_expr_alloc(&low->location, low->dtype,