Skip to content

Commit f1a8c6f

Browse files
author
CKI Backport Bot
committed
selftests: netfilter: nft_fib.sh: add 'type' mode tests
JIRA: https://issues.redhat.com/browse/RHEL-88574 commit 839340f Author: Florian Westphal <fw@strlen.de> Date: Wed May 21 11:38:45 2025 +0200 selftests: netfilter: nft_fib.sh: add 'type' mode tests fib can either lookup the interface id/name of the output interface that would be used for the given address, or it can check for the type of the address according to the fib, e.g. local, unicast, multicast and so on. This can be used to e.g. make a locally configured address only reachable through its interface. Example: given eth0:10.1.1.1 and eth1:10.1.2.1 then 'fib daddr type' for 10.1.1.1 arriving on eth1 will be 'local', but 'fib daddr . iif type' is expected to return 'unicast', whereas 'fib daddr' and 'fib daddr . iif' are expected to indicate 'local' if such a packet arrives on eth0. So far nft_fib.sh only covered oif/oifname, not type. Repeat tests both with default and a policy (ip rule) based setup. Also try to run all remaining tests even if a subtest has failed. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
1 parent 6f003a8 commit f1a8c6f

File tree

1 file changed

+174
-10
lines changed

1 file changed

+174
-10
lines changed

tools/testing/selftests/net/netfilter/nft_fib.sh

Lines changed: 174 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
# This tests the fib expression.
44
#
55
# Kselftest framework requirement - SKIP code is 4.
6+
#
7+
# 10.0.1.99 10.0.1.1 10.0.2.1 10.0.2.99
8+
# dead:1::99 dead:1::1 dead:2::1 dead:2::99
9+
# ns1 <-------> [ veth0 ] nsrouter [veth1] <-------> ns2
610

711
source lib.sh
812

@@ -72,6 +76,89 @@ table inet filter {
7276
EOF
7377
}
7478

79+
load_type_ruleset() {
80+
local netns=$1
81+
82+
for family in ip ip6;do
83+
ip netns exec "$netns" nft -f /dev/stdin <<EOF
84+
table $family filter {
85+
chain type_match_in {
86+
fib daddr type local counter comment "daddr configured on other iface"
87+
fib daddr . iif type local counter comment "daddr configured on iif"
88+
fib daddr type unicast counter comment "daddr not local"
89+
fib daddr . iif type unicast counter comment "daddr not configured on iif"
90+
}
91+
92+
chain type_match_out {
93+
fib daddr type unicast counter
94+
fib daddr . oif type unicast counter
95+
fib daddr type local counter
96+
fib daddr . oif type local counter
97+
}
98+
99+
chain prerouting {
100+
type filter hook prerouting priority 0;
101+
icmp type echo-request counter jump type_match_in
102+
icmpv6 type echo-request counter jump type_match_in
103+
}
104+
105+
chain input {
106+
type filter hook input priority 0;
107+
icmp type echo-request counter jump type_match_in
108+
icmpv6 type echo-request counter jump type_match_in
109+
}
110+
111+
chain forward {
112+
type filter hook forward priority 0;
113+
icmp type echo-request counter jump type_match_in
114+
icmpv6 type echo-request counter jump type_match_in
115+
}
116+
117+
chain output {
118+
type filter hook output priority 0;
119+
icmp type echo-request counter jump type_match_out
120+
icmpv6 type echo-request counter jump type_match_out
121+
}
122+
123+
chain postrouting {
124+
type filter hook postrouting priority 0;
125+
icmp type echo-request counter jump type_match_out
126+
icmpv6 type echo-request counter jump type_match_out
127+
}
128+
}
129+
EOF
130+
done
131+
}
132+
133+
reload_type_ruleset() {
134+
ip netns exec "$1" nft flush table ip filter
135+
ip netns exec "$1" nft flush table ip6 filter
136+
load_type_ruleset "$1"
137+
}
138+
139+
check_fib_type_counter_family() {
140+
local family="$1"
141+
local want="$2"
142+
local ns="$3"
143+
local chain="$4"
144+
local what="$5"
145+
local errmsg="$6"
146+
147+
if ! ip netns exec "$ns" nft list chain "$family" filter "$chain" | grep "$what" | grep -q "packets $want";then
148+
echo "Netns $ns $family fib type counter doesn't match expected packet count of $want for $what $errmsg" 1>&2
149+
ip netns exec "$ns" nft list chain "$family" filter "$chain"
150+
ret=1
151+
return 1
152+
fi
153+
154+
return 0
155+
}
156+
157+
check_fib_type_counter() {
158+
check_fib_type_counter_family "ip" "$@" || return 1
159+
check_fib_type_counter_family "ip6" "$@" || return 1
160+
}
161+
75162
load_ruleset_count() {
76163
local netns=$1
77164

@@ -90,6 +177,7 @@ check_drops() {
90177
if dmesg | grep -q ' nft_rpfilter: ';then
91178
dmesg | grep ' nft_rpfilter: '
92179
echo "FAIL: rpfilter did drop packets"
180+
ret=1
93181
return 1
94182
fi
95183

@@ -164,17 +252,70 @@ test_ping() {
164252
return 0
165253
}
166254

255+
test_fib_type() {
256+
local notice="$1"
257+
local errmsg="addr-on-if"
258+
local lret=0
259+
260+
if ! load_type_ruleset "$nsrouter";then
261+
echo "SKIP: Could not load fib type ruleset"
262+
[ $ret -eq 0 ] && ret=$ksft_skip
263+
return
264+
fi
265+
266+
# makes router receive packet for addresses configured on incoming
267+
# interface.
268+
test_ping 10.0.1.1 dead:1::1 || return 1
269+
270+
# expectation: triggers all 'local' in prerouting/input.
271+
check_fib_type_counter 2 "$nsrouter" "type_match_in" "fib daddr type local" "$errmsg" || lret=1
272+
check_fib_type_counter 2 "$nsrouter" "type_match_in" "fib daddr . iif type local" "$errmsg" || lret=1
273+
274+
reload_type_ruleset "$nsrouter"
275+
# makes router receive packet for address configured on a different (but local)
276+
# interface.
277+
test_ping 10.0.2.1 dead:2::1 || return 1
278+
279+
# expectation: triggers 'unicast' in prerouting/input for daddr . iif and local for 'daddr'.
280+
errmsg="addr-on-host"
281+
check_fib_type_counter 2 "$nsrouter" "type_match_in" "fib daddr type local" "$errmsg" || lret=1
282+
check_fib_type_counter 2 "$nsrouter" "type_match_in" "fib daddr . iif type unicast" "$errmsg" || lret=1
283+
284+
reload_type_ruleset "$nsrouter"
285+
test_ping 10.0.2.99 dead:2::99 || return 1
286+
errmsg="addr-on-otherhost"
287+
check_fib_type_counter 2 "$nsrouter" "type_match_in" "fib daddr type unicast" "$errmsg" || lret=1
288+
check_fib_type_counter 2 "$nsrouter" "type_match_in" "fib daddr . iif type unicast" "$errmsg" || lret=1
289+
290+
if [ $lret -eq 0 ];then
291+
echo "PASS: fib expression address types match ($notice)"
292+
else
293+
echo "FAIL: fib expression address types match ($notice)"
294+
ret=1
295+
fi
296+
}
297+
167298
ip netns exec "$nsrouter" sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
168299
ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
169300
ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
170301

171302
test_ping 10.0.2.1 dead:2::1 || exit 1
172-
check_drops || exit 1
303+
check_drops
173304

174305
test_ping 10.0.2.99 dead:2::99 || exit 1
175-
check_drops || exit 1
306+
check_drops
176307

177-
echo "PASS: fib expression did not cause unwanted packet drops"
308+
[ $ret -eq 0 ] && echo "PASS: fib expression did not cause unwanted packet drops"
309+
310+
load_input_ruleset "$ns1"
311+
312+
test_ping 127.0.0.1 ::1
313+
check_drops
314+
315+
test_ping 10.0.1.99 dead:1::99
316+
check_drops
317+
318+
[ $ret -eq 0 ] && echo "PASS: fib expression did not discard loopback packets"
178319

179320
load_input_ruleset "$ns1"
180321

@@ -234,7 +375,7 @@ ip -net "$nsrouter" addr del dead:2::1/64 dev veth0
234375
# ... pbr ruleset for the router, check iif+oif.
235376
if ! load_pbr_ruleset "$nsrouter";then
236377
echo "SKIP: Could not load fib forward ruleset"
237-
exit $ksft_skip
378+
[ "$ret" -eq 0 ] && ret=$ksft_skip
238379
fi
239380

240381
ip -net "$nsrouter" rule add from all table 128
@@ -245,11 +386,34 @@ ip -net "$nsrouter" route add table 129 to 10.0.2.0/24 dev veth1
245386
# drop main ipv4 table
246387
ip -net "$nsrouter" -4 rule delete table main
247388

248-
if ! test_ping 10.0.2.99 dead:2::99;then
249-
ip -net "$nsrouter" nft list ruleset
250-
echo "FAIL: fib mismatch in pbr setup"
251-
exit 1
389+
if test_ping 10.0.2.99 dead:2::99;then
390+
echo "PASS: fib expression forward check with policy based routing"
391+
else
392+
echo "FAIL: fib expression forward check with policy based routing"
393+
ret=1
252394
fi
253395

254-
echo "PASS: fib expression forward check with policy based routing"
255-
exit 0
396+
test_fib_type "policy routing"
397+
ip netns exec "$nsrouter" nft delete table ip filter
398+
ip netns exec "$nsrouter" nft delete table ip6 filter
399+
400+
# Un-do policy routing changes
401+
ip -net "$nsrouter" rule del from all table 128
402+
ip -net "$nsrouter" rule del from all iif veth0 table 129
403+
404+
ip -net "$nsrouter" route del table 128 to 10.0.1.0/24 dev veth0
405+
ip -net "$nsrouter" route del table 129 to 10.0.2.0/24 dev veth1
406+
407+
ip -net "$ns1" -4 route del default
408+
ip -net "$ns1" -6 route del default
409+
410+
ip -net "$ns1" -4 route add default via 10.0.1.1
411+
ip -net "$ns1" -6 route add default via dead:1::1
412+
413+
ip -net "$nsrouter" -4 rule add from all table main priority 32766
414+
415+
test_fib_type "default table"
416+
ip netns exec "$nsrouter" nft delete table ip filter
417+
ip netns exec "$nsrouter" nft delete table ip6 filter
418+
419+
exit $ret

0 commit comments

Comments
 (0)