Skip to content

Commit 26f7fe4

Browse files
Florian Westphalummakynes
authored andcommitted
selftests: netfilter: add ebtables broute test case
ebtables -t broute allows to redirect packets in a way that they get pushed up the stack, even if the interface is part of a bridge. In case of IP packets to non-local address, this means those IP packets are routed instead of bridged-forwarded, just as if the bridge would not have existed. Expected test output is: PASS: netns connectivity: ns1 and ns2 can reach each other PASS: ns1/ns2 connectivity with active broute rule PASS: ns1/ns2 connectivity with active broute rule and bridge forward drop Signed-off-by: Florian Westphal <[email protected]> Acked-by: David S. Miller <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 610a431 commit 26f7fe4

File tree

2 files changed

+147
-1
lines changed

2 files changed

+147
-1
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0
22
# Makefile for netfilter selftests
33

4-
TEST_PROGS := nft_trans_stress.sh nft_nat.sh
4+
TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh
55

66
include ../lib.mk
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/bin/bash
2+
#
3+
# This test is for bridge 'brouting', i.e. make some packets being routed
4+
# rather than getting bridged even though they arrive on interface that is
5+
# part of a bridge.
6+
7+
# eth0 br0 eth0
8+
# setup is: ns1 <-> ns0 <-> ns2
9+
10+
# Kselftest framework requirement - SKIP code is 4.
11+
ksft_skip=4
12+
ret=0
13+
14+
ebtables -V > /dev/null 2>&1
15+
if [ $? -ne 0 ];then
16+
echo "SKIP: Could not run test without ebtables"
17+
exit $ksft_skip
18+
fi
19+
20+
ip -Version > /dev/null 2>&1
21+
if [ $? -ne 0 ];then
22+
echo "SKIP: Could not run test without ip tool"
23+
exit $ksft_skip
24+
fi
25+
26+
ip netns add ns0
27+
ip netns add ns1
28+
ip netns add ns2
29+
30+
ip link add veth0 netns ns0 type veth peer name eth0 netns ns1
31+
if [ $? -ne 0 ]; then
32+
echo "SKIP: Can't create veth device"
33+
exit $ksft_skip
34+
fi
35+
ip link add veth1 netns ns0 type veth peer name eth0 netns ns2
36+
37+
ip -net ns0 link set lo up
38+
ip -net ns0 link set veth0 up
39+
ip -net ns0 link set veth1 up
40+
41+
ip -net ns0 link add br0 type bridge
42+
if [ $? -ne 0 ]; then
43+
echo "SKIP: Can't create bridge br0"
44+
exit $ksft_skip
45+
fi
46+
47+
ip -net ns0 link set veth0 master br0
48+
ip -net ns0 link set veth1 master br0
49+
ip -net ns0 link set br0 up
50+
ip -net ns0 addr add 10.0.0.1/24 dev br0
51+
52+
# place both in same subnet, ns1 and ns2 connected via ns0:br0
53+
for i in 1 2; do
54+
ip -net ns$i link set lo up
55+
ip -net ns$i link set eth0 up
56+
ip -net ns$i addr add 10.0.0.1$i/24 dev eth0
57+
done
58+
59+
test_ebtables_broute()
60+
{
61+
local cipt
62+
63+
# redirect is needed so the dstmac is rewritten to the bridge itself,
64+
# ip stack won't process OTHERHOST (foreign unicast mac) packets.
65+
ip netns exec ns0 ebtables -t broute -A BROUTING -p ipv4 --ip-protocol icmp -j redirect --redirect-target=DROP
66+
if [ $? -ne 0 ]; then
67+
echo "SKIP: Could not add ebtables broute redirect rule"
68+
return $ksft_skip
69+
fi
70+
71+
# ping netns1, expected to not work (ip forwarding is off)
72+
ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 2>&1
73+
if [ $? -eq 0 ]; then
74+
echo "ERROR: ping works, should have failed" 1>&2
75+
return 1
76+
fi
77+
78+
# enable forwarding on both interfaces.
79+
# neither needs an ip address, but at least the bridge needs
80+
# an ip address in same network segment as ns1 and ns2 (ns0
81+
# needs to be able to determine route for to-be-forwarded packet).
82+
ip netns exec ns0 sysctl -q net.ipv4.conf.veth0.forwarding=1
83+
ip netns exec ns0 sysctl -q net.ipv4.conf.veth1.forwarding=1
84+
85+
sleep 1
86+
87+
ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null
88+
if [ $? -ne 0 ]; then
89+
echo "ERROR: ping did not work, but it should (broute+forward)" 1>&2
90+
return 1
91+
fi
92+
93+
echo "PASS: ns1/ns2 connectivity with active broute rule"
94+
ip netns exec ns0 ebtables -t broute -F
95+
96+
# ping netns1, expected to work (frames are bridged)
97+
ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null
98+
if [ $? -ne 0 ]; then
99+
echo "ERROR: ping did not work, but it should (bridged)" 1>&2
100+
return 1
101+
fi
102+
103+
ip netns exec ns0 ebtables -t filter -A FORWARD -p ipv4 --ip-protocol icmp -j DROP
104+
105+
# ping netns1, expected to not work (DROP in bridge forward)
106+
ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 2>&1
107+
if [ $? -eq 0 ]; then
108+
echo "ERROR: ping works, should have failed (icmp forward drop)" 1>&2
109+
return 1
110+
fi
111+
112+
# re-activate brouter
113+
ip netns exec ns0 ebtables -t broute -A BROUTING -p ipv4 --ip-protocol icmp -j redirect --redirect-target=DROP
114+
115+
ip netns exec ns2 ping -q -c 1 10.0.0.11 > /dev/null
116+
if [ $? -ne 0 ]; then
117+
echo "ERROR: ping did not work, but it should (broute+forward 2)" 1>&2
118+
return 1
119+
fi
120+
121+
echo "PASS: ns1/ns2 connectivity with active broute rule and bridge forward drop"
122+
return 0
123+
}
124+
125+
# test basic connectivity
126+
ip netns exec ns1 ping -c 1 -q 10.0.0.12 > /dev/null
127+
if [ $? -ne 0 ]; then
128+
echo "ERROR: Could not reach ns2 from ns1" 1>&2
129+
ret=1
130+
fi
131+
132+
ip netns exec ns2 ping -c 1 -q 10.0.0.11 > /dev/null
133+
if [ $? -ne 0 ]; then
134+
echo "ERROR: Could not reach ns1 from ns2" 1>&2
135+
ret=1
136+
fi
137+
138+
if [ $ret -eq 0 ];then
139+
echo "PASS: netns connectivity: ns1 and ns2 can reach each other"
140+
fi
141+
142+
test_ebtables_broute
143+
ret=$?
144+
for i in 0 1 2; do ip netns del ns$i;done
145+
146+
exit $ret

0 commit comments

Comments
 (0)