Skip to content

Commit 73db1b5

Browse files
Phil Sutterummakynes
authored andcommitted
selftests: netfilter: Torture nftables netdev hooks
Add a ruleset which binds to various interface names via netdev-family chains and flowtables and massage the notifiers by frequently renaming interfaces to match these names. While doing so: - Keep an 'nft monitor' running in background to receive the notifications - Loop over 'nft list ruleset' to exercise ruleset dump codepath - Have iperf running so the involved chains/flowtables see traffic If supported, also test interface wildcard support separately by creating a flowtable with 'wild*' interface spec and quickly add/remove matching dummy interfaces. Signed-off-by: Phil Sutter <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 465b9ee commit 73db1b5

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

tools/testing/selftests/net/netfilter/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ TEST_PROGS += nft_concat_range.sh
2424
TEST_PROGS += nft_conntrack_helper.sh
2525
TEST_PROGS += nft_fib.sh
2626
TEST_PROGS += nft_flowtable.sh
27+
TEST_PROGS += nft_interface_stress.sh
2728
TEST_PROGS += nft_meta.sh
2829
TEST_PROGS += nft_nat.sh
2930
TEST_PROGS += nft_nat_zones.sh
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/bin/bash -e
2+
#
3+
# SPDX-License-Identifier: GPL-2.0
4+
#
5+
# Torture nftables' netdevice notifier callbacks and related code by frequent
6+
# renaming of interfaces which netdev-family chains and flowtables hook into.
7+
8+
source lib.sh
9+
10+
checktool "nft --version" "run test without nft tool"
11+
checktool "iperf3 --version" "run test without iperf3 tool"
12+
13+
# how many seconds to torture the kernel?
14+
# default to 80% of max run time but don't exceed 48s
15+
TEST_RUNTIME=$((${kselftest_timeout:-60} * 8 / 10))
16+
[[ $TEST_RUNTIME -gt 48 ]] && TEST_RUNTIME=48
17+
18+
trap "cleanup_all_ns" EXIT
19+
20+
setup_ns nsc nsr nss
21+
22+
ip -net $nsc link add cr0 type veth peer name rc0 netns $nsr
23+
ip -net $nsc addr add 10.0.0.1/24 dev cr0
24+
ip -net $nsc link set cr0 up
25+
ip -net $nsc route add default via 10.0.0.2
26+
27+
ip -net $nss link add sr0 type veth peer name rs0 netns $nsr
28+
ip -net $nss addr add 10.1.0.1/24 dev sr0
29+
ip -net $nss link set sr0 up
30+
ip -net $nss route add default via 10.1.0.2
31+
32+
ip -net $nsr addr add 10.0.0.2/24 dev rc0
33+
ip -net $nsr link set rc0 up
34+
ip -net $nsr addr add 10.1.0.2/24 dev rs0
35+
ip -net $nsr link set rs0 up
36+
ip netns exec $nsr sysctl -q net.ipv4.ip_forward=1
37+
ip netns exec $nsr sysctl -q net.ipv4.conf.all.forwarding=1
38+
39+
{
40+
echo "table netdev t {"
41+
for ((i = 0; i < 10; i++)); do
42+
cat <<-EOF
43+
chain chain_rc$i {
44+
type filter hook ingress device rc$i priority 0
45+
counter
46+
}
47+
chain chain_rs$i {
48+
type filter hook ingress device rs$i priority 0
49+
counter
50+
}
51+
EOF
52+
done
53+
echo "}"
54+
echo "table ip t {"
55+
for ((i = 0; i < 10; i++)); do
56+
cat <<-EOF
57+
flowtable ft_${i} {
58+
hook ingress priority 0
59+
devices = { rc$i, rs$i }
60+
}
61+
EOF
62+
done
63+
echo "chain c {"
64+
echo "type filter hook forward priority 0"
65+
for ((i = 0; i < 10; i++)); do
66+
echo -n "iifname rc$i oifname rs$i "
67+
echo "ip protocol tcp counter flow add @ft_${i}"
68+
done
69+
echo "counter"
70+
echo "}"
71+
echo "}"
72+
} | ip netns exec $nsr nft -f - || {
73+
echo "SKIP: Could not load nft ruleset"
74+
exit $ksft_skip
75+
}
76+
77+
for ((o=0, n=1; ; o=n, n++, n %= 10)); do
78+
ip -net $nsr link set rc$o name rc$n
79+
ip -net $nsr link set rs$o name rs$n
80+
done &
81+
rename_loop_pid=$!
82+
83+
while true; do ip netns exec $nsr nft list ruleset >/dev/null 2>&1; done &
84+
nft_list_pid=$!
85+
86+
ip netns exec $nsr nft monitor >/dev/null &
87+
nft_monitor_pid=$!
88+
89+
ip netns exec $nss iperf3 --server --daemon -1
90+
summary_expr='s,^\[SUM\] .* \([0-9\.]\+\) Kbits/sec .* receiver,\1,p'
91+
rate=$(ip netns exec $nsc iperf3 \
92+
--format k -c 10.1.0.1 --time $TEST_RUNTIME \
93+
--length 56 --parallel 10 -i 0 | sed -n "$summary_expr")
94+
95+
kill $nft_list_pid
96+
kill $nft_monitor_pid
97+
kill $rename_loop_pid
98+
wait
99+
100+
ip netns exec $nsr nft -f - <<EOF
101+
table ip t {
102+
flowtable ft_wild {
103+
hook ingress priority 0
104+
devices = { wild* }
105+
}
106+
}
107+
EOF
108+
if [[ $? -ne 0 ]]; then
109+
echo "SKIP wildcard tests: not supported by host's nft?"
110+
else
111+
for ((i = 0; i < 100; i++)); do
112+
ip -net $nsr link add wild$i type dummy &
113+
done
114+
wait
115+
for ((i = 80; i < 100; i++)); do
116+
ip -net $nsr link del wild$i &
117+
done
118+
for ((i = 0; i < 80; i++)); do
119+
ip -net $nsr link del wild$i &
120+
done
121+
wait
122+
for ((i = 0; i < 100; i += 10)); do
123+
(
124+
for ((j = 0; j < 10; j++)); do
125+
ip -net $nsr link add wild$((i + j)) type dummy
126+
done
127+
for ((j = 0; j < 10; j++)); do
128+
ip -net $nsr link del wild$((i + j))
129+
done
130+
) &
131+
done
132+
wait
133+
fi
134+
135+
[[ $(</proc/sys/kernel/tainted) -eq 0 ]] || {
136+
echo "FAIL: Kernel is tainted!"
137+
exit $ksft_fail
138+
}
139+
140+
[[ $rate -gt 0 ]] || {
141+
echo "FAIL: Zero throughput in iperf3"
142+
exit $ksft_fail
143+
}
144+
145+
[[ -f /sys/kernel/debug/kmemleak && \
146+
-n $(</sys/kernel/debug/kmemleak) ]] && {
147+
echo "FAIL: non-empty kmemleak report"
148+
exit $ksft_fail
149+
}
150+
151+
exit $ksft_pass

0 commit comments

Comments
 (0)