2 # SPDX-License-Identifier: GPL-2.0
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 |
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 |
15 # +----|------------------+ +----|-------------------+
17 # +----|--------------------------------------------------|-------------------+
19 # | +--|--------------------------------------------------|-----------------+ |
20 # | | + $swp1 BR0 (802.1q) + $swp2 | |
21 # | | vid 10 vid 10 | |
22 # | | vid 20 vid 20 | |
24 # | +-----------------------------------------------------------------------+ |
25 # +---------------------------------------------------------------------------+
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
54 vlan_create $h2 10 v$h2 192.0.2.2/28
55 vlan_create $h2 20 v$h2 198.51.100.2/24
67 ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0 \
68 mcast_snooping 1 mcast_igmp_version 3 mcast_mld_version 2
69 bridge vlan add vid 10 dev br0 self
70 bridge vlan add vid 20 dev br0 self
71 ip link set dev br0 up
73 ip link set dev $swp1 master br0
74 ip link set dev $swp1 up
75 bridge vlan add vid 10 dev $swp1
76 bridge vlan add vid 20 dev $swp1
78 ip link set dev $swp2 master br0
79 ip link set dev $swp2 up
80 bridge vlan add vid 10 dev $swp2
81 bridge vlan add vid 20 dev $swp2
83 tc qdisc add dev br0 clsact
84 tc qdisc add dev $h2 clsact
89 tc qdisc del dev $h2 clsact
90 tc qdisc del dev br0 clsact
92 bridge vlan del vid 20 dev $swp2
93 bridge vlan del vid 10 dev $swp2
94 ip link set dev $swp2 down
95 ip link set dev $swp2 nomaster
97 bridge vlan del vid 20 dev $swp1
98 bridge vlan del vid 10 dev $swp1
99 ip link set dev $swp1 down
100 ip link set dev $swp1 nomaster
102 ip link set dev br0 down
103 bridge vlan del vid 20 dev br0 self
104 bridge vlan del vid 10 dev br0 self
136 cfg_test_host_common()
141 local state=$1; shift
142 local invalid_state=$1; shift
146 # Check basic add, replace and delete behavior.
147 bridge mdb add dev br0 port br0 grp $grp $state vid 10
148 bridge mdb show dev br0 vid 10 | grep -q "$grp"
149 check_err $? "Failed to add $name host entry"
151 bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null
152 check_fail $? "Managed to replace $name host entry"
154 bridge mdb del dev br0 port br0 grp $grp $state vid 10
155 bridge mdb show dev br0 vid 10 | grep -q "$grp"
156 check_fail $? "Failed to delete $name host entry"
159 bridge mdb add dev br0 port br0 grp $grp $invalid_state vid 10 \
161 check_fail $? "Managed to add $name host entry with a $invalid_state state"
163 bridge mdb add dev br0 port br0 grp $grp src $src $state vid 10 \
165 check_fail $? "Managed to add $name host entry with a source"
167 bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
168 filter_mode exclude &> /dev/null
169 check_fail $? "Managed to add $name host entry with a filter mode"
171 bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
172 source_list $src &> /dev/null
173 check_fail $? "Managed to add $name host entry with a source list"
175 bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
176 proto 123 &> /dev/null
177 check_fail $? "Managed to add $name host entry with a protocol"
179 log_test "Common host entries configuration tests ($name)"
182 # Check configuration of host entries from all types.
186 log_info "# Host entries configuration tests"
188 cfg_test_host_common "IPv4" "239.1.1.1" "192.0.2.1" "temp" "permanent"
189 cfg_test_host_common "IPv6" "ff0e::1" "2001:db8:1::1" "temp" "permanent"
190 cfg_test_host_common "L2" "01:02:03:04:05:06" "00:00:00:00:00:01" \
194 cfg_test_port_common()
197 local grp_key=$1; shift
201 # Check basic add, replace and delete behavior.
202 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
203 bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
204 check_err $? "Failed to add $name entry"
206 bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
208 check_err $? "Failed to replace $name entry"
210 bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
211 bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
212 check_fail $? "Failed to delete $name entry"
214 # Check default protocol and replacement.
215 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
216 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "static"
217 check_err $? "$name entry not added with default \"static\" protocol"
219 bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
221 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "123"
222 check_err $? "Failed to replace protocol of $name entry"
223 bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
225 # Check behavior when VLAN is not specified.
226 bridge mdb add dev br0 port $swp1 $grp_key permanent
227 bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
228 check_err $? "$name entry with VLAN 10 not added when VLAN was not specified"
229 bridge mdb show dev br0 vid 20 | grep -q "$grp_key"
230 check_err $? "$name entry with VLAN 20 not added when VLAN was not specified"
232 bridge mdb del dev br0 port $swp1 $grp_key permanent
233 bridge mdb show dev br0 vid 10 | grep -q "$grp_key"
234 check_fail $? "$name entry with VLAN 10 not deleted when VLAN was not specified"
235 bridge mdb show dev br0 vid 20 | grep -q "$grp_key"
236 check_fail $? "$name entry with VLAN 20 not deleted when VLAN was not specified"
238 # Check behavior when bridge port is down.
239 ip link set dev $swp1 down
241 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
242 check_err $? "Failed to add $name permanent entry when bridge port is down"
244 bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
246 bridge mdb add dev br0 port $swp1 $grp_key temp vid 10 &> /dev/null
247 check_fail $? "Managed to add $name temporary entry when bridge port is down"
249 ip link set dev $swp1 up
253 ip link set dev br0 down
254 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 \
256 check_fail $? "Managed to add $name entry when bridge is down"
257 ip link set dev br0 up
259 ip link set dev br0 type bridge mcast_snooping 0
260 bridge mdb add dev br0 port $swp1 $grp_key permanent vid \
262 check_fail $? "Managed to add $name entry when multicast snooping is disabled"
263 ip link set dev br0 type bridge mcast_snooping 1
265 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 5000 \
267 check_fail $? "Managed to add $name entry with an invalid VLAN"
269 log_test "Common port group entries configuration tests ($name)"
274 local src_prefix=$1; shift
275 local num_srcs=$1; shift
279 for i in $(seq 1 $num_srcs); do
280 src_list=${src_list},${src_prefix}${i}
283 echo $src_list | cut -c 2-
286 __cfg_test_port_ip_star_g()
290 local invalid_grp=$1; shift
291 local src_prefix=$1; shift
292 local src1=${src_prefix}1
293 local src2=${src_prefix}2
294 local src3=${src_prefix}3
300 bridge mdb add dev br0 port $swp1 grp $grp vid 10
301 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "exclude"
302 check_err $? "Default filter mode is not \"exclude\""
303 bridge mdb del dev br0 port $swp1 grp $grp vid 10
305 # Check basic add and delete behavior.
306 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
308 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q -v "src"
309 check_err $? "(*, G) entry not created"
310 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
311 check_err $? "(S, G) entry not created"
312 bridge mdb del dev br0 port $swp1 grp $grp vid 10
313 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q -v "src"
314 check_fail $? "(*, G) entry not deleted"
315 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
316 check_fail $? "(S, G) entry not deleted"
318 ## State (permanent / temp) tests.
320 # Check that group and source timer are not set for permanent entries.
321 bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
322 filter_mode exclude source_list $src1
324 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
326 check_err $? "(*, G) entry not added as \"permanent\" when should"
327 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
329 check_err $? "(S, G) entry not added as \"permanent\" when should"
331 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
333 check_err $? "(*, G) \"permanent\" entry has a pending group timer"
334 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
336 check_err $? "\"permanent\" source entry has a pending source timer"
338 bridge mdb del dev br0 port $swp1 grp $grp vid 10
340 # Check that group timer is set for temporary (*, G) EXCLUDE, but not
342 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
343 filter_mode exclude source_list $src1
345 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
347 check_err $? "(*, G) EXCLUDE entry not added as \"temp\" when should"
348 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
350 check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should"
352 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
354 check_fail $? "(*, G) EXCLUDE entry does not have a pending group timer"
355 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
357 check_err $? "\"blocked\" source entry has a pending source timer"
359 bridge mdb del dev br0 port $swp1 grp $grp vid 10
361 # Check that group timer is not set for temporary (*, G) INCLUDE, but
362 # that the source timer is set.
363 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
364 filter_mode include source_list $src1
366 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
368 check_err $? "(*, G) INCLUDE entry not added as \"temp\" when should"
369 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
371 check_err $? "(S, G) entry not added as \"temp\" when should"
373 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
375 check_err $? "(*, G) INCLUDE entry has a pending group timer"
376 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
378 check_fail $? "Source entry does not have a pending source timer"
380 bridge mdb del dev br0 port $swp1 grp $grp vid 10
382 # Check that group timer is never set for (S, G) entries.
383 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
384 filter_mode include source_list $src1
386 bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
388 check_err $? "(S, G) entry has a pending group timer"
390 bridge mdb del dev br0 port $swp1 grp $grp vid 10
392 ## Filter mode (include / exclude) tests.
394 # Check that (*, G) INCLUDE entries are added with correct filter mode
395 # and that (S, G) entries are not marked as "blocked".
396 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
397 filter_mode include source_list $src1
399 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
401 check_err $? "(*, G) INCLUDE not added with \"include\" filter mode"
402 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
404 check_fail $? "(S, G) entry marked as \"blocked\" when should not"
406 bridge mdb del dev br0 port $swp1 grp $grp vid 10
408 # Check that (*, G) EXCLUDE entries are added with correct filter mode
409 # and that (S, G) entries are marked as "blocked".
410 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
411 filter_mode exclude source_list $src1
413 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
415 check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode"
416 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
418 check_err $? "(S, G) entry not marked as \"blocked\" when should"
420 bridge mdb del dev br0 port $swp1 grp $grp vid 10
424 # Check that (*, G) and (S, G) entries are added with the specified
426 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
427 filter_mode exclude source_list $src1 proto zebra
429 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
431 check_err $? "(*, G) entry not added with \"zebra\" protocol"
432 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
434 check_err $? "(S, G) entry not marked added with \"zebra\" protocol"
436 bridge mdb del dev br0 port $swp1 grp $grp vid 10
440 # Check that state can be modified.
441 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
442 filter_mode exclude source_list $src1
444 bridge mdb replace dev br0 port $swp1 grp $grp permanent vid 10 \
445 filter_mode exclude source_list $src1
446 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
448 check_err $? "(*, G) entry not marked as \"permanent\" after replace"
449 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
451 check_err $? "(S, G) entry not marked as \"permanent\" after replace"
453 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
454 filter_mode exclude source_list $src1
455 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
457 check_err $? "(*, G) entry not marked as \"temp\" after replace"
458 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
460 check_err $? "(S, G) entry not marked as \"temp\" after replace"
462 bridge mdb del dev br0 port $swp1 grp $grp vid 10
464 # Check that filter mode can be modified.
465 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
466 filter_mode exclude source_list $src1
468 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
469 filter_mode include source_list $src1
470 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
472 check_err $? "(*, G) not marked with \"include\" filter mode after replace"
473 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
475 check_fail $? "(S, G) marked as \"blocked\" after replace"
477 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
478 filter_mode exclude source_list $src1
479 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
481 check_err $? "(*, G) not marked with \"exclude\" filter mode after replace"
482 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
484 check_err $? "(S, G) not marked as \"blocked\" after replace"
486 bridge mdb del dev br0 port $swp1 grp $grp vid 10
488 # Check that sources can be added to and removed from the source list.
489 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
490 filter_mode exclude source_list $src1
492 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
493 filter_mode exclude source_list $src1,$src2,$src3
494 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
495 check_err $? "(S, G) entry for source $src1 not created after replace"
496 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src2"
497 check_err $? "(S, G) entry for source $src2 not created after replace"
498 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src3"
499 check_err $? "(S, G) entry for source $src3 not created after replace"
501 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
502 filter_mode exclude source_list $src1,$src3
503 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src1"
504 check_err $? "(S, G) entry for source $src1 not created after second replace"
505 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src2"
506 check_fail $? "(S, G) entry for source $src2 created after second replace"
507 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -q "src $src3"
508 check_err $? "(S, G) entry for source $src3 not created after second replace"
510 bridge mdb del dev br0 port $swp1 grp $grp vid 10
512 # Check that protocol can be modified.
513 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
514 filter_mode exclude source_list $src1 proto zebra
516 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
517 filter_mode exclude source_list $src1 proto bgp
518 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \
520 check_err $? "(*, G) protocol not changed to \"bgp\" after replace"
521 bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \
523 check_err $? "(S, G) protocol not changed to \"bgp\" after replace"
525 bridge mdb del dev br0 port $swp1 grp $grp vid 10
527 ## Star exclude tests.
529 # Check star exclude functionality. When adding a new EXCLUDE (*, G),
530 # it needs to be also added to all (S, G) entries for proper
532 bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
533 filter_mode include source_list $src1
534 bridge mdb add dev br0 port $swp1 grp $grp vid 10
535 bridge -d mdb show dev br0 vid 10 | grep "$swp1" | grep "$grp" | \
536 grep "$src1" | grep -q "added_by_star_ex"
537 check_err $? "\"added_by_star_ex\" entry not created after adding (*, G) entry"
538 bridge mdb del dev br0 port $swp1 grp $grp vid 10
539 bridge mdb del dev br0 port $swp2 grp $grp src $src1 vid 10
541 ## Error cases tests.
543 bridge mdb add dev br0 port $swp1 grp $invalid_grp vid 10 &> /dev/null
544 check_fail $? "Managed to add an entry with an invalid group"
546 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
548 check_fail $? "Managed to add an INCLUDE entry with an empty source list"
550 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
551 source_list $grp &> /dev/null
552 check_fail $? "Managed to add an entry with an invalid source in source list"
554 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
555 source_list $src &> /dev/null
556 check_fail $? "Managed to add an entry with a source list and no filter mode"
558 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
560 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
561 source_list $src1 &> /dev/null
562 check_fail $? "Managed to replace an entry without using replace"
563 bridge mdb del dev br0 port $swp1 grp $grp vid 10
565 bridge mdb add dev br0 port $swp1 grp $grp src $src2 vid 10
566 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
567 source_list $src1,$src2,$src3 &> /dev/null
568 check_fail $? "Managed to add a source that already has a forwarding entry"
569 bridge mdb del dev br0 port $swp1 grp $grp src $src2 vid 10
571 # Check maximum number of sources.
572 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
573 source_list $(src_list_create $src_prefix $max_srcs)
574 num_srcs=$(bridge -d mdb show dev br0 vid 10 | grep "$grp" | \
576 [[ $num_srcs -eq $max_srcs ]]
577 check_err $? "Failed to configure maximum number of sources ($max_srcs)"
578 bridge mdb del dev br0 port $swp1 grp $grp vid 10
580 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
581 source_list $(src_list_create $src_prefix $((max_srcs + 1))) \
583 check_fail $? "Managed to exceed maximum number of sources ($max_srcs)"
585 log_test "$name (*, G) port group entries configuration tests"
588 cfg_test_port_ip_star_g()
591 log_info "# Port group entries configuration tests - (*, G)"
593 cfg_test_port_common "IPv4 (*, G)" "grp 239.1.1.1"
594 cfg_test_port_common "IPv6 (*, G)" "grp ff0e::1"
595 __cfg_test_port_ip_star_g "IPv4" "239.1.1.1" "224.0.0.1" "192.0.2."
596 __cfg_test_port_ip_star_g "IPv6" "ff0e::1" "ff02::1" "2001:db8:1::"
599 __cfg_test_port_ip_sg()
604 local grp_key="grp $grp src $src"
608 bridge mdb add dev br0 port $swp1 $grp_key vid 10
609 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | grep -q "include"
610 check_err $? "Default filter mode is not \"include\""
611 bridge mdb del dev br0 port $swp1 $grp_key vid 10
613 # Check that entries can be added as both permanent and temp and that
614 # group timer is set correctly.
615 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
616 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
618 check_err $? "Entry not added as \"permanent\" when should"
619 bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
621 check_err $? "\"permanent\" entry has a pending group timer"
622 bridge mdb del dev br0 port $swp1 $grp_key vid 10
624 bridge mdb add dev br0 port $swp1 $grp_key temp vid 10
625 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
627 check_err $? "Entry not added as \"temp\" when should"
628 bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
630 check_fail $? "\"temp\" entry has an unpending group timer"
631 bridge mdb del dev br0 port $swp1 $grp_key vid 10
634 bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
635 filter_mode include &> /dev/null
636 check_fail $? "Managed to add an entry with a filter mode"
638 bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
639 filter_mode include source_list $src &> /dev/null
640 check_fail $? "Managed to add an entry with a source list"
642 bridge mdb add dev br0 port $swp1 grp $grp src $grp vid 10 &> /dev/null
643 check_fail $? "Managed to add an entry with an invalid source"
645 bridge mdb add dev br0 port $swp1 $grp_key vid 10 temp
646 bridge mdb add dev br0 port $swp1 $grp_key vid 10 permanent &> /dev/null
647 check_fail $? "Managed to replace an entry without using replace"
648 bridge mdb del dev br0 port $swp1 $grp_key vid 10
650 # Check that we can replace available attributes.
651 bridge mdb add dev br0 port $swp1 $grp_key vid 10 proto 123
652 bridge mdb replace dev br0 port $swp1 $grp_key vid 10 proto 111
653 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
655 check_err $? "Failed to replace protocol"
657 bridge mdb replace dev br0 port $swp1 $grp_key vid 10 permanent
658 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
660 check_err $? "Entry not marked as \"permanent\" after replace"
661 bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
663 check_err $? "Entry has a pending group timer after replace"
665 bridge mdb replace dev br0 port $swp1 $grp_key vid 10 temp
666 bridge -d mdb show dev br0 vid 10 | grep "$grp_key" | \
668 check_err $? "Entry not marked as \"temp\" after replace"
669 bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \
671 check_fail $? "Entry has an unpending group timer after replace"
672 bridge mdb del dev br0 port $swp1 $grp_key vid 10
674 # Check star exclude functionality. When adding a (S, G), all matching
675 # (*, G) ports need to be added to it.
676 bridge mdb add dev br0 port $swp2 grp $grp vid 10
677 bridge mdb add dev br0 port $swp1 $grp_key vid 10
678 bridge mdb show dev br0 vid 10 | grep "$grp_key" | grep $swp2 | \
679 grep -q "added_by_star_ex"
680 check_err $? "\"added_by_star_ex\" entry not created after adding (S, G) entry"
681 bridge mdb del dev br0 port $swp1 $grp_key vid 10
682 bridge mdb del dev br0 port $swp2 grp $grp vid 10
684 log_test "$name (S, G) port group entries configuration tests"
687 cfg_test_port_ip_sg()
690 log_info "# Port group entries configuration tests - (S, G)"
692 cfg_test_port_common "IPv4 (S, G)" "grp 239.1.1.1 src 192.0.2.1"
693 cfg_test_port_common "IPv6 (S, G)" "grp ff0e::1 src 2001:db8:1::1"
694 __cfg_test_port_ip_sg "IPv4" "239.1.1.1" "192.0.2.1"
695 __cfg_test_port_ip_sg "IPv6" "ff0e::1" "2001:db8:1::1"
700 cfg_test_port_ip_star_g
706 local grp="01:02:03:04:05:06"
710 bridge meb add dev br0 port $swp grp 00:01:02:03:04:05 \
711 permanent vid 10 &> /dev/null
712 check_fail $? "Managed to add an entry with unicast MAC"
714 bridge mdb add dev br0 port $swp grp $grp src 00:01:02:03:04:05 \
715 permanent vid 10 &> /dev/null
716 check_fail $? "Managed to add an entry with a source"
718 bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
719 filter_mode include &> /dev/null
720 check_fail $? "Managed to add an entry with a filter mode"
722 bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
723 source_list 00:01:02:03:04:05 &> /dev/null
724 check_fail $? "Managed to add an entry with a source list"
726 log_test "L2 (*, G) port group entries configuration tests"
732 log_info "# Port group entries configuration tests - L2"
734 cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06"
738 # Check configuration of regular (port) entries of all types.
747 local max_grps=$1; shift
750 for i in $(seq 0 $((max_grps - 1))); do
757 local max_grps=$1; shift
760 for i in $(seq 0 $((max_grps - 1))); do
761 echo "ff0e::$(printf %x $i)"
767 local max_grps=$1; shift
770 for i in $(seq 0 $((max_grps - 1))); do
771 echo "01:00:00:00:00:$(printf %02x $i)"
775 cfg_test_dump_common()
789 # Create net devices.
790 for i in $(seq 1 $max_bridges); do
791 ip link add name br-test${i} up type bridge vlan_filtering 1 \
793 for j in $(seq 1 $max_ports); do
794 ip link add name br-test${i}-du${j} up \
795 master br-test${i} type dummy
799 # Create batch file with MDB entries.
801 for i in $(seq 1 $max_bridges); do
802 for j in $(seq 1 $max_ports); do
803 for grp in $($fn $max_grps); do
804 echo "mdb add dev br-test${i} \
805 port br-test${i}-du${j} grp $grp \
806 permanent vid 1" >> $batch_file
811 # Program the batch file and check for expected number of entries.
812 bridge -b $batch_file
813 for i in $(seq 1 $max_bridges); do
814 num_entries=$(bridge mdb show dev br-test${i} | \
815 grep "permanent" | wc -l)
816 [[ $num_entries -eq $((max_grps * max_ports)) ]]
817 check_err $? "Wrong number of entries in br-test${i}"
822 for i in $(seq 1 $max_bridges); do
823 ip link del dev br-test${i}
824 for j in $(seq $max_ports); do
825 ip link del dev br-test${i}-du${j}
829 log_test "$name large scale dump tests"
832 # Check large scale dump.
836 log_info "# Large scale dump tests"
838 cfg_test_dump_common "IPv4" ipv4_grps_get
839 cfg_test_dump_common "IPv6" ipv6_grps_get
840 cfg_test_dump_common "L2" l2_grps_get
861 if [[ $mode == "-4" ]]; then
869 tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \
870 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \
873 # Packet should only be flooded to multicast router ports when there is
874 # no matching MDB entry. The bridge is not configured as a multicast
876 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
877 tc_check_packets "dev br0 ingress" 1 0
878 check_err $? "Packet locally received after flood"
880 # Install a regular port group entry and expect the packet to not be
882 bridge mdb add dev br0 port $swp2 grp $grp temp vid 10
883 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
884 tc_check_packets "dev br0 ingress" 1 0
885 check_err $? "Packet locally received after installing a regular entry"
887 # Add a host entry and expect the packet to be locally received.
888 bridge mdb add dev br0 port br0 grp $grp temp vid 10
889 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
890 tc_check_packets "dev br0 ingress" 1 1
891 check_err $? "Packet not locally received after adding a host entry"
893 # Remove the host entry and expect the packet to not be locally
895 bridge mdb del dev br0 port br0 grp $grp vid 10
896 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
897 tc_check_packets "dev br0 ingress" 1 1
898 check_err $? "Packet locally received after removing a host entry"
900 bridge mdb del dev br0 port $swp2 grp $grp vid 10
902 tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower
904 log_test "$name host entries forwarding tests"
909 __fwd_test_host_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "-4"
910 __fwd_test_host_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "-6"
915 local dmac=01:02:03:04:05:06
919 tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \
920 dst_mac $dmac action drop
922 # Packet should be flooded and locally received when there is no
923 # matching MDB entry.
924 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
925 tc_check_packets "dev br0 ingress" 1 1
926 check_err $? "Packet not locally received after flood"
928 # Install a regular port group entry and expect the packet to not be
930 bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
931 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
932 tc_check_packets "dev br0 ingress" 1 1
933 check_err $? "Packet locally received after installing a regular entry"
935 # Add a host entry and expect the packet to be locally received.
936 bridge mdb add dev br0 port br0 grp $dmac permanent vid 10
937 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
938 tc_check_packets "dev br0 ingress" 1 2
939 check_err $? "Packet not locally received after adding a host entry"
941 # Remove the host entry and expect the packet to not be locally
943 bridge mdb del dev br0 port br0 grp $dmac permanent vid 10
944 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
945 tc_check_packets "dev br0 ingress" 1 2
946 check_err $? "Packet locally received after removing a host entry"
948 bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
950 tc filter del dev br0 ingress protocol all pref 1 handle 1 flower
952 log_test "L2 host entries forwarding tests"
957 # Disable multicast router on the bridge to ensure that packets are
958 # only locally received when a matching host entry is present.
959 ip link set dev br0 type bridge mcast_router 0
964 ip link set dev br0 type bridge mcast_router 1
971 local valid_src=$1; shift
972 local invalid_src=$1; shift
974 local filter_mode=$1; shift
981 if [[ $mode == "-4" ]]; then
989 # The valid source is the one we expect to get packets from after
991 if [[ $filter_mode == "include" ]]; then
994 src_list=$invalid_src
997 tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \
998 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
999 src_ip $valid_src action drop
1000 tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \
1001 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
1002 src_ip $invalid_src action drop
1004 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1005 tc_check_packets "dev $h2 ingress" 1 0
1006 check_err $? "Packet from valid source received on H2 before adding entry"
1008 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1009 tc_check_packets "dev $h2 ingress" 2 0
1010 check_err $? "Packet from invalid source received on H2 before adding entry"
1012 bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
1013 filter_mode $filter_mode source_list $src_list
1015 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1016 tc_check_packets "dev $h2 ingress" 1 1
1017 check_err $? "Packet from valid source not received on H2 after adding entry"
1019 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1020 tc_check_packets "dev $h2 ingress" 2 0
1021 check_err $? "Packet from invalid source received on H2 after adding entry"
1023 bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \
1026 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1027 tc_check_packets "dev $h2 ingress" 1 2
1028 check_err $? "Packet from valid source not received on H2 after allowing all sources"
1030 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1031 tc_check_packets "dev $h2 ingress" 2 1
1032 check_err $? "Packet from invalid source not received on H2 after allowing all sources"
1034 bridge mdb del dev br0 port $swp2 grp $grp vid 10
1036 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
1037 tc_check_packets "dev $h2 ingress" 1 2
1038 check_err $? "Packet from valid source received on H2 after deleting entry"
1040 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
1041 tc_check_packets "dev $h2 ingress" 2 1
1042 check_err $? "Packet from invalid source received on H2 after deleting entry"
1044 tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower
1045 tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower
1047 log_test "$name port group \"$filter_mode\" entries forwarding tests"
1052 __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "exclude"
1053 __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
1055 __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "include"
1056 __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
1062 local dmac=01:02:03:04:05:06
1066 tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \
1067 dst_mac $dmac action drop
1069 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1070 tc_check_packets "dev $h2 ingress" 1 0
1071 check_err $? "Packet received on H2 before adding entry"
1073 bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
1074 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1075 tc_check_packets "dev $h2 ingress" 1 1
1076 check_err $? "Packet not received on H2 after adding entry"
1078 bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
1079 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
1080 tc_check_packets "dev $h2 ingress" 1 1
1081 check_err $? "Packet received on H2 after deleting entry"
1083 tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower
1085 log_test "L2 port entries forwarding tests"
1090 # Disable multicast flooding to ensure that packets are only forwarded
1091 # out of a port when a matching port group entry is present.
1092 bridge link set dev $swp2 mcast_flood off
1097 bridge link set dev $swp2 mcast_flood on
1103 log_info "# Forwarding tests"
1105 # Forwarding according to MDB entries only takes place when the bridge
1106 # detects that there is a valid querier in the network. Set the bridge
1107 # as the querier and assign it a valid IPv6 link-local address to be
1108 # used as the source address for MLD queries.
1109 ip -6 address add fe80::1/64 nodad dev br0
1110 ip link set dev br0 type bridge mcast_querier 1
1111 # Wait the default Query Response Interval (10 seconds) for the bridge
1112 # to determine that there are no other queriers in the network.
1118 ip link set dev br0 type bridge mcast_querier 0
1119 ip -6 address del fe80::1/64 dev br0
1122 ctrl_igmpv3_is_in_test()
1126 # Add a permanent entry and check that it is not affected by the
1127 # received IGMP packet.
1128 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \
1129 filter_mode include source_list 192.0.2.1
1131 # IS_IN ( 192.0.2.2 )
1132 $MZ $h1.10 -c 1 -a own -b 01:00:5e:01:01:01 -A 192.0.2.1 -B 239.1.1.1 \
1133 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
1135 bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -q 192.0.2.2
1136 check_fail $? "Permanent entry affected by IGMP packet"
1138 # Replace the permanent entry with a temporary one and check that after
1139 # processing the IGMP packet, a new source is added to the list along
1140 # with a new forwarding entry.
1141 bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \
1142 filter_mode include source_list 192.0.2.1
1144 # IS_IN ( 192.0.2.2 )
1145 $MZ $h1.10 -a own -b 01:00:5e:01:01:01 -c 1 -A 192.0.2.1 -B 239.1.1.1 \
1146 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
1148 bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -v "src" | \
1150 check_err $? "Source not add to source list"
1152 bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | \
1153 grep -q "src 192.0.2.2"
1154 check_err $? "(S, G) entry not created for new source"
1156 bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10
1158 log_test "IGMPv3 MODE_IS_INCLUDE tests"
1161 ctrl_mldv2_is_in_test()
1165 # Add a permanent entry and check that it is not affected by the
1166 # received MLD packet.
1167 bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \
1168 filter_mode include source_list 2001:db8:1::1
1170 # IS_IN ( 2001:db8:1::2 )
1171 local p=$(mldv2_is_in_get fe80::1 ff0e::1 2001:db8:1::2)
1172 $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
1173 -t ip hop=1,next=0,p="$p" -q
1175 bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \
1176 grep -q 2001:db8:1::2
1177 check_fail $? "Permanent entry affected by MLD packet"
1179 # Replace the permanent entry with a temporary one and check that after
1180 # processing the MLD packet, a new source is added to the list along
1181 # with a new forwarding entry.
1182 bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \
1183 filter_mode include source_list 2001:db8:1::1
1185 # IS_IN ( 2001:db8:1::2 )
1186 $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
1187 -t ip hop=1,next=0,p="$p" -q
1189 bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | grep -v "src" | \
1190 grep -q 2001:db8:1::2
1191 check_err $? "Source not add to source list"
1193 bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \
1194 grep -q "src 2001:db8:1::2"
1195 check_err $? "(S, G) entry not created for new source"
1197 bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10
1199 log_test "MLDv2 MODE_IS_INCLUDE tests"
1205 log_info "# Control packets tests"
1207 ctrl_igmpv3_is_in_test
1208 ctrl_mldv2_is_in_test
1211 if ! bridge mdb help 2>&1 | grep -q "replace"; then
1212 echo "SKIP: iproute2 too old, missing bridge mdb replace support"