[PATCH net 2/2] selftests: netfilter: cover IPv6 FIB rule suppression
From: Leonard Lausen
Date: Tue Nov 10 2026 - 08:52:26 EST
Extend nft_fib.sh using its existing namespaces, interfaces and counter
helper to exercise suppress_prefixlength and suppress_ifgroup.
Check that a default route and a route through a matching interface group
are suppressed, while a non-default route and a nonmatching group remain
usable. Also check that blackhole, unreachable and prohibit routes remain
terminal under either suppression attribute despite a usable route in a
later table.
Count an arriving probe only when the nftables FIB result matches the
expected output interface or reject type. Compare this with an ordinary
route lookup, which must select the expected device or fail for a reject
route. Requiring a positive counter avoids treating a missing packet as
proof of correct suppression.
Assisted-by: LLM
Signed-off-by: Leonard Lausen <leonard@xxxxxxxxx>
---
.../selftests/net/netfilter/nft_fib.sh | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/tools/testing/selftests/net/netfilter/nft_fib.sh b/tools/testing/selftests/net/netfilter/nft_fib.sh
index 04544905c216..02b625794669 100755
--- a/tools/testing/selftests/net/netfilter/nft_fib.sh
+++ b/tools/testing/selftests/net/netfilter/nft_fib.sh
@@ -202,6 +202,38 @@ check_fib_counter() {
return 0
}
+# Count and drop probes before the existing RPF rules can log expected failures.
+test_fib_suppress() {
+ local label="$1" expected="$2"
+ local result="${3:-oifname}" err=0
+
+ ip netns exec "$nsrouter" nft -f /dev/stdin <<EOF || return 1
+flush table ip6 filter
+table ip6 filter {
+ chain prerouting {
+ type filter hook prerouting priority -1;
+ ip6 saddr dead:1::99 icmpv6 type echo-request \
+ fib saddr . mark $result "$expected" counter drop
+ }
+}
+EOF
+ ip netns exec "$ns1" ping -6 -c 1 -W 0.1 -q dead:1::1 > /dev/null 2>&1
+ if [ "$result" = type ]; then
+ ip -net "$nsrouter" -6 route get dead:1::99 from dead:1::1 > /dev/null 2>&1 && err=1
+ else
+ ip -net "$nsrouter" -6 route get dead:1::99 from dead:1::1 |
+ grep -q "dev $expected " || err=1
+ fi
+ if check_fib_type_counter_family ip6 1 "$nsrouter" prerouting "$result" "$label" &&
+ [ "$err" -eq 0 ]; then
+ echo "PASS: $label"
+ else
+ echo "FAIL: $label"
+ ret=1
+ return 1
+ fi
+}
+
load_ruleset "$nsrouter"
load_ruleset "$ns1"
load_ruleset "$ns2"
@@ -724,6 +756,42 @@ test_fib_vrf()
check_fib_veth_vrf_type "fib expression address types match (iif in vrf)"
}
+# Test both suppression attributes before the other policy-routing tests.
+# The non-default route and nonmatching group must remain usable.
+ip -net "$nsrouter" -6 route add table 128 default dev veth1 || exit 1
+ip -net "$nsrouter" -6 route add table 129 dead:1::/64 dev veth0 || exit 1
+ip -net "$nsrouter" link set veth1 group 42 || exit 1
+ip -net "$nsrouter" -6 rule add pref 100 to dead:1::99 table 128 suppress_prefixlength 0 || exit 1
+ip -net "$nsrouter" -6 rule add pref 101 to dead:1::99 table 129 || exit 1
+ip netns exec "$nsrouter" nft add table ip6 filter || exit 1
+
+test_fib_suppress "suppress default route" veth0 || ret=1
+ip -net "$nsrouter" -6 route add table 128 dead:1::/64 dev veth1 || exit 1
+test_fib_suppress "retain non-default route" veth1 || ret=1
+ip -net "$nsrouter" -6 rule del pref 100
+ip -net "$nsrouter" -6 rule add pref 100 to dead:1::99 table 128 suppress_ifgroup 42 || exit 1
+test_fib_suppress "suppress matching interface group" veth0 || ret=1
+ip -net "$nsrouter" link set veth1 group 43 || exit 1
+test_fib_suppress "retain nonmatching interface group" veth1 || ret=1
+
+# Reject routes use loopback (group 0) and must remain terminal.
+ip -net "$nsrouter" -6 route flush table 128
+for suppress in suppress_prefixlength suppress_ifgroup; do
+ ip -net "$nsrouter" -6 rule del pref 100
+ ip -net "$nsrouter" -6 rule add pref 100 to dead:1::99 table 128 "$suppress" 0 || exit 1
+ for type in blackhole unreachable prohibit; do
+ ip -net "$nsrouter" -6 route replace "$type" default table 128 || exit 1
+ test_fib_suppress "retain $type ($suppress)" "$type" type || ret=1
+ done
+done
+
+ip -net "$nsrouter" -6 rule del pref 100
+ip -net "$nsrouter" -6 rule del pref 101
+ip -net "$nsrouter" -6 route flush table 128
+ip -net "$nsrouter" -6 route flush table 129
+ip -net "$nsrouter" link set veth1 group 0
+ip netns exec "$nsrouter" nft delete table ip6 filter
+
ip netns exec "$nsrouter" sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
--
2.55.0