xref: /linux/tools/testing/selftests/net/forwarding/router_multicast.sh (revision 2b64b2ed277ff23e785fbdb65098ee7e1252d64f)
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
31ALL_TESTS="mcast_v4 mcast_v6"
32NUM_NETIFS=6
33source lib.sh
34source tc_common.sh
35
36require_command $MCD
37require_command $MC_CLI
38table_name=selftests
39
40h1_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
51h1_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
62h2_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
75h2_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
88h3_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
101h3_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
114router_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
129router_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
144start_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
157kill_mcd()
158{
159	pkill $MCD
160	rm -rf $SMCROUTEDIR
161}
162
163setup_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
187cleanup()
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
204create_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
214delete_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
224mcast_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
264mcast_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
304trap cleanup EXIT
305
306setup_prepare
307setup_wait
308
309tests_run
310
311exit $EXIT_STATUS
312