1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +-----------------------+                          +------------------------+
5# | H1 (vrf)              |                          | H2 (vrf)               |
6# | + $h1.10              |                          | + $h2.10               |
7# | | 192.0.2.1/28        |                          | | 192.0.2.2/28         |
8# | | 2001:db8:1::1/64    |                          | | 2001:db8:1::2/64     |
9# | |                     |                          | |                      |
10# | |  + $h1.20           |                          | |  + $h2.20            |
11# | \  | 198.51.100.1/24  |                          | \  | 198.51.100.2/24   |
12# |  \ | 2001:db8:2::1/64 |                          |  \ | 2001:db8:2::2/64  |
13# |   \|                  |                          |   \|                   |
14# |    + $h1              |                          |    + $h2               |
15# +----|------------------+                          +----|-------------------+
16#      |                                                  |
17# +----|--------------------------------------------------|-------------------+
18# | SW |                                                  |                   |
19# | +--|--------------------------------------------------|-----------------+ |
20# | |  + $swp1                   BR0 (802.1q)             + $swp2           | |
21# | |     vid 10                                             vid 10         | |
22# | |     vid 20                                             vid 20         | |
23# | |                                                                       | |
24# | +-----------------------------------------------------------------------+ |
25# +---------------------------------------------------------------------------+
26
27ALL_TESTS="
28	test_8021d
29	test_8021q
30	test_8021qvs
31"
32
33NUM_NETIFS=4
34source lib.sh
35source tc_common.sh
36
37h1_create()
38{
39	simple_if_init $h1
40	vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64
41	vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64
42}
43
44h1_destroy()
45{
46	vlan_destroy $h1 20
47	vlan_destroy $h1 10
48	simple_if_fini $h1
49}
50
51h2_create()
52{
53	simple_if_init $h2
54	vlan_create $h2 10 v$h2 192.0.2.2/28
55	vlan_create $h2 20 v$h2 198.51.100.2/24
56}
57
58h2_destroy()
59{
60	vlan_destroy $h2 20
61	vlan_destroy $h2 10
62	simple_if_fini $h2
63}
64
65switch_create_8021d()
66{
67	log_info "802.1d tests"
68
69	ip link add name br0 type bridge vlan_filtering 0 \
70		mcast_snooping 1 \
71		mcast_igmp_version 3 mcast_mld_version 2
72	ip link set dev br0 up
73
74	ip link set dev $swp1 master br0
75	ip link set dev $swp1 up
76	bridge link set dev $swp1 fastleave on
77
78	ip link set dev $swp2 master br0
79	ip link set dev $swp2 up
80}
81
82switch_create_8021q()
83{
84	local br_flags=$1; shift
85
86	log_info "802.1q $br_flags${br_flags:+ }tests"
87
88	ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0 \
89		mcast_snooping 1 $br_flags \
90		mcast_igmp_version 3 mcast_mld_version 2
91	bridge vlan add vid 10 dev br0 self
92	bridge vlan add vid 20 dev br0 self
93	ip link set dev br0 up
94
95	ip link set dev $swp1 master br0
96	ip link set dev $swp1 up
97	bridge link set dev $swp1 fastleave on
98	bridge vlan add vid 10 dev $swp1
99	bridge vlan add vid 20 dev $swp1
100
101	ip link set dev $swp2 master br0
102	ip link set dev $swp2 up
103	bridge vlan add vid 10 dev $swp2
104	bridge vlan add vid 20 dev $swp2
105}
106
107switch_create_8021qvs()
108{
109	switch_create_8021q "mcast_vlan_snooping 1"
110	bridge vlan global set dev br0 vid 10 mcast_igmp_version 3
111	bridge vlan global set dev br0 vid 10 mcast_mld_version 2
112	bridge vlan global set dev br0 vid 20 mcast_igmp_version 3
113	bridge vlan global set dev br0 vid 20 mcast_mld_version 2
114}
115
116switch_destroy()
117{
118	ip link set dev $swp2 down
119	ip link set dev $swp2 nomaster
120
121	ip link set dev $swp1 down
122	ip link set dev $swp1 nomaster
123
124	ip link set dev br0 down
125	ip link del dev br0
126}
127
128setup_prepare()
129{
130	h1=${NETIFS[p1]}
131	swp1=${NETIFS[p2]}
132
133	swp2=${NETIFS[p3]}
134	h2=${NETIFS[p4]}
135
136	vrf_prepare
137	forwarding_enable
138
139	h1_create
140	h2_create
141}
142
143cleanup()
144{
145	pre_cleanup
146
147	switch_destroy 2>/dev/null
148	h2_destroy
149	h1_destroy
150
151	forwarding_restore
152	vrf_cleanup
153}
154
155cfg_src_list()
156{
157	local IPs=("$@")
158	local IPstr=$(echo ${IPs[@]} | tr '[:space:]' , | sed 's/,$//')
159
160	echo ${IPstr:+source_list }${IPstr}
161}
162
163cfg_group_op()
164{
165	local op=$1; shift
166	local locus=$1; shift
167	local GRP=$1; shift
168	local state=$1; shift
169	local IPs=("$@")
170
171	local source_list=$(cfg_src_list ${IPs[@]})
172
173	# Everything besides `bridge mdb' uses the "dev X vid Y" syntax,
174	# so we use it here as well and convert.
175	local br_locus=$(echo "$locus" | sed 's/^dev /port /')
176
177	bridge mdb $op dev br0 $br_locus grp $GRP $state \
178	       filter_mode include $source_list
179}
180
181cfg4_entries_op()
182{
183	local op=$1; shift
184	local locus=$1; shift
185	local state=$1; shift
186	local n=$1; shift
187	local grp=${1:-1}; shift
188
189	local GRP=239.1.1.${grp}
190	local IPs=$(seq -f 192.0.2.%g 1 $((n - 1)))
191	cfg_group_op "$op" "$locus" "$GRP" "$state" ${IPs[@]}
192}
193
194cfg4_entries_add()
195{
196	cfg4_entries_op add "$@"
197}
198
199cfg4_entries_del()
200{
201	cfg4_entries_op del "$@"
202}
203
204cfg6_entries_op()
205{
206	local op=$1; shift
207	local locus=$1; shift
208	local state=$1; shift
209	local n=$1; shift
210	local grp=${1:-1}; shift
211
212	local GRP=ff0e::${grp}
213	local IPs=$(printf "2001:db8:1::%x\n" $(seq 1 $((n - 1))))
214	cfg_group_op "$op" "$locus" "$GRP" "$state" ${IPs[@]}
215}
216
217cfg6_entries_add()
218{
219	cfg6_entries_op add "$@"
220}
221
222cfg6_entries_del()
223{
224	cfg6_entries_op del "$@"
225}
226
227locus_dev_peer()
228{
229	local dev_kw=$1; shift
230	local dev=$1; shift
231	local vid_kw=$1; shift
232	local vid=$1; shift
233
234	echo "$h1.${vid:-10}"
235}
236
237locus_dev()
238{
239	local dev_kw=$1; shift
240	local dev=$1; shift
241
242	echo $dev
243}
244
245ctl4_entries_add()
246{
247	local locus=$1; shift
248	local state=$1; shift
249	local n=$1; shift
250	local grp=${1:-1}; shift
251
252	local IPs=$(seq -f 192.0.2.%g 1 $((n - 1)))
253	local peer=$(locus_dev_peer $locus)
254	local GRP=239.1.1.${grp}
255	$MZ $peer -c 1 -A 192.0.2.1 -B $GRP \
256		-t ip proto=2,p=$(igmpv3_is_in_get $GRP $IPs) -q
257	sleep 1
258
259	local nn=$(bridge mdb show dev br0 | grep $GRP | wc -l)
260	if ((nn != n)); then
261		echo mcast_max_groups > /dev/stderr
262		false
263	fi
264}
265
266ctl4_entries_del()
267{
268	local locus=$1; shift
269	local state=$1; shift
270	local n=$1; shift
271	local grp=${1:-1}; shift
272
273	local peer=$(locus_dev_peer $locus)
274	local GRP=239.1.1.${grp}
275	$MZ $peer -c 1 -A 192.0.2.1 -B 224.0.0.2 \
276		-t ip proto=2,p=$(igmpv2_leave_get $GRP) -q
277	sleep 1
278	! bridge mdb show dev br0 | grep -q $GRP
279}
280
281ctl6_entries_add()
282{
283	local locus=$1; shift
284	local state=$1; shift
285	local n=$1; shift
286	local grp=${1:-1}; shift
287
288	local IPs=$(printf "2001:db8:1::%x\n" $(seq 1 $((n - 1))))
289	local peer=$(locus_dev_peer $locus)
290	local SIP=fe80::1
291	local GRP=ff0e::${grp}
292	local p=$(mldv2_is_in_get $SIP $GRP $IPs)
293	$MZ -6 $peer -c 1 -A $SIP -B $GRP -t ip hop=1,next=0,p="$p" -q
294	sleep 1
295
296	local nn=$(bridge mdb show dev br0 | grep $GRP | wc -l)
297	if ((nn != n)); then
298		echo mcast_max_groups > /dev/stderr
299		false
300	fi
301}
302
303ctl6_entries_del()
304{
305	local locus=$1; shift
306	local state=$1; shift
307	local n=$1; shift
308	local grp=${1:-1}; shift
309
310	local peer=$(locus_dev_peer $locus)
311	local SIP=fe80::1
312	local GRP=ff0e::${grp}
313	local p=$(mldv1_done_get $SIP $GRP)
314	$MZ -6 $peer -c 1 -A $SIP -B $GRP -t ip hop=1,next=0,p="$p" -q
315	sleep 1
316	! bridge mdb show dev br0 | grep -q $GRP
317}
318
319bridge_maxgroups_errmsg_check_cfg()
320{
321	local msg=$1; shift
322	local needle=$1; shift
323
324	echo "$msg" | grep -q mcast_max_groups
325	check_err $? "Adding MDB entries failed for the wrong reason: $msg"
326}
327
328bridge_maxgroups_errmsg_check_cfg4()
329{
330	bridge_maxgroups_errmsg_check_cfg "$@"
331}
332
333bridge_maxgroups_errmsg_check_cfg6()
334{
335	bridge_maxgroups_errmsg_check_cfg "$@"
336}
337
338bridge_maxgroups_errmsg_check_ctl4()
339{
340	:
341}
342
343bridge_maxgroups_errmsg_check_ctl6()
344{
345	:
346}
347
348bridge_port_ngroups_get()
349{
350	local locus=$1; shift
351
352	bridge -j -d link show $locus |
353	    jq '.[].mcast_n_groups'
354}
355
356bridge_port_maxgroups_get()
357{
358	local locus=$1; shift
359
360	bridge -j -d link show $locus |
361	    jq '.[].mcast_max_groups'
362}
363
364bridge_port_maxgroups_set()
365{
366	local locus=$1; shift
367	local max=$1; shift
368
369	bridge link set dev $(locus_dev $locus) mcast_max_groups $max
370}
371
372bridge_port_vlan_ngroups_get()
373{
374	local locus=$1; shift
375
376	bridge -j -d vlan show $locus |
377	    jq '.[].vlans[].mcast_n_groups'
378}
379
380bridge_port_vlan_maxgroups_get()
381{
382	local locus=$1; shift
383
384	bridge -j -d vlan show $locus |
385	    jq '.[].vlans[].mcast_max_groups'
386}
387
388bridge_port_vlan_maxgroups_set()
389{
390	local locus=$1; shift
391	local max=$1; shift
392
393	bridge vlan set $locus mcast_max_groups $max
394}
395
396test_ngroups_reporting()
397{
398	local CFG=$1; shift
399	local context=$1; shift
400	local locus=$1; shift
401
402	RET=0
403
404	local n0=$(bridge_${context}_ngroups_get "$locus")
405	${CFG}_entries_add "$locus" temp 5
406	check_err $? "Couldn't add MDB entries"
407	local n1=$(bridge_${context}_ngroups_get "$locus")
408
409	((n1 == n0 + 5))
410	check_err $? "Number of groups was $n0, now is $n1, but $((n0 + 5)) expected"
411
412	${CFG}_entries_del "$locus" temp 5
413	check_err $? "Couldn't delete MDB entries"
414	local n2=$(bridge_${context}_ngroups_get "$locus")
415
416	((n2 == n0))
417	check_err $? "Number of groups was $n0, now is $n2, but should be back to $n0"
418
419	log_test "$CFG: $context: ngroups reporting"
420}
421
422test_8021d_ngroups_reporting_cfg4()
423{
424	test_ngroups_reporting cfg4 port "dev $swp1"
425}
426
427test_8021d_ngroups_reporting_ctl4()
428{
429	test_ngroups_reporting ctl4 port "dev $swp1"
430}
431
432test_8021d_ngroups_reporting_cfg6()
433{
434	test_ngroups_reporting cfg6 port "dev $swp1"
435}
436
437test_8021d_ngroups_reporting_ctl6()
438{
439	test_ngroups_reporting ctl6 port "dev $swp1"
440}
441
442test_8021q_ngroups_reporting_cfg4()
443{
444	test_ngroups_reporting cfg4 port "dev $swp1 vid 10"
445}
446
447test_8021q_ngroups_reporting_ctl4()
448{
449	test_ngroups_reporting ctl4 port "dev $swp1 vid 10"
450}
451
452test_8021q_ngroups_reporting_cfg6()
453{
454	test_ngroups_reporting cfg6 port "dev $swp1 vid 10"
455}
456
457test_8021q_ngroups_reporting_ctl6()
458{
459	test_ngroups_reporting ctl6 port "dev $swp1 vid 10"
460}
461
462test_8021qvs_ngroups_reporting_cfg4()
463{
464	test_ngroups_reporting cfg4 port_vlan "dev $swp1 vid 10"
465}
466
467test_8021qvs_ngroups_reporting_ctl4()
468{
469	test_ngroups_reporting ctl4 port_vlan "dev $swp1 vid 10"
470}
471
472test_8021qvs_ngroups_reporting_cfg6()
473{
474	test_ngroups_reporting cfg6 port_vlan "dev $swp1 vid 10"
475}
476
477test_8021qvs_ngroups_reporting_ctl6()
478{
479	test_ngroups_reporting ctl6 port_vlan "dev $swp1 vid 10"
480}
481
482test_ngroups_cross_vlan()
483{
484	local CFG=$1; shift
485
486	local locus1="dev $swp1 vid 10"
487	local locus2="dev $swp1 vid 20"
488
489	RET=0
490
491	local n10=$(bridge_port_vlan_ngroups_get "$locus1")
492	local n20=$(bridge_port_vlan_ngroups_get "$locus2")
493	${CFG}_entries_add "$locus1" temp 5 111
494	check_err $? "Couldn't add MDB entries to VLAN 10"
495	local n11=$(bridge_port_vlan_ngroups_get "$locus1")
496	local n21=$(bridge_port_vlan_ngroups_get "$locus2")
497
498	((n11 == n10 + 5))
499	check_err $? "Number of groups at VLAN 10 was $n10, now is $n11, but 5 entries added on VLAN 10, $((n10 + 5)) expected"
500
501	((n21 == n20))
502	check_err $? "Number of groups at VLAN 20 was $n20, now is $n21, but no change expected on VLAN 20"
503
504	${CFG}_entries_add "$locus2" temp 5 112
505	check_err $? "Couldn't add MDB entries to VLAN 20"
506	local n12=$(bridge_port_vlan_ngroups_get "$locus1")
507	local n22=$(bridge_port_vlan_ngroups_get "$locus2")
508
509	((n12 == n11))
510	check_err $? "Number of groups at VLAN 10 was $n11, now is $n12, but no change expected on VLAN 10"
511
512	((n22 == n21 + 5))
513	check_err $? "Number of groups at VLAN 20 was $n21, now is $n22, but 5 entries added on VLAN 20, $((n21 + 5)) expected"
514
515	${CFG}_entries_del "$locus1" temp 5 111
516	check_err $? "Couldn't delete MDB entries from VLAN 10"
517	${CFG}_entries_del "$locus2" temp 5 112
518	check_err $? "Couldn't delete MDB entries from VLAN 20"
519	local n13=$(bridge_port_vlan_ngroups_get "$locus1")
520	local n23=$(bridge_port_vlan_ngroups_get "$locus2")
521
522	((n13 == n10))
523	check_err $? "Number of groups at VLAN 10 was $n10, now is $n13, but should be back to $n10"
524
525	((n23 == n20))
526	check_err $? "Number of groups at VLAN 20 was $n20, now is $n23, but should be back to $n20"
527
528	log_test "$CFG: port_vlan: isolation of port and per-VLAN ngroups"
529}
530
531test_8021qvs_ngroups_cross_vlan_cfg4()
532{
533	test_ngroups_cross_vlan cfg4
534}
535
536test_8021qvs_ngroups_cross_vlan_ctl4()
537{
538	test_ngroups_cross_vlan ctl4
539}
540
541test_8021qvs_ngroups_cross_vlan_cfg6()
542{
543	test_ngroups_cross_vlan cfg6
544}
545
546test_8021qvs_ngroups_cross_vlan_ctl6()
547{
548	test_ngroups_cross_vlan ctl6
549}
550
551test_maxgroups_zero()
552{
553	local CFG=$1; shift
554	local context=$1; shift
555	local locus=$1; shift
556
557	RET=0
558	local max
559
560	max=$(bridge_${context}_maxgroups_get "$locus")
561	((max == 0))
562	check_err $? "Max groups on $locus should be 0, but $max reported"
563
564	bridge_${context}_maxgroups_set "$locus" 100
565	check_err $? "Failed to set max to 100"
566	max=$(bridge_${context}_maxgroups_get "$locus")
567	((max == 100))
568	check_err $? "Max groups expected to be 100, but $max reported"
569
570	bridge_${context}_maxgroups_set "$locus" 0
571	check_err $? "Couldn't set maximum to 0"
572
573	# Test that setting 0 explicitly still serves as infinity.
574	${CFG}_entries_add "$locus" temp 5
575	check_err $? "Adding 5 MDB entries failed but should have passed"
576	${CFG}_entries_del "$locus" temp 5
577	check_err $? "Couldn't delete MDB entries"
578
579	log_test "$CFG: $context maxgroups: reporting and treatment of 0"
580}
581
582test_8021d_maxgroups_zero_cfg4()
583{
584	test_maxgroups_zero cfg4 port "dev $swp1"
585}
586
587test_8021d_maxgroups_zero_ctl4()
588{
589	test_maxgroups_zero ctl4 port "dev $swp1"
590}
591
592test_8021d_maxgroups_zero_cfg6()
593{
594	test_maxgroups_zero cfg6 port "dev $swp1"
595}
596
597test_8021d_maxgroups_zero_ctl6()
598{
599	test_maxgroups_zero ctl6 port "dev $swp1"
600}
601
602test_8021q_maxgroups_zero_cfg4()
603{
604	test_maxgroups_zero cfg4 port "dev $swp1 vid 10"
605}
606
607test_8021q_maxgroups_zero_ctl4()
608{
609	test_maxgroups_zero ctl4 port "dev $swp1 vid 10"
610}
611
612test_8021q_maxgroups_zero_cfg6()
613{
614	test_maxgroups_zero cfg6 port "dev $swp1 vid 10"
615}
616
617test_8021q_maxgroups_zero_ctl6()
618{
619	test_maxgroups_zero ctl6 port "dev $swp1 vid 10"
620}
621
622test_8021qvs_maxgroups_zero_cfg4()
623{
624	test_maxgroups_zero cfg4 port_vlan "dev $swp1 vid 10"
625}
626
627test_8021qvs_maxgroups_zero_ctl4()
628{
629	test_maxgroups_zero ctl4 port_vlan "dev $swp1 vid 10"
630}
631
632test_8021qvs_maxgroups_zero_cfg6()
633{
634	test_maxgroups_zero cfg6 port_vlan "dev $swp1 vid 10"
635}
636
637test_8021qvs_maxgroups_zero_ctl6()
638{
639	test_maxgroups_zero ctl6 port_vlan "dev $swp1 vid 10"
640}
641
642test_maxgroups_zero_cross_vlan()
643{
644	local CFG=$1; shift
645
646	local locus0="dev $swp1"
647	local locus1="dev $swp1 vid 10"
648	local locus2="dev $swp1 vid 20"
649	local max
650
651	RET=0
652
653	bridge_port_vlan_maxgroups_set "$locus1" 100
654	check_err $? "$locus1: Failed to set max to 100"
655
656	max=$(bridge_port_maxgroups_get "$locus0")
657	((max == 0))
658	check_err $? "$locus0: Max groups expected to be 0, but $max reported"
659
660	max=$(bridge_port_vlan_maxgroups_get "$locus2")
661	((max == 0))
662	check_err $? "$locus2: Max groups expected to be 0, but $max reported"
663
664	bridge_port_vlan_maxgroups_set "$locus2" 100
665	check_err $? "$locus2: Failed to set max to 100"
666
667	max=$(bridge_port_maxgroups_get "$locus0")
668	((max == 0))
669	check_err $? "$locus0: Max groups expected to be 0, but $max reported"
670
671	max=$(bridge_port_vlan_maxgroups_get "$locus2")
672	((max == 100))
673	check_err $? "$locus2: Max groups expected to be 100, but $max reported"
674
675	bridge_port_maxgroups_set "$locus0" 100
676	check_err $? "$locus0: Failed to set max to 100"
677
678	max=$(bridge_port_maxgroups_get "$locus0")
679	((max == 100))
680	check_err $? "$locus0: Max groups expected to be 100, but $max reported"
681
682	max=$(bridge_port_vlan_maxgroups_get "$locus2")
683	((max == 100))
684	check_err $? "$locus2: Max groups expected to be 100, but $max reported"
685
686	bridge_port_vlan_maxgroups_set "$locus1" 0
687	check_err $? "$locus1: Failed to set max to 0"
688
689	max=$(bridge_port_maxgroups_get "$locus0")
690	((max == 100))
691	check_err $? "$locus0: Max groups expected to be 100, but $max reported"
692
693	max=$(bridge_port_vlan_maxgroups_get "$locus2")
694	((max == 100))
695	check_err $? "$locus2: Max groups expected to be 100, but $max reported"
696
697	bridge_port_vlan_maxgroups_set "$locus2" 0
698	check_err $? "$locus2: Failed to set max to 0"
699
700	max=$(bridge_port_maxgroups_get "$locus0")
701	((max == 100))
702	check_err $? "$locus0: Max groups expected to be 100, but $max reported"
703
704	max=$(bridge_port_vlan_maxgroups_get "$locus2")
705	((max == 0))
706	check_err $? "$locus2: Max groups expected to be 0 but $max reported"
707
708	bridge_port_maxgroups_set "$locus0" 0
709	check_err $? "$locus0: Failed to set max to 0"
710
711	max=$(bridge_port_maxgroups_get "$locus0")
712	((max == 0))
713	check_err $? "$locus0: Max groups expected to be 0, but $max reported"
714
715	max=$(bridge_port_vlan_maxgroups_get "$locus2")
716	((max == 0))
717	check_err $? "$locus2: Max groups expected to be 0, but $max reported"
718
719	log_test "$CFG: port_vlan maxgroups: isolation of port and per-VLAN maximums"
720}
721
722test_8021qvs_maxgroups_zero_cross_vlan_cfg4()
723{
724	test_maxgroups_zero_cross_vlan cfg4
725}
726
727test_8021qvs_maxgroups_zero_cross_vlan_ctl4()
728{
729	test_maxgroups_zero_cross_vlan ctl4
730}
731
732test_8021qvs_maxgroups_zero_cross_vlan_cfg6()
733{
734	test_maxgroups_zero_cross_vlan cfg6
735}
736
737test_8021qvs_maxgroups_zero_cross_vlan_ctl6()
738{
739	test_maxgroups_zero_cross_vlan ctl6
740}
741
742test_maxgroups_too_low()
743{
744	local CFG=$1; shift
745	local context=$1; shift
746	local locus=$1; shift
747
748	RET=0
749
750	local n=$(bridge_${context}_ngroups_get "$locus")
751	local msg
752
753	${CFG}_entries_add "$locus" temp 5 111
754	check_err $? "$locus: Couldn't add MDB entries"
755
756	bridge_${context}_maxgroups_set "$locus" $((n+2))
757	check_err $? "$locus: Setting maxgroups to $((n+2)) failed"
758
759	msg=$(${CFG}_entries_add "$locus" temp 2 112 2>&1)
760	check_fail $? "$locus: Adding more entries passed when max<n"
761	bridge_maxgroups_errmsg_check_cfg "$msg"
762
763	${CFG}_entries_del "$locus" temp 5 111
764	check_err $? "$locus: Couldn't delete MDB entries"
765
766	${CFG}_entries_add "$locus" temp 2 112
767	check_err $? "$locus: Adding more entries failed"
768
769	${CFG}_entries_del "$locus" temp 2 112
770	check_err $? "$locus: Deleting more entries failed"
771
772	bridge_${context}_maxgroups_set "$locus" 0
773	check_err $? "$locus: Couldn't set maximum to 0"
774
775	log_test "$CFG: $context maxgroups: configure below ngroups"
776}
777
778test_8021d_maxgroups_too_low_cfg4()
779{
780	test_maxgroups_too_low cfg4 port "dev $swp1"
781}
782
783test_8021d_maxgroups_too_low_ctl4()
784{
785	test_maxgroups_too_low ctl4 port "dev $swp1"
786}
787
788test_8021d_maxgroups_too_low_cfg6()
789{
790	test_maxgroups_too_low cfg6 port "dev $swp1"
791}
792
793test_8021d_maxgroups_too_low_ctl6()
794{
795	test_maxgroups_too_low ctl6 port "dev $swp1"
796}
797
798test_8021q_maxgroups_too_low_cfg4()
799{
800	test_maxgroups_too_low cfg4 port "dev $swp1 vid 10"
801}
802
803test_8021q_maxgroups_too_low_ctl4()
804{
805	test_maxgroups_too_low ctl4 port "dev $swp1 vid 10"
806}
807
808test_8021q_maxgroups_too_low_cfg6()
809{
810	test_maxgroups_too_low cfg6 port "dev $swp1 vid 10"
811}
812
813test_8021q_maxgroups_too_low_ctl6()
814{
815	test_maxgroups_too_low ctl6 port "dev $swp1 vid 10"
816}
817
818test_8021qvs_maxgroups_too_low_cfg4()
819{
820	test_maxgroups_too_low cfg4 port_vlan "dev $swp1 vid 10"
821}
822
823test_8021qvs_maxgroups_too_low_ctl4()
824{
825	test_maxgroups_too_low ctl4 port_vlan "dev $swp1 vid 10"
826}
827
828test_8021qvs_maxgroups_too_low_cfg6()
829{
830	test_maxgroups_too_low cfg6 port_vlan "dev $swp1 vid 10"
831}
832
833test_8021qvs_maxgroups_too_low_ctl6()
834{
835	test_maxgroups_too_low ctl6 port_vlan "dev $swp1 vid 10"
836}
837
838test_maxgroups_too_many_entries()
839{
840	local CFG=$1; shift
841	local context=$1; shift
842	local locus=$1; shift
843
844	RET=0
845
846	local n=$(bridge_${context}_ngroups_get "$locus")
847	local msg
848
849	# Configure a low maximum
850	bridge_${context}_maxgroups_set "$locus" $((n+1))
851	check_err $? "$locus: Couldn't set maximum"
852
853	# Try to add more entries than the configured maximum
854	msg=$(${CFG}_entries_add "$locus" temp 5 2>&1)
855	check_fail $? "Adding 5 MDB entries passed, but should have failed"
856	bridge_maxgroups_errmsg_check_${CFG} "$msg"
857
858	# When adding entries through the control path, as many as possible
859	# get created. That's consistent with the mcast_hash_max behavior.
860	# So there, drop the entries explicitly.
861	if [[ ${CFG%[46]} == ctl ]]; then
862		${CFG}_entries_del "$locus" temp 17 2>&1
863	fi
864
865	local n2=$(bridge_${context}_ngroups_get "$locus")
866	((n2 == n))
867	check_err $? "Number of groups was $n, but after a failed attempt to add MDB entries it changed to $n2"
868
869	bridge_${context}_maxgroups_set "$locus" 0
870	check_err $? "$locus: Couldn't set maximum to 0"
871
872	log_test "$CFG: $context maxgroups: add too many MDB entries"
873}
874
875test_8021d_maxgroups_too_many_entries_cfg4()
876{
877	test_maxgroups_too_many_entries cfg4 port "dev $swp1"
878}
879
880test_8021d_maxgroups_too_many_entries_ctl4()
881{
882	test_maxgroups_too_many_entries ctl4 port "dev $swp1"
883}
884
885test_8021d_maxgroups_too_many_entries_cfg6()
886{
887	test_maxgroups_too_many_entries cfg6 port "dev $swp1"
888}
889
890test_8021d_maxgroups_too_many_entries_ctl6()
891{
892	test_maxgroups_too_many_entries ctl6 port "dev $swp1"
893}
894
895test_8021q_maxgroups_too_many_entries_cfg4()
896{
897	test_maxgroups_too_many_entries cfg4 port "dev $swp1 vid 10"
898}
899
900test_8021q_maxgroups_too_many_entries_ctl4()
901{
902	test_maxgroups_too_many_entries ctl4 port "dev $swp1 vid 10"
903}
904
905test_8021q_maxgroups_too_many_entries_cfg6()
906{
907	test_maxgroups_too_many_entries cfg6 port "dev $swp1 vid 10"
908}
909
910test_8021q_maxgroups_too_many_entries_ctl6()
911{
912	test_maxgroups_too_many_entries ctl6 port "dev $swp1 vid 10"
913}
914
915test_8021qvs_maxgroups_too_many_entries_cfg4()
916{
917	test_maxgroups_too_many_entries cfg4 port_vlan "dev $swp1 vid 10"
918}
919
920test_8021qvs_maxgroups_too_many_entries_ctl4()
921{
922	test_maxgroups_too_many_entries ctl4 port_vlan "dev $swp1 vid 10"
923}
924
925test_8021qvs_maxgroups_too_many_entries_cfg6()
926{
927	test_maxgroups_too_many_entries cfg6 port_vlan "dev $swp1 vid 10"
928}
929
930test_8021qvs_maxgroups_too_many_entries_ctl6()
931{
932	test_maxgroups_too_many_entries ctl6 port_vlan "dev $swp1 vid 10"
933}
934
935test_maxgroups_too_many_cross_vlan()
936{
937	local CFG=$1; shift
938
939	RET=0
940
941	local locus0="dev $swp1"
942	local locus1="dev $swp1 vid 10"
943	local locus2="dev $swp1 vid 20"
944	local n1=$(bridge_port_vlan_ngroups_get "$locus1")
945	local n2=$(bridge_port_vlan_ngroups_get "$locus2")
946	local msg
947
948	if ((n1 > n2)); then
949		local tmp=$n1
950		n1=$n2
951		n2=$tmp
952
953		tmp="$locus1"
954		locus1="$locus2"
955		locus2="$tmp"
956	fi
957
958	# Now 0 <= n1 <= n2.
959	${CFG}_entries_add "$locus2" temp 5 112
960	check_err $? "Couldn't add 5 entries"
961
962	n2=$(bridge_port_vlan_ngroups_get "$locus2")
963	# Now 0 <= n1 < n2-1.
964
965	# Setting locus1'maxgroups to n2-1 should pass. The number is
966	# smaller than both the absolute number of MDB entries, and in
967	# particular than number of locus2's number of entries, but it is
968	# large enough to cover locus1's entries. Thus we check that
969	# individual VLAN's ngroups are independent.
970	bridge_port_vlan_maxgroups_set "$locus1" $((n2-1))
971	check_err $? "Setting ${locus1}'s maxgroups to $((n2-1)) failed"
972
973	msg=$(${CFG}_entries_add "$locus1" temp $n2 111 2>&1)
974	check_fail $? "$locus1: Adding $n2 MDB entries passed, but should have failed"
975	bridge_maxgroups_errmsg_check_${CFG} "$msg"
976
977	bridge_port_maxgroups_set "$locus0" $((n1 + n2 + 2))
978	check_err $? "$locus0: Couldn't set maximum"
979
980	msg=$(${CFG}_entries_add "$locus1" temp 5 111 2>&1)
981	check_fail $? "$locus1: Adding 5 MDB entries passed, but should have failed"
982	bridge_maxgroups_errmsg_check_${CFG} "$msg"
983
984	# IGMP/MLD packets can cause several entries to be added, before
985	# the maximum is hit and the rest is then bounced. Remove what was
986	# committed, if anything.
987	${CFG}_entries_del "$locus1" temp 5 111 2>/dev/null
988
989	${CFG}_entries_add "$locus1" temp 2 111
990	check_err $? "$locus1: Adding 2 MDB entries failed, but should have passed"
991
992	${CFG}_entries_del "$locus1" temp 2 111
993	check_err $? "Couldn't delete MDB entries"
994
995	${CFG}_entries_del "$locus2" temp 5 112
996	check_err $? "Couldn't delete MDB entries"
997
998	bridge_port_vlan_maxgroups_set "$locus1" 0
999	check_err $? "$locus1: Couldn't set maximum to 0"
1000
1001	bridge_port_maxgroups_set "$locus0" 0
1002	check_err $? "$locus0: Couldn't set maximum to 0"
1003
1004	log_test "$CFG: port_vlan maxgroups: isolation of port and per-VLAN ngroups"
1005}
1006
1007test_8021qvs_maxgroups_too_many_cross_vlan_cfg4()
1008{
1009	test_maxgroups_too_many_cross_vlan cfg4
1010}
1011
1012test_8021qvs_maxgroups_too_many_cross_vlan_ctl4()
1013{
1014	test_maxgroups_too_many_cross_vlan ctl4
1015}
1016
1017test_8021qvs_maxgroups_too_many_cross_vlan_cfg6()
1018{
1019	test_maxgroups_too_many_cross_vlan cfg6
1020}
1021
1022test_8021qvs_maxgroups_too_many_cross_vlan_ctl6()
1023{
1024	test_maxgroups_too_many_cross_vlan ctl6
1025}
1026
1027test_vlan_attributes()
1028{
1029	local locus=$1; shift
1030	local expect=$1; shift
1031
1032	RET=0
1033
1034	local max=$(bridge_port_vlan_maxgroups_get "$locus")
1035	local n=$(bridge_port_vlan_ngroups_get "$locus")
1036
1037	eval "[[ $max $expect ]]"
1038	check_err $? "$locus: maxgroups attribute expected to be $expect, but was $max"
1039
1040	eval "[[ $n $expect ]]"
1041	check_err $? "$locus: ngroups attribute expected to be $expect, but was $n"
1042
1043	log_test "port_vlan: presence of ngroups and maxgroups attributes"
1044}
1045
1046test_8021q_vlan_attributes()
1047{
1048	test_vlan_attributes "dev $swp1 vid 10" "== null"
1049}
1050
1051test_8021qvs_vlan_attributes()
1052{
1053	test_vlan_attributes "dev $swp1 vid 10" "-ge 0"
1054}
1055
1056test_toggle_vlan_snooping()
1057{
1058	local mode=$1; shift
1059
1060	RET=0
1061
1062	local CFG=cfg4
1063	local context=port_vlan
1064	local locus="dev $swp1 vid 10"
1065
1066	${CFG}_entries_add "$locus" $mode 5
1067	check_err $? "Couldn't add MDB entries"
1068
1069	bridge_${context}_maxgroups_set "$locus" 100
1070	check_err $? "Failed to set max to 100"
1071
1072	ip link set dev br0 type bridge mcast_vlan_snooping 0
1073	sleep 1
1074	ip link set dev br0 type bridge mcast_vlan_snooping 1
1075
1076	local n=$(bridge_${context}_ngroups_get "$locus")
1077	local nn=$(bridge mdb show dev br0 | grep $swp1 | wc -l)
1078	((nn == n))
1079	check_err $? "mcast_n_groups expected to be $nn, but $n reported"
1080
1081	local max=$(bridge_${context}_maxgroups_get "$locus")
1082	((max == 100))
1083	check_err $? "Max groups expected to be 100 but $max reported"
1084
1085	bridge_${context}_maxgroups_set "$locus" 0
1086	check_err $? "Failed to set max to 0"
1087
1088	log_test "$CFG: $context: $mode: mcast_vlan_snooping toggle"
1089}
1090
1091test_toggle_vlan_snooping_temp()
1092{
1093	test_toggle_vlan_snooping temp
1094}
1095
1096test_toggle_vlan_snooping_permanent()
1097{
1098	test_toggle_vlan_snooping permanent
1099}
1100
1101# ngroup test suites
1102
1103test_8021d_ngroups_cfg4()
1104{
1105	test_8021d_ngroups_reporting_cfg4
1106}
1107
1108test_8021d_ngroups_ctl4()
1109{
1110	test_8021d_ngroups_reporting_ctl4
1111}
1112
1113test_8021d_ngroups_cfg6()
1114{
1115	test_8021d_ngroups_reporting_cfg6
1116}
1117
1118test_8021d_ngroups_ctl6()
1119{
1120	test_8021d_ngroups_reporting_ctl6
1121}
1122
1123test_8021q_ngroups_cfg4()
1124{
1125	test_8021q_ngroups_reporting_cfg4
1126}
1127
1128test_8021q_ngroups_ctl4()
1129{
1130	test_8021q_ngroups_reporting_ctl4
1131}
1132
1133test_8021q_ngroups_cfg6()
1134{
1135	test_8021q_ngroups_reporting_cfg6
1136}
1137
1138test_8021q_ngroups_ctl6()
1139{
1140	test_8021q_ngroups_reporting_ctl6
1141}
1142
1143test_8021qvs_ngroups_cfg4()
1144{
1145	test_8021qvs_ngroups_reporting_cfg4
1146	test_8021qvs_ngroups_cross_vlan_cfg4
1147}
1148
1149test_8021qvs_ngroups_ctl4()
1150{
1151	test_8021qvs_ngroups_reporting_ctl4
1152	test_8021qvs_ngroups_cross_vlan_ctl4
1153}
1154
1155test_8021qvs_ngroups_cfg6()
1156{
1157	test_8021qvs_ngroups_reporting_cfg6
1158	test_8021qvs_ngroups_cross_vlan_cfg6
1159}
1160
1161test_8021qvs_ngroups_ctl6()
1162{
1163	test_8021qvs_ngroups_reporting_ctl6
1164	test_8021qvs_ngroups_cross_vlan_ctl6
1165}
1166
1167# maxgroups test suites
1168
1169test_8021d_maxgroups_cfg4()
1170{
1171	test_8021d_maxgroups_zero_cfg4
1172	test_8021d_maxgroups_too_low_cfg4
1173	test_8021d_maxgroups_too_many_entries_cfg4
1174}
1175
1176test_8021d_maxgroups_ctl4()
1177{
1178	test_8021d_maxgroups_zero_ctl4
1179	test_8021d_maxgroups_too_low_ctl4
1180	test_8021d_maxgroups_too_many_entries_ctl4
1181}
1182
1183test_8021d_maxgroups_cfg6()
1184{
1185	test_8021d_maxgroups_zero_cfg6
1186	test_8021d_maxgroups_too_low_cfg6
1187	test_8021d_maxgroups_too_many_entries_cfg6
1188}
1189
1190test_8021d_maxgroups_ctl6()
1191{
1192	test_8021d_maxgroups_zero_ctl6
1193	test_8021d_maxgroups_too_low_ctl6
1194	test_8021d_maxgroups_too_many_entries_ctl6
1195}
1196
1197test_8021q_maxgroups_cfg4()
1198{
1199	test_8021q_maxgroups_zero_cfg4
1200	test_8021q_maxgroups_too_low_cfg4
1201	test_8021q_maxgroups_too_many_entries_cfg4
1202}
1203
1204test_8021q_maxgroups_ctl4()
1205{
1206	test_8021q_maxgroups_zero_ctl4
1207	test_8021q_maxgroups_too_low_ctl4
1208	test_8021q_maxgroups_too_many_entries_ctl4
1209}
1210
1211test_8021q_maxgroups_cfg6()
1212{
1213	test_8021q_maxgroups_zero_cfg6
1214	test_8021q_maxgroups_too_low_cfg6
1215	test_8021q_maxgroups_too_many_entries_cfg6
1216}
1217
1218test_8021q_maxgroups_ctl6()
1219{
1220	test_8021q_maxgroups_zero_ctl6
1221	test_8021q_maxgroups_too_low_ctl6
1222	test_8021q_maxgroups_too_many_entries_ctl6
1223}
1224
1225test_8021qvs_maxgroups_cfg4()
1226{
1227	test_8021qvs_maxgroups_zero_cfg4
1228	test_8021qvs_maxgroups_zero_cross_vlan_cfg4
1229	test_8021qvs_maxgroups_too_low_cfg4
1230	test_8021qvs_maxgroups_too_many_entries_cfg4
1231	test_8021qvs_maxgroups_too_many_cross_vlan_cfg4
1232}
1233
1234test_8021qvs_maxgroups_ctl4()
1235{
1236	test_8021qvs_maxgroups_zero_ctl4
1237	test_8021qvs_maxgroups_zero_cross_vlan_ctl4
1238	test_8021qvs_maxgroups_too_low_ctl4
1239	test_8021qvs_maxgroups_too_many_entries_ctl4
1240	test_8021qvs_maxgroups_too_many_cross_vlan_ctl4
1241}
1242
1243test_8021qvs_maxgroups_cfg6()
1244{
1245	test_8021qvs_maxgroups_zero_cfg6
1246	test_8021qvs_maxgroups_zero_cross_vlan_cfg6
1247	test_8021qvs_maxgroups_too_low_cfg6
1248	test_8021qvs_maxgroups_too_many_entries_cfg6
1249	test_8021qvs_maxgroups_too_many_cross_vlan_cfg6
1250}
1251
1252test_8021qvs_maxgroups_ctl6()
1253{
1254	test_8021qvs_maxgroups_zero_ctl6
1255	test_8021qvs_maxgroups_zero_cross_vlan_ctl6
1256	test_8021qvs_maxgroups_too_low_ctl6
1257	test_8021qvs_maxgroups_too_many_entries_ctl6
1258	test_8021qvs_maxgroups_too_many_cross_vlan_ctl6
1259}
1260
1261# other test suites
1262
1263test_8021qvs_toggle_vlan_snooping()
1264{
1265	test_toggle_vlan_snooping_temp
1266	test_toggle_vlan_snooping_permanent
1267}
1268
1269# test groups
1270
1271test_8021d()
1272{
1273	# Tests for vlan_filtering 0 mcast_vlan_snooping 0.
1274
1275	switch_create_8021d
1276	setup_wait
1277
1278	test_8021d_ngroups_cfg4
1279	test_8021d_ngroups_ctl4
1280	test_8021d_ngroups_cfg6
1281	test_8021d_ngroups_ctl6
1282	test_8021d_maxgroups_cfg4
1283	test_8021d_maxgroups_ctl4
1284	test_8021d_maxgroups_cfg6
1285	test_8021d_maxgroups_ctl6
1286
1287	switch_destroy
1288}
1289
1290test_8021q()
1291{
1292	# Tests for vlan_filtering 1 mcast_vlan_snooping 0.
1293
1294	switch_create_8021q
1295	setup_wait
1296
1297	test_8021q_vlan_attributes
1298	test_8021q_ngroups_cfg4
1299	test_8021q_ngroups_ctl4
1300	test_8021q_ngroups_cfg6
1301	test_8021q_ngroups_ctl6
1302	test_8021q_maxgroups_cfg4
1303	test_8021q_maxgroups_ctl4
1304	test_8021q_maxgroups_cfg6
1305	test_8021q_maxgroups_ctl6
1306
1307	switch_destroy
1308}
1309
1310test_8021qvs()
1311{
1312	# Tests for vlan_filtering 1 mcast_vlan_snooping 1.
1313
1314	switch_create_8021qvs
1315	setup_wait
1316
1317	test_8021qvs_vlan_attributes
1318	test_8021qvs_ngroups_cfg4
1319	test_8021qvs_ngroups_ctl4
1320	test_8021qvs_ngroups_cfg6
1321	test_8021qvs_ngroups_ctl6
1322	test_8021qvs_maxgroups_cfg4
1323	test_8021qvs_maxgroups_ctl4
1324	test_8021qvs_maxgroups_cfg6
1325	test_8021qvs_maxgroups_ctl6
1326	test_8021qvs_toggle_vlan_snooping
1327
1328	switch_destroy
1329}
1330
1331trap cleanup EXIT
1332
1333setup_prepare
1334tests_run
1335
1336exit $EXIT_STATUS
1337