Blob Blame Raw
From 3a2016f539e46183965bada40946e259c33158d9 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Tue, 30 Jun 2020 16:20:23 +0200
Subject: [PATCH] segtree: Fix get element command with prefixes

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1832235
Upstream Status: nftables commit 506fb113f7ca4

commit 506fb113f7ca4fbb3d6da09ef6f9dc2b31f54a1f
Author: Phil Sutter <phil@nwl.cc>
Date:   Thu Apr 30 14:02:44 2020 +0200

    segtree: Fix get element command with prefixes

    Code wasn't aware of prefix elements in interval sets. With previous
    changes in place, they merely need to be accepted in
    get_set_interval_find() - value comparison and expression duplication is
    identical to ranges.

    Extend sets/0034get_element_0 test to cover prefixes as well. While
    being at it, also cover concatenated ranges.

    Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 src/segtree.c                                |  1 +
 tests/shell/testcases/sets/0034get_element_0 | 62 ++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/src/segtree.c b/src/segtree.c
index 6e1f696..073c6ec 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -689,6 +689,7 @@ static struct expr *get_set_interval_find(const struct table *table,
 
 	list_for_each_entry(i, &set->init->expressions, list) {
 		switch (i->key->etype) {
+		case EXPR_PREFIX:
 		case EXPR_RANGE:
 			range_expr_value_low(val, i);
 			if (left && mpz_cmp(left->key->value, val))
diff --git a/tests/shell/testcases/sets/0034get_element_0 b/tests/shell/testcases/sets/0034get_element_0
index e23dbda..3343529 100755
--- a/tests/shell/testcases/sets/0034get_element_0
+++ b/tests/shell/testcases/sets/0034get_element_0
@@ -2,43 +2,69 @@
 
 RC=0
 
-check() { # (elems, expected)
-	out=$($NFT get element ip t s "{ $1 }")
+check() { # (set, elems, expected)
+	out=$($NFT get element ip t $1 "{ $2 }")
 	out=$(grep "elements =" <<< "$out")
 	out="${out#* \{ }"
 	out="${out% \}}"
-	[[ "$out" == "$2" ]] && return
-	echo "ERROR: asked for '$1', expecting '$2' but got '$out'"
+	[[ "$out" == "$3" ]] && return
+	echo "ERROR: asked for '$2' in set $1, expecting '$3' but got '$out'"
 	((RC++))
 }
 
 RULESET="add table ip t
 add set ip t s { type inet_service; flags interval; }
 add element ip t s { 10, 20-30, 40, 50-60 }
+add set ip t ips { type ipv4_addr; flags interval; }
+add element ip t ips { 10.0.0.1, 10.0.0.5-10.0.0.8 }
+add element ip t ips { 10.0.0.128/25, 10.0.1.0/24, 10.0.2.3-10.0.2.12 }
+add set ip t cs { type ipv4_addr . inet_service; flags interval; }
+add element ip t cs { 10.0.0.1 . 22, 10.1.0.0/16 . 1-1024 }
+add element ip t cs { 10.2.0.1-10.2.0.8 . 1024-65535 }
 "
 
 $NFT -f - <<< "$RULESET"
 
 # simple cases, (non-)existing values and ranges
-check 10 10
-check 11 ""
-check 20-30 20-30
-check 15-18 ""
+check s 10 10
+check s 11 ""
+check s 20-30 20-30
+check s 15-18 ""
 
 # multiple single elements, ranges smaller than present
-check "10, 40" "10, 40"
-check "22-24, 26-28" "20-30, 20-30"
-check 21-29 20-30
+check s "10, 40" "10, 40"
+check s "22-24, 26-28" "20-30, 20-30"
+check s 21-29 20-30
 
 # mixed single elements and ranges
-check "10, 20" "10, 20-30"
-check "10, 22" "10, 20-30"
-check "10, 22-24" "10, 20-30"
+check s "10, 20" "10, 20-30"
+check s "10, 22" "10, 20-30"
+check s "10, 22-24" "10, 20-30"
 
 # non-existing ranges matching elements
-check 10-40 ""
-check 10-20 ""
-check 10-25 ""
-check 25-55 ""
+check s 10-40 ""
+check s 10-20 ""
+check s 10-25 ""
+check s 25-55 ""
+
+# playing with IPs, ranges and prefixes
+check ips 10.0.0.1 10.0.0.1
+check ips 10.0.0.2 ""
+check ips 10.0.1.0/24 10.0.1.0/24
+check ips 10.0.1.2/31 10.0.1.0/24
+check ips 10.0.1.0 10.0.1.0/24
+check ips 10.0.1.3 10.0.1.0/24
+check ips 10.0.1.255 10.0.1.0/24
+check ips 10.0.2.3-10.0.2.12 10.0.2.3-10.0.2.12
+check ips 10.0.2.10 10.0.2.3-10.0.2.12
+check ips 10.0.2.12 10.0.2.3-10.0.2.12
+
+# test concatenated ranges, i.e. Pi, Pa and Po
+check cs "10.0.0.1 . 22" "10.0.0.1 . 22"
+check cs "10.0.0.1 . 23" ""
+check cs "10.0.0.2 . 22" ""
+check cs "10.1.0.1 . 42" "10.1.0.0/16 . 1-1024"
+check cs "10.1.1.0/24 . 10-20" "10.1.0.0/16 . 1-1024"
+check cs "10.2.0.3 . 20000" "10.2.0.1-10.2.0.8 . 1024-65535"
 
 exit $RC
-- 
1.8.3.1