* [PATCH ipset 1/5] tests: check_extensions: introduce and use IPSET_MACHINE_SLOW
2026-07-23 10:34 [PATCH ipset 0/5] ipset test updates Florian Westphal
@ 2026-07-23 10:35 ` Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 2/5] tests: hash:net.t: prefer tail -n Florian Westphal
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2026-07-23 10:35 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, Florian Westphal
Running ipset tests on my laptop with a debug kernel (i.e. kasan,
kmemleak and so on) fails the check_extensions subtests because the
observed timeout is below the lower threshold. Add IPSET_MACHINE_SLOW,
similar to KSFT_MACHINE_SLOW used in the kernel kselftest framework.
If set, raise the slack value to 30s.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/check_extensions | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/tests/check_extensions b/tests/check_extensions
index 77e7c2cd8b90..ce39366ad46d 100755
--- a/tests/check_extensions
+++ b/tests/check_extensions
@@ -1,11 +1,26 @@
#!/bin/bash
ipset=${IPSET_BIN:-../src/ipset}
+setname="$1"
+elem="$2"
+wanted_timeout="$3"
+wanted_packets="$4"
+wanted_bytes="$5"
-read ip t timeout p packets b bytes <<< $($ipset l $1 | grep ^$2)
-test -z "$timeout" -o -z "$packets" -o -z "$bytes" && exit 1
-test $timeout -gt $3 -o $timeout -lt $(($3 - 10)) && exit 1
-test $packets -ne $4 -o $bytes -ne $5 && exit 1
+allowed_slack=10
+[ "$IPSET_MACHINE_SLOW" = "yes" ] && allowed_slack=30
+
+die() {
+ echo "FAIL: $0: $@"
+ exit 1
+}
+
+timeout_lower=$((wanted_timeout - allowed_slack))
+
+read ip t timeout p packets b bytes <<< $($ipset l $setname | grep ^$elem)
+test -z "$timeout" -o -z "$packets" -o -z "$bytes" && die "at least of one timeout $timeout, packets $packets, bytes $bytes not set"
+test $timeout -gt $wanted_timeout -o $timeout -lt $timeout_lower && die "timeout $timeout gt $wanted_timeout or $timeout lt $timeout_lower"
+test $packets -ne $wanted_packets -o $bytes -ne $wanted_bytes && die "packets $packets ne $wanted_packets or $bytes ne $wanted_bytes"
exit 0
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH ipset 2/5] tests: hash:net.t: prefer tail -n
2026-07-23 10:34 [PATCH ipset 0/5] ipset test updates Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 1/5] tests: check_extensions: introduce and use IPSET_MACHINE_SLOW Florian Westphal
@ 2026-07-23 10:35 ` Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 3/5] tests: prefer diff -u to cmp Florian Westphal
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2026-07-23 10:35 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, Florian Westphal
seen on fedora 44:
tail: cannot open '+2' for reading: No such file or directory
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/hash:net.t | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/hash:net.t b/tests/hash:net.t
index 4f88327684a4..73e36b5f80ab 100644
--- a/tests/hash:net.t
+++ b/tests/hash:net.t
@@ -61,7 +61,7 @@
# List set and check the number of elements
0 n=`ipset -L test|grep '^10.'|wc -l` && test $n -eq 43520
# Stress test del with range notation
-0 ./netgen.sh | tail +2|sed 's/^a/d/' | ipset restore
+0 ./netgen.sh | tail -n +2 | sed 's/^a/d/' | ipset restore
# List set and check the number of elements
0 n=`ipset -L test|grep '^10.'|wc -l` && test $n -eq 0
# Destroy test set
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH ipset 3/5] tests: prefer diff -u to cmp
2026-07-23 10:34 [PATCH ipset 0/5] ipset test updates Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 1/5] tests: check_extensions: introduce and use IPSET_MACHINE_SLOW Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 2/5] tests: hash:net.t: prefer tail -n Florian Westphal
@ 2026-07-23 10:35 ` Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 4/5] tests: hash:net,iface.t: add reproducer for UaF Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 5/5] tests: match_target.t check for proper cidr matching Florian Westphal
4 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2026-07-23 10:35 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, Florian Westphal
Irrelevant when things are working as expected, but is beneficial when they
are not: diff -u is much easier to decipher than: "differ, byte x line y"
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/iphash.t | 8 ++++----
tests/restore.t | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/iphash.t b/tests/iphash.t
index c7c0b081e34a..e4386bbf6f52 100644
--- a/tests/iphash.t
+++ b/tests/iphash.t
@@ -33,13 +33,13 @@
# IP: Restore values so that rehashing is triggered, old format
0 ipset -R < iphash.t.restore.old
# IP: Check that all values are restored
-0 (grep add iphash.t.restore | sort > "$IPSET_TMP/.foo.1") && (ipset -S test | grep add | sort > "$IPSET_TMP/.foo.2") && cmp "$IPSET_TMP/"{.foo.1,.foo.2}
+0 (grep add iphash.t.restore | sort > "$IPSET_TMP/.foo.1") && (ipset -S test | grep add | sort > "$IPSET_TMP/.foo.2") && diff -u "$IPSET_TMP/"{.foo.1,.foo.2}
# IP: Delete test set
0 ipset -X test
# IP: Restore values so that rehashing is triggered
0 ipset -R < iphash.t.restore
# IP: Check that all values are restored
-0 (grep add iphash.t.restore | sort > "$IPSET_TMP/.foo.1") && (ipset -S test | grep add | sort > "$IPSET_TMP/.foo.2") && cmp "$IPSET_TMP/"{.foo.1,.foo.2}
+0 (grep add iphash.t.restore | sort > "$IPSET_TMP/.foo.1") && (ipset -S test | grep add | sort > "$IPSET_TMP/.foo.2") && diff -u "$IPSET_TMP/"{.foo.1,.foo.2}
# IP: Flush test set
0 ipset -F test
# IP: Delete test set
@@ -55,7 +55,7 @@
# IP: Save sets
0 ipset -s -f "$IPSET_TMP/.foo0" save && ./ignore.sh "$IPSET_TMP/.foo0"
# IP: Compare sorted save and restore
-0 cmp "$IPSET_TMP/.foo" iphash.t.restore.sorted
+0 diff -u "$IPSET_TMP/.foo" iphash.t.restore.sorted
# IP: Delete test set
0 ipset x test
# IP: Delete test2 set
@@ -65,7 +65,7 @@
# IP: Save the restored set
0 (ipset save test | sort > "$IPSET_TMP/.foo.1") && ./ignore.sh "$IPSET_TMP/.foo.1"
# IP: Compare save and restore
-0 (sort iphash.t.large > "$IPSET_TMP/.foo.2") && (cmp "$IPSET_TMP/.foo" "$IPSET_TMP/.foo.2")
+0 (sort iphash.t.large > "$IPSET_TMP/.foo.2") && (diff -u "$IPSET_TMP/.foo" "$IPSET_TMP/.foo.2")
# IP: Delete all elements, one by one
0 ipset list test | sed '1,/Members/d' | xargs -n1 ipset del test
# IP: Delete test set
diff --git a/tests/restore.t b/tests/restore.t
index 02da4465af94..dddd72481784 100644
--- a/tests/restore.t
+++ b/tests/restore.t
@@ -1,7 +1,7 @@
# Check multi-set restore
0 ipset restore < restore.t.multi
# Save sets and compare
-0 ipset save > "$IPSET_TMP/.foo" && diff restore.t.multi.saved "$IPSET_TMP/.foo"
+0 ipset save > "$IPSET_TMP/.foo" && diff -u restore.t.multi.saved "$IPSET_TMP/.foo"
# Delete all sets
0 ipset x
# Check auto-increasing maximal number of sets
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH ipset 4/5] tests: hash:net,iface.t: add reproducer for UaF
2026-07-23 10:34 [PATCH ipset 0/5] ipset test updates Florian Westphal
` (2 preceding siblings ...)
2026-07-23 10:35 ` [PATCH ipset 3/5] tests: prefer diff -u to cmp Florian Westphal
@ 2026-07-23 10:35 ` Florian Westphal
2026-07-23 10:35 ` [PATCH ipset 5/5] tests: match_target.t check for proper cidr matching Florian Westphal
4 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2026-07-23 10:35 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, Florian Westphal
A faulty (never merged) kernel patch for ipset had a use-after-free
where an element was free'd without unlinking it from the table, yet
the faulty kernel passed all tests. Check that we don't free
non-matching elements, the request to delete is for non-existing
element, no free must happen and the command must fail.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/hash:net,iface.t | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/hash:net,iface.t b/tests/hash:net,iface.t
index bcd0ba451c62..556d56df5c4b 100644
--- a/tests/hash:net,iface.t
+++ b/tests/hash:net,iface.t
@@ -228,6 +228,11 @@
0 ipset -! a test 2.0.0.20/25,wlan0 timeout 700
# Counters and timeout: check counters
0 ./check_extensions test 2.0.0.0/25,wlan0 700 13 12479
+0 ipset flush test
+0 ipset add test 10.0.1.0/24,eth0
+1 ( for i in $(seq 1 10000); do ipset del test 10.0.1.0/24,eth1 ; done )
+0 ipset t test 10.0.1.0/24,eth0
+0 ipset list
# Counters and timeout: destroy set
0 ipset x test
# eof
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH ipset 5/5] tests: match_target.t check for proper cidr matching
2026-07-23 10:34 [PATCH ipset 0/5] ipset test updates Florian Westphal
` (3 preceding siblings ...)
2026-07-23 10:35 ` [PATCH ipset 4/5] tests: hash:net,iface.t: add reproducer for UaF Florian Westphal
@ 2026-07-23 10:35 ` Florian Westphal
4 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2026-07-23 10:35 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, Florian Westphal
Add a test that covers CIDR matching ("multi" flag).
In ipsets CIDR-prefix loop, the multi-flag is re-set so the loop can
continue to less-specific prefixes when an element matched key+iface but
failed the counter constraint. Without the reset, the loop stops at the
first prefix that has any non-expired element.
(The kernel patch that removed this reset was never
merged, but add test coverage for this).
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Florian Westphal <fw@strlen.de>
---
tests/match_target.t | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tests/match_target.t b/tests/match_target.t
index c3ead171dd00..c4fc777ffdd9 100644
--- a/tests/match_target.t
+++ b/tests/match_target.t
@@ -54,7 +54,7 @@
0 ./iptables.sh inet del
# Send probe packet 10.255.255.64,icmp:host-prohibited
0 ./sendip.sh -d r10 -p ipv4 -id 127.0.0.1 -is 10.255.255.64 -p icmp -ct 3 -cd 10 127.0.0.1
-# Check that 10.255.255.64,icmp:3/10 isn't in ipport
+# Check that 10.255.255.64,icmp:3/10 is not in ipport
1 ipset test ipport 10.255.255.64,icmp:host-prohibited
# Destroy sets and rules
0 ./iptables.sh inet stop
@@ -118,4 +118,16 @@
0 ipset l test |grep -q '^10.255.255.64 packets 2'
# Destroy sets and rules
0 ./iptables.sh inet stop
+# hash:net,iface set with counters.
+# /24 entry: low counter -> will fail --packets-gt 50
+# /16 entry: high counter -> would pass --packets-gt 50
+0 ipset create test hash:net,iface counters
+0 ipset add test 127.0.0.0/24,lo packets 5 bytes 500
+0 ipset add test 127.0.0.0/16,lo packets 100 bytes 10000
+# Match the set with a counter threshold of 50.
+0 iptables -A INPUT -i lo -p icmp -m set --match-set test src,src --packets-gt 50 -j ACCEPT
+0 ping -c 1 -W 1 127.0.0.1 > /dev/null 2>&1
+# Check whether the iptables rule matched.
+0 (set -e; pkts=$(iptables -v -n -L INPUT | grep test | awk '{print $1}') ; [ "${pkts:-0}" -ge 1 ] && exit 0 )
+0 ./iptables.sh inet stop
# eof
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread