xref: /linux/tools/testing/selftests/net/forwarding/bridge_igmp.sh (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="
5	v2reportleave_test
6	v3include_test
7	v3inc_allow_test
8	v3inc_is_include_test
9	v3inc_is_exclude_test
10	v3inc_to_exclude_test
11	v3exc_allow_test
12	v3exc_is_include_test
13	v3exc_is_exclude_test
14	v3exc_to_exclude_test
15	v3inc_block_test
16	v3exc_block_test
17	v3exc_timeout_test
18	v3star_ex_auto_add_test
19	v2per_vlan_snooping_port_stp_test
20	v2per_vlan_snooping_vlan_stp_test
21"
22NUM_NETIFS=4
23CHECK_TC="yes"
24TEST_GROUP="239.10.10.10"
25TEST_GROUP_MAC="01:00:5e:0a:0a:0a"
26
27ALL_GROUP="224.0.0.1"
28ALL_MAC="01:00:5e:00:00:01"
29
30# IGMPv3 is_in report: grp 239.10.10.10 is_include 192.0.2.1,192.0.2.2,192.0.2.3
31MZPKT_IS_INC="22:00:9d:de:00:00:00:01:01:00:00:03:ef:0a:0a:0a:c0:00:02:01:c0:00:02:02:c0:00:02:03"
32# IGMPv3 is_in report: grp 239.10.10.10 is_include 192.0.2.10,192.0.2.11,192.0.2.12
33MZPKT_IS_INC2="22:00:9d:c3:00:00:00:01:01:00:00:03:ef:0a:0a:0a:c0:00:02:0a:c0:00:02:0b:c0:00:02:0c"
34# IGMPv3 is_in report: grp 239.10.10.10 is_include 192.0.2.20,192.0.2.30
35MZPKT_IS_INC3="22:00:5f:b4:00:00:00:01:01:00:00:02:ef:0a:0a:0a:c0:00:02:14:c0:00:02:1e"
36# IGMPv3 allow report: grp 239.10.10.10 allow 192.0.2.10,192.0.2.11,192.0.2.12
37MZPKT_ALLOW="22:00:99:c3:00:00:00:01:05:00:00:03:ef:0a:0a:0a:c0:00:02:0a:c0:00:02:0b:c0:00:02:0c"
38# IGMPv3 allow report: grp 239.10.10.10 allow 192.0.2.20,192.0.2.30
39MZPKT_ALLOW2="22:00:5b:b4:00:00:00:01:05:00:00:02:ef:0a:0a:0a:c0:00:02:14:c0:00:02:1e"
40# IGMPv3 is_ex report: grp 239.10.10.10 is_exclude 192.0.2.1,192.0.2.2,192.0.2.20,192.0.2.21
41MZPKT_IS_EXC="22:00:da:b6:00:00:00:01:02:00:00:04:ef:0a:0a:0a:c0:00:02:01:c0:00:02:02:c0:00:02:14:c0:00:02:15"
42# IGMPv3 is_ex report: grp 239.10.10.10 is_exclude 192.0.2.20,192.0.2.30
43MZPKT_IS_EXC2="22:00:5e:b4:00:00:00:01:02:00:00:02:ef:0a:0a:0a:c0:00:02:14:c0:00:02:1e"
44# IGMPv3 to_ex report: grp 239.10.10.10 to_exclude 192.0.2.1,192.0.2.20,192.0.2.30
45MZPKT_TO_EXC="22:00:9a:b1:00:00:00:01:04:00:00:03:ef:0a:0a:0a:c0:00:02:01:c0:00:02:14:c0:00:02:1e"
46# IGMPv3 block report: grp 239.10.10.10 block 192.0.2.1,192.0.2.20,192.0.2.30
47MZPKT_BLOCK="22:00:98:b1:00:00:00:01:06:00:00:03:ef:0a:0a:0a:c0:00:02:01:c0:00:02:14:c0:00:02:1e"
48
49source lib.sh
50
51h1_create()
52{
53	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
54}
55
56h1_destroy()
57{
58	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
59}
60
61h2_create()
62{
63	simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
64}
65
66h2_destroy()
67{
68	simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
69}
70
71switch_create()
72{
73	ip link add dev br0 type bridge mcast_snooping 1 mcast_querier 1
74
75	ip link set dev $swp1 master br0
76	ip link set dev $swp2 master br0
77
78	ip link set dev br0 up
79	ip link set dev $swp1 up
80	ip link set dev $swp2 up
81}
82
83switch_destroy()
84{
85	ip link set dev $swp2 down
86	ip link set dev $swp1 down
87
88	ip link del dev br0
89}
90
91setup_prepare()
92{
93	h1=${NETIFS[p1]}
94	swp1=${NETIFS[p2]}
95
96	swp2=${NETIFS[p3]}
97	h2=${NETIFS[p4]}
98
99	vrf_prepare
100
101	h1_create
102	h2_create
103
104	switch_create
105}
106
107cleanup()
108{
109	pre_cleanup
110
111	switch_destroy
112
113	h2_destroy
114	h1_destroy
115
116	vrf_cleanup
117}
118
119v2reportleave_test()
120{
121	RET=0
122	ip address add dev $h2 $TEST_GROUP/32 autojoin
123	check_err $? "Could not join $TEST_GROUP"
124
125	sleep 5
126	bridge mdb show dev br0 | grep $TEST_GROUP 1>/dev/null
127	check_err $? "IGMPv2 report didn't create mdb entry for $TEST_GROUP"
128
129	mcast_packet_test $TEST_GROUP_MAC 192.0.2.1 $TEST_GROUP $h1 $h2
130	check_fail $? "Traffic to $TEST_GROUP wasn't forwarded"
131
132	log_test "IGMPv2 report $TEST_GROUP"
133
134	RET=0
135	bridge mdb show dev br0 | grep $TEST_GROUP 1>/dev/null
136	check_err $? "mdb entry for $TEST_GROUP is missing"
137
138	ip address del dev $h2 $TEST_GROUP/32
139	check_err $? "Could not leave $TEST_GROUP"
140
141	sleep 5
142	bridge mdb show dev br0 | grep $TEST_GROUP 1>/dev/null
143	check_fail $? "Leave didn't delete mdb entry for $TEST_GROUP"
144
145	mcast_packet_test $TEST_GROUP_MAC 192.0.2.1 $TEST_GROUP $h1 $h2
146	check_err $? "Traffic to $TEST_GROUP was forwarded without mdb entry"
147
148	log_test "IGMPv2 leave $TEST_GROUP"
149}
150
151v3include_prepare()
152{
153	local host1_if=$1
154	local mac=$2
155	local group=$3
156	local X=("192.0.2.1" "192.0.2.2" "192.0.2.3")
157
158	ip link set dev br0 type bridge mcast_igmp_version 3
159	check_err $? "Could not change bridge IGMP version to 3"
160
161	$MZ $host1_if -b $mac -c 1 -B $group -t ip "proto=2,p=$MZPKT_IS_INC" -q
162	sleep 1
163	bridge -j -d -s mdb show dev br0 \
164		| jq -e ".[].mdb[] | \
165			 select(.grp == \"$TEST_GROUP\" and .source_list != null)" &>/dev/null
166	check_err $? "Missing *,G entry with source list"
167	bridge -j -d -s mdb show dev br0 \
168		| jq -e ".[].mdb[] | \
169			 select(.grp == \"$TEST_GROUP\" and \
170				.source_list != null and .filter_mode == \"include\")" &>/dev/null
171	check_err $? "Wrong *,G entry filter mode"
172	brmcast_check_sg_entries "is_include" "${X[@]}"
173}
174
175v3exclude_prepare()
176{
177	local host1_if=$1
178	local mac=$2
179	local group=$3
180	local pkt=$4
181	local X=("192.0.2.1" "192.0.2.2")
182	local Y=("192.0.2.20" "192.0.2.21")
183
184	v3include_prepare $host1_if $mac $group
185
186	$MZ $host1_if -c 1 -b $mac -B $group -t ip "proto=2,p=$MZPKT_IS_EXC" -q
187	sleep 1
188	bridge -j -d -s mdb show dev br0 \
189		| jq -e ".[].mdb[] | \
190			 select(.grp == \"$TEST_GROUP\" and \
191				.source_list != null and .filter_mode == \"exclude\")" &>/dev/null
192	check_err $? "Wrong *,G entry filter mode"
193
194	brmcast_check_sg_entries "is_exclude" "${X[@]}" "${Y[@]}"
195
196	brmcast_check_sg_state 0 "${X[@]}"
197	brmcast_check_sg_state 1 "${Y[@]}"
198
199	bridge -j -d -s mdb show dev br0 \
200		| jq -e ".[].mdb[] | \
201			 select(.grp == \"$TEST_GROUP\" and \
202				.source_list != null and
203				.source_list[].address == \"192.0.2.3\")" &>/dev/null
204	check_fail $? "Wrong *,G entry source list, 192.0.2.3 entry still exists"
205}
206
207v3cleanup()
208{
209	local port=$1
210	local group=$2
211
212	bridge mdb del dev br0 port $port grp $group
213	ip link set dev br0 type bridge mcast_igmp_version 2
214}
215
216v3include_test()
217{
218	RET=0
219	local X=("192.0.2.1" "192.0.2.2" "192.0.2.3")
220
221	v3include_prepare $h1 $ALL_MAC $ALL_GROUP
222
223	brmcast_check_sg_state 0 "${X[@]}"
224
225	brmcast_check_sg_fwding 1 "${X[@]}"
226	brmcast_check_sg_fwding 0 "192.0.2.100"
227
228	log_test "IGMPv3 report $TEST_GROUP is_include"
229
230	v3cleanup $swp1 $TEST_GROUP
231}
232
233v3inc_allow_test()
234{
235	RET=0
236	local X=("192.0.2.10" "192.0.2.11" "192.0.2.12")
237
238	v3include_prepare $h1 $ALL_MAC $ALL_GROUP
239
240	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW" -q
241	sleep 1
242	brmcast_check_sg_entries "allow" "${X[@]}"
243
244	brmcast_check_sg_state 0 "${X[@]}"
245
246	brmcast_check_sg_fwding 1 "${X[@]}"
247	brmcast_check_sg_fwding 0 "192.0.2.100"
248
249	log_test "IGMPv3 report $TEST_GROUP include -> allow"
250
251	v3cleanup $swp1 $TEST_GROUP
252}
253
254v3inc_is_include_test()
255{
256	RET=0
257	local X=("192.0.2.10" "192.0.2.11" "192.0.2.12")
258
259	v3include_prepare $h1 $ALL_MAC $ALL_GROUP
260
261	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_INC2" -q
262	sleep 1
263	brmcast_check_sg_entries "is_include" "${X[@]}"
264
265	brmcast_check_sg_state 0 "${X[@]}"
266
267	brmcast_check_sg_fwding 1 "${X[@]}"
268	brmcast_check_sg_fwding 0 "192.0.2.100"
269
270	log_test "IGMPv3 report $TEST_GROUP include -> is_include"
271
272	v3cleanup $swp1 $TEST_GROUP
273}
274
275v3inc_is_exclude_test()
276{
277	RET=0
278
279	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
280
281	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
282	brmcast_check_sg_fwding 0 "${Y[@]}"
283
284	log_test "IGMPv3 report $TEST_GROUP include -> is_exclude"
285
286	v3cleanup $swp1 $TEST_GROUP
287}
288
289v3inc_to_exclude_test()
290{
291	RET=0
292	local X=("192.0.2.1")
293	local Y=("192.0.2.20" "192.0.2.30")
294
295	v3include_prepare $h1 $ALL_MAC $ALL_GROUP
296
297	ip link set dev br0 type bridge mcast_last_member_interval 500
298	check_err $? "Could not change mcast_last_member_interval to 5s"
299
300	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_TO_EXC" -q
301	sleep 1
302	bridge -j -d -s mdb show dev br0 \
303		| jq -e ".[].mdb[] | \
304			 select(.grp == \"$TEST_GROUP\" and \
305				.source_list != null and .filter_mode == \"exclude\")" &>/dev/null
306	check_err $? "Wrong *,G entry filter mode"
307
308	brmcast_check_sg_entries "to_exclude" "${X[@]}" "${Y[@]}"
309
310	brmcast_check_sg_state 0 "${X[@]}"
311	brmcast_check_sg_state 1 "${Y[@]}"
312
313	bridge -j -d -s mdb show dev br0 \
314		| jq -e ".[].mdb[] | \
315			 select(.grp == \"$TEST_GROUP\" and \
316				.source_list != null and
317				.source_list[].address == \"192.0.2.2\")" &>/dev/null
318	check_fail $? "Wrong *,G entry source list, 192.0.2.2 entry still exists"
319	bridge -j -d -s mdb show dev br0 \
320		| jq -e ".[].mdb[] | \
321			 select(.grp == \"$TEST_GROUP\" and \
322				.source_list != null and
323				.source_list[].address == \"192.0.2.21\")" &>/dev/null
324	check_fail $? "Wrong *,G entry source list, 192.0.2.21 entry still exists"
325
326	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
327	brmcast_check_sg_fwding 0 "${Y[@]}"
328
329	log_test "IGMPv3 report $TEST_GROUP include -> to_exclude"
330
331	ip link set dev br0 type bridge mcast_last_member_interval 100
332
333	v3cleanup $swp1 $TEST_GROUP
334}
335
336v3exc_allow_test()
337{
338	RET=0
339	local X=("192.0.2.1" "192.0.2.2" "192.0.2.20" "192.0.2.30")
340	local Y=("192.0.2.21")
341
342	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
343
344	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW2" -q
345	sleep 1
346	brmcast_check_sg_entries "allow" "${X[@]}" "${Y[@]}"
347
348	brmcast_check_sg_state 0 "${X[@]}"
349	brmcast_check_sg_state 1 "${Y[@]}"
350
351	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
352	brmcast_check_sg_fwding 0 "${Y[@]}"
353
354	log_test "IGMPv3 report $TEST_GROUP exclude -> allow"
355
356	v3cleanup $swp1 $TEST_GROUP
357}
358
359v3exc_is_include_test()
360{
361	RET=0
362	local X=("192.0.2.1" "192.0.2.2" "192.0.2.20" "192.0.2.30")
363	local Y=("192.0.2.21")
364
365	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
366
367	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_INC3" -q
368	sleep 1
369	brmcast_check_sg_entries "is_include" "${X[@]}" "${Y[@]}"
370
371	brmcast_check_sg_state 0 "${X[@]}"
372	brmcast_check_sg_state 1 "${Y[@]}"
373
374	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
375	brmcast_check_sg_fwding 0 "${Y[@]}"
376
377	log_test "IGMPv3 report $TEST_GROUP exclude -> is_include"
378
379	v3cleanup $swp1 $TEST_GROUP
380}
381
382v3exc_is_exclude_test()
383{
384	RET=0
385	local X=("192.0.2.30")
386	local Y=("192.0.2.20")
387
388	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
389
390	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_EXC2" -q
391	sleep 1
392	brmcast_check_sg_entries "is_exclude" "${X[@]}" "${Y[@]}"
393
394	brmcast_check_sg_state 0 "${X[@]}"
395	brmcast_check_sg_state 1 "${Y[@]}"
396
397	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
398	brmcast_check_sg_fwding 0 "${Y[@]}"
399
400	log_test "IGMPv3 report $TEST_GROUP exclude -> is_exclude"
401
402	v3cleanup $swp1 $TEST_GROUP
403}
404
405v3exc_to_exclude_test()
406{
407	RET=0
408	local X=("192.0.2.1" "192.0.2.30")
409	local Y=("192.0.2.20")
410
411	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
412
413	ip link set dev br0 type bridge mcast_last_member_interval 500
414	check_err $? "Could not change mcast_last_member_interval to 5s"
415
416	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_TO_EXC" -q
417	sleep 1
418	brmcast_check_sg_entries "to_exclude" "${X[@]}" "${Y[@]}"
419
420	brmcast_check_sg_state 0 "${X[@]}"
421	brmcast_check_sg_state 1 "${Y[@]}"
422
423	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
424	brmcast_check_sg_fwding 0 "${Y[@]}"
425
426	log_test "IGMPv3 report $TEST_GROUP exclude -> to_exclude"
427
428	ip link set dev br0 type bridge mcast_last_member_interval 100
429
430	v3cleanup $swp1 $TEST_GROUP
431}
432
433v3inc_block_test()
434{
435	RET=0
436	local X=("192.0.2.2" "192.0.2.3")
437
438	v3include_prepare $h1 $ALL_MAC $ALL_GROUP
439
440	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_BLOCK" -q
441	# make sure the lowered timers have expired (by default 2 seconds)
442	sleep 3
443	brmcast_check_sg_entries "block" "${X[@]}"
444
445	brmcast_check_sg_state 0 "${X[@]}"
446
447	bridge -j -d -s mdb show dev br0 \
448		| jq -e ".[].mdb[] | \
449			 select(.grp == \"$TEST_GROUP\" and \
450				.source_list != null and
451				.source_list[].address == \"192.0.2.1\")" &>/dev/null
452	check_fail $? "Wrong *,G entry source list, 192.0.2.1 entry still exists"
453
454	brmcast_check_sg_fwding 1 "${X[@]}"
455	brmcast_check_sg_fwding 0 "192.0.2.100"
456
457	log_test "IGMPv3 report $TEST_GROUP include -> block"
458
459	v3cleanup $swp1 $TEST_GROUP
460}
461
462v3exc_block_test()
463{
464	RET=0
465	local X=("192.0.2.1" "192.0.2.2" "192.0.2.30")
466	local Y=("192.0.2.20" "192.0.2.21")
467
468	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
469
470	ip link set dev br0 type bridge mcast_last_member_interval 500
471	check_err $? "Could not change mcast_last_member_interval to 5s"
472
473	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_BLOCK" -q
474	sleep 1
475	brmcast_check_sg_entries "block" "${X[@]}" "${Y[@]}"
476
477	brmcast_check_sg_state 0 "${X[@]}"
478	brmcast_check_sg_state 1 "${Y[@]}"
479
480	brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
481	brmcast_check_sg_fwding 0 "${Y[@]}"
482
483	log_test "IGMPv3 report $TEST_GROUP exclude -> block"
484
485	ip link set dev br0 type bridge mcast_last_member_interval 100
486
487	v3cleanup $swp1 $TEST_GROUP
488}
489
490v3exc_timeout_test()
491{
492	RET=0
493	local X=("192.0.2.20" "192.0.2.30")
494
495	# GMI should be 5 seconds
496	ip link set dev br0 type bridge mcast_query_interval 100 \
497					mcast_query_response_interval 100 \
498					mcast_membership_interval 500
499
500	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
501	ip link set dev br0 type bridge mcast_query_interval 500 \
502					mcast_query_response_interval 500 \
503					mcast_membership_interval 1500
504
505	$MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW2" -q
506	sleep 5
507	bridge -j -d -s mdb show dev br0 \
508		| jq -e ".[].mdb[] | \
509			 select(.grp == \"$TEST_GROUP\" and \
510				.source_list != null and .filter_mode == \"include\")" &>/dev/null
511	check_err $? "Wrong *,G entry filter mode"
512
513	bridge -j -d -s mdb show dev br0 \
514		| jq -e ".[].mdb[] | \
515			 select(.grp == \"$TEST_GROUP\" and \
516				.source_list != null and
517				.source_list[].address == \"192.0.2.1\")" &>/dev/null
518	check_fail $? "Wrong *,G entry source list, 192.0.2.1 entry still exists"
519	bridge -j -d -s mdb show dev br0 \
520		| jq -e ".[].mdb[] | \
521			 select(.grp == \"$TEST_GROUP\" and \
522				.source_list != null and
523				.source_list[].address == \"192.0.2.2\")" &>/dev/null
524	check_fail $? "Wrong *,G entry source list, 192.0.2.2 entry still exists"
525
526	brmcast_check_sg_entries "allow" "${X[@]}"
527
528	brmcast_check_sg_state 0 "${X[@]}"
529
530	brmcast_check_sg_fwding 1 "${X[@]}"
531	brmcast_check_sg_fwding 0 192.0.2.100
532
533	log_test "IGMPv3 group $TEST_GROUP exclude timeout"
534
535	ip link set dev br0 type bridge mcast_query_interval 12500 \
536					mcast_query_response_interval 1000 \
537					mcast_membership_interval 26000
538
539	v3cleanup $swp1 $TEST_GROUP
540}
541
542v3star_ex_auto_add_test()
543{
544	RET=0
545
546	v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
547
548	$MZ $h2 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_INC" -q
549	sleep 1
550	bridge -j -d -s mdb show dev br0 \
551		| jq -e ".[].mdb[] | \
552			 select(.grp == \"$TEST_GROUP\" and .src == \"192.0.2.3\" and \
553				.port == \"$swp1\")" &>/dev/null
554	check_err $? "S,G entry for *,G port doesn't exist"
555
556	bridge -j -d -s mdb show dev br0 \
557		| jq -e ".[].mdb[] | \
558			 select(.grp == \"$TEST_GROUP\" and .src == \"192.0.2.3\" and \
559				.port == \"$swp1\" and \
560				.flags[] == \"added_by_star_ex\")" &>/dev/null
561	check_err $? "Auto-added S,G entry doesn't have added_by_star_ex flag"
562
563	brmcast_check_sg_fwding 1 192.0.2.3
564
565	log_test "IGMPv3 S,G port entry automatic add to a *,G port"
566
567	v3cleanup $swp1 $TEST_GROUP
568	v3cleanup $swp2 $TEST_GROUP
569}
570
571v2per_vlan_snooping_stp_test()
572{
573	local is_port=$1
574
575	local msg="port"
576	[[ $is_port -ne 1 ]] && msg="vlan"
577
578	ip link set br0 up type bridge vlan_filtering 1 \
579					mcast_igmp_version 2 \
580					mcast_snooping 1 \
581					mcast_vlan_snooping 1 \
582					mcast_querier 1 \
583					mcast_stats_enabled 1
584	bridge vlan global set vid 1 dev br0 \
585					mcast_snooping 1 \
586					mcast_querier 1 \
587					mcast_query_interval 100 \
588					mcast_startup_query_count 0
589	[[ $is_port -eq 1 ]] && bridge link set dev $swp1 state 0
590	[[ $is_port -ne 1 ]] && bridge vlan set vid 1 dev $swp1 state 4
591	sleep 5
592	local tx_s=$(ip -j -p stats show dev $swp1 \
593			group xstats_slave subgroup bridge suite mcast \
594			| jq '.[]["multicast"]["igmp_queries"]["tx_v2"]')
595
596	[[ $is_port -eq 1 ]] && bridge link set dev $swp1 state 3
597	[[ $is_port -ne 1 ]] && bridge vlan set vid 1 dev $swp1 state 3
598	sleep 5
599	local tx_e=$(ip -j -p stats show dev $swp1 \
600			group xstats_slave subgroup bridge suite mcast \
601			| jq '.[]["multicast"]["igmp_queries"]["tx_v2"]')
602
603	RET=0
604	local tx=$(expr $tx_e - $tx_s)
605	test $tx -gt 0
606	check_err $? "No IGMP queries after STP state becomes forwarding"
607	log_test "per vlan snooping with $msg stp state change"
608
609	# restore settings
610	bridge vlan global set vid 1 dev br0 \
611					mcast_querier 0 \
612					mcast_query_interval 12500 \
613					mcast_startup_query_count 2
614	ip link set br0 up type bridge vlan_filtering 0 \
615					mcast_vlan_snooping 0 \
616					mcast_stats_enabled 0
617}
618
619v2per_vlan_snooping_port_stp_test()
620{
621	v2per_vlan_snooping_stp_test 1
622}
623
624v2per_vlan_snooping_vlan_stp_test()
625{
626	v2per_vlan_snooping_stp_test 0
627}
628
629trap cleanup EXIT
630
631setup_prepare
632setup_wait
633
634tests_run
635
636exit $EXIT_STATUS
637