Skip to content

Commit 6523cf5

Browse files
Florian Westphalummakynes
authored andcommitted
selftests: netfilter: add bridge conntrack + multicast test case
Add test case for multicast packet confirm race. Without preceding patch, this should result in: WARNING: CPU: 0 PID: 38 at net/netfilter/nf_conntrack_core.c:1198 __nf_conntrack_confirm+0x3ed/0x5f0 Workqueue: events_unbound macvlan_process_broadcast RIP: 0010:__nf_conntrack_confirm+0x3ed/0x5f0 ? __nf_conntrack_confirm+0x3ed/0x5f0 nf_confirm+0x2ad/0x2d0 nf_hook_slow+0x36/0xd0 ip_local_deliver+0xce/0x110 __netif_receive_skb_one_core+0x4f/0x70 process_backlog+0x8c/0x130 [..] Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 62e7151 commit 6523cf5

2 files changed

Lines changed: 190 additions & 1 deletion

File tree

tools/testing/selftests/netfilter/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \
77
nft_queue.sh nft_meta.sh nf_nat_edemux.sh \
88
ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \
99
conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh \
10-
conntrack_sctp_collision.sh xt_string.sh
10+
conntrack_sctp_collision.sh xt_string.sh \
11+
bridge_netfilter.sh
1112

1213
HOSTPKG_CONFIG := pkg-config
1314

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
#
4+
# Test bridge netfilter + conntrack, a combination that doesn't really work,
5+
# with multicast/broadcast packets racing for hash table insertion.
6+
7+
# eth0 br0 eth0
8+
# setup is: ns1 <->,ns0 <-> ns3
9+
# ns2 <-' `'-> ns4
10+
11+
# Kselftest framework requirement - SKIP code is 4.
12+
ksft_skip=4
13+
ret=0
14+
15+
sfx=$(mktemp -u "XXXXXXXX")
16+
ns0="ns0-$sfx"
17+
ns1="ns1-$sfx"
18+
ns2="ns2-$sfx"
19+
ns3="ns3-$sfx"
20+
ns4="ns4-$sfx"
21+
22+
ebtables -V > /dev/null 2>&1
23+
if [ $? -ne 0 ];then
24+
echo "SKIP: Could not run test without ebtables"
25+
exit $ksft_skip
26+
fi
27+
28+
ip -Version > /dev/null 2>&1
29+
if [ $? -ne 0 ];then
30+
echo "SKIP: Could not run test without ip tool"
31+
exit $ksft_skip
32+
fi
33+
34+
for i in $(seq 0 4); do
35+
eval ip netns add \$ns$i
36+
done
37+
38+
cleanup() {
39+
for i in $(seq 0 4); do eval ip netns del \$ns$i;done
40+
}
41+
42+
trap cleanup EXIT
43+
44+
do_ping()
45+
{
46+
fromns="$1"
47+
dstip="$2"
48+
49+
ip netns exec $fromns ping -c 1 -q $dstip > /dev/null
50+
if [ $? -ne 0 ]; then
51+
echo "ERROR: ping from $fromns to $dstip"
52+
ip netns exec ${ns0} nft list ruleset
53+
ret=1
54+
fi
55+
}
56+
57+
bcast_ping()
58+
{
59+
fromns="$1"
60+
dstip="$2"
61+
62+
for i in $(seq 1 1000); do
63+
ip netns exec $fromns ping -q -f -b -c 1 -q $dstip > /dev/null 2>&1
64+
if [ $? -ne 0 ]; then
65+
echo "ERROR: ping -b from $fromns to $dstip"
66+
ip netns exec ${ns0} nft list ruleset
67+
fi
68+
done
69+
}
70+
71+
ip link add veth1 netns ${ns0} type veth peer name eth0 netns ${ns1}
72+
if [ $? -ne 0 ]; then
73+
echo "SKIP: Can't create veth device"
74+
exit $ksft_skip
75+
fi
76+
77+
ip link add veth2 netns ${ns0} type veth peer name eth0 netns $ns2
78+
ip link add veth3 netns ${ns0} type veth peer name eth0 netns $ns3
79+
ip link add veth4 netns ${ns0} type veth peer name eth0 netns $ns4
80+
81+
ip -net ${ns0} link set lo up
82+
83+
for i in $(seq 1 4); do
84+
ip -net ${ns0} link set veth$i up
85+
done
86+
87+
ip -net ${ns0} link add br0 type bridge stp_state 0 forward_delay 0 nf_call_iptables 1 nf_call_ip6tables 1 nf_call_arptables 1
88+
if [ $? -ne 0 ]; then
89+
echo "SKIP: Can't create bridge br0"
90+
exit $ksft_skip
91+
fi
92+
93+
# make veth0,1,2 part of bridge.
94+
for i in $(seq 1 3); do
95+
ip -net ${ns0} link set veth$i master br0
96+
done
97+
98+
# add a macvlan on top of the bridge.
99+
MACVLAN_ADDR=ba:f3:13:37:42:23
100+
ip -net ${ns0} link add link br0 name macvlan0 type macvlan mode private
101+
ip -net ${ns0} link set macvlan0 address ${MACVLAN_ADDR}
102+
ip -net ${ns0} link set macvlan0 up
103+
ip -net ${ns0} addr add 10.23.0.1/24 dev macvlan0
104+
105+
# add a macvlan on top of veth4.
106+
MACVLAN_ADDR=ba:f3:13:37:42:24
107+
ip -net ${ns0} link add link veth4 name macvlan4 type macvlan mode vepa
108+
ip -net ${ns0} link set macvlan4 address ${MACVLAN_ADDR}
109+
ip -net ${ns0} link set macvlan4 up
110+
111+
# make the macvlan part of the bridge.
112+
# veth4 is not a bridge port, only the macvlan on top of it.
113+
ip -net ${ns0} link set macvlan4 master br0
114+
115+
ip -net ${ns0} link set br0 up
116+
ip -net ${ns0} addr add 10.0.0.1/24 dev br0
117+
ip netns exec ${ns0} sysctl -q net.bridge.bridge-nf-call-iptables=1
118+
ret=$?
119+
if [ $ret -ne 0 ] ; then
120+
echo "SKIP: bridge netfilter not available"
121+
ret=$ksft_skip
122+
fi
123+
124+
# for testing, so namespaces will reply to ping -b probes.
125+
ip netns exec ${ns0} sysctl -q net.ipv4.icmp_echo_ignore_broadcasts=0
126+
127+
# enable conntrack in ns0 and drop broadcast packets in forward to
128+
# avoid them from getting confirmed in the postrouting hook before
129+
# the cloned skb is passed up the stack.
130+
ip netns exec ${ns0} nft -f - <<EOF
131+
table ip filter {
132+
chain input {
133+
type filter hook input priority 1; policy accept
134+
iifname br0 counter
135+
ct state new accept
136+
}
137+
}
138+
139+
table bridge filter {
140+
chain forward {
141+
type filter hook forward priority 0; policy accept
142+
meta pkttype broadcast ip protocol icmp counter drop
143+
}
144+
}
145+
EOF
146+
147+
# place 1, 2 & 3 in same subnet, connected via ns0:br0.
148+
# ns4 is placed in same subnet as well, but its not
149+
# part of the bridge: the corresponding veth4 is not
150+
# part of the bridge, only its macvlan interface.
151+
for i in $(seq 1 4); do
152+
eval ip -net \$ns$i link set lo up
153+
eval ip -net \$ns$i link set eth0 up
154+
done
155+
for i in $(seq 1 2); do
156+
eval ip -net \$ns$i addr add 10.0.0.1$i/24 dev eth0
157+
done
158+
159+
ip -net ${ns3} addr add 10.23.0.13/24 dev eth0
160+
ip -net ${ns4} addr add 10.23.0.14/24 dev eth0
161+
162+
# test basic connectivity
163+
do_ping ${ns1} 10.0.0.12
164+
do_ping ${ns3} 10.23.0.1
165+
do_ping ${ns4} 10.23.0.1
166+
167+
if [ $ret -eq 0 ];then
168+
echo "PASS: netns connectivity: ns1 can reach ns2, ns3 and ns4 can reach ns0"
169+
fi
170+
171+
bcast_ping ${ns1} 10.0.0.255
172+
173+
# This should deliver broadcast to macvlan0, which is on top of ns0:br0.
174+
bcast_ping ${ns3} 10.23.0.255
175+
176+
# same, this time via veth4:macvlan4.
177+
bcast_ping ${ns4} 10.23.0.255
178+
179+
read t < /proc/sys/kernel/tainted
180+
181+
if [ $t -eq 0 ];then
182+
echo PASS: kernel not tainted
183+
else
184+
echo ERROR: kernel is tainted
185+
ret=1
186+
fi
187+
188+
exit $ret

0 commit comments

Comments
 (0)