Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
[linux-2.6-microblaze.git] / tools / testing / selftests / net / forwarding / router_multicast.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 # +------------------+
5 # | H1 (v$h1)        |
6 # | 2001:db8:1::2/64 |
7 # | 198.51.100.2/28  |
8 # |         $h1 +    |
9 # +-------------|----+
10 #               |
11 # +-------------|-------------------------------+
12 # | SW1         |                               |
13 # |        $rp1 +                               |
14 # | 198.51.100.1/28                             |
15 # | 2001:db8:1::1/64                            |
16 # |                                             |
17 # | 2001:db8:2::1/64           2001:db8:3::1/64 |
18 # | 198.51.100.17/28           198.51.100.33/28 |
19 # |         $rp2 +                     $rp3 +   |
20 # +--------------|--------------------------|---+
21 #                |                          |
22 #                |                          |
23 # +--------------|---+       +--------------|---+
24 # | H2 (v$h2)    |   |       | H3 (v$h3)    |   |
25 # |          $h2 +   |       |          $h3 +   |
26 # | 198.51.100.18/28 |       | 198.51.100.34/28 |
27 # | 2001:db8:2::2/64 |       | 2001:db8:3::2/64 |
28 # +------------------+       +------------------+
29 #
30
31 ALL_TESTS="mcast_v4 mcast_v6"
32 NUM_NETIFS=6
33 source lib.sh
34 source tc_common.sh
35
36 require_command $MCD
37 require_command $MC_CLI
38 table_name=selftests
39
40 h1_create()
41 {
42         simple_if_init $h1 198.51.100.2/28 2001:db8:1::2/64
43
44         ip route add 198.51.100.16/28 vrf v$h1 nexthop via 198.51.100.1
45         ip route add 198.51.100.32/28 vrf v$h1 nexthop via 198.51.100.1
46
47         ip route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::1
48         ip route add 2001:db8:3::/64 vrf v$h1 nexthop via 2001:db8:1::1
49 }
50
51 h1_destroy()
52 {
53         ip route del 2001:db8:3::/64 vrf v$h1
54         ip route del 2001:db8:2::/64 vrf v$h1
55
56         ip route del 198.51.100.32/28 vrf v$h1
57         ip route del 198.51.100.16/28 vrf v$h1
58
59         simple_if_fini $h1 198.51.100.2/28 2001:db8:1::2/64
60 }
61
62 h2_create()
63 {
64         simple_if_init $h2 198.51.100.18/28 2001:db8:2::2/64
65
66         ip route add 198.51.100.0/28 vrf v$h2 nexthop via 198.51.100.17
67         ip route add 198.51.100.32/28 vrf v$h2 nexthop via 198.51.100.17
68
69         ip route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1
70         ip route add 2001:db8:3::/64 vrf v$h2 nexthop via 2001:db8:2::1
71
72         tc qdisc add dev $h2 ingress
73 }
74
75 h2_destroy()
76 {
77         tc qdisc del dev $h2 ingress
78
79         ip route del 2001:db8:3::/64 vrf v$h2
80         ip route del 2001:db8:1::/64 vrf v$h2
81
82         ip route del 198.51.100.32/28 vrf v$h2
83         ip route del 198.51.100.0/28 vrf v$h2
84
85         simple_if_fini $h2 198.51.100.18/28 2001:db8:2::2/64
86 }
87
88 h3_create()
89 {
90         simple_if_init $h3 198.51.100.34/28 2001:db8:3::2/64
91
92         ip route add 198.51.100.0/28 vrf v$h3 nexthop via 198.51.100.33
93         ip route add 198.51.100.16/28 vrf v$h3 nexthop via 198.51.100.33
94
95         ip route add 2001:db8:1::/64 vrf v$h3 nexthop via 2001:db8:3::1
96         ip route add 2001:db8:2::/64 vrf v$h3 nexthop via 2001:db8:3::1
97
98         tc qdisc add dev $h3 ingress
99 }
100
101 h3_destroy()
102 {
103         tc qdisc del dev $h3 ingress
104
105         ip route del 2001:db8:2::/64 vrf v$h3
106         ip route del 2001:db8:1::/64 vrf v$h3
107
108         ip route del 198.51.100.16/28 vrf v$h3
109         ip route del 198.51.100.0/28 vrf v$h3
110
111         simple_if_fini $h3 198.51.100.34/28 2001:db8:3::2/64
112 }
113
114 router_create()
115 {
116         ip link set dev $rp1 up
117         ip link set dev $rp2 up
118         ip link set dev $rp3 up
119
120         ip address add 198.51.100.1/28 dev $rp1
121         ip address add 198.51.100.17/28 dev $rp2
122         ip address add 198.51.100.33/28 dev $rp3
123
124         ip address add 2001:db8:1::1/64 dev $rp1
125         ip address add 2001:db8:2::1/64 dev $rp2
126         ip address add 2001:db8:3::1/64 dev $rp3
127 }
128
129 router_destroy()
130 {
131         ip address del 2001:db8:3::1/64 dev $rp3
132         ip address del 2001:db8:2::1/64 dev $rp2
133         ip address del 2001:db8:1::1/64 dev $rp1
134
135         ip address del 198.51.100.33/28 dev $rp3
136         ip address del 198.51.100.17/28 dev $rp2
137         ip address del 198.51.100.1/28 dev $rp1
138
139         ip link set dev $rp3 down
140         ip link set dev $rp2 down
141         ip link set dev $rp1 down
142 }
143
144 start_mcd()
145 {
146         SMCROUTEDIR="$(mktemp -d)"
147
148         for ((i = 1; i <= $NUM_NETIFS; ++i)); do
149                 echo "phyint ${NETIFS[p$i]} enable" >> \
150                         $SMCROUTEDIR/$table_name.conf
151         done
152
153         $MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \
154                 -P $SMCROUTEDIR/$table_name.pid
155 }
156
157 kill_mcd()
158 {
159         pkill $MCD
160         rm -rf $SMCROUTEDIR
161 }
162
163 setup_prepare()
164 {
165         h1=${NETIFS[p1]}
166         rp1=${NETIFS[p2]}
167
168         rp2=${NETIFS[p3]}
169         h2=${NETIFS[p4]}
170
171         rp3=${NETIFS[p5]}
172         h3=${NETIFS[p6]}
173
174         start_mcd
175
176         vrf_prepare
177
178         h1_create
179         h2_create
180         h3_create
181
182         router_create
183
184         forwarding_enable
185 }
186
187 cleanup()
188 {
189         pre_cleanup
190
191         forwarding_restore
192
193         router_destroy
194
195         h3_destroy
196         h2_destroy
197         h1_destroy
198
199         vrf_cleanup
200
201         kill_mcd
202 }
203
204 create_mcast_sg()
205 {
206         local if_name=$1; shift
207         local s_addr=$1; shift
208         local mcast=$1; shift
209         local dest_ifs=${@}
210
211         $MC_CLI -I $table_name add $if_name $s_addr $mcast $dest_ifs
212 }
213
214 delete_mcast_sg()
215 {
216         local if_name=$1; shift
217         local s_addr=$1; shift
218         local mcast=$1; shift
219         local dest_ifs=${@}
220
221         $MC_CLI -I $table_name remove $if_name $s_addr $mcast $dest_ifs
222 }
223
224 mcast_v4()
225 {
226         # Add two interfaces to an MC group, send a packet to the MC group and
227         # verify packets are received on both. Then delete the route and verify
228         # packets are no longer received.
229
230         RET=0
231
232         tc filter add dev $h2 ingress protocol ip pref 1 handle 122 flower \
233                 dst_ip 225.1.2.3 action drop
234         tc filter add dev $h3 ingress protocol ip pref 1 handle 133 flower \
235                 dst_ip 225.1.2.3 action drop
236
237         create_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
238
239         # Send frames with the corresponding L2 destination address.
240         $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
241                 -A 198.51.100.2 -B 225.1.2.3 -q
242
243         tc_check_packets "dev $h2 ingress" 122 5
244         check_err $? "Multicast not received on first host"
245         tc_check_packets "dev $h3 ingress" 133 5
246         check_err $? "Multicast not received on second host"
247
248         delete_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
249
250         $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
251                 -A 198.51.100.2 -B 225.1.2.3 -q
252
253         tc_check_packets "dev $h2 ingress" 122 5
254         check_err $? "Multicast received on host although deleted"
255         tc_check_packets "dev $h3 ingress" 133 5
256         check_err $? "Multicast received on second host although deleted"
257
258         tc filter del dev $h3 ingress protocol ip pref 1 handle 133 flower
259         tc filter del dev $h2 ingress protocol ip pref 1 handle 122 flower
260
261         log_test "mcast IPv4"
262 }
263
264 mcast_v6()
265 {
266         # Add two interfaces to an MC group, send a packet to the MC group and
267         # verify packets are received on both. Then delete the route and verify
268         # packets are no longer received.
269
270         RET=0
271
272         tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 122 flower \
273                 dst_ip ff0e::3 action drop
274         tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 133 flower \
275                 dst_ip ff0e::3 action drop
276
277         create_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
278
279         # Send frames with the corresponding L2 destination address.
280         $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \
281                 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q
282
283         tc_check_packets "dev $h2 ingress" 122 5
284         check_err $? "Multicast not received on first host"
285         tc_check_packets "dev $h3 ingress" 133 5
286         check_err $? "Multicast not received on second host"
287
288         delete_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
289
290         $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \
291                 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q
292
293         tc_check_packets "dev $h2 ingress" 122 5
294         check_err $? "Multicast received on first host although deleted"
295         tc_check_packets "dev $h3 ingress" 133 5
296         check_err $? "Multicast received on second host although deleted"
297
298         tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 133 flower
299         tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 122 flower
300
301         log_test "mcast IPv6"
302 }
303
304 trap cleanup EXIT
305
306 setup_prepare
307 setup_wait
308
309 tests_run
310
311 exit $EXIT_STATUS