xref: /linux/tools/testing/selftests/net/forwarding/vxlan_bridge_1q_mc_ul.sh (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +-----------------------------------------+
5# | + $h1.10             + $h1.20           |
6# | | 192.0.2.1/28       | 2001:db8:1::1/64 |
7# | \________   ________/                   |
8# |          \ /                            |
9# |           + $h1                H1 (vrf) |
10# +-----------|-----------------------------+
11#             |
12# +-----------|----------------------------------------------------------------+
13# | +---------|--------------------------------------+       SWITCH (main vrf) |
14# | |         + $swp1                   BR1 (802.1q) |                         |
15# | |            vid 10 20                           |                         |
16# | |                                                |                         |
17# | |  + vx10 (vxlan)         + vx20 (vxlan)         |      + lo10 (dummy)     |
18# | |    local 192.0.2.100      local 2001:db8:4::1  |        192.0.2.100/28   |
19# | |    group 233.252.0.1      group ff0e::1:2:3    |        2001:db8:4::1/64 |
20# | |    id 1000                id 2000              |                         |
21# | |    vid 10 pvid untagged   vid 20 pvid untagged |                         |
22# | +------------------------------------------------+                         |
23# |                                                                            |
24# |   + $swp2                                                        $swp3 +   |
25# |   | 192.0.2.33/28                                        192.0.2.65/28 |   |
26# |   | 2001:db8:2::1/64                                  2001:db8:3::1/64 |   |
27# |   |                                                                    |   |
28# +---|--------------------------------------------------------------------|---+
29#     |                                                                    |
30# +---|--------------------------------+  +--------------------------------|---+
31# |   |                      H2 (vrf)  |  | H3 (vrf)                       |   |
32# | +-|----------------------------+   |  |  +-----------------------------|-+ |
33# | | + $h2           BR2 (802.1d) |   |  |  | BR3 (802.1d)            $h3 + | |
34# | |                              |   |  |  |                               | |
35# | | + v1$h2 (veth)               |   |  |  |                v1$h3 (veth) + | |
36# | +-|----------------------------+   |  |  +-----------------------------|-+ |
37# |   |                                |  |                                |   |
38# +---|--------------------------------+  +--------------------------------|---+
39#     |                                                                    |
40# +---|--------------------------------+  +--------------------------------|---+
41# |   + v2$h2 (veth)       NS2 (netns) |  | NS3 (netns)       v2$h3 (veth) +   |
42# |     192.0.2.34/28                  |  |                  192.0.2.66/28     |
43# |     2001:db8:2::2/64               |  |               2001:db8:3::2/64     |
44# |                                    |  |                                    |
45# | +--------------------------------+ |  | +--------------------------------+ |
46# | |                  BR1 (802.1q)  | |  | |                   BR1 (802.1q) | |
47# | |  + vx10 (vxlan)                | |  | |  + vx10 (vxlan)                | |
48# | |    local 192.0.2.34            | |  | |    local 192.0.2.50            | |
49# | |    group 233.252.0.1 dev v2$h2 | |  | |    group 233.252.0.1 dev v2$h3 | |
50# | |    id 1000 dstport $VXPORT     | |  | |    id 1000 dstport $VXPORT     | |
51# | |    vid 10 pvid untagged        | |  | |    vid 10 pvid untagged        | |
52# | |                                | |  | |                                | |
53# | |  + vx20 (vxlan)                | |  | |  + vx20 (vxlan)                | |
54# | |    local 2001:db8:2::2         | |  | |    local 2001:db8:3::2         | |
55# | |    group ff0e::1:2:3 dev v2$h2 | |  | |    group ff0e::1:2:3 dev v2$h3 | |
56# | |    id 2000 dstport $VXPORT     | |  | |    id 2000 dstport $VXPORT     | |
57# | |    vid 20 pvid untagged        | |  | |    vid 20 pvid untagged        | |
58# | |                                | |  | |                                | |
59# | |  + w1 (veth)                   | |  | |  + w1 (veth)                   | |
60# | |  | vid 10 20                   | |  | |  | vid 10 20                   | |
61# | +--|-----------------------------+ |  | +--|-----------------------------+ |
62# |    |                               |  |    |                               |
63# | +--|-----------------------------+ |  | +--|-----------------------------+ |
64# | |  + w2 (veth)        VW2 (vrf)  | |  | |  + w2 (veth)        VW2 (vrf)  | |
65# | |  |\                            | |  | |  |\                            | |
66# | |  | + w2.10                     | |  | |  | + w2.10                     | |
67# | |  |   192.0.2.3/28              | |  | |  |   192.0.2.4/28              | |
68# | |  |                             | |  | |  |                             | |
69# | |  + w2.20                       | |  | |  + w2.20                       | |
70# | |    2001:db8:1::3/64            | |  | |    2001:db8:1::4/64            | |
71# | +--------------------------------+ |  | +--------------------------------+ |
72# +------------------------------------+  +------------------------------------+
73#
74#shellcheck disable=SC2317 # SC doesn't see our uses of functions.
75
76: "${VXPORT:=4789}"
77export VXPORT
78
79: "${GROUP4:=233.252.0.1}"
80export GROUP4
81
82: "${GROUP6:=ff0e::1:2:3}"
83export GROUP6
84
85: "${IPMR:=lo10}"
86
87ALL_TESTS="
88	ipv4_nomcroute
89	ipv4_mcroute
90	ipv4_mcroute_changelink
91	ipv4_mcroute_starg
92	ipv4_mcroute_noroute
93	ipv4_mcroute_fdb
94	ipv4_mcroute_fdb_oif0
95	ipv4_mcroute_fdb_oif0_sep
96
97	ipv6_nomcroute
98	ipv6_mcroute
99	ipv6_mcroute_changelink
100	ipv6_mcroute_starg
101	ipv6_mcroute_noroute
102	ipv6_mcroute_fdb
103	ipv6_mcroute_fdb_oif0
104
105	ipv4_nomcroute_rx
106	ipv4_mcroute_rx
107	ipv4_mcroute_starg_rx
108	ipv4_mcroute_fdb_oif0_sep_rx
109	ipv4_mcroute_fdb_sep_rx
110
111	ipv6_nomcroute_rx
112	ipv6_mcroute_rx
113	ipv6_mcroute_starg_rx
114	ipv6_mcroute_fdb_sep_rx
115"
116
117NUM_NETIFS=6
118source lib.sh
119
120h1_create()
121{
122	adf_simple_if_init "$h1"
123
124	adf_ip_link_add "$h1.10" master "v$h1" link "$h1" type vlan id 10
125	adf_ip_link_set_up "$h1.10"
126	adf_ip_addr_add "$h1.10" 192.0.2.1/28
127
128	adf_ip_link_add "$h1.20" master "v$h1" link "$h1" type vlan id 20
129	adf_ip_link_set_up "$h1.20"
130	adf_ip_addr_add "$h1.20" 2001:db8:1::1/64
131}
132
133install_capture()
134{
135	local dev=$1; shift
136
137	tc qdisc add dev "$dev" clsact
138	defer tc qdisc del dev "$dev" clsact
139
140	tc filter add dev "$dev" ingress proto ip pref 104 \
141	   flower skip_hw ip_proto udp dst_port "$VXPORT" \
142	   action pass
143	defer tc filter del dev "$dev" ingress proto ip pref 104
144
145	tc filter add dev "$dev" ingress proto ipv6 pref 106 \
146	   flower skip_hw ip_proto udp dst_port "$VXPORT" \
147	   action pass
148	defer tc filter del dev "$dev" ingress proto ipv6 pref 106
149}
150
151h2_create()
152{
153	# $h2
154	adf_ip_link_set_up "$h2"
155
156	# H2
157	vrf_create "v$h2"
158	defer vrf_destroy "v$h2"
159
160	adf_ip_link_set_up "v$h2"
161
162	# br2
163	adf_ip_link_add br2 type bridge vlan_filtering 0 mcast_snooping 0
164	adf_ip_link_set_master br2 "v$h2"
165	adf_ip_link_set_up br2
166
167	# $h2
168	adf_ip_link_set_master "$h2" br2
169	install_capture "$h2"
170
171	# v1$h2
172	adf_ip_link_set_up "v1$h2"
173	adf_ip_link_set_master "v1$h2" br2
174}
175
176h3_create()
177{
178	# $h3
179	adf_ip_link_set_up "$h3"
180
181	# H3
182	vrf_create "v$h3"
183	defer vrf_destroy "v$h3"
184
185	adf_ip_link_set_up "v$h3"
186
187	# br3
188	adf_ip_link_add br3 type bridge vlan_filtering 0 mcast_snooping 0
189	adf_ip_link_set_master br3 "v$h3"
190	adf_ip_link_set_up br3
191
192	# $h3
193	adf_ip_link_set_master "$h3" br3
194	install_capture "$h3"
195
196	# v1$h3
197	adf_ip_link_set_up "v1$h3"
198	adf_ip_link_set_master "v1$h3" br3
199}
200
201switch_create()
202{
203	local swp1_mac
204
205	# br1
206	swp1_mac=$(mac_get "$swp1")
207	adf_ip_link_add br1 type bridge vlan_filtering 1 \
208			    vlan_default_pvid 0 mcast_snooping 0
209	adf_ip_link_set_addr br1 "$swp1_mac"
210	adf_ip_link_set_up br1
211
212	# A dummy to force the IPv6 OIF=0 test to install a suitable MC route on
213	# $IPMR to be deterministic. Also used for the IPv6 RX!=TX ping test.
214	adf_ip_link_add "X$IPMR" up type dummy
215
216	# IPMR
217	adf_ip_link_add "$IPMR" up type dummy
218	adf_ip_addr_add "$IPMR" 192.0.2.100/28
219	adf_ip_addr_add "$IPMR" 2001:db8:4::1/64
220
221	# $swp1
222	adf_ip_link_set_up "$swp1"
223	adf_ip_link_set_master "$swp1" br1
224	adf_bridge_vlan_add vid 10 dev "$swp1"
225	adf_bridge_vlan_add vid 20 dev "$swp1"
226
227	# $swp2
228	adf_ip_link_set_up "$swp2"
229	adf_ip_addr_add "$swp2" 192.0.2.33/28
230	adf_ip_addr_add "$swp2" 2001:db8:2::1/64
231
232	# $swp3
233	adf_ip_link_set_up "$swp3"
234	adf_ip_addr_add "$swp3" 192.0.2.65/28
235	adf_ip_addr_add "$swp3" 2001:db8:3::1/64
236}
237
238vx_create()
239{
240	local name=$1; shift
241	local vid=$1; shift
242
243	adf_ip_link_add "$name" up type vxlan dstport "$VXPORT" \
244		nolearning noudpcsum tos inherit ttl 16 \
245		"$@"
246	adf_ip_link_set_master "$name" br1
247	adf_bridge_vlan_add vid "$vid" dev "$name" pvid untagged
248}
249export -f vx_create
250
251vx_wait()
252{
253	# Wait for all the ARP, IGMP etc. noise to settle down so that the
254	# tunnel is clear for measurements.
255	sleep 10
256}
257
258vx10_create()
259{
260	vx_create vx10 10 id 1000 "$@"
261}
262export -f vx10_create
263
264vx20_create()
265{
266	vx_create vx20 20 id 2000 "$@"
267}
268export -f vx20_create
269
270vx10_create_wait()
271{
272	vx10_create "$@"
273	vx_wait
274}
275
276vx20_create_wait()
277{
278	vx20_create "$@"
279	vx_wait
280}
281
282ns_init_common()
283{
284	local ns=$1; shift
285	local if_in=$1; shift
286	local ipv4_in=$1; shift
287	local ipv6_in=$1; shift
288	local ipv4_host=$1; shift
289	local ipv6_host=$1; shift
290
291	# v2$h2 / v2$h3
292	adf_ip_link_set_up "$if_in"
293	adf_ip_addr_add "$if_in" "$ipv4_in"
294	adf_ip_addr_add "$if_in" "$ipv6_in"
295
296	# br1
297	adf_ip_link_add br1 type bridge vlan_filtering 1 \
298		    vlan_default_pvid 0 mcast_snooping 0
299	adf_ip_link_set_up br1
300
301	# vx10, vx20
302	vx10_create local "${ipv4_in%/*}" group "$GROUP4" dev "$if_in"
303	vx20_create local "${ipv6_in%/*}" group "$GROUP6" dev "$if_in"
304
305	# w1
306	adf_ip_link_add w1 type veth peer name w2
307	adf_ip_link_set_master w1 br1
308	adf_ip_link_set_up w1
309	adf_bridge_vlan_add vid 10 dev w1
310	adf_bridge_vlan_add vid 20 dev w1
311
312	# w2
313	adf_simple_if_init w2
314
315	# w2.10
316	adf_ip_link_add w2.10 master vw2 link w2 type vlan id 10
317	adf_ip_link_set_up w2.10
318	adf_ip_addr_add w2.10 "$ipv4_host"
319
320	# w2.20
321	adf_ip_link_add w2.20 master vw2 link w2 type vlan id 20
322	adf_ip_link_set_up w2.20
323	adf_ip_addr_add w2.20 "$ipv6_host"
324}
325export -f ns_init_common
326
327ns2_create()
328{
329	# NS2
330	ip netns add ns2
331	defer ip netns del ns2
332
333	# v2$h2
334	ip link set dev "v2$h2" netns ns2
335	defer ip -n ns2 link set dev "v2$h2" netns 1
336
337	in_ns ns2 \
338	      ns_init_common ns2 "v2$h2" \
339			     192.0.2.34/28 2001:db8:2::2/64 \
340			     192.0.2.3/28  2001:db8:1::3/64
341}
342
343ns3_create()
344{
345	# NS3
346	ip netns add ns3
347	defer ip netns del ns3
348
349	# v2$h3
350	ip link set dev "v2$h3" netns ns3
351	defer ip -n ns3 link set dev "v2$h3" netns 1
352
353	ip -n ns3 link set dev "v2$h3" up
354
355	in_ns ns3 \
356	      ns_init_common ns3 "v2$h3" \
357			     192.0.2.66/28 2001:db8:3::2/64 \
358			     192.0.2.4/28  2001:db8:1::4/64
359}
360
361setup_prepare()
362{
363	h1=${NETIFS[p1]}
364	swp1=${NETIFS[p2]}
365
366	swp2=${NETIFS[p3]}
367	h2=${NETIFS[p4]}
368
369	swp3=${NETIFS[p5]}
370	h3=${NETIFS[p6]}
371
372	adf_vrf_prepare
373	adf_forwarding_enable
374
375	adf_ip_link_add "v1$h2" type veth peer name "v2$h2"
376	adf_ip_link_add "v1$h3" type veth peer name "v2$h3"
377
378	h1_create
379	h2_create
380	h3_create
381	switch_create
382	ns2_create
383	ns3_create
384}
385
386adf_install_broken_sg()
387{
388	adf_mcd_start "$IPMR" || exit "$EXIT_STATUS"
389
390	mc_cli add "$swp2" 192.0.2.100 "$GROUP4" "$swp1" "$swp3"
391	defer mc_cli remove "$swp2" 192.0.2.100 "$GROUP4" "$swp1" "$swp3"
392
393	mc_cli add "$swp2" 2001:db8:4::1 "$GROUP6" "$swp1" "$swp3"
394	defer mc_cli remove "$swp2" 2001:db8:4::1 "$GROUP6" "$swp1" "$swp3"
395}
396
397adf_install_rx()
398{
399	mc_cli add "$swp2" 0.0.0.0 "$GROUP4" "$IPMR"
400	defer mc_cli remove "$swp2" 0.0.0.0 "$GROUP4" lo10
401
402	mc_cli add "$swp3" 0.0.0.0 "$GROUP4" "$IPMR"
403	defer mc_cli remove "$swp3" 0.0.0.0 "$GROUP4" lo10
404
405	mc_cli add "$swp2" :: "$GROUP6" "$IPMR"
406	defer mc_cli remove "$swp2" :: "$GROUP6" lo10
407
408	mc_cli add "$swp3" :: "$GROUP6" "$IPMR"
409	defer mc_cli remove "$swp3" :: "$GROUP6" lo10
410}
411
412adf_install_sg()
413{
414	adf_mcd_start "$IPMR" || exit "$EXIT_STATUS"
415
416	mc_cli add "$IPMR" 192.0.2.100 "$GROUP4" "$swp2" "$swp3"
417	defer mc_cli remove "$IPMR" 192.0.2.33 "$GROUP4" "$swp2" "$swp3"
418
419	mc_cli add "$IPMR" 2001:db8:4::1 "$GROUP6" "$swp2" "$swp3"
420	defer mc_cli remove "$IPMR" 2001:db8:4::1 "$GROUP6" "$swp2" "$swp3"
421
422	adf_install_rx
423}
424
425adf_install_sg_sep()
426{
427	adf_mcd_start lo || exit "$EXIT_STATUS"
428
429	mc_cli add lo 192.0.2.120 "$GROUP4" "$swp2" "$swp3"
430	defer mc_cli remove lo 192.0.2.120 "$GROUP4" "$swp2" "$swp3"
431
432	mc_cli add lo 2001:db8:5::1 "$GROUP6" "$swp2" "$swp3"
433	defer mc_cli remove lo 2001:db8:5::1 "$GROUP6" "$swp2" "$swp3"
434}
435
436adf_install_sg_sep_rx()
437{
438	local lo=$1; shift
439
440	adf_mcd_start "$IPMR" "$lo" || exit "$EXIT_STATUS"
441
442	mc_cli add "$lo" 192.0.2.120 "$GROUP4" "$swp2" "$swp3"
443	defer mc_cli remove "$lo" 192.0.2.120 "$GROUP4" "$swp2" "$swp3"
444
445	mc_cli add "$lo" 2001:db8:5::1 "$GROUP6" "$swp2" "$swp3"
446	defer mc_cli remove "$lo" 2001:db8:5::1 "$GROUP6" "$swp2" "$swp3"
447
448	adf_install_rx
449}
450
451adf_install_starg()
452{
453	adf_mcd_start "$IPMR" || exit "$EXIT_STATUS"
454
455	mc_cli add "$IPMR" 0.0.0.0 "$GROUP4" "$swp2" "$swp3"
456	defer mc_cli remove "$IPMR" 0.0.0.0 "$GROUP4" "$swp2" "$swp3"
457
458	mc_cli add "$IPMR" :: "$GROUP6" "$swp2" "$swp3"
459	defer mc_cli remove "$IPMR" :: "$GROUP6" "$swp2" "$swp3"
460
461	adf_install_rx
462}
463
464do_packets_v4()
465{
466	local mac
467
468	mac=$(mac_get "$h2")
469	"$MZ" "$h1" -Q 10 -c 10 -d 100msec -p 64 -a own -b "$mac" \
470	    -A 192.0.2.1 -B 192.0.2.2 -t udp sp=1234,dp=2345 -q
471}
472
473do_packets_v6()
474{
475	local mac
476
477	mac=$(mac_get "$h2")
478	"$MZ" -6 "$h1" -Q 20 -c 10 -d 100msec -p 64 -a own -b "$mac" \
479	    -A 2001:db8:1::1 -B 2001:db8:1::2 -t udp sp=1234,dp=2345 -q
480}
481
482do_test()
483{
484	local ipv=$1; shift
485	local expect_h2=$1; shift
486	local expect_h3=$1; shift
487	local what=$1; shift
488
489	local pref=$((100 + ipv))
490	local t0_h2
491	local t0_h3
492	local t1_h2
493	local t1_h3
494	local d_h2
495	local d_h3
496
497	RET=0
498
499	t0_h2=$(tc_rule_stats_get "$h2" "$pref" ingress)
500	t0_h3=$(tc_rule_stats_get "$h3" "$pref" ingress)
501
502	"do_packets_v$ipv"
503	sleep 1
504
505	t1_h2=$(tc_rule_stats_get "$h2" "$pref" ingress)
506	t1_h3=$(tc_rule_stats_get "$h3" "$pref" ingress)
507
508	d_h2=$((t1_h2 - t0_h2))
509	d_h3=$((t1_h3 - t0_h3))
510
511	((d_h2 == expect_h2))
512	check_err $? "Expected $expect_h2 packets on H2, got $d_h2"
513
514	((d_h3 == expect_h3))
515	check_err $? "Expected $expect_h3 packets on H3, got $d_h3"
516
517	log_test "VXLAN MC flood $what"
518}
519
520ipv4_do_test_rx()
521{
522	local h3_should_fail=$1; shift
523	local what=$1; shift
524
525	RET=0
526
527	ping_do "$h1.10" 192.0.2.3
528	check_err $? "H2 should respond"
529
530	ping_do "$h1.10" 192.0.2.4
531	check_err_fail "$h3_should_fail" $? "H3 responds"
532
533	log_test "VXLAN MC flood $what"
534}
535
536ipv6_do_test_rx()
537{
538	local h3_should_fail=$1; shift
539	local what=$1; shift
540
541	RET=0
542
543	ping6_do "$h1.20" 2001:db8:1::3
544	check_err $? "H2 should respond"
545
546	ping6_do "$h1.20" 2001:db8:1::4
547	check_err_fail "$h3_should_fail" $? "H3 responds"
548
549	log_test "VXLAN MC flood $what"
550}
551
552ipv4_nomcroute()
553{
554	# Install a misleading (S,G) rule to attempt to trick the system into
555	# pushing the packets elsewhere.
556	adf_install_broken_sg
557	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$swp2"
558	do_test 4 10 0 "IPv4 nomcroute"
559}
560
561ipv6_nomcroute()
562{
563	# Like for IPv4, install a misleading (S,G).
564	adf_install_broken_sg
565	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$swp2"
566	do_test 6 10 0 "IPv6 nomcroute"
567}
568
569ipv4_nomcroute_rx()
570{
571	vx10_create local 192.0.2.100 group "$GROUP4" dev "$swp2"
572	ipv4_do_test_rx 1 "IPv4 nomcroute ping"
573}
574
575ipv6_nomcroute_rx()
576{
577	vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$swp2"
578	ipv6_do_test_rx 1 "IPv6 nomcroute ping"
579}
580
581ipv4_mcroute()
582{
583	adf_install_sg
584	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
585	do_test 4 10 10 "IPv4 mcroute"
586}
587
588ipv6_mcroute()
589{
590	adf_install_sg
591	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
592	do_test 6 10 10 "IPv6 mcroute"
593}
594
595ipv4_mcroute_rx()
596{
597	adf_install_sg
598	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
599	ipv4_do_test_rx 0 "IPv4 mcroute ping"
600}
601
602ipv6_mcroute_rx()
603{
604	adf_install_sg
605	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
606	ipv6_do_test_rx 0 "IPv6 mcroute ping"
607}
608
609ipv4_mcroute_changelink()
610{
611	adf_install_sg
612	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR"
613	ip link set dev vx10 type vxlan mcroute
614	sleep 1
615	do_test 4 10 10 "IPv4 mcroute changelink"
616}
617
618ipv6_mcroute_changelink()
619{
620	adf_install_sg
621	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
622	ip link set dev vx20 type vxlan mcroute
623	sleep 1
624	do_test 6 10 10 "IPv6 mcroute changelink"
625}
626
627ipv4_mcroute_starg()
628{
629	adf_install_starg
630	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
631	do_test 4 10 10 "IPv4 mcroute (*,G)"
632}
633
634ipv6_mcroute_starg()
635{
636	adf_install_starg
637	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
638	do_test 6 10 10 "IPv6 mcroute (*,G)"
639}
640
641ipv4_mcroute_starg_rx()
642{
643	adf_install_starg
644	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
645	ipv4_do_test_rx 0 "IPv4 mcroute (*,G) ping"
646}
647
648ipv6_mcroute_starg_rx()
649{
650	adf_install_starg
651	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
652	ipv6_do_test_rx 0 "IPv6 mcroute (*,G) ping"
653}
654
655ipv4_mcroute_noroute()
656{
657	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
658	do_test 4 0 0 "IPv4 mcroute, no route"
659}
660
661ipv6_mcroute_noroute()
662{
663	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
664	do_test 6 0 0 "IPv6 mcroute, no route"
665}
666
667ipv4_mcroute_fdb()
668{
669	adf_install_sg
670	vx10_create_wait local 192.0.2.100 dev "$IPMR" mcroute
671	bridge fdb add dev vx10 \
672		00:00:00:00:00:00 self static dst "$GROUP4" via "$IPMR"
673	do_test 4 10 10 "IPv4 mcroute FDB"
674}
675
676ipv6_mcroute_fdb()
677{
678	adf_install_sg
679	vx20_create_wait local 2001:db8:4::1 dev "$IPMR" mcroute
680	bridge -6 fdb add dev vx20 \
681		00:00:00:00:00:00 self static dst "$GROUP6" via "$IPMR"
682	do_test 6 10 10 "IPv6 mcroute FDB"
683}
684
685# Use FDB to configure VXLAN in a way where oif=0 for purposes of FIB lookup.
686ipv4_mcroute_fdb_oif0()
687{
688	adf_install_sg
689	vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
690	bridge fdb del dev vx10 00:00:00:00:00:00
691	bridge fdb add dev vx10 00:00:00:00:00:00 self static dst "$GROUP4"
692	do_test 4 10 10 "IPv4 mcroute oif=0"
693}
694
695ipv6_mcroute_fdb_oif0()
696{
697	# The IPv6 tunnel lookup does not fall back to selection by source
698	# address. Instead it just does a FIB match, and that would find one of
699	# the several ff00::/8 multicast routes -- each device has one. In order
700	# to reliably force the $IPMR device, add a /128 route for the
701	# destination group address.
702	ip -6 route add table local multicast "$GROUP6/128" dev "$IPMR"
703	defer ip -6 route del table local multicast "$GROUP6/128" dev "$IPMR"
704
705	adf_install_sg
706	vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
707	bridge -6 fdb del dev vx20 00:00:00:00:00:00
708	bridge -6 fdb add dev vx20 00:00:00:00:00:00 self static dst "$GROUP6"
709	do_test 6 10 10 "IPv6 mcroute oif=0"
710}
711
712# In oif=0 test as above, have FIB lookup resolve to loopback instead of IPMR.
713# This doesn't work with IPv6 -- a MC route on lo would be marked as RTF_REJECT.
714ipv4_mcroute_fdb_oif0_sep()
715{
716	adf_install_sg_sep
717
718	adf_ip_addr_add lo 192.0.2.120/28
719	vx10_create_wait local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
720	bridge fdb del dev vx10 00:00:00:00:00:00
721	bridge fdb add dev vx10 00:00:00:00:00:00 self static dst "$GROUP4"
722	do_test 4 10 10 "IPv4 mcroute TX!=RX oif=0"
723}
724
725ipv4_mcroute_fdb_oif0_sep_rx()
726{
727	adf_install_sg_sep_rx lo
728
729	adf_ip_addr_add lo 192.0.2.120/28
730	vx10_create_wait local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
731	bridge fdb del dev vx10 00:00:00:00:00:00
732	bridge fdb add dev vx10 00:00:00:00:00:00 self static dst "$GROUP4"
733	ipv4_do_test_rx 0 "IPv4 mcroute TX!=RX oif=0 ping"
734}
735
736ipv4_mcroute_fdb_sep_rx()
737{
738	adf_install_sg_sep_rx lo
739
740	adf_ip_addr_add lo 192.0.2.120/28
741	vx10_create_wait local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
742	bridge fdb del dev vx10 00:00:00:00:00:00
743	bridge fdb add \
744	       dev vx10 00:00:00:00:00:00 self static dst "$GROUP4" via lo
745	ipv4_do_test_rx 0 "IPv4 mcroute TX!=RX ping"
746}
747
748ipv6_mcroute_fdb_sep_rx()
749{
750	adf_install_sg_sep_rx "X$IPMR"
751
752	adf_ip_addr_add "X$IPMR" 2001:db8:5::1/64
753	vx20_create_wait local 2001:db8:5::1 group "$GROUP6" dev "$IPMR" mcroute
754	bridge -6 fdb del dev vx20 00:00:00:00:00:00
755	bridge -6 fdb add dev vx20 00:00:00:00:00:00 \
756			  self static dst "$GROUP6" via "X$IPMR"
757	ipv6_do_test_rx 0 "IPv6 mcroute TX!=RX ping"
758}
759
760trap cleanup EXIT
761
762setup_prepare
763setup_wait
764tests_run
765
766exit "$EXIT_STATUS"
767