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