Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: forwarding: Add bridge MDB test

Add a selftests that includes the following test cases:

1. Configuration tests. Both valid and invalid configurations are
tested across all entry types (e.g., L2, IPv4).

2. Forwarding tests. Both host and port group entries are tested across
all entry types.

3. Interaction between user installed MDB entries and IGMP / MLD control
packets.

Example output:

INFO: # Host entries configuration tests
TEST: Common host entries configuration tests (IPv4) [ OK ]
TEST: Common host entries configuration tests (IPv6) [ OK ]
TEST: Common host entries configuration tests (L2) [ OK ]

INFO: # Port group entries configuration tests - (*, G)
TEST: Common port group entries configuration tests (IPv4 (*, G)) [ OK ]
TEST: Common port group entries configuration tests (IPv6 (*, G)) [ OK ]
TEST: IPv4 (*, G) port group entries configuration tests [ OK ]
TEST: IPv6 (*, G) port group entries configuration tests [ OK ]

INFO: # Port group entries configuration tests - (S, G)
TEST: Common port group entries configuration tests (IPv4 (S, G)) [ OK ]
TEST: Common port group entries configuration tests (IPv6 (S, G)) [ OK ]
TEST: IPv4 (S, G) port group entries configuration tests [ OK ]
TEST: IPv6 (S, G) port group entries configuration tests [ OK ]

INFO: # Port group entries configuration tests - L2
TEST: Common port group entries configuration tests (L2 (*, G)) [ OK ]
TEST: L2 (*, G) port group entries configuration tests [ OK ]

INFO: # Forwarding tests
TEST: IPv4 host entries forwarding tests [ OK ]
TEST: IPv6 host entries forwarding tests [ OK ]
TEST: L2 host entries forwarding tests [ OK ]
TEST: IPv4 port group "exclude" entries forwarding tests [ OK ]
TEST: IPv6 port group "exclude" entries forwarding tests [ OK ]
TEST: IPv4 port group "include" entries forwarding tests [ OK ]
TEST: IPv6 port group "include" entries forwarding tests [ OK ]
TEST: L2 port entries forwarding tests [ OK ]

INFO: # Control packets tests
TEST: IGMPv3 MODE_IS_INCLUE tests [ OK ]
TEST: MLDv2 MODE_IS_INCLUDE tests [ OK ]

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Ido Schimmel and committed by
Jakub Kicinski
b6d00da0 f9923a67

+1165
+1
tools/testing/selftests/net/forwarding/Makefile
··· 2 2 3 3 TEST_PROGS = bridge_igmp.sh \ 4 4 bridge_locked_port.sh \ 5 + bridge_mdb.sh \ 5 6 bridge_mdb_host.sh \ 6 7 bridge_mdb_port_down.sh \ 7 8 bridge_mld.sh \
+1164
tools/testing/selftests/net/forwarding/bridge_mdb.sh
··· 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 + 27 + ALL_TESTS=" 28 + cfg_test 29 + fwd_test 30 + ctrl_test 31 + " 32 + 33 + NUM_NETIFS=4 34 + source lib.sh 35 + source tc_common.sh 36 + 37 + h1_create() 38 + { 39 + simple_if_init $h1 40 + vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64 41 + vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64 42 + } 43 + 44 + h1_destroy() 45 + { 46 + vlan_destroy $h1 20 47 + vlan_destroy $h1 10 48 + simple_if_fini $h1 49 + } 50 + 51 + h2_create() 52 + { 53 + simple_if_init $h2 54 + vlan_create $h2 10 v$h2 192.0.2.2/28 55 + vlan_create $h2 20 v$h2 198.51.100.2/24 56 + } 57 + 58 + h2_destroy() 59 + { 60 + vlan_destroy $h2 20 61 + vlan_destroy $h2 10 62 + simple_if_fini $h2 63 + } 64 + 65 + switch_create() 66 + { 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 72 + 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 77 + 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 82 + 83 + tc qdisc add dev br0 clsact 84 + tc qdisc add dev $h2 clsact 85 + } 86 + 87 + switch_destroy() 88 + { 89 + tc qdisc del dev $h2 clsact 90 + tc qdisc del dev br0 clsact 91 + 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 96 + 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 101 + 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 105 + ip link del dev br0 106 + } 107 + 108 + setup_prepare() 109 + { 110 + h1=${NETIFS[p1]} 111 + swp1=${NETIFS[p2]} 112 + 113 + swp2=${NETIFS[p3]} 114 + h2=${NETIFS[p4]} 115 + 116 + vrf_prepare 117 + forwarding_enable 118 + 119 + h1_create 120 + h2_create 121 + switch_create 122 + } 123 + 124 + cleanup() 125 + { 126 + pre_cleanup 127 + 128 + switch_destroy 129 + h2_destroy 130 + h1_destroy 131 + 132 + forwarding_restore 133 + vrf_cleanup 134 + } 135 + 136 + cfg_test_host_common() 137 + { 138 + local name=$1; shift 139 + local grp=$1; shift 140 + local src=$1; shift 141 + local state=$1; shift 142 + local invalid_state=$1; shift 143 + 144 + RET=0 145 + 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" 150 + 151 + bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null 152 + check_fail $? "Managed to replace $name host entry" 153 + 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" 157 + 158 + # Check error cases. 159 + bridge mdb add dev br0 port br0 grp $grp $invalid_state vid 10 \ 160 + &> /dev/null 161 + check_fail $? "Managed to add $name host entry with a $invalid_state state" 162 + 163 + bridge mdb add dev br0 port br0 grp $grp src $src $state vid 10 \ 164 + &> /dev/null 165 + check_fail $? "Managed to add $name host entry with a source" 166 + 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" 170 + 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" 174 + 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" 178 + 179 + log_test "Common host entries configuration tests ($name)" 180 + } 181 + 182 + # Check configuration of host entries from all types. 183 + cfg_test_host() 184 + { 185 + echo 186 + log_info "# Host entries configuration tests" 187 + 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" \ 191 + "permanent" "temp" 192 + } 193 + 194 + cfg_test_port_common() 195 + { 196 + local name=$1;shift 197 + local grp_key=$1; shift 198 + 199 + RET=0 200 + 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" 205 + 206 + bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \ 207 + &> /dev/null 208 + check_err $? "Failed to replace $name entry" 209 + 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" 213 + 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" 218 + 219 + bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \ 220 + proto 123 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 224 + 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" 231 + 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" 237 + 238 + # Check behavior when bridge port is down. 239 + ip link set dev $swp1 down 240 + 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" 243 + 244 + bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10 245 + 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" 248 + 249 + ip link set dev $swp1 up 250 + setup_wait_dev $swp1 251 + 252 + # Check error cases. 253 + ip link set dev br0 down 254 + bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 \ 255 + &> /dev/null 256 + check_fail $? "Managed to add $name entry when bridge is down" 257 + ip link set dev br0 up 258 + 259 + ip link set dev br0 type bridge mcast_snooping 0 260 + bridge mdb add dev br0 port $swp1 $grp_key permanent vid \ 261 + 10 &> /dev/null 262 + check_fail $? "Managed to add $name entry when multicast snooping is disabled" 263 + ip link set dev br0 type bridge mcast_snooping 1 264 + 265 + bridge mdb add dev br0 port $swp1 $grp_key permanent vid 5000 \ 266 + &> /dev/null 267 + check_fail $? "Managed to add $name entry with an invalid VLAN" 268 + 269 + log_test "Common port group entries configuration tests ($name)" 270 + } 271 + 272 + src_list_create() 273 + { 274 + local src_prefix=$1; shift 275 + local num_srcs=$1; shift 276 + local src_list 277 + local i 278 + 279 + for i in $(seq 1 $num_srcs); do 280 + src_list=${src_list},${src_prefix}${i} 281 + done 282 + 283 + echo $src_list | cut -c 2- 284 + } 285 + 286 + __cfg_test_port_ip_star_g() 287 + { 288 + local name=$1; shift 289 + local grp=$1; shift 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 295 + local max_srcs=31 296 + local num_srcs 297 + 298 + RET=0 299 + 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 304 + 305 + # Check basic add and delete behavior. 306 + bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \ 307 + source_list $src1 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" 317 + 318 + ## State (permanent / temp) tests. 319 + 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 323 + 324 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 325 + grep -q "permanent" 326 + check_err $? "(*, G) entry not added as \"permanent\" when should" 327 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 328 + grep -q "permanent" 329 + check_err $? "(S, G) entry not added as \"permanent\" when should" 330 + 331 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 332 + grep -q " 0.00" 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" | \ 335 + grep -q "\/0.00" 336 + check_err $? "\"permanent\" source entry has a pending source timer" 337 + 338 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 339 + 340 + # Check that group timer is set for temporary (*, G) EXCLUDE, but not 341 + # the source timer. 342 + bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \ 343 + filter_mode exclude source_list $src1 344 + 345 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 346 + grep -q "temp" 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" | \ 349 + grep -q "temp" 350 + check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should" 351 + 352 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 353 + grep -q " 0.00" 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" | \ 356 + grep -q "\/0.00" 357 + check_err $? "\"blocked\" source entry has a pending source timer" 358 + 359 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 360 + 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 365 + 366 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 367 + grep -q "temp" 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" | \ 370 + grep -q "temp" 371 + check_err $? "(S, G) entry not added as \"temp\" when should" 372 + 373 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 374 + grep -q " 0.00" 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" | \ 377 + grep -q "\/0.00" 378 + check_fail $? "Source entry does not have a pending source timer" 379 + 380 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 381 + 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 385 + 386 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 387 + grep -q " 0.00" 388 + check_err $? "(S, G) entry has a pending group timer" 389 + 390 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 391 + 392 + ## Filter mode (include / exclude) tests. 393 + 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 398 + 399 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 400 + grep -q "include" 401 + check_err $? "(*, G) INCLUDE not added with \"include\" filter mode" 402 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 403 + grep -q "blocked" 404 + check_fail $? "(S, G) entry marked as \"blocked\" when should not" 405 + 406 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 407 + 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 412 + 413 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 414 + grep -q "exclude" 415 + check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode" 416 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 417 + grep -q "blocked" 418 + check_err $? "(S, G) entry not marked as \"blocked\" when should" 419 + 420 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 421 + 422 + ## Protocol tests. 423 + 424 + # Check that (*, G) and (S, G) entries are added with the specified 425 + # protocol. 426 + bridge mdb add dev br0 port $swp1 grp $grp vid 10 \ 427 + filter_mode exclude source_list $src1 proto zebra 428 + 429 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep -v "src" | \ 430 + grep -q "zebra" 431 + check_err $? "(*, G) entry not added with \"zebra\" protocol" 432 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 433 + grep -q "zebra" 434 + check_err $? "(S, G) entry not marked added with \"zebra\" protocol" 435 + 436 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 437 + 438 + ## Replace tests. 439 + 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 443 + 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" | \ 447 + grep -q "permanent" 448 + check_err $? "(*, G) entry not marked as \"permanent\" after replace" 449 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 450 + grep -q "permanent" 451 + check_err $? "(S, G) entry not marked as \"permanent\" after replace" 452 + 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" | \ 456 + grep -q "temp" 457 + check_err $? "(*, G) entry not marked as \"temp\" after replace" 458 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 459 + grep -q "temp" 460 + check_err $? "(S, G) entry not marked as \"temp\" after replace" 461 + 462 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 463 + 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 467 + 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" | \ 471 + grep -q "include" 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" | \ 474 + grep -q "blocked" 475 + check_fail $? "(S, G) marked as \"blocked\" after replace" 476 + 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" | \ 480 + grep -q "exclude" 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" | \ 483 + grep -q "blocked" 484 + check_err $? "(S, G) not marked as \"blocked\" after replace" 485 + 486 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 487 + 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 491 + 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" 500 + 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" 509 + 510 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 511 + 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 515 + 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" | \ 519 + grep -q "bgp" 520 + check_err $? "(*, G) protocol not changed to \"bgp\" after replace" 521 + bridge -d mdb show dev br0 vid 10 | grep "$grp" | grep "src" | \ 522 + grep -q "bgp" 523 + check_err $? "(S, G) protocol not changed to \"bgp\" after replace" 524 + 525 + bridge mdb del dev br0 port $swp1 grp $grp vid 10 526 + 527 + ## Star exclude tests. 528 + 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 531 + # replication. 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 540 + 541 + ## Error cases tests. 542 + 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" 545 + 546 + bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \ 547 + &> /dev/null 548 + check_fail $? "Managed to add an INCLUDE entry with an empty source list" 549 + 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" 553 + 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" 557 + 558 + bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \ 559 + source_list $src1 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 564 + 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 570 + 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" | \ 575 + grep "src" | wc -l) 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 579 + 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))) \ 582 + &> /dev/null 583 + check_fail $? "Managed to exceed maximum number of sources ($max_srcs)" 584 + 585 + log_test "$name (*, G) port group entries configuration tests" 586 + } 587 + 588 + cfg_test_port_ip_star_g() 589 + { 590 + echo 591 + log_info "# Port group entries configuration tests - (*, G)" 592 + 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::" 597 + } 598 + 599 + __cfg_test_port_ip_sg() 600 + { 601 + local name=$1; shift 602 + local grp=$1; shift 603 + local src=$1; shift 604 + local grp_key="grp $grp src $src" 605 + 606 + RET=0 607 + 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 612 + 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" | \ 617 + grep -q "permanent" 618 + check_err $? "Entry not added as \"permanent\" when should" 619 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \ 620 + grep -q "0.00" 621 + check_err $? "\"permanent\" entry has a pending group timer" 622 + bridge mdb del dev br0 port $swp1 $grp_key vid 10 623 + 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" | \ 626 + grep -q "temp" 627 + check_err $? "Entry not added as \"temp\" when should" 628 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \ 629 + grep -q "0.00" 630 + check_fail $? "\"temp\" entry has an unpending group timer" 631 + bridge mdb del dev br0 port $swp1 $grp_key vid 10 632 + 633 + # Check error cases. 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" 637 + 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" 641 + 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" 644 + 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 649 + 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" | \ 654 + grep -q "111" 655 + check_err $? "Failed to replace protocol" 656 + 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" | \ 659 + grep -q "permanent" 660 + check_err $? "Entry not marked as \"permanent\" after replace" 661 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \ 662 + grep -q "0.00" 663 + check_err $? "Entry has a pending group timer after replace" 664 + 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" | \ 667 + grep -q "temp" 668 + check_err $? "Entry not marked as \"temp\" after replace" 669 + bridge -d -s mdb show dev br0 vid 10 | grep "$grp_key" | \ 670 + grep -q "0.00" 671 + check_fail $? "Entry has an unpending group timer after replace" 672 + bridge mdb del dev br0 port $swp1 $grp_key vid 10 673 + 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 683 + 684 + log_test "$name (S, G) port group entries configuration tests" 685 + } 686 + 687 + cfg_test_port_ip_sg() 688 + { 689 + echo 690 + log_info "# Port group entries configuration tests - (S, G)" 691 + 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" 696 + } 697 + 698 + cfg_test_port_ip() 699 + { 700 + cfg_test_port_ip_star_g 701 + cfg_test_port_ip_sg 702 + } 703 + 704 + __cfg_test_port_l2() 705 + { 706 + local grp="01:02:03:04:05:06" 707 + 708 + RET=0 709 + 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" 713 + 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" 717 + 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" 721 + 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" 725 + 726 + log_test "L2 (*, G) port group entries configuration tests" 727 + } 728 + 729 + cfg_test_port_l2() 730 + { 731 + echo 732 + log_info "# Port group entries configuration tests - L2" 733 + 734 + cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06" 735 + __cfg_test_port_l2 736 + } 737 + 738 + # Check configuration of regular (port) entries of all types. 739 + cfg_test_port() 740 + { 741 + cfg_test_port_ip 742 + cfg_test_port_l2 743 + } 744 + 745 + cfg_test() 746 + { 747 + cfg_test_host 748 + cfg_test_port 749 + } 750 + 751 + __fwd_test_host_ip() 752 + { 753 + local grp=$1; shift 754 + local src=$1; shift 755 + local mode=$1; shift 756 + local name 757 + local eth_type 758 + 759 + RET=0 760 + 761 + if [[ $mode == "-4" ]]; then 762 + name="IPv4" 763 + eth_type="ipv4" 764 + else 765 + name="IPv6" 766 + eth_type="ipv6" 767 + fi 768 + 769 + tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \ 770 + vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \ 771 + action drop 772 + 773 + # Packet should only be flooded to multicast router ports when there is 774 + # no matching MDB entry. The bridge is not configured as a multicast 775 + # router port. 776 + $MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q 777 + tc_check_packets "dev br0 ingress" 1 0 778 + check_err $? "Packet locally received after flood" 779 + 780 + # Install a regular port group entry and expect the packet to not be 781 + # locally received. 782 + bridge mdb add dev br0 port $swp2 grp $grp temp vid 10 783 + $MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q 784 + tc_check_packets "dev br0 ingress" 1 0 785 + check_err $? "Packet locally received after installing a regular entry" 786 + 787 + # Add a host entry and expect the packet to be locally received. 788 + bridge mdb add dev br0 port br0 grp $grp temp vid 10 789 + $MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q 790 + tc_check_packets "dev br0 ingress" 1 1 791 + check_err $? "Packet not locally received after adding a host entry" 792 + 793 + # Remove the host entry and expect the packet to not be locally 794 + # received. 795 + bridge mdb del dev br0 port br0 grp $grp vid 10 796 + $MZ $mode $h1.10 -c 1 -p 128 -A $src -B $grp -t udp -q 797 + tc_check_packets "dev br0 ingress" 1 1 798 + check_err $? "Packet locally received after removing a host entry" 799 + 800 + bridge mdb del dev br0 port $swp2 grp $grp vid 10 801 + 802 + tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower 803 + 804 + log_test "$name host entries forwarding tests" 805 + } 806 + 807 + fwd_test_host_ip() 808 + { 809 + __fwd_test_host_ip "239.1.1.1" "192.0.2.1" "-4" 810 + __fwd_test_host_ip "ff0e::1" "2001:db8:1::1" "-6" 811 + } 812 + 813 + fwd_test_host_l2() 814 + { 815 + local dmac=01:02:03:04:05:06 816 + 817 + RET=0 818 + 819 + tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \ 820 + dst_mac $dmac action drop 821 + 822 + # Packet should be flooded and locally received when there is no 823 + # matching MDB entry. 824 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 825 + tc_check_packets "dev br0 ingress" 1 1 826 + check_err $? "Packet not locally received after flood" 827 + 828 + # Install a regular port group entry and expect the packet to not be 829 + # locally received. 830 + bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10 831 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 832 + tc_check_packets "dev br0 ingress" 1 1 833 + check_err $? "Packet locally received after installing a regular entry" 834 + 835 + # Add a host entry and expect the packet to be locally received. 836 + bridge mdb add dev br0 port br0 grp $dmac permanent vid 10 837 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 838 + tc_check_packets "dev br0 ingress" 1 2 839 + check_err $? "Packet not locally received after adding a host entry" 840 + 841 + # Remove the host entry and expect the packet to not be locally 842 + # received. 843 + bridge mdb del dev br0 port br0 grp $dmac permanent vid 10 844 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 845 + tc_check_packets "dev br0 ingress" 1 2 846 + check_err $? "Packet locally received after removing a host entry" 847 + 848 + bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10 849 + 850 + tc filter del dev br0 ingress protocol all pref 1 handle 1 flower 851 + 852 + log_test "L2 host entries forwarding tests" 853 + } 854 + 855 + fwd_test_host() 856 + { 857 + # Disable multicast router on the bridge to ensure that packets are 858 + # only locally received when a matching host entry is present. 859 + ip link set dev br0 type bridge mcast_router 0 860 + 861 + fwd_test_host_ip 862 + fwd_test_host_l2 863 + 864 + ip link set dev br0 type bridge mcast_router 1 865 + } 866 + 867 + __fwd_test_port_ip() 868 + { 869 + local grp=$1; shift 870 + local valid_src=$1; shift 871 + local invalid_src=$1; shift 872 + local mode=$1; shift 873 + local filter_mode=$1; shift 874 + local name 875 + local eth_type 876 + local src_list 877 + 878 + RET=0 879 + 880 + if [[ $mode == "-4" ]]; then 881 + name="IPv4" 882 + eth_type="ipv4" 883 + else 884 + name="IPv6" 885 + eth_type="ipv6" 886 + fi 887 + 888 + # The valid source is the one we expect to get packets from after 889 + # adding the entry. 890 + if [[ $filter_mode == "include" ]]; then 891 + src_list=$valid_src 892 + else 893 + src_list=$invalid_src 894 + fi 895 + 896 + tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \ 897 + vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \ 898 + src_ip $valid_src action drop 899 + tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \ 900 + vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \ 901 + src_ip $invalid_src action drop 902 + 903 + $MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q 904 + tc_check_packets "dev $h2 ingress" 1 0 905 + check_err $? "Packet from valid source received on H2 before adding entry" 906 + 907 + $MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 908 + tc_check_packets "dev $h2 ingress" 2 0 909 + check_err $? "Packet from invalid source received on H2 before adding entry" 910 + 911 + bridge mdb add dev br0 port $swp2 grp $grp vid 10 \ 912 + filter_mode $filter_mode source_list $src_list 913 + 914 + $MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q 915 + tc_check_packets "dev $h2 ingress" 1 1 916 + check_err $? "Packet from valid source not received on H2 after adding entry" 917 + 918 + $MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 919 + tc_check_packets "dev $h2 ingress" 2 0 920 + check_err $? "Packet from invalid source received on H2 after adding entry" 921 + 922 + bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \ 923 + filter_mode exclude 924 + 925 + $MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q 926 + tc_check_packets "dev $h2 ingress" 1 2 927 + check_err $? "Packet from valid source not received on H2 after allowing all sources" 928 + 929 + $MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 930 + tc_check_packets "dev $h2 ingress" 2 1 931 + check_err $? "Packet from invalid source not received on H2 after allowing all sources" 932 + 933 + bridge mdb del dev br0 port $swp2 grp $grp vid 10 934 + 935 + $MZ $mode $h1.10 -c 1 -p 128 -A $valid_src -B $grp -t udp -q 936 + tc_check_packets "dev $h2 ingress" 1 2 937 + check_err $? "Packet from valid source received on H2 after deleting entry" 938 + 939 + $MZ $mode $h1.10 -c 1 -p 128 -A $invalid_src -B $grp -t udp -q 940 + tc_check_packets "dev $h2 ingress" 2 1 941 + check_err $? "Packet from invalid source received on H2 after deleting entry" 942 + 943 + tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower 944 + tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower 945 + 946 + log_test "$name port group \"$filter_mode\" entries forwarding tests" 947 + } 948 + 949 + fwd_test_port_ip() 950 + { 951 + __fwd_test_port_ip "239.1.1.1" "192.0.2.1" "192.0.2.2" "-4" "exclude" 952 + __fwd_test_port_ip "ff0e::1" "2001:db8:1::1" "2001:db8:1::2" "-6" \ 953 + "exclude" 954 + __fwd_test_port_ip "239.1.1.1" "192.0.2.1" "192.0.2.2" "-4" "include" 955 + __fwd_test_port_ip "ff0e::1" "2001:db8:1::1" "2001:db8:1::2" "-6" \ 956 + "include" 957 + } 958 + 959 + fwd_test_port_l2() 960 + { 961 + local dmac=01:02:03:04:05:06 962 + 963 + RET=0 964 + 965 + tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \ 966 + dst_mac $dmac action drop 967 + 968 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 969 + tc_check_packets "dev $h2 ingress" 1 0 970 + check_err $? "Packet received on H2 before adding entry" 971 + 972 + bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10 973 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 974 + tc_check_packets "dev $h2 ingress" 1 1 975 + check_err $? "Packet not received on H2 after adding entry" 976 + 977 + bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10 978 + $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q 979 + tc_check_packets "dev $h2 ingress" 1 1 980 + check_err $? "Packet received on H2 after deleting entry" 981 + 982 + tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower 983 + 984 + log_test "L2 port entries forwarding tests" 985 + } 986 + 987 + fwd_test_port() 988 + { 989 + # Disable multicast flooding to ensure that packets are only forwarded 990 + # out of a port when a matching port group entry is present. 991 + bridge link set dev $swp2 mcast_flood off 992 + 993 + fwd_test_port_ip 994 + fwd_test_port_l2 995 + 996 + bridge link set dev $swp2 mcast_flood on 997 + } 998 + 999 + fwd_test() 1000 + { 1001 + echo 1002 + log_info "# Forwarding tests" 1003 + 1004 + # Forwarding according to MDB entries only takes place when the bridge 1005 + # detects that there is a valid querier in the network. Set the bridge 1006 + # as the querier and assign it a valid IPv6 link-local address to be 1007 + # used as the source address for MLD queries. 1008 + ip -6 address add fe80::1/64 nodad dev br0 1009 + ip link set dev br0 type bridge mcast_querier 1 1010 + # Wait the default Query Response Interval (10 seconds) for the bridge 1011 + # to determine that there are no other queriers in the network. 1012 + sleep 10 1013 + 1014 + fwd_test_host 1015 + fwd_test_port 1016 + 1017 + ip link set dev br0 type bridge mcast_querier 0 1018 + ip -6 address del fe80::1/64 dev br0 1019 + } 1020 + 1021 + igmpv3_is_in_get() 1022 + { 1023 + local igmpv3 1024 + 1025 + igmpv3=$(: 1026 + )"22:"$( : Type - Membership Report 1027 + )"00:"$( : Reserved 1028 + )"2a:f8:"$( : Checksum 1029 + )"00:00:"$( : Reserved 1030 + )"00:01:"$( : Number of Group Records 1031 + )"01:"$( : Record Type - IS_IN 1032 + )"00:"$( : Aux Data Len 1033 + )"00:01:"$( : Number of Sources 1034 + )"ef:01:01:01:"$( : Multicast Address - 239.1.1.1 1035 + )"c0:00:02:02"$( : Source Address - 192.0.2.2 1036 + ) 1037 + 1038 + echo $igmpv3 1039 + } 1040 + 1041 + ctrl_igmpv3_is_in_test() 1042 + { 1043 + RET=0 1044 + 1045 + # Add a permanent entry and check that it is not affected by the 1046 + # received IGMP packet. 1047 + bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \ 1048 + filter_mode include source_list 192.0.2.1 1049 + 1050 + # IS_IN ( 192.0.2.2 ) 1051 + $MZ $h1.10 -c 1 -A 192.0.2.1 -B 239.1.1.1 \ 1052 + -t ip proto=2,p=$(igmpv3_is_in_get) -q 1053 + 1054 + bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -q 192.0.2.2 1055 + check_fail $? "Permanent entry affected by IGMP packet" 1056 + 1057 + # Replace the permanent entry with a temporary one and check that after 1058 + # processing the IGMP packet, a new source is added to the list along 1059 + # with a new forwarding entry. 1060 + bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \ 1061 + filter_mode include source_list 192.0.2.1 1062 + 1063 + # IS_IN ( 192.0.2.2 ) 1064 + $MZ $h1.10 -c 1 -A 192.0.2.1 -B 239.1.1.1 \ 1065 + -t ip proto=2,p=$(igmpv3_is_in_get) -q 1066 + 1067 + bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | grep -v "src" | \ 1068 + grep -q 192.0.2.2 1069 + check_err $? "Source not add to source list" 1070 + 1071 + bridge -d mdb show dev br0 vid 10 | grep 239.1.1.1 | \ 1072 + grep -q "src 192.0.2.2" 1073 + check_err $? "(S, G) entry not created for new source" 1074 + 1075 + bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10 1076 + 1077 + log_test "IGMPv3 MODE_IS_INCLUE tests" 1078 + } 1079 + 1080 + mldv2_is_in_get() 1081 + { 1082 + local hbh 1083 + local icmpv6 1084 + 1085 + hbh=$(: 1086 + )"3a:"$( : Next Header - ICMPv6 1087 + )"00:"$( : Hdr Ext Len 1088 + )"00:00:00:00:00:00:"$( : Options and Padding 1089 + ) 1090 + 1091 + icmpv6=$(: 1092 + )"8f:"$( : Type - MLDv2 Report 1093 + )"00:"$( : Code 1094 + )"45:39:"$( : Checksum 1095 + )"00:00:"$( : Reserved 1096 + )"00:01:"$( : Number of Group Records 1097 + )"01:"$( : Record Type - IS_IN 1098 + )"00:"$( : Aux Data Len 1099 + )"00:01:"$( : Number of Sources 1100 + )"ff:0e:00:00:00:00:00:00:"$( : Multicast address - ff0e::1 1101 + )"00:00:00:00:00:00:00:01:"$( : 1102 + )"20:01:0d:b8:00:01:00:00:"$( : Source Address - 2001:db8:1::2 1103 + )"00:00:00:00:00:00:00:02:"$( : 1104 + ) 1105 + 1106 + echo ${hbh}${icmpv6} 1107 + } 1108 + 1109 + ctrl_mldv2_is_in_test() 1110 + { 1111 + RET=0 1112 + 1113 + # Add a permanent entry and check that it is not affected by the 1114 + # received MLD packet. 1115 + bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \ 1116 + filter_mode include source_list 2001:db8:1::1 1117 + 1118 + # IS_IN ( 2001:db8:1::2 ) 1119 + $MZ -6 $h1.10 -c 1 -A fe80::1 -B ff0e::1 \ 1120 + -t ip hop=1,next=0,p=$(mldv2_is_in_get) -q 1121 + 1122 + bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \ 1123 + grep -q 2001:db8:1::2 1124 + check_fail $? "Permanent entry affected by MLD packet" 1125 + 1126 + # Replace the permanent entry with a temporary one and check that after 1127 + # processing the MLD packet, a new source is added to the list along 1128 + # with a new forwarding entry. 1129 + bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \ 1130 + filter_mode include source_list 2001:db8:1::1 1131 + 1132 + # IS_IN ( 2001:db8:1::2 ) 1133 + $MZ -6 $h1.10 -c 1 -A fe80::1 -B ff0e::1 \ 1134 + -t ip hop=1,next=0,p=$(mldv2_is_in_get) -q 1135 + 1136 + bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | grep -v "src" | \ 1137 + grep -q 2001:db8:1::2 1138 + check_err $? "Source not add to source list" 1139 + 1140 + bridge -d mdb show dev br0 vid 10 | grep ff0e::1 | \ 1141 + grep -q "src 2001:db8:1::2" 1142 + check_err $? "(S, G) entry not created for new source" 1143 + 1144 + bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10 1145 + 1146 + log_test "MLDv2 MODE_IS_INCLUDE tests" 1147 + } 1148 + 1149 + ctrl_test() 1150 + { 1151 + echo 1152 + log_info "# Control packets tests" 1153 + 1154 + ctrl_igmpv3_is_in_test 1155 + ctrl_mldv2_is_in_test 1156 + } 1157 + 1158 + trap cleanup EXIT 1159 + 1160 + setup_prepare 1161 + setup_wait 1162 + tests_run 1163 + 1164 + exit $EXIT_STATUS