0001
0002
0003
0004 ALL_TESTS="vlmc_control_test vlmc_querier_test vlmc_igmp_mld_version_test \
0005 vlmc_last_member_test vlmc_startup_query_test vlmc_membership_test \
0006 vlmc_querier_intvl_test vlmc_query_intvl_test vlmc_query_response_intvl_test \
0007 vlmc_router_port_test vlmc_filtering_test"
0008 NUM_NETIFS=4
0009 CHECK_TC="yes"
0010 TEST_GROUP="239.10.10.10"
0011
0012 source lib.sh
0013
0014 h1_create()
0015 {
0016 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
0017 ip link add l $h1 $h1.10 up type vlan id 10
0018 }
0019
0020 h1_destroy()
0021 {
0022 ip link del $h1.10
0023 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
0024 }
0025
0026 h2_create()
0027 {
0028 simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
0029 ip link add l $h2 $h2.10 up type vlan id 10
0030 }
0031
0032 h2_destroy()
0033 {
0034 ip link del $h2.10
0035 simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
0036 }
0037
0038 switch_create()
0039 {
0040 ip link add dev br0 type bridge mcast_snooping 1 mcast_querier 1 vlan_filtering 1
0041
0042 ip link set dev $swp1 master br0
0043 ip link set dev $swp2 master br0
0044
0045 ip link set dev br0 up
0046 ip link set dev $swp1 up
0047 ip link set dev $swp2 up
0048
0049 tc qdisc add dev $swp1 clsact
0050 tc qdisc add dev $swp2 clsact
0051
0052 bridge vlan add vid 10-11 dev $swp1 master
0053 bridge vlan add vid 10-11 dev $swp2 master
0054
0055 ip link set dev br0 type bridge mcast_vlan_snooping 1
0056 check_err $? "Could not enable global vlan multicast snooping"
0057 log_test "Vlan multicast snooping enable"
0058 }
0059
0060 switch_destroy()
0061 {
0062 ip link set dev $swp2 down
0063 ip link set dev $swp1 down
0064
0065 ip link del dev br0
0066 }
0067
0068 setup_prepare()
0069 {
0070 h1=${NETIFS[p1]}
0071 swp1=${NETIFS[p2]}
0072
0073 swp2=${NETIFS[p3]}
0074 h2=${NETIFS[p4]}
0075
0076 vrf_prepare
0077
0078 h1_create
0079 h2_create
0080
0081 switch_create
0082 }
0083
0084 cleanup()
0085 {
0086 pre_cleanup
0087
0088 switch_destroy
0089
0090 h2_destroy
0091 h1_destroy
0092
0093 vrf_cleanup
0094 }
0095
0096 vlmc_v2join_test()
0097 {
0098 local expect=$1
0099
0100 RET=0
0101 ip address add dev $h2.10 $TEST_GROUP/32 autojoin
0102 check_err $? "Could not join $TEST_GROUP"
0103
0104 sleep 5
0105 bridge -j mdb show dev br0 |
0106 jq -e ".[].mdb[] | select(.grp == \"$TEST_GROUP\" and .vid == 10)" &>/dev/null
0107 if [ $expect -eq 0 ]; then
0108 check_err $? "IGMPv2 report didn't create mdb entry for $TEST_GROUP"
0109 else
0110 check_fail $? "IGMPv2 report shouldn't have created mdb entry for $TEST_GROUP"
0111 fi
0112
0113
0114 if [ $RET -eq 0 ]; then
0115 ip address del dev $h2.10 $TEST_GROUP/32 2>&1 1>/dev/null
0116 sleep 5
0117 bridge -j mdb show dev br0 |
0118 jq -e ".[].mdb[] | select(.grp == \"$TEST_GROUP\" and \
0119 .vid == 10)" &>/dev/null
0120 check_fail $? "IGMPv2 leave didn't remove mdb entry for $TEST_GROUP"
0121 fi
0122 }
0123
0124 vlmc_control_test()
0125 {
0126 RET=0
0127 local goutput=`bridge -j vlan global show`
0128 echo -n $goutput |
0129 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0130 check_err $? "Could not find vlan 10's global options"
0131 log_test "Vlan global options existence"
0132
0133 RET=0
0134 echo -n $goutput |
0135 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_snooping == 1) " &>/dev/null
0136 check_err $? "Wrong default mcast_snooping global option value"
0137 log_test "Vlan mcast_snooping global option default value"
0138
0139 RET=0
0140 vlmc_v2join_test 0
0141 bridge vlan global set vid 10 dev br0 mcast_snooping 0
0142 check_err $? "Could not disable multicast snooping in vlan 10"
0143 vlmc_v2join_test 1
0144 log_test "Vlan 10 multicast snooping control"
0145 }
0146
0147
0148 vlmc_query_cnt_xstats()
0149 {
0150 local type=$1
0151 local version=$2
0152 local dev=$3
0153
0154 ip -j link xstats type bridge_slave dev $dev | \
0155 jq -e ".[].multicast.${type}_queries.tx_v${version}"
0156 }
0157
0158 vlmc_query_cnt_setup()
0159 {
0160 local type=$1
0161 local dev=$2
0162
0163 if [[ $type == "igmp" ]]; then
0164 tc filter add dev $dev egress pref 10 prot 802.1Q \
0165 flower vlan_id 10 vlan_ethtype ipv4 dst_ip 224.0.0.1 ip_proto 2 \
0166 action pass
0167 else
0168 tc filter add dev $dev egress pref 10 prot 802.1Q \
0169 flower vlan_id 10 vlan_ethtype ipv6 dst_ip ff02::1 ip_proto icmpv6 \
0170 action pass
0171 fi
0172
0173 ip link set dev br0 type bridge mcast_stats_enabled 1
0174 }
0175
0176 vlmc_query_cnt_cleanup()
0177 {
0178 local dev=$1
0179
0180 ip link set dev br0 type bridge mcast_stats_enabled 0
0181 tc filter del dev $dev egress pref 10
0182 }
0183
0184 vlmc_check_query()
0185 {
0186 local type=$1
0187 local version=$2
0188 local dev=$3
0189 local expect=$4
0190 local time=$5
0191 local ret=0
0192
0193 vlmc_query_cnt_setup $type $dev
0194
0195 local pre_tx_xstats=$(vlmc_query_cnt_xstats $type $version $dev)
0196 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1
0197 ret=$?
0198 if [[ $ret -eq 0 ]]; then
0199 sleep $time
0200
0201 local tcstats=$(tc_rule_stats_get $dev 10 egress)
0202 local post_tx_xstats=$(vlmc_query_cnt_xstats $type $version $dev)
0203
0204 if [[ $tcstats != $expect || \
0205 $(($post_tx_xstats-$pre_tx_xstats)) != $expect || \
0206 $tcstats != $(($post_tx_xstats-$pre_tx_xstats)) ]]; then
0207 ret=1
0208 fi
0209 fi
0210
0211 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 0
0212 vlmc_query_cnt_cleanup $dev
0213
0214 return $ret
0215 }
0216
0217 vlmc_querier_test()
0218 {
0219 RET=0
0220 local goutput=`bridge -j vlan global show`
0221 echo -n $goutput |
0222 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0223 check_err $? "Could not find vlan 10's global options"
0224
0225 echo -n $goutput |
0226 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_querier == 0) " &>/dev/null
0227 check_err $? "Wrong default mcast_querier global vlan option value"
0228 log_test "Vlan mcast_querier global option default value"
0229
0230 RET=0
0231 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1
0232 check_err $? "Could not enable querier in vlan 10"
0233 log_test "Vlan 10 multicast querier enable"
0234 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 0
0235
0236 RET=0
0237 vlmc_check_query igmp 2 $swp1 1 1
0238 check_err $? "No vlan tagged IGMPv2 general query packets sent"
0239 log_test "Vlan 10 tagged IGMPv2 general query sent"
0240
0241 RET=0
0242 vlmc_check_query mld 1 $swp1 1 1
0243 check_err $? "No vlan tagged MLD general query packets sent"
0244 log_test "Vlan 10 tagged MLD general query sent"
0245 }
0246
0247 vlmc_igmp_mld_version_test()
0248 {
0249 RET=0
0250 local goutput=`bridge -j vlan global show`
0251 echo -n $goutput |
0252 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0253 check_err $? "Could not find vlan 10's global options"
0254
0255 echo -n $goutput |
0256 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_igmp_version == 2) " &>/dev/null
0257 check_err $? "Wrong default mcast_igmp_version global vlan option value"
0258 log_test "Vlan mcast_igmp_version global option default value"
0259
0260 RET=0
0261 echo -n $goutput |
0262 jq -e ".[].vlans[] | select(.vlan == 10 and .mcast_mld_version == 1) " &>/dev/null
0263 check_err $? "Wrong default mcast_mld_version global vlan option value"
0264 log_test "Vlan mcast_mld_version global option default value"
0265
0266 RET=0
0267 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version 3
0268 check_err $? "Could not set mcast_igmp_version in vlan 10"
0269 log_test "Vlan 10 mcast_igmp_version option changed to 3"
0270
0271 RET=0
0272 vlmc_check_query igmp 3 $swp1 1 1
0273 check_err $? "No vlan tagged IGMPv3 general query packets sent"
0274 log_test "Vlan 10 tagged IGMPv3 general query sent"
0275
0276 RET=0
0277 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 2
0278 check_err $? "Could not set mcast_mld_version in vlan 10"
0279 log_test "Vlan 10 mcast_mld_version option changed to 2"
0280
0281 RET=0
0282 vlmc_check_query mld 2 $swp1 1 1
0283 check_err $? "No vlan tagged MLDv2 general query packets sent"
0284 log_test "Vlan 10 tagged MLDv2 general query sent"
0285
0286 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version 2
0287 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 1
0288 }
0289
0290 vlmc_last_member_test()
0291 {
0292 RET=0
0293 local goutput=`bridge -j vlan global show`
0294 echo -n $goutput |
0295 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0296 check_err $? "Could not find vlan 10's global options"
0297
0298 echo -n $goutput |
0299 jq -e ".[].vlans[] | select(.vlan == 10 and \
0300 .mcast_last_member_count == 2) " &>/dev/null
0301 check_err $? "Wrong default mcast_last_member_count global vlan option value"
0302 log_test "Vlan mcast_last_member_count global option default value"
0303
0304 RET=0
0305 echo -n $goutput |
0306 jq -e ".[].vlans[] | select(.vlan == 10 and \
0307 .mcast_last_member_interval == 100) " &>/dev/null
0308 check_err $? "Wrong default mcast_last_member_interval global vlan option value"
0309 log_test "Vlan mcast_last_member_interval global option default value"
0310
0311 RET=0
0312 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_count 3
0313 check_err $? "Could not set mcast_last_member_count in vlan 10"
0314 log_test "Vlan 10 mcast_last_member_count option changed to 3"
0315 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_count 2
0316
0317 RET=0
0318 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_interval 200
0319 check_err $? "Could not set mcast_last_member_interval in vlan 10"
0320 log_test "Vlan 10 mcast_last_member_interval option changed to 200"
0321 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_last_member_interval 100
0322 }
0323
0324 vlmc_startup_query_test()
0325 {
0326 RET=0
0327 local goutput=`bridge -j vlan global show`
0328 echo -n $goutput |
0329 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0330 check_err $? "Could not find vlan 10's global options"
0331
0332 echo -n $goutput |
0333 jq -e ".[].vlans[] | select(.vlan == 10 and \
0334 .mcast_startup_query_interval == 3125) " &>/dev/null
0335 check_err $? "Wrong default mcast_startup_query_interval global vlan option value"
0336 log_test "Vlan mcast_startup_query_interval global option default value"
0337
0338 RET=0
0339 echo -n $goutput |
0340 jq -e ".[].vlans[] | select(.vlan == 10 and \
0341 .mcast_startup_query_count == 2) " &>/dev/null
0342 check_err $? "Wrong default mcast_startup_query_count global vlan option value"
0343 log_test "Vlan mcast_startup_query_count global option default value"
0344
0345 RET=0
0346 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_interval 100
0347 check_err $? "Could not set mcast_startup_query_interval in vlan 10"
0348 vlmc_check_query igmp 2 $swp1 2 3
0349 check_err $? "Wrong number of tagged IGMPv2 general queries sent"
0350 log_test "Vlan 10 mcast_startup_query_interval option changed to 100"
0351
0352 RET=0
0353 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 3
0354 check_err $? "Could not set mcast_startup_query_count in vlan 10"
0355 vlmc_check_query igmp 2 $swp1 3 4
0356 check_err $? "Wrong number of tagged IGMPv2 general queries sent"
0357 log_test "Vlan 10 mcast_startup_query_count option changed to 3"
0358
0359 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_interval 3125
0360 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 2
0361 }
0362
0363 vlmc_membership_test()
0364 {
0365 RET=0
0366 local goutput=`bridge -j vlan global show`
0367 echo -n $goutput |
0368 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0369 check_err $? "Could not find vlan 10's global options"
0370
0371 echo -n $goutput |
0372 jq -e ".[].vlans[] | select(.vlan == 10 and \
0373 .mcast_membership_interval == 26000) " &>/dev/null
0374 check_err $? "Wrong default mcast_membership_interval global vlan option value"
0375 log_test "Vlan mcast_membership_interval global option default value"
0376
0377 RET=0
0378 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_membership_interval 200
0379 check_err $? "Could not set mcast_membership_interval in vlan 10"
0380 log_test "Vlan 10 mcast_membership_interval option changed to 200"
0381
0382 RET=0
0383 vlmc_v2join_test 1
0384 log_test "Vlan 10 mcast_membership_interval mdb entry expire"
0385
0386 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_membership_interval 26000
0387 }
0388
0389 vlmc_querier_intvl_test()
0390 {
0391 RET=0
0392 local goutput=`bridge -j vlan global show`
0393 echo -n $goutput |
0394 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0395 check_err $? "Could not find vlan 10's global options"
0396
0397 echo -n $goutput |
0398 jq -e ".[].vlans[] | select(.vlan == 10 and \
0399 .mcast_querier_interval == 25500) " &>/dev/null
0400 check_err $? "Wrong default mcast_querier_interval global vlan option value"
0401 log_test "Vlan mcast_querier_interval global option default value"
0402
0403 RET=0
0404 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier_interval 100
0405 check_err $? "Could not set mcast_querier_interval in vlan 10"
0406 log_test "Vlan 10 mcast_querier_interval option changed to 100"
0407
0408 RET=0
0409 ip link add dev br1 type bridge mcast_snooping 1 mcast_querier 1 vlan_filtering 1 \
0410 mcast_vlan_snooping 1
0411 bridge vlan add vid 10 dev br1 self pvid untagged
0412 ip link set dev $h1 master br1
0413 ip link set dev br1 up
0414 bridge vlan add vid 10 dev $h1 master
0415 bridge vlan global set vid 10 dev br1 mcast_snooping 1 mcast_querier 1
0416 sleep 2
0417 ip link del dev br1
0418 ip addr replace 2001:db8:1::1/64 dev $h1
0419 vlmc_check_query igmp 2 $swp1 1 1
0420 check_err $? "Wrong number of IGMPv2 general queries after querier interval"
0421 log_test "Vlan 10 mcast_querier_interval expire after outside query"
0422
0423 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier_interval 25500
0424 }
0425
0426 vlmc_query_intvl_test()
0427 {
0428 RET=0
0429 local goutput=`bridge -j vlan global show`
0430 echo -n $goutput |
0431 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0432 check_err $? "Could not find vlan 10's global options"
0433
0434 echo -n $goutput |
0435 jq -e ".[].vlans[] | select(.vlan == 10 and \
0436 .mcast_query_interval == 12500) " &>/dev/null
0437 check_err $? "Wrong default mcast_query_interval global vlan option value"
0438 log_test "Vlan mcast_query_interval global option default value"
0439
0440 RET=0
0441 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 0
0442 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interval 200
0443 check_err $? "Could not set mcast_query_interval in vlan 10"
0444
0445 vlmc_check_query igmp 2 $swp1 3 5
0446 check_err $? "Wrong number of tagged IGMPv2 general queries sent"
0447 log_test "Vlan 10 mcast_query_interval option changed to 200"
0448
0449 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_query_count 2
0450 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interval 12500
0451 }
0452
0453 vlmc_query_response_intvl_test()
0454 {
0455 RET=0
0456 local goutput=`bridge -j vlan global show`
0457 echo -n $goutput |
0458 jq -e ".[].vlans[] | select(.vlan == 10)" &>/dev/null
0459 check_err $? "Could not find vlan 10's global options"
0460
0461 echo -n $goutput |
0462 jq -e ".[].vlans[] | select(.vlan == 10 and \
0463 .mcast_query_response_interval == 1000) " &>/dev/null
0464 check_err $? "Wrong default mcast_query_response_interval global vlan option value"
0465 log_test "Vlan mcast_query_response_interval global option default value"
0466
0467 RET=0
0468 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_response_interval 200
0469 check_err $? "Could not set mcast_query_response_interval in vlan 10"
0470 log_test "Vlan 10 mcast_query_response_interval option changed to 200"
0471
0472 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_response_interval 1000
0473 }
0474
0475 vlmc_router_port_test()
0476 {
0477 RET=0
0478 local goutput=`bridge -j -d vlan show`
0479 echo -n $goutput |
0480 jq -e ".[] | select(.ifname == \"$swp1\" and \
0481 .vlans[].vlan == 10)" &>/dev/null
0482 check_err $? "Could not find port vlan 10's options"
0483
0484 echo -n $goutput |
0485 jq -e ".[] | select(.ifname == \"$swp1\" and \
0486 .vlans[].vlan == 10 and \
0487 .vlans[].mcast_router == 1)" &>/dev/null
0488 check_err $? "Wrong default port mcast_router option value"
0489 log_test "Port vlan 10 option mcast_router default value"
0490
0491 RET=0
0492 bridge vlan set vid 10 dev $swp1 mcast_router 2
0493 check_err $? "Could not set port vlan 10's mcast_router option"
0494 log_test "Port vlan 10 mcast_router option changed to 2"
0495
0496 RET=0
0497 tc filter add dev $swp1 egress pref 10 prot 802.1Q \
0498 flower vlan_id 10 vlan_ethtype ipv4 dst_ip 239.1.1.1 ip_proto udp action pass
0499 tc filter add dev $swp2 egress pref 10 prot 802.1Q \
0500 flower vlan_id 10 vlan_ethtype ipv4 dst_ip 239.1.1.1 ip_proto udp action pass
0501 bridge vlan set vid 10 dev $swp2 mcast_router 0
0502
0503
0504 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1 \
0505 mcast_query_response_interval 0
0506 bridge vlan add vid 10 dev br0 self
0507 sleep 1
0508 mausezahn br0 -Q 10 -c 10 -p 128 -b 01:00:5e:01:01:01 -B 239.1.1.1 \
0509 -t udp "dp=1024" &>/dev/null
0510 local swp1_tcstats=$(tc_rule_stats_get $swp1 10 egress)
0511 if [[ $swp1_tcstats != 10 ]]; then
0512 check_err 1 "Wrong number of vlan 10 multicast packets flooded"
0513 fi
0514 local swp2_tcstats=$(tc_rule_stats_get $swp2 10 egress)
0515 check_err $swp2_tcstats "Vlan 10 multicast packets flooded to non-router port"
0516 log_test "Flood unknown vlan multicast packets to router port only"
0517
0518 tc filter del dev $swp2 egress pref 10
0519 tc filter del dev $swp1 egress pref 10
0520 bridge vlan del vid 10 dev br0 self
0521 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_response_interval 1000
0522 bridge vlan set vid 10 dev $swp2 mcast_router 1
0523 bridge vlan set vid 10 dev $swp1 mcast_router 1
0524 }
0525
0526 vlmc_filtering_test()
0527 {
0528 RET=0
0529 ip link set dev br0 type bridge vlan_filtering 0
0530 ip -j -d link show dev br0 | \
0531 jq -e "select(.[0].linkinfo.info_data.mcast_vlan_snooping == 1)" &>/dev/null
0532 check_fail $? "Vlan filtering is disabled but multicast vlan snooping is still enabled"
0533 log_test "Disable multicast vlan snooping when vlan filtering is disabled"
0534 }
0535
0536 trap cleanup EXIT
0537
0538 setup_prepare
0539 setup_wait
0540
0541 tests_run
0542
0543 exit $EXIT_STATUS