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 cfg_test 29 fwd_test 30 ctrl_test 31 disable_test 32" 33 34NUM_NETIFS=4 35source lib.sh 36source tc_common.sh 37 38h1_create() 39{ 40 simple_if_init $h1 41 vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64 42 vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64 43} 44 45h1_destroy() 46{ 47 vlan_destroy $h1 20 48 vlan_destroy $h1 10 49 simple_if_fini $h1 50} 51 52h2_create() 53{ 54 simple_if_init $h2 55 vlan_create $h2 10 v$h2 192.0.2.2/28 56 vlan_create $h2 20 v$h2 198.51.100.2/24 57} 58 59h2_destroy() 60{ 61 vlan_destroy $h2 20 62 vlan_destroy $h2 10 63 simple_if_fini $h2 64} 65 66switch_create() 67{ 68 local vlan_filtering=$1; shift 69 70 ip link add name br0 type bridge \ 71 vlan_filtering "$vlan_filtering" vlan_default_pvid 0 \ 72 mcast_snooping 1 mcast_igmp_version 3 mcast_mld_version 2 73 bridge vlan add vid 10 dev br0 self 74 bridge vlan add vid 20 dev br0 self 75 ip link set dev br0 up 76 77 ip link set dev $swp1 master br0 78 ip link set dev $swp1 up 79 bridge vlan add vid 10 dev $swp1 80 bridge vlan add vid 20 dev $swp1 81 82 ip link set dev $swp2 master br0 83 ip link set dev $swp2 up 84 bridge vlan add vid 10 dev $swp2 85 bridge vlan add vid 20 dev $swp2 86 87 tc qdisc add dev br0 clsact 88 tc qdisc add dev $h2 clsact 89} 90 91switch_destroy() 92{ 93 tc qdisc del dev $h2 clsact 94 tc qdisc del dev br0 clsact 95 96 bridge vlan del vid 20 dev $swp2 97 bridge vlan del vid 10 dev $swp2 98 ip link set dev $swp2 down 99 ip link set dev $swp2 nomaster 100 101 bridge vlan del vid 20 dev $swp1 102 bridge vlan del vid 10 dev $swp1 103 ip link set dev $swp1 down 104 ip link set dev $swp1 nomaster 105 106 ip link set dev br0 down 107 bridge vlan del vid 20 dev br0 self 108 bridge vlan del vid 10 dev br0 self 109 ip link del dev br0 110} 111 112setup_prepare() 113{ 114 h1=${NETIFS[p1]} 115 swp1=${NETIFS[p2]} 116 117 swp2=${NETIFS[p3]} 118 h2=${NETIFS[p4]} 119 120 vrf_prepare 121 forwarding_enable 122 123 h1_create 124 h2_create 125 switch_create 1 126} 127 128cleanup() 129{ 130 pre_cleanup 131 132 switch_destroy 133 h2_destroy 134 h1_destroy 135 136 forwarding_restore 137 vrf_cleanup 138} 139 140cfg_test_host_common() 141{ 142 local name=$1; shift 143 local grp=$1; shift 144 local src=$1; shift 145 local state=$1; shift 146 local invalid_state=$1; shift 147 148 RET=0 149 150 # Check basic add, replace and delete behavior. 151 bridge mdb add dev br0 port br0 grp $grp $state vid 10 152 bridge mdb get dev br0 grp $grp vid 10 &> /dev/null 153 check_err $? "Failed to add $name host entry" 154 155 bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null 156 check_err $? "Failed to replace $name host entry" 157 158 bridge mdb del dev br0 port br0 grp $grp $state vid 10 159 bridge mdb get dev br0 grp $grp vid 10 &> /dev/null 160 check_fail $? "Failed to delete $name host entry" 161 162 # Check error cases. 163 bridge mdb add dev br0 port br0 grp $grp $invalid_state vid 10 \ 164 &> /dev/null 165 check_fail $? "Managed to add $name host entry with a $invalid_state state" 166 167 bridge mdb add dev br0 port br0 grp $grp src $src $state vid 10 \ 168 &> /dev/null 169 check_fail $? "Managed to add $name host entry with a source" 170 171 bridge mdb add dev br0 port br0 grp $grp $state vid 10 \ 172 filter_mode exclude &> /dev/null 173 check_fail $? "Managed to add $name host entry with a filter mode" 174 175 bridge mdb add dev br0 port br0 grp $grp $state vid 10 \ 176 source_list $src &> /dev/null 177 check_fail $? "Managed to add $name host entry with a source list" 178 179 bridge mdb add dev br0 port br0 grp $grp $state vid 10 \ 180 proto 123 &> /dev/null 181 check_fail $? "Managed to add $name host entry with a protocol" 182 183 log_test "Common host entries configuration tests ($name)" 184} 185 186# Check configuration of host entries from all types. 187cfg_test_host() 188{ 189 echo 190 log_info "# Host entries configuration tests" 191 192 cfg_test_host_common "IPv4" "239.1.1.1" "192.0.2.1" "temp" "permanent" 193 cfg_test_host_common "IPv6" "ff0e::1" "2001:db8:1::1" "temp" "permanent" 194 cfg_test_host_common "L2" "01:02:03:04:05:06" "00:00:00:00:00:01" \ 195 "permanent" "temp" 196} 197 198cfg_test_port_common() 199{ 200 local name=$1;shift 201 local grp_key=$1; shift 202 203 RET=0 204 205 # Check basic add, replace and delete behavior. 206 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 207 bridge mdb get dev br0 $grp_key vid 10 &> /dev/null 208 check_err $? "Failed to add $name entry" 209 210 bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \ 211 &> /dev/null 212 check_err $? "Failed to replace $name entry" 213 214 bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10 215 bridge mdb get dev br0 $grp_key vid 10 &> /dev/null 216 check_fail $? "Failed to delete $name entry" 217 218 # Check default protocol and replacement. 219 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 220 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "static" 221 check_err $? "$name entry not added with default \"static\" protocol" 222 223 bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \ 224 proto 123 225 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "123" 226 check_err $? "Failed to replace protocol of $name entry" 227 bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10 228 229 # Check behavior when VLAN is not specified. 230 bridge mdb add dev br0 port $swp1 $grp_key permanent 231 bridge mdb get dev br0 $grp_key vid 10 &> /dev/null 232 check_err $? "$name entry with VLAN 10 not added when VLAN was not specified" 233 bridge mdb get dev br0 $grp_key vid 20 &> /dev/null 234 check_err $? "$name entry with VLAN 20 not added when VLAN was not specified" 235 236 bridge mdb del dev br0 port $swp1 $grp_key permanent 237 bridge mdb get dev br0 $grp_key vid 10 &> /dev/null 238 check_fail $? "$name entry with VLAN 10 not deleted when VLAN was not specified" 239 bridge mdb get dev br0 $grp_key vid 20 &> /dev/null 240 check_fail $? "$name entry with VLAN 20 not deleted when VLAN was not specified" 241 242 # Check behavior when bridge port is down. 243 ip link set dev $swp1 down 244 245 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 246 check_err $? "Failed to add $name permanent entry when bridge port is down" 247 248 bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10 249 250 bridge mdb add dev br0 port $swp1 $grp_key temp vid 10 &> /dev/null 251 check_fail $? "Managed to add $name temporary entry when bridge port is down" 252 253 ip link set dev $swp1 up 254 setup_wait_dev $swp1 255 256 # Check error cases. 257 ip link set dev br0 down 258 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 \ 259 &> /dev/null 260 check_fail $? "Managed to add $name entry when bridge is down" 261 ip link set dev br0 up 262 263 ip link set dev br0 type bridge mcast_snooping 0 264 bridge mdb add dev br0 port $swp1 $grp_key permanent vid \ 265 10 &> /dev/null 266 check_fail $? "Managed to add $name entry when multicast snooping is disabled" 267 ip link set dev br0 type bridge mcast_snooping 1 268 269 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 5000 \ 270 &> /dev/null 271 check_fail $? "Managed to add $name entry with an invalid VLAN" 272 273 log_test "Common port group entries configuration tests ($name)" 274} 275 276src_list_create() 277{ 278 local src_prefix=$1; shift 279 local num_srcs=$1; shift 280 local src_list 281 local i 282 283 for i in $(seq 1 $num_srcs); do 284 src_list=${src_list},${src_prefix}${i} 285 done 286 287 echo $src_list | cut -c 2- 288} 289 290__cfg_test_port_ip_star_g() 291{ 292 local name=$1; shift 293 local grp=$1; shift 294 local invalid_grp=$1; shift 295 local src_prefix=$1; shift 296 local src1=${src_prefix}1 297 local src2=${src_prefix}2 298 local src3=${src_prefix}3 299 local max_srcs=31 300 local num_srcs 301 302 RET=0 303 304 bridge mdb add dev br0 port $swp1 grp $grp vid 10 305 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude" 306 check_err $? "Default filter mode is not \"exclude\"" 307 bridge mdb del dev br0 port $swp1 grp $grp vid 10 308 309 # Check basic add and delete behavior. 310 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \ 311 source_list $src1 312 bridge -d mdb get dev br0 grp $grp vid 10 &> /dev/null 313 check_err $? "(*, G) entry not created" 314 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null 315 check_err $? "(S, G) entry not created" 316 bridge mdb del dev br0 port $swp1 grp $grp vid 10 317 bridge -d mdb get dev br0 grp $grp vid 10 &> /dev/null 318 check_fail $? "(*, G) entry not deleted" 319 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null 320 check_fail $? "(S, G) entry not deleted" 321 322 ## State (permanent / temp) tests. 323 324 # Check that group and source timer are not set for permanent entries. 325 bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \ 326 filter_mode exclude source_list $src1 327 328 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "permanent" 329 check_err $? "(*, G) entry not added as \"permanent\" when should" 330 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | \ 331 grep -q "permanent" 332 check_err $? "(S, G) entry not added as \"permanent\" when should" 333 334 bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00" 335 check_err $? "(*, G) \"permanent\" entry has a pending group timer" 336 bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00" 337 check_err $? "\"permanent\" source entry has a pending source timer" 338 339 bridge mdb del dev br0 port $swp1 grp $grp vid 10 340 341 # Check that group timer is set for temporary (*, G) EXCLUDE, but not 342 # the source timer. 343 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 344 filter_mode exclude source_list $src1 345 346 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp" 347 check_err $? "(*, G) EXCLUDE entry not added as \"temp\" when should" 348 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp" 349 check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should" 350 351 bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00" 352 check_fail $? "(*, G) EXCLUDE entry does not have a pending group timer" 353 bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00" 354 check_err $? "\"blocked\" source entry has a pending source timer" 355 356 bridge mdb del dev br0 port $swp1 grp $grp vid 10 357 358 # Check that group timer is not set for temporary (*, G) INCLUDE, but 359 # that the source timer is set. 360 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 361 filter_mode include source_list $src1 362 363 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp" 364 check_err $? "(*, G) INCLUDE entry not added as \"temp\" when should" 365 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp" 366 check_err $? "(S, G) entry not added as \"temp\" when should" 367 368 bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00" 369 check_err $? "(*, G) INCLUDE entry has a pending group timer" 370 bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00" 371 check_fail $? "Source entry does not have a pending source timer" 372 373 bridge mdb del dev br0 port $swp1 grp $grp vid 10 374 375 # Check that group timer is never set for (S, G) entries. 376 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 377 filter_mode include source_list $src1 378 379 bridge -d -s mdb get dev br0 grp $grp src $src1 vid 10 | grep -q " 0.00" 380 check_err $? "(S, G) entry has a pending group timer" 381 382 bridge mdb del dev br0 port $swp1 grp $grp vid 10 383 384 ## Filter mode (include / exclude) tests. 385 386 # Check that (*, G) INCLUDE entries are added with correct filter mode 387 # and that (S, G) entries are not marked as "blocked". 388 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \ 389 filter_mode include source_list $src1 390 391 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "include" 392 check_err $? "(*, G) INCLUDE not added with \"include\" filter mode" 393 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked" 394 check_fail $? "(S, G) entry marked as \"blocked\" when should not" 395 396 bridge mdb del dev br0 port $swp1 grp $grp vid 10 397 398 # Check that (*, G) EXCLUDE entries are added with correct filter mode 399 # and that (S, G) entries are marked as "blocked". 400 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \ 401 filter_mode exclude source_list $src1 402 403 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude" 404 check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode" 405 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked" 406 check_err $? "(S, G) entry not marked as \"blocked\" when should" 407 408 bridge mdb del dev br0 port $swp1 grp $grp vid 10 409 410 ## Protocol tests. 411 412 # Check that (*, G) and (S, G) entries are added with the specified 413 # protocol. 414 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \ 415 filter_mode exclude source_list $src1 proto zebra 416 417 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "zebra" 418 check_err $? "(*, G) entry not added with \"zebra\" protocol" 419 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "zebra" 420 check_err $? "(S, G) entry not marked added with \"zebra\" protocol" 421 422 bridge mdb del dev br0 port $swp1 grp $grp vid 10 423 424 ## Replace tests. 425 426 # Check that state can be modified. 427 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 428 filter_mode exclude source_list $src1 429 430 bridge mdb replace dev br0 port $swp1 grp $grp permanent vid 10 \ 431 filter_mode exclude source_list $src1 432 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "permanent" 433 check_err $? "(*, G) entry not marked as \"permanent\" after replace" 434 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "permanent" 435 check_err $? "(S, G) entry not marked as \"permanent\" after replace" 436 437 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \ 438 filter_mode exclude source_list $src1 439 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp" 440 check_err $? "(*, G) entry not marked as \"temp\" after replace" 441 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp" 442 check_err $? "(S, G) entry not marked as \"temp\" after replace" 443 444 bridge mdb del dev br0 port $swp1 grp $grp vid 10 445 446 # Check that filter mode can be modified. 447 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 448 filter_mode exclude source_list $src1 449 450 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \ 451 filter_mode include source_list $src1 452 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "include" 453 check_err $? "(*, G) not marked with \"include\" filter mode after replace" 454 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked" 455 check_fail $? "(S, G) marked as \"blocked\" after replace" 456 457 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \ 458 filter_mode exclude source_list $src1 459 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude" 460 check_err $? "(*, G) not marked with \"exclude\" filter mode after replace" 461 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked" 462 check_err $? "(S, G) not marked as \"blocked\" after replace" 463 464 bridge mdb del dev br0 port $swp1 grp $grp vid 10 465 466 # Check that sources can be added to and removed from the source list. 467 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 468 filter_mode exclude source_list $src1 469 470 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \ 471 filter_mode exclude source_list $src1,$src2,$src3 472 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null 473 check_err $? "(S, G) entry for source $src1 not created after replace" 474 bridge -d mdb get dev br0 grp $grp src $src2 vid 10 &> /dev/null 475 check_err $? "(S, G) entry for source $src2 not created after replace" 476 bridge -d mdb get dev br0 grp $grp src $src3 vid 10 &> /dev/null 477 check_err $? "(S, G) entry for source $src3 not created after replace" 478 479 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \ 480 filter_mode exclude source_list $src1,$src3 481 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null 482 check_err $? "(S, G) entry for source $src1 not created after second replace" 483 bridge -d mdb get dev br0 grp $grp src $src2 vid 10 &> /dev/null 484 check_fail $? "(S, G) entry for source $src2 created after second replace" 485 bridge -d mdb get dev br0 grp $grp src $src3 vid 10 &> /dev/null 486 check_err $? "(S, G) entry for source $src3 not created after second replace" 487 488 bridge mdb del dev br0 port $swp1 grp $grp vid 10 489 490 # Check that protocol can be modified. 491 bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 492 filter_mode exclude source_list $src1 proto zebra 493 494 bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \ 495 filter_mode exclude source_list $src1 proto bgp 496 bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "bgp" 497 check_err $? "(*, G) protocol not changed to \"bgp\" after replace" 498 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "bgp" 499 check_err $? "(S, G) protocol not changed to \"bgp\" after replace" 500 501 bridge mdb del dev br0 port $swp1 grp $grp vid 10 502 503 ## Star exclude tests. 504 505 # Check star exclude functionality. When adding a new EXCLUDE (*, G), 506 # it needs to be also added to all (S, G) entries for proper 507 # replication. 508 bridge mdb add dev br0 port $swp2 grp $grp vid 10 \ 509 filter_mode include source_list $src1 510 bridge mdb add dev br0 port $swp1 grp $grp vid 10 511 bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep "$swp1" | \ 512 grep -q "added_by_star_ex" 513 check_err $? "\"added_by_star_ex\" entry not created after adding (*, G) entry" 514 bridge mdb del dev br0 port $swp1 grp $grp vid 10 515 bridge mdb del dev br0 port $swp2 grp $grp src $src1 vid 10 516 517 ## Error cases tests. 518 519 bridge mdb add dev br0 port $swp1 grp $invalid_grp vid 10 &> /dev/null 520 check_fail $? "Managed to add an entry with an invalid group" 521 522 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \ 523 &> /dev/null 524 check_fail $? "Managed to add an INCLUDE entry with an empty source list" 525 526 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \ 527 source_list $grp &> /dev/null 528 check_fail $? "Managed to add an entry with an invalid source in source list" 529 530 bridge mdb add dev br0 port $swp1 grp $grp vid 10 \ 531 source_list $src &> /dev/null 532 check_fail $? "Managed to add an entry with a source list and no filter mode" 533 534 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \ 535 source_list $src1 536 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \ 537 source_list $src1 &> /dev/null 538 check_fail $? "Managed to replace an entry without using replace" 539 bridge mdb del dev br0 port $swp1 grp $grp vid 10 540 541 bridge mdb add dev br0 port $swp1 grp $grp src $src2 vid 10 542 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \ 543 source_list $src1,$src2,$src3 &> /dev/null 544 check_fail $? "Managed to add a source that already has a forwarding entry" 545 bridge mdb del dev br0 port $swp1 grp $grp src $src2 vid 10 546 547 # Check maximum number of sources. 548 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \ 549 source_list $(src_list_create $src_prefix $max_srcs) 550 num_srcs=$(bridge -d mdb show dev br0 vid 10 | grep "$grp" | \ 551 grep "src" | wc -l) 552 [[ $num_srcs -eq $max_srcs ]] 553 check_err $? "Failed to configure maximum number of sources ($max_srcs)" 554 bridge mdb del dev br0 port $swp1 grp $grp vid 10 555 556 bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \ 557 source_list $(src_list_create $src_prefix $((max_srcs + 1))) \ 558 &> /dev/null 559 check_fail $? "Managed to exceed maximum number of sources ($max_srcs)" 560 561 log_test "$name (*, G) port group entries configuration tests" 562} 563 564cfg_test_port_ip_star_g() 565{ 566 echo 567 log_info "# Port group entries configuration tests - (*, G)" 568 569 cfg_test_port_common "IPv4 (*, G)" "grp 239.1.1.1" 570 cfg_test_port_common "IPv6 (*, G)" "grp ff0e::1" 571 __cfg_test_port_ip_star_g "IPv4" "239.1.1.1" "224.0.0.1" "192.0.2." 572 __cfg_test_port_ip_star_g "IPv6" "ff0e::1" "ff02::1" "2001:db8:1::" 573} 574 575__cfg_test_port_ip_sg() 576{ 577 local name=$1; shift 578 local grp=$1; shift 579 local src=$1; shift 580 local grp_key="grp $grp src $src" 581 582 RET=0 583 584 bridge mdb add dev br0 port $swp1 $grp_key vid 10 585 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "include" 586 check_err $? "Default filter mode is not \"include\"" 587 bridge mdb del dev br0 port $swp1 $grp_key vid 10 588 589 # Check that entries can be added as both permanent and temp and that 590 # group timer is set correctly. 591 bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 592 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "permanent" 593 check_err $? "Entry not added as \"permanent\" when should" 594 bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00" 595 check_err $? "\"permanent\" entry has a pending group timer" 596 bridge mdb del dev br0 port $swp1 $grp_key vid 10 597 598 bridge mdb add dev br0 port $swp1 $grp_key temp vid 10 599 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "temp" 600 check_err $? "Entry not added as \"temp\" when should" 601 bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00" 602 check_fail $? "\"temp\" entry has an unpending group timer" 603 bridge mdb del dev br0 port $swp1 $grp_key vid 10 604 605 # Check error cases. 606 bridge mdb add dev br0 port $swp1 $grp_key vid 10 \ 607 filter_mode include &> /dev/null 608 check_fail $? "Managed to add an entry with a filter mode" 609 610 bridge mdb add dev br0 port $swp1 $grp_key vid 10 \ 611 filter_mode include source_list $src &> /dev/null 612 check_fail $? "Managed to add an entry with a source list" 613 614 bridge mdb add dev br0 port $swp1 grp $grp src $grp vid 10 &> /dev/null 615 check_fail $? "Managed to add an entry with an invalid source" 616 617 bridge mdb add dev br0 port $swp1 $grp_key vid 10 temp 618 bridge mdb add dev br0 port $swp1 $grp_key vid 10 permanent &> /dev/null 619 check_fail $? "Managed to replace an entry without using replace" 620 bridge mdb del dev br0 port $swp1 $grp_key vid 10 621 622 # Check that we can replace available attributes. 623 bridge mdb add dev br0 port $swp1 $grp_key vid 10 proto 123 624 bridge mdb replace dev br0 port $swp1 $grp_key vid 10 proto 111 625 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "111" 626 check_err $? "Failed to replace protocol" 627 628 bridge mdb replace dev br0 port $swp1 $grp_key vid 10 permanent 629 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "permanent" 630 check_err $? "Entry not marked as \"permanent\" after replace" 631 bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00" 632 check_err $? "Entry has a pending group timer after replace" 633 634 bridge mdb replace dev br0 port $swp1 $grp_key vid 10 temp 635 bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "temp" 636 check_err $? "Entry not marked as \"temp\" after replace" 637 bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00" 638 check_fail $? "Entry has an unpending group timer after replace" 639 bridge mdb del dev br0 port $swp1 $grp_key vid 10 640 641 # Check star exclude functionality. When adding a (S, G), all matching 642 # (*, G) ports need to be added to it. 643 bridge mdb add dev br0 port $swp2 grp $grp vid 10 644 bridge mdb add dev br0 port $swp1 $grp_key vid 10 645 bridge mdb get dev br0 $grp_key vid 10 | grep $swp2 | \ 646 grep -q "added_by_star_ex" 647 check_err $? "\"added_by_star_ex\" entry not created after adding (S, G) entry" 648 bridge mdb del dev br0 port $swp1 $grp_key vid 10 649 bridge mdb del dev br0 port $swp2 grp $grp vid 10 650 651 log_test "$name (S, G) port group entries configuration tests" 652} 653 654cfg_test_port_ip_sg() 655{ 656 echo 657 log_info "# Port group entries configuration tests - (S, G)" 658 659 cfg_test_port_common "IPv4 (S, G)" "grp 239.1.1.1 src 192.0.2.1" 660 cfg_test_port_common "IPv6 (S, G)" "grp ff0e::1 src 2001:db8:1::1" 661 __cfg_test_port_ip_sg "IPv4" "239.1.1.1" "192.0.2.1" 662 __cfg_test_port_ip_sg "IPv6" "ff0e::1" "2001:db8:1::1" 663} 664 665cfg_test_port_ip() 666{ 667 cfg_test_port_ip_star_g 668 cfg_test_port_ip_sg 669} 670 671__cfg_test_port_l2() 672{ 673 local grp="01:02:03:04:05:06" 674 675 RET=0 676 677 bridge meb add dev br0 port $swp grp 00:01:02:03:04:05 \ 678 permanent vid 10 &> /dev/null 679 check_fail $? "Managed to add an entry with unicast MAC" 680 681 bridge mdb add dev br0 port $swp grp $grp src 00:01:02:03:04:05 \ 682 permanent vid 10 &> /dev/null 683 check_fail $? "Managed to add an entry with a source" 684 685 bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \ 686 filter_mode include &> /dev/null 687 check_fail $? "Managed to add an entry with a filter mode" 688 689 bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \ 690 source_list 00:01:02:03:04:05 &> /dev/null 691 check_fail $? "Managed to add an entry with a source list" 692 693 log_test "L2 (*, G) port group entries configuration tests" 694} 695 696cfg_test_port_l2() 697{ 698 echo 699 log_info "# Port group entries configuration tests - L2" 700 701 cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06" 702 __cfg_test_port_l2 703} 704 705# Check configuration of regular (port) entries of all types. 706cfg_test_port() 707{ 708 cfg_test_port_ip 709 cfg_test_port_l2 710} 711 712ipv4_grps_get() 713{ 714 local max_grps=$1; shift 715 local i 716 717 for i in $(seq 0 $((max_grps - 1))); do 718 echo "239.1.1.$i" 719 done 720} 721 722ipv6_grps_get() 723{ 724 local max_grps=$1; shift 725 local i 726 727 for i in $(seq 0 $((max_grps - 1))); do 728 echo "ff0e::$(printf %x $i)" 729 done 730} 731 732l2_grps_get() 733{ 734 local max_grps=$1; shift 735 local i 736 737 for i in $(seq 0 $((max_grps - 1))); do 738 echo "01:00:00:00:00:$(printf %02x $i)" 739 done 740} 741 742cfg_test_dump_common() 743{ 744 local name=$1; shift 745 local fn=$1; shift 746 local max_bridges=2 747 local max_grps=256 748 local max_ports=32 749 local num_entries 750 local batch_file 751 local grp 752 local i j 753 754 RET=0 755 756 # Create net devices. 757 for i in $(seq 1 $max_bridges); do 758 ip link add name br-test${i} up type bridge vlan_filtering 1 \ 759 mcast_snooping 1 760 for j in $(seq 1 $max_ports); do 761 ip link add name br-test${i}-du${j} up \ 762 master br-test${i} type dummy 763 done 764 done 765 766 # Create batch file with MDB entries. 767 batch_file=$(mktemp) 768 for i in $(seq 1 $max_bridges); do 769 for j in $(seq 1 $max_ports); do 770 for grp in $($fn $max_grps); do 771 echo "mdb add dev br-test${i} \ 772 port br-test${i}-du${j} grp $grp \ 773 permanent vid 1" >> $batch_file 774 done 775 done 776 done 777 778 # Program the batch file and check for expected number of entries. 779 bridge -b $batch_file 780 for i in $(seq 1 $max_bridges); do 781 num_entries=$(bridge mdb show dev br-test${i} | \ 782 grep "permanent" | wc -l) 783 [[ $num_entries -eq $((max_grps * max_ports)) ]] 784 check_err $? "Wrong number of entries in br-test${i}" 785 done 786 787 # Cleanup. 788 rm $batch_file 789 for i in $(seq 1 $max_bridges); do 790 ip link del dev br-test${i} 791 for j in $(seq $max_ports); do 792 ip link del dev br-test${i}-du${j} 793 done 794 done 795 796 log_test "$name large scale dump tests" 797} 798 799# Check large scale dump. 800cfg_test_dump() 801{ 802 echo 803 log_info "# Large scale dump tests" 804 805 cfg_test_dump_common "IPv4" ipv4_grps_get 806 cfg_test_dump_common "IPv6" ipv6_grps_get 807 cfg_test_dump_common "L2" l2_grps_get 808} 809 810# Check flush functionality with different parameters. 811cfg_test_flush() 812{ 813 local num_entries 814 815 # Add entries with different attributes and check that they are all 816 # flushed when the flush command is given with no parameters. 817 818 # Different port. 819 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10 820 bridge mdb add dev br0 port $swp2 grp 239.1.1.2 vid 10 821 822 # Different VLAN ID. 823 bridge mdb add dev br0 port $swp1 grp 239.1.1.3 vid 10 824 bridge mdb add dev br0 port $swp1 grp 239.1.1.4 vid 20 825 826 # Different routing protocol. 827 bridge mdb add dev br0 port $swp1 grp 239.1.1.5 vid 10 proto bgp 828 bridge mdb add dev br0 port $swp1 grp 239.1.1.6 vid 10 proto zebra 829 830 # Different state. 831 bridge mdb add dev br0 port $swp1 grp 239.1.1.7 vid 10 permanent 832 bridge mdb add dev br0 port $swp1 grp 239.1.1.8 vid 10 temp 833 834 bridge mdb flush dev br0 835 num_entries=$(bridge mdb show dev br0 | wc -l) 836 [[ $num_entries -eq 0 ]] 837 check_err $? 0 "Not all entries flushed after flush all" 838 839 # Check that when flushing by port only entries programmed with the 840 # specified port are flushed and the rest are not. 841 842 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10 843 bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10 844 bridge mdb add dev br0 port br0 grp 239.1.1.1 vid 10 845 846 bridge mdb flush dev br0 port $swp1 847 848 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1" 849 check_fail $? "Entry not flushed by specified port" 850 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2" 851 check_err $? "Entry flushed by wrong port" 852 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0" 853 check_err $? "Host entry flushed by wrong port" 854 855 bridge mdb flush dev br0 port br0 856 857 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0" 858 check_fail $? "Host entry not flushed by specified port" 859 860 bridge mdb flush dev br0 861 862 # Check that when flushing by VLAN ID only entries programmed with the 863 # specified VLAN ID are flushed and the rest are not. 864 865 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10 866 bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10 867 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 20 868 bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 20 869 870 bridge mdb flush dev br0 vid 10 871 872 bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null 873 check_fail $? "Entry not flushed by specified VLAN ID" 874 bridge mdb get dev br0 grp 239.1.1.1 vid 20 &> /dev/null 875 check_err $? "Entry flushed by wrong VLAN ID" 876 877 bridge mdb flush dev br0 878 879 # Check that all permanent entries are flushed when "permanent" is 880 # specified and that temporary entries are not. 881 882 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 883 bridge mdb add dev br0 port $swp2 grp 239.1.1.1 temp vid 10 884 885 bridge mdb flush dev br0 permanent 886 887 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1" 888 check_fail $? "Entry not flushed by \"permanent\" state" 889 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2" 890 check_err $? "Entry flushed by wrong state (\"permanent\")" 891 892 bridge mdb flush dev br0 893 894 # Check that all temporary entries are flushed when "nopermanent" is 895 # specified and that permanent entries are not. 896 897 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 898 bridge mdb add dev br0 port $swp2 grp 239.1.1.1 temp vid 10 899 900 bridge mdb flush dev br0 nopermanent 901 902 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1" 903 check_err $? "Entry flushed by wrong state (\"nopermanent\")" 904 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2" 905 check_fail $? "Entry not flushed by \"nopermanent\" state" 906 907 bridge mdb flush dev br0 908 909 # Check that L2 host entries are not flushed when "nopermanent" is 910 # specified, but flushed when "permanent" is specified. 911 912 bridge mdb add dev br0 port br0 grp 01:02:03:04:05:06 permanent vid 10 913 914 bridge mdb flush dev br0 nopermanent 915 916 bridge mdb get dev br0 grp 01:02:03:04:05:06 vid 10 &> /dev/null 917 check_err $? "L2 host entry flushed by wrong state (\"nopermanent\")" 918 919 bridge mdb flush dev br0 permanent 920 921 bridge mdb get dev br0 grp 01:02:03:04:05:06 vid 10 &> /dev/null 922 check_fail $? "L2 host entry not flushed by \"permanent\" state" 923 924 bridge mdb flush dev br0 925 926 # Check that IPv4 host entries are not flushed when "permanent" is 927 # specified, but flushed when "nopermanent" is specified. 928 929 bridge mdb add dev br0 port br0 grp 239.1.1.1 temp vid 10 930 931 bridge mdb flush dev br0 permanent 932 933 bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null 934 check_err $? "IPv4 host entry flushed by wrong state (\"permanent\")" 935 936 bridge mdb flush dev br0 nopermanent 937 938 bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null 939 check_fail $? "IPv4 host entry not flushed by \"nopermanent\" state" 940 941 bridge mdb flush dev br0 942 943 # Check that IPv6 host entries are not flushed when "permanent" is 944 # specified, but flushed when "nopermanent" is specified. 945 946 bridge mdb add dev br0 port br0 grp ff0e::1 temp vid 10 947 948 bridge mdb flush dev br0 permanent 949 950 bridge mdb get dev br0 grp ff0e::1 vid 10 &> /dev/null 951 check_err $? "IPv6 host entry flushed by wrong state (\"permanent\")" 952 953 bridge mdb flush dev br0 nopermanent 954 955 bridge mdb get dev br0 grp ff0e::1 vid 10 &> /dev/null 956 check_fail $? "IPv6 host entry not flushed by \"nopermanent\" state" 957 958 bridge mdb flush dev br0 959 960 # Check that when flushing by routing protocol only entries programmed 961 # with the specified routing protocol are flushed and the rest are not. 962 963 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10 proto bgp 964 bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10 proto zebra 965 bridge mdb add dev br0 port br0 grp 239.1.1.1 vid 10 966 967 bridge mdb flush dev br0 proto bgp 968 969 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1" 970 check_fail $? "Entry not flushed by specified routing protocol" 971 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2" 972 check_err $? "Entry flushed by wrong routing protocol" 973 bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0" 974 check_err $? "Host entry flushed by wrong routing protocol" 975 976 bridge mdb flush dev br0 977 978 # Test that an error is returned when trying to flush using unsupported 979 # parameters. 980 981 bridge mdb flush dev br0 src_vni 10 &> /dev/null 982 check_fail $? "Managed to flush by source VNI" 983 984 bridge mdb flush dev br0 dst 198.51.100.1 &> /dev/null 985 check_fail $? "Managed to flush by destination IP" 986 987 bridge mdb flush dev br0 dst_port 4789 &> /dev/null 988 check_fail $? "Managed to flush by UDP destination port" 989 990 bridge mdb flush dev br0 vni 10 &> /dev/null 991 check_fail $? "Managed to flush by destination VNI" 992 993 log_test "Flush tests" 994} 995 996cfg_test() 997{ 998 cfg_test_host 999 cfg_test_port 1000 cfg_test_dump 1001 cfg_test_flush 1002} 1003 1004__fwd_test_host_ip() 1005{ 1006 local grp=$1; shift 1007 local dmac=$1; shift 1008 local src=$1; shift 1009 local mode=$1; shift 1010 local name 1011 local eth_type 1012 1013 RET=0 1014 1015 if [[ $mode == "-4" ]]; then 1016 name="IPv4" 1017 eth_type="ipv4" 1018 else 1019 name="IPv6" 1020 eth_type="ipv6" 1021 fi 1022 1023 tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \ 1024 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \ 1025 action drop 1026 1027 # Packet should only be flooded to multicast router ports when there is 1028 # no matching MDB entry. The bridge is not configured as a multicast 1029 # router port. 1030 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q 1031 tc_check_packets "dev br0 ingress" 1 0 1032 check_err $? "Packet locally received after flood" 1033 1034 # Install a regular port group entry and expect the packet to not be 1035 # locally received. 1036 bridge mdb add dev br0 port $swp2 grp $grp temp vid 10 1037 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q 1038 tc_check_packets "dev br0 ingress" 1 0 1039 check_err $? "Packet locally received after installing a regular entry" 1040 1041 # Add a host entry and expect the packet to be locally received. 1042 bridge mdb add dev br0 port br0 grp $grp temp vid 10 1043 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q 1044 tc_check_packets "dev br0 ingress" 1 1 1045 check_err $? "Packet not locally received after adding a host entry" 1046 1047 # Remove the host entry and expect the packet to not be locally 1048 # received. 1049 bridge mdb del dev br0 port br0 grp $grp vid 10 1050 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q 1051 tc_check_packets "dev br0 ingress" 1 1 1052 check_err $? "Packet locally received after removing a host entry" 1053 1054 bridge mdb del dev br0 port $swp2 grp $grp vid 10 1055 1056 tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower 1057 1058 log_test "$name host entries forwarding tests" 1059} 1060 1061fwd_test_host_ip() 1062{ 1063 __fwd_test_host_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "-4" 1064 __fwd_test_host_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "-6" 1065} 1066 1067fwd_test_host_l2() 1068{ 1069 local dmac=01:02:03:04:05:06 1070 1071 RET=0 1072 1073 tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \ 1074 dst_mac $dmac action drop 1075 1076 # Packet should be flooded and locally received when there is no 1077 # matching MDB entry. 1078 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1079 tc_check_packets "dev br0 ingress" 1 1 1080 check_err $? "Packet not locally received after flood" 1081 1082 # Install a regular port group entry and expect the packet to not be 1083 # locally received. 1084 bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10 1085 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1086 tc_check_packets "dev br0 ingress" 1 1 1087 check_err $? "Packet locally received after installing a regular entry" 1088 1089 # Add a host entry and expect the packet to be locally received. 1090 bridge mdb add dev br0 port br0 grp $dmac permanent vid 10 1091 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1092 tc_check_packets "dev br0 ingress" 1 2 1093 check_err $? "Packet not locally received after adding a host entry" 1094 1095 # Remove the host entry and expect the packet to not be locally 1096 # received. 1097 bridge mdb del dev br0 port br0 grp $dmac permanent vid 10 1098 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1099 tc_check_packets "dev br0 ingress" 1 2 1100 check_err $? "Packet locally received after removing a host entry" 1101 1102 bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10 1103 1104 tc filter del dev br0 ingress protocol all pref 1 handle 1 flower 1105 1106 log_test "L2 host entries forwarding tests" 1107} 1108 1109fwd_test_host() 1110{ 1111 # Disable multicast router on the bridge to ensure that packets are 1112 # only locally received when a matching host entry is present. 1113 ip link set dev br0 type bridge mcast_router 0 1114 1115 fwd_test_host_ip 1116 fwd_test_host_l2 1117 1118 ip link set dev br0 type bridge mcast_router 1 1119} 1120 1121__fwd_test_port_ip() 1122{ 1123 local grp=$1; shift 1124 local dmac=$1; shift 1125 local valid_src=$1; shift 1126 local invalid_src=$1; shift 1127 local mode=$1; shift 1128 local filter_mode=$1; shift 1129 local name 1130 local eth_type 1131 local src_list 1132 1133 RET=0 1134 1135 if [[ $mode == "-4" ]]; then 1136 name="IPv4" 1137 eth_type="ipv4" 1138 else 1139 name="IPv6" 1140 eth_type="ipv6" 1141 fi 1142 1143 # The valid source is the one we expect to get packets from after 1144 # adding the entry. 1145 if [[ $filter_mode == "include" ]]; then 1146 src_list=$valid_src 1147 else 1148 src_list=$invalid_src 1149 fi 1150 1151 tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \ 1152 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \ 1153 src_ip $valid_src action drop 1154 tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \ 1155 vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \ 1156 src_ip $invalid_src action drop 1157 1158 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q 1159 tc_check_packets "dev $h2 ingress" 1 0 1160 check_err $? "Packet from valid source received on H2 before adding entry" 1161 1162 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 1163 tc_check_packets "dev $h2 ingress" 2 0 1164 check_err $? "Packet from invalid source received on H2 before adding entry" 1165 1166 bridge mdb add dev br0 port $swp2 grp $grp vid 10 \ 1167 filter_mode $filter_mode source_list $src_list 1168 1169 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q 1170 tc_check_packets "dev $h2 ingress" 1 1 1171 check_err $? "Packet from valid source not received on H2 after adding entry" 1172 1173 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 1174 tc_check_packets "dev $h2 ingress" 2 0 1175 check_err $? "Packet from invalid source received on H2 after adding entry" 1176 1177 bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \ 1178 filter_mode exclude 1179 1180 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q 1181 tc_check_packets "dev $h2 ingress" 1 2 1182 check_err $? "Packet from valid source not received on H2 after allowing all sources" 1183 1184 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 1185 tc_check_packets "dev $h2 ingress" 2 1 1186 check_err $? "Packet from invalid source not received on H2 after allowing all sources" 1187 1188 bridge mdb del dev br0 port $swp2 grp $grp vid 10 1189 1190 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q 1191 tc_check_packets "dev $h2 ingress" 1 2 1192 check_err $? "Packet from valid source received on H2 after deleting entry" 1193 1194 $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 1195 tc_check_packets "dev $h2 ingress" 2 1 1196 check_err $? "Packet from invalid source received on H2 after deleting entry" 1197 1198 tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower 1199 tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower 1200 1201 log_test "$name port group \"$filter_mode\" entries forwarding tests" 1202} 1203 1204fwd_test_port_ip() 1205{ 1206 __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "exclude" 1207 __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \ 1208 "exclude" 1209 __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "include" 1210 __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \ 1211 "include" 1212} 1213 1214fwd_test_port_l2() 1215{ 1216 local dmac=01:02:03:04:05:06 1217 1218 RET=0 1219 1220 tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \ 1221 dst_mac $dmac action drop 1222 1223 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1224 tc_check_packets "dev $h2 ingress" 1 0 1225 check_err $? "Packet received on H2 before adding entry" 1226 1227 bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10 1228 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1229 tc_check_packets "dev $h2 ingress" 1 1 1230 check_err $? "Packet not received on H2 after adding entry" 1231 1232 bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10 1233 $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 1234 tc_check_packets "dev $h2 ingress" 1 1 1235 check_err $? "Packet received on H2 after deleting entry" 1236 1237 tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower 1238 1239 log_test "L2 port entries forwarding tests" 1240} 1241 1242fwd_test_port() 1243{ 1244 # Disable multicast flooding to ensure that packets are only forwarded 1245 # out of a port when a matching port group entry is present. 1246 bridge link set dev $swp2 mcast_flood off 1247 1248 fwd_test_port_ip 1249 fwd_test_port_l2 1250 1251 bridge link set dev $swp2 mcast_flood on 1252} 1253 1254fwd_test() 1255{ 1256 echo 1257 log_info "# Forwarding tests" 1258 1259 # Set the Max Response Delay to 100 centiseconds (1 second) so that the 1260 # bridge will start forwarding according to its MDB soon after a 1261 # multicast querier is enabled. 1262 ip link set dev br0 type bridge mcast_query_response_interval 100 1263 1264 # Forwarding according to MDB entries only takes place when the bridge 1265 # detects that there is a valid querier in the network. Set the bridge 1266 # as the querier and assign it a valid IPv6 link-local address to be 1267 # used as the source address for MLD queries. 1268 ip -6 address add fe80::1/64 nodad dev br0 1269 ip link set dev br0 type bridge mcast_querier 1 1270 sleep 10 1271 1272 fwd_test_host 1273 fwd_test_port 1274 1275 ip link set dev br0 type bridge mcast_querier 0 1276 ip -6 address del fe80::1/64 dev br0 1277 ip link set dev br0 type bridge mcast_query_response_interval 1000 1278} 1279 1280ctrl_igmpv3_is_in_test() 1281{ 1282 RET=0 1283 1284 # Add a permanent entry and check that it is not affected by the 1285 # received IGMP packet. 1286 bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \ 1287 filter_mode include source_list 192.0.2.1 1288 1289 # IS_IN ( 192.0.2.2 ) 1290 $MZ $h1.10 -c 1 -a own -b 01:00:5e:01:01:01 -A 192.0.2.1 -B 239.1.1.1 \ 1291 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q 1292 1293 bridge mdb get dev br0 grp 239.1.1.1 src 192.0.2.2 vid 10 &> /dev/null 1294 check_fail $? "Permanent entry affected by IGMP packet" 1295 1296 # Replace the permanent entry with a temporary one and check that after 1297 # processing the IGMP packet, a new source is added to the list along 1298 # with a new forwarding entry. 1299 bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \ 1300 filter_mode include source_list 192.0.2.1 1301 1302 # IS_IN ( 192.0.2.2 ) 1303 $MZ $h1.10 -a own -b 01:00:5e:01:01:01 -c 1 -A 192.0.2.1 -B 239.1.1.1 \ 1304 -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q 1305 1306 bridge -d mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q 192.0.2.2 1307 check_err $? "Source not add to source list" 1308 1309 bridge mdb get dev br0 grp 239.1.1.1 src 192.0.2.2 vid 10 &> /dev/null 1310 check_err $? "(S, G) entry not created for new source" 1311 1312 bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10 1313 1314 log_test "IGMPv3 MODE_IS_INCLUDE tests" 1315} 1316 1317ctrl_mldv2_is_in_test() 1318{ 1319 RET=0 1320 1321 # Add a permanent entry and check that it is not affected by the 1322 # received MLD packet. 1323 bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \ 1324 filter_mode include source_list 2001:db8:1::1 1325 1326 # IS_IN ( 2001:db8:1::2 ) 1327 local p=$(mldv2_is_in_get fe80::1 ff0e::1 2001:db8:1::2) 1328 $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \ 1329 -t ip hop=1,next=0,p="$p" -q 1330 1331 bridge mdb get dev br0 grp ff0e::1 src 2001:db8:1::2 vid 10 &> /dev/null 1332 check_fail $? "Permanent entry affected by MLD packet" 1333 1334 # Replace the permanent entry with a temporary one and check that after 1335 # processing the MLD packet, a new source is added to the list along 1336 # with a new forwarding entry. 1337 bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \ 1338 filter_mode include source_list 2001:db8:1::1 1339 1340 # IS_IN ( 2001:db8:1::2 ) 1341 $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \ 1342 -t ip hop=1,next=0,p="$p" -q 1343 1344 bridge -d mdb get dev br0 grp ff0e::1 vid 10 | grep -q 2001:db8:1::2 1345 check_err $? "Source not add to source list" 1346 1347 bridge mdb get dev br0 grp ff0e::1 src 2001:db8:1::2 vid 10 &> /dev/null 1348 check_err $? "(S, G) entry not created for new source" 1349 1350 bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10 1351 1352 log_test "MLDv2 MODE_IS_INCLUDE tests" 1353} 1354 1355ctrl_test() 1356{ 1357 echo 1358 log_info "# Control packets tests" 1359 1360 ctrl_igmpv3_is_in_test 1361 ctrl_mldv2_is_in_test 1362} 1363 1364check_group() 1365{ 1366 local group=$1; shift 1367 local vid=$1; shift 1368 local should_fail=$1; shift 1369 local when=$1; shift 1370 local -a vidkws 1371 1372 if ((vid)); then 1373 vidkws=(vid "$vid") 1374 fi 1375 1376 bridge mdb get dev br0 grp "$group" "${vidkws[@]}" 2>/dev/null | 1377 grep -q "port $swp1" 1378 check_err_fail "$should_fail" $? "$group seen $when snooping disable:" 1379} 1380 1381__disable_test() 1382{ 1383 local vid=$1; shift 1384 local what=$1; shift 1385 local -a vidkws 1386 1387 if ((vid)); then 1388 vidkws=(vid "$vid") 1389 fi 1390 1391 RET=0 1392 1393 bridge mdb add dev br0 port "$swp1" grp ff0e::1 permanent \ 1394 "${vidkws[@]}" filter_mode include source_list 2001:db8:1::1 1395 bridge mdb add dev br0 port "$swp1" grp ff0e::2 permanent \ 1396 "${vidkws[@]}" filter_mode exclude 1397 1398 bridge mdb add dev br0 port "$swp1" grp ff0e::3 \ 1399 "${vidkws[@]}" filter_mode include source_list 2001:db8:1::2 1400 bridge mdb add dev br0 port "$swp1" grp ff0e::4 \ 1401 "${vidkws[@]}" filter_mode exclude 1402 1403 bridge mdb add dev br0 port "$swp1" grp 239.1.1.1 permanent \ 1404 "${vidkws[@]}" filter_mode include source_list 192.0.2.1 1405 bridge mdb add dev br0 port "$swp1" grp 239.1.1.2 permanent \ 1406 "${vidkws[@]}" filter_mode exclude 1407 1408 bridge mdb add dev br0 port "$swp1" grp 239.1.1.3 \ 1409 "${vidkws[@]}" filter_mode include source_list 192.0.2.2 1410 bridge mdb add dev br0 port "$swp1" grp 239.1.1.4 \ 1411 "${vidkws[@]}" filter_mode exclude 1412 1413 check_group ff0e::1 "$vid" 0 "before" 1414 check_group ff0e::2 "$vid" 0 "before" 1415 check_group ff0e::3 "$vid" 0 "before" 1416 check_group ff0e::4 "$vid" 0 "before" 1417 1418 check_group 239.1.1.1 "$vid" 0 "before" 1419 check_group 239.1.1.2 "$vid" 0 "before" 1420 check_group 239.1.1.3 "$vid" 0 "before" 1421 check_group 239.1.1.4 "$vid" 0 "before" 1422 1423 ip link set dev br0 type bridge mcast_snooping 0 1424 1425 check_group ff0e::1 "$vid" 0 "after" 1426 check_group ff0e::2 "$vid" 0 "after" 1427 check_group ff0e::3 "$vid" 1 "after" 1428 check_group ff0e::4 "$vid" 1 "after" 1429 1430 check_group 239.1.1.1 "$vid" 0 "after" 1431 check_group 239.1.1.2 "$vid" 0 "after" 1432 check_group 239.1.1.3 "$vid" 1 "after" 1433 check_group 239.1.1.4 "$vid" 1 "after" 1434 1435 log_test "$what: Flush after disable" 1436 1437 ip link set dev br0 type bridge mcast_snooping 1 1438 sleep 10 1439} 1440 1441disable_test() 1442{ 1443 __disable_test 10 802.1q 1444 1445 switch_destroy 1446 switch_create 0 1447 setup_wait 1448 1449 __disable_test 0 802.1d 1450 1451 switch_destroy 1452 switch_create 1 1453 setup_wait 1454} 1455 1456if ! bridge mdb help 2>&1 | grep -q "flush"; then 1457 echo "SKIP: iproute2 too old, missing bridge mdb flush support" 1458 exit $ksft_skip 1459fi 1460 1461trap cleanup EXIT 1462 1463setup_prepare 1464setup_wait 1465tests_run 1466 1467exit $EXIT_STATUS 1468