547 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4ALL_TESTS="vlmc_control_test vlmc_querier_test vlmc_igmp_mld_version_test \5 vlmc_last_member_test vlmc_startup_query_test vlmc_membership_test \6 vlmc_querier_intvl_test vlmc_query_intvl_test vlmc_query_response_intvl_test \7 vlmc_router_port_test vlmc_filtering_test"8NUM_NETIFS=49CHECK_TC="yes"10TEST_GROUP="239.10.10.10"11 12source lib.sh13 14h1_create()15{16 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/6417 ip link add l $h1 $h1.10 up type vlan id 1018}19 20h1_destroy()21{22 ip link del $h1.1023 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/6424}25 26h2_create()27{28 simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/6429 ip link add l $h2 $h2.10 up type vlan id 1030}31 32h2_destroy()33{34 ip link del $h2.1035 simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/6436}37 38switch_create()39{40 ip link add dev br0 type bridge mcast_snooping 1 mcast_querier 1 vlan_filtering 141 42 ip link set dev $swp1 master br043 ip link set dev $swp2 master br044 45 ip link set dev br0 up46 ip link set dev $swp1 up47 ip link set dev $swp2 up48 49 tc qdisc add dev $swp1 clsact50 tc qdisc add dev $swp2 clsact51 52 bridge vlan add vid 10-11 dev $swp1 master53 bridge vlan add vid 10-11 dev $swp2 master54 55 ip link set dev br0 type bridge mcast_vlan_snooping 156 check_err $? "Could not enable global vlan multicast snooping"57 log_test "Vlan multicast snooping enable"58}59 60switch_destroy()61{62 tc qdisc del dev $swp2 clsact63 tc qdisc del dev $swp1 clsact64 65 ip link set dev $swp2 down66 ip link set dev $swp1 down67 68 ip link del dev br069}70 71setup_prepare()72{73 h1=${NETIFS[p1]}74 swp1=${NETIFS[p2]}75 76 swp2=${NETIFS[p3]}77 h2=${NETIFS[p4]}78 79 vrf_prepare80 81 h1_create82 h2_create83 84 switch_create85}86 87cleanup()88{89 pre_cleanup90 91 switch_destroy92 93 h2_destroy94 h1_destroy95 96 vrf_cleanup97}98 99vlmc_v2join_test()100{101 local expect=$1102 103 RET=0104 ip address add dev $h2.10 $TEST_GROUP/32 autojoin105 check_err $? "Could not join $TEST_GROUP"106 107 sleep 5108 bridge -j mdb show dev br0 |109 jq -e ".[].mdb[] | select(.grp == \"$TEST_GROUP\" and .vid == 10)" &>/dev/null110 if [ $expect -eq 0 ]; then111 check_err $? "IGMPv2 report didn't create mdb entry for $TEST_GROUP"112 else113 check_fail $? "IGMPv2 report shouldn't have created mdb entry for $TEST_GROUP"114 fi115 116 # check if we need to cleanup117 if [ $RET -eq 0 ]; then118 ip address del dev $h2.10 $TEST_GROUP/32 2>&1 1>/dev/null119 sleep 5120 bridge -j mdb show dev br0 |121 jq -e ".[].mdb[] | select(.grp == \"$TEST_GROUP\" and \122 .vid == 10)" &>/dev/null123 check_fail $? "IGMPv2 leave didn't remove mdb entry for $TEST_GROUP"124 fi125}126 127vlmc_control_test()128{129 RET=0130 local goutput=`bridge -j vlan global show`131 echo -n $goutput |132 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null133 check_err $? "Could not find vlan 10's global options"134 log_test "Vlan global options existence"135 136 RET=0137 echo -n $goutput |138 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_snooping == 1) " &>/dev/null139 check_err $? "Wrong default mcast_snooping global option value"140 log_test "Vlan mcast_snooping global option default value"141 142 RET=0143 vlmc_v2join_test 0144 bridge vlan global set vid 10 dev br0 mcast_snooping 0145 check_err $? "Could not disable multicast snooping in vlan 10"146 vlmc_v2join_test 1147 log_test "Vlan 10 multicast snooping control"148}149 150# setup for general query counting151vlmc_query_cnt_xstats()152{153 local type=$1154 local version=$2155 local dev=$3156 157 ip -j link xstats type bridge_slave dev $dev | \158 jq -e ".[].multicast.${type}_queries.tx_v${version}"159}160 161vlmc_query_cnt_setup()162{163 local type=$1164 local dev=$2165 166 if [[ $type == "igmp" ]]; then167 tc filter add dev $dev egress pref 10 prot 802.1Q \168 flower vlan_id 10 vlan_ethtype ipv4 dst_ip 224.0.0.1 ip_proto 2 \169 action pass170 else171 tc filter add dev $dev egress pref 10 prot 802.1Q \172 flower vlan_id 10 vlan_ethtype ipv6 dst_ip ff02::1 ip_proto icmpv6 \173 action pass174 fi175 176 ip link set dev br0 type bridge mcast_stats_enabled 1177}178 179vlmc_query_cnt_cleanup()180{181 local dev=$1182 183 ip link set dev br0 type bridge mcast_stats_enabled 0184 tc filter del dev $dev egress pref 10185}186 187vlmc_check_query()188{189 local type=$1190 local version=$2191 local dev=$3192 local expect=$4193 local time=$5194 local ret=0195 196 vlmc_query_cnt_setup $type $dev197 198 local pre_tx_xstats=$(vlmc_query_cnt_xstats $type $version $dev)199 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1200 ret=$?201 if [[ $ret -eq 0 ]]; then202 sleep $time203 204 local tcstats=$(tc_rule_stats_get $dev 10 egress)205 local post_tx_xstats=$(vlmc_query_cnt_xstats $type $version $dev)206 207 if [[ $tcstats != $expect || \208 $(($post_tx_xstats-$pre_tx_xstats)) != $expect || \209 $tcstats != $(($post_tx_xstats-$pre_tx_xstats)) ]]; then210 ret=1211 fi212 fi213 214 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 0215 vlmc_query_cnt_cleanup $dev216 217 return $ret218}219 220vlmc_querier_test()221{222 RET=0223 local goutput=`bridge -j vlan global show`224 echo -n $goutput |225 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null226 check_err $? "Could not find vlan 10's global options"227 228 echo -n $goutput |229 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_querier == 0) " &>/dev/null230 check_err $? "Wrong default mcast_querier global vlan option value"231 log_test "Vlan mcast_querier global option default value"232 233 RET=0234 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1235 check_err $? "Could not enable querier in vlan 10"236 log_test "Vlan 10 multicast querier enable"237 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 0238 239 RET=0240 vlmc_check_query igmp 2 $swp1 1 1241 check_err $? "No vlan tagged IGMPv2 general query packets sent"242 log_test "Vlan 10 tagged IGMPv2 general query sent"243 244 RET=0245 vlmc_check_query mld 1 $swp1 1 1246 check_err $? "No vlan tagged MLD general query packets sent"247 log_test "Vlan 10 tagged MLD general query sent"248}249 250vlmc_igmp_mld_version_test()251{252 RET=0253 local goutput=`bridge -j vlan global show`254 echo -n $goutput |255 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null256 check_err $? "Could not find vlan 10's global options"257 258 echo -n $goutput |259 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_igmp_version == 2) " &>/dev/null260 check_err $? "Wrong default mcast_igmp_version global vlan option value"261 log_test "Vlan mcast_igmp_version global option default value"262 263 RET=0264 echo -n $goutput |265 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_mld_version == 1) " &>/dev/null266 check_err $? "Wrong default mcast_mld_version global vlan option value"267 log_test "Vlan mcast_mld_version global option default value"268 269 RET=0270 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version 3271 check_err $? "Could not set mcast_igmp_version in vlan 10"272 log_test "Vlan 10 mcast_igmp_version option changed to 3"273 274 RET=0275 vlmc_check_query igmp 3 $swp1 1 1276 check_err $? "No vlan tagged IGMPv3 general query packets sent"277 log_test "Vlan 10 tagged IGMPv3 general query sent"278 279 RET=0280 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 2281 check_err $? "Could not set mcast_mld_version in vlan 10"282 log_test "Vlan 10 mcast_mld_version option changed to 2"283 284 RET=0285 vlmc_check_query mld 2 $swp1 1 1286 check_err $? "No vlan tagged MLDv2 general query packets sent"287 log_test "Vlan 10 tagged MLDv2 general query sent"288 289 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version 2290 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 1291}292 293vlmc_last_member_test()294{295 RET=0296 local goutput=`bridge -j vlan global show`297 echo -n $goutput |298 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null299 check_err $? "Could not find vlan 10's global options"300 301 echo -n $goutput |302 jq -e ".[].vlans[] | select(.vlan == 10 and \303 .mcast_last_member_count == 2) " &>/dev/null304 check_err $? "Wrong default mcast_last_member_count global vlan option value"305 log_test "Vlan mcast_last_member_count global option default value"306 307 RET=0308 echo -n $goutput |309 jq -e ".[].vlans[] | select(.vlan == 10 and \310 .mcast_last_member_interval == 100) " &>/dev/null311 check_err $? "Wrong default mcast_last_member_interval global vlan option value"312 log_test "Vlan mcast_last_member_interval global option default value"313 314 RET=0315 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_count 3316 check_err $? "Could not set mcast_last_member_count in vlan 10"317 log_test "Vlan 10 mcast_last_member_count option changed to 3"318 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_count 2319 320 RET=0321 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_interval 200322 check_err $? "Could not set mcast_last_member_interval in vlan 10"323 log_test "Vlan 10 mcast_last_member_interval option changed to 200"324 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_interval 100325}326 327vlmc_startup_query_test()328{329 RET=0330 local goutput=`bridge -j vlan global show`331 echo -n $goutput |332 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null333 check_err $? "Could not find vlan 10's global options"334 335 echo -n $goutput |336 jq -e ".[].vlans[] | select(.vlan == 10 and \337 .mcast_startup_query_interval == 3125) " &>/dev/null338 check_err $? "Wrong default mcast_startup_query_interval global vlan option value"339 log_test "Vlan mcast_startup_query_interval global option default value"340 341 RET=0342 echo -n $goutput |343 jq -e ".[].vlans[] | select(.vlan == 10 and \344 .mcast_startup_query_count == 2) " &>/dev/null345 check_err $? "Wrong default mcast_startup_query_count global vlan option value"346 log_test "Vlan mcast_startup_query_count global option default value"347 348 RET=0349 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_interval 100350 check_err $? "Could not set mcast_startup_query_interval in vlan 10"351 vlmc_check_query igmp 2 $swp1 2 3352 check_err $? "Wrong number of tagged IGMPv2 general queries sent"353 log_test "Vlan 10 mcast_startup_query_interval option changed to 100"354 355 RET=0356 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 3357 check_err $? "Could not set mcast_startup_query_count in vlan 10"358 vlmc_check_query igmp 2 $swp1 3 4359 check_err $? "Wrong number of tagged IGMPv2 general queries sent"360 log_test "Vlan 10 mcast_startup_query_count option changed to 3"361 362 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_interval 3125363 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 2364}365 366vlmc_membership_test()367{368 RET=0369 local goutput=`bridge -j vlan global show`370 echo -n $goutput |371 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null372 check_err $? "Could not find vlan 10's global options"373 374 echo -n $goutput |375 jq -e ".[].vlans[] | select(.vlan == 10 and \376 .mcast_membership_interval == 26000) " &>/dev/null377 check_err $? "Wrong default mcast_membership_interval global vlan option value"378 log_test "Vlan mcast_membership_interval global option default value"379 380 RET=0381 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_membership_interval 200382 check_err $? "Could not set mcast_membership_interval in vlan 10"383 log_test "Vlan 10 mcast_membership_interval option changed to 200"384 385 RET=0386 vlmc_v2join_test 1387 log_test "Vlan 10 mcast_membership_interval mdb entry expire"388 389 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_membership_interval 26000390}391 392vlmc_querier_intvl_test()393{394 RET=0395 local goutput=`bridge -j vlan global show`396 echo -n $goutput |397 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null398 check_err $? "Could not find vlan 10's global options"399 400 echo -n $goutput |401 jq -e ".[].vlans[] | select(.vlan == 10 and \402 .mcast_querier_interval == 25500) " &>/dev/null403 check_err $? "Wrong default mcast_querier_interval global vlan option value"404 log_test "Vlan mcast_querier_interval global option default value"405 406 RET=0407 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier_interval 100408 check_err $? "Could not set mcast_querier_interval in vlan 10"409 log_test "Vlan 10 mcast_querier_interval option changed to 100"410 411 RET=0412 ip link add dev br1 type bridge mcast_snooping 1 mcast_querier 1 vlan_filtering 1 \413 mcast_vlan_snooping 1414 bridge vlan add vid 10 dev br1 self pvid untagged415 ip link set dev $h1 master br1416 ip link set dev br1 up417 bridge vlan add vid 10 dev $h1 master418 bridge vlan global set vid 10 dev br1 mcast_snooping 1 mcast_querier 1419 sleep 2420 ip link del dev br1421 ip addr replace 2001:db8:1::1/64 dev $h1422 vlmc_check_query igmp 2 $swp1 1 1423 check_err $? "Wrong number of IGMPv2 general queries after querier interval"424 log_test "Vlan 10 mcast_querier_interval expire after outside query"425 426 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier_interval 25500427}428 429vlmc_query_intvl_test()430{431 RET=0432 local goutput=`bridge -j vlan global show`433 echo -n $goutput |434 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null435 check_err $? "Could not find vlan 10's global options"436 437 echo -n $goutput |438 jq -e ".[].vlans[] | select(.vlan == 10 and \439 .mcast_query_interval == 12500) " &>/dev/null440 check_err $? "Wrong default mcast_query_interval global vlan option value"441 log_test "Vlan mcast_query_interval global option default value"442 443 RET=0444 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 0445 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interval 200446 check_err $? "Could not set mcast_query_interval in vlan 10"447 # 1 is sent immediately, then 2 more in the next 5 seconds448 vlmc_check_query igmp 2 $swp1 3 5449 check_err $? "Wrong number of tagged IGMPv2 general queries sent"450 log_test "Vlan 10 mcast_query_interval option changed to 200"451 452 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 2453 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interval 12500454}455 456vlmc_query_response_intvl_test()457{458 RET=0459 local goutput=`bridge -j vlan global show`460 echo -n $goutput |461 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null462 check_err $? "Could not find vlan 10's global options"463 464 echo -n $goutput |465 jq -e ".[].vlans[] | select(.vlan == 10 and \466 .mcast_query_response_interval == 1000) " &>/dev/null467 check_err $? "Wrong default mcast_query_response_interval global vlan option value"468 log_test "Vlan mcast_query_response_interval global option default value"469 470 RET=0471 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_response_interval 200472 check_err $? "Could not set mcast_query_response_interval in vlan 10"473 log_test "Vlan 10 mcast_query_response_interval option changed to 200"474 475 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_response_interval 1000476}477 478vlmc_router_port_test()479{480 RET=0481 local goutput=`bridge -j -d vlan show`482 echo -n $goutput |483 jq -e ".[] | select(.ifname == \"$swp1\" and \484 .vlans[].vlan == 10)" &>/dev/null485 check_err $? "Could not find port vlan 10's options"486 487 echo -n $goutput |488 jq -e ".[] | select(.ifname == \"$swp1\" and \489 .vlans[].vlan == 10 and \490 .vlans[].mcast_router == 1)" &>/dev/null491 check_err $? "Wrong default port mcast_router option value"492 log_test "Port vlan 10 option mcast_router default value"493 494 RET=0495 bridge vlan set vid 10 dev $swp1 mcast_router 2496 check_err $? "Could not set port vlan 10's mcast_router option"497 log_test "Port vlan 10 mcast_router option changed to 2"498 499 RET=0500 tc filter add dev $swp1 egress pref 10 prot 802.1Q \501 flower vlan_id 10 vlan_ethtype ipv4 dst_ip 239.1.1.1 ip_proto udp action pass502 tc filter add dev $swp2 egress pref 10 prot 802.1Q \503 flower vlan_id 10 vlan_ethtype ipv4 dst_ip 239.1.1.1 ip_proto udp action pass504 bridge vlan set vid 10 dev $swp2 mcast_router 0505 # we need to enable querier and disable query response interval to506 # make sure packets are flooded only to router ports507 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1 \508 mcast_query_response_interval 0509 bridge vlan add vid 10 dev br0 self510 sleep 1511 mausezahn br0 -Q 10 -c 10 -p 128 -b 01:00:5e:01:01:01 -B 239.1.1.1 \512 -t udp "dp=1024" &>/dev/null513 local swp1_tcstats=$(tc_rule_stats_get $swp1 10 egress)514 if [[ $swp1_tcstats != 10 ]]; then515 check_err 1 "Wrong number of vlan 10 multicast packets flooded"516 fi517 local swp2_tcstats=$(tc_rule_stats_get $swp2 10 egress)518 check_err $swp2_tcstats "Vlan 10 multicast packets flooded to non-router port"519 log_test "Flood unknown vlan multicast packets to router port only"520 521 tc filter del dev $swp2 egress pref 10522 tc filter del dev $swp1 egress pref 10523 bridge vlan del vid 10 dev br0 self524 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_response_interval 1000525 bridge vlan set vid 10 dev $swp2 mcast_router 1526 bridge vlan set vid 10 dev $swp1 mcast_router 1527}528 529vlmc_filtering_test()530{531 RET=0532 ip link set dev br0 type bridge vlan_filtering 0533 ip -j -d link show dev br0 | \534 jq -e "select(.[0].linkinfo.info_data.mcast_vlan_snooping == 1)" &>/dev/null535 check_fail $? "Vlan filtering is disabled but multicast vlan snooping is still enabled"536 log_test "Disable multicast vlan snooping when vlan filtering is disabled"537}538 539trap cleanup EXIT540 541setup_prepare542setup_wait543 544tests_run545 546exit $EXIT_STATUS547