Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
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         # check if we need to cleanup
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 # setup for general query counting
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         # 1 is sent immediately, then 2 more in the next 5 seconds
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         # we need to enable querier and disable query response interval to
0503         # make sure packets are flooded only to router ports
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