Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / tools / testing / selftests / netfilter / bridge_brouter.sh
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