linux/tools/testing/selftests/net/forwarding/bridge_igmp.sh
<<
>>
Prefs
   1#!/bin/bash
   2# SPDX-License-Identifier: GPL-2.0
   3
   4ALL_TESTS="v2reportleave_test v3include_test v3inc_allow_test v3inc_is_include_test \
   5           v3inc_is_exclude_test v3inc_to_exclude_test v3exc_allow_test v3exc_is_include_test \
   6           v3exc_is_exclude_test v3exc_to_exclude_test v3inc_block_test v3exc_block_test \
   7           v3exc_timeout_test v3star_ex_auto_add_test"
   8NUM_NETIFS=4
   9CHECK_TC="yes"
  10TEST_GROUP="239.10.10.10"
  11TEST_GROUP_MAC="01:00:5e:0a:0a:0a"
  12
  13ALL_GROUP="224.0.0.1"
  14ALL_MAC="01:00:5e:00:00:01"
  15
  16# IGMPv3 is_in report: grp 239.10.10.10 is_include 192.0.2.1,192.0.2.2,192.0.2.3
  17MZPKT_IS_INC="22:00:9d:de:00:00:00:01:01:00:00:03:ef:0a:0a:0a:c0:00:02:01:c0:00:02:02:c0:00:02:03"
  18# IGMPv3 is_in report: grp 239.10.10.10 is_include 192.0.2.10,192.0.2.11,192.0.2.12
  19MZPKT_IS_INC2="22:00:9d:c3:00:00:00:01:01:00:00:03:ef:0a:0a:0a:c0:00:02:0a:c0:00:02:0b:c0:00:02:0c"
  20# IGMPv3 is_in report: grp 239.10.10.10 is_include 192.0.2.20,192.0.2.30
  21MZPKT_IS_INC3="22:00:5f:b4:00:00:00:01:01:00:00:02:ef:0a:0a:0a:c0:00:02:14:c0:00:02:1e"
  22# IGMPv3 allow report: grp 239.10.10.10 allow 192.0.2.10,192.0.2.11,192.0.2.12
  23MZPKT_ALLOW="22:00:99:c3:00:00:00:01:05:00:00:03:ef:0a:0a:0a:c0:00:02:0a:c0:00:02:0b:c0:00:02:0c"
  24# IGMPv3 allow report: grp 239.10.10.10 allow 192.0.2.20,192.0.2.30
  25MZPKT_ALLOW2="22:00:5b:b4:00:00:00:01:05:00:00:02:ef:0a:0a:0a:c0:00:02:14:c0:00:02:1e"
  26# IGMPv3 is_ex report: grp 239.10.10.10 is_exclude 192.0.2.1,192.0.2.2,192.0.2.20,192.0.2.21
  27MZPKT_IS_EXC="22:00:da:b6:00:00:00:01:02:00:00:04:ef:0a:0a:0a:c0:00:02:01:c0:00:02:02:c0:00:02:14:c0:00:02:15"
  28# IGMPv3 is_ex report: grp 239.10.10.10 is_exclude 192.0.2.20,192.0.2.30
  29MZPKT_IS_EXC2="22:00:5e:b4:00:00:00:01:02:00:00:02:ef:0a:0a:0a:c0:00:02:14:c0:00:02:1e"
  30# IGMPv3 to_ex report: grp 239.10.10.10 to_exclude 192.0.2.1,192.0.2.20,192.0.2.30
  31MZPKT_TO_EXC="22:00:9a:b1:00:00:00:01:04:00:00:03:ef:0a:0a:0a:c0:00:02:01:c0:00:02:14:c0:00:02:1e"
  32# IGMPv3 block report: grp 239.10.10.10 block 192.0.2.1,192.0.2.20,192.0.2.30
  33MZPKT_BLOCK="22:00:98:b1:00:00:00:01:06:00:00:03:ef:0a:0a:0a:c0:00:02:01:c0:00:02:14:c0:00:02:1e"
  34
  35source lib.sh
  36
  37h1_create()
  38{
  39        simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
  40}
  41
  42h1_destroy()
  43{
  44        simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
  45}
  46
  47h2_create()
  48{
  49        simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
  50}
  51
  52h2_destroy()
  53{
  54        simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
  55}
  56
  57switch_create()
  58{
  59        ip link add dev br0 type bridge mcast_snooping 1 mcast_querier 1
  60
  61        ip link set dev $swp1 master br0
  62        ip link set dev $swp2 master br0
  63
  64        ip link set dev br0 up
  65        ip link set dev $swp1 up
  66        ip link set dev $swp2 up
  67}
  68
  69switch_destroy()
  70{
  71        ip link set dev $swp2 down
  72        ip link set dev $swp1 down
  73
  74        ip link del dev br0
  75}
  76
  77setup_prepare()
  78{
  79        h1=${NETIFS[p1]}
  80        swp1=${NETIFS[p2]}
  81
  82        swp2=${NETIFS[p3]}
  83        h2=${NETIFS[p4]}
  84
  85        vrf_prepare
  86
  87        h1_create
  88        h2_create
  89
  90        switch_create
  91}
  92
  93cleanup()
  94{
  95        pre_cleanup
  96
  97        switch_destroy
  98
  99        # Always cleanup the mcast group
 100        ip address del dev $h2 $TEST_GROUP/32 2>&1 1>/dev/null
 101
 102        h2_destroy
 103        h1_destroy
 104
 105        vrf_cleanup
 106}
 107
 108v2reportleave_test()
 109{
 110        RET=0
 111        ip address add dev $h2 $TEST_GROUP/32 autojoin
 112        check_err $? "Could not join $TEST_GROUP"
 113
 114        sleep 5
 115        bridge mdb show dev br0 | grep $TEST_GROUP 1>/dev/null
 116        check_err $? "IGMPv2 report didn't create mdb entry for $TEST_GROUP"
 117
 118        mcast_packet_test $TEST_GROUP_MAC 192.0.2.1 $TEST_GROUP $h1 $h2
 119        check_fail $? "Traffic to $TEST_GROUP wasn't forwarded"
 120
 121        log_test "IGMPv2 report $TEST_GROUP"
 122
 123        RET=0
 124        bridge mdb show dev br0 | grep $TEST_GROUP 1>/dev/null
 125        check_err $? "mdb entry for $TEST_GROUP is missing"
 126
 127        ip address del dev $h2 $TEST_GROUP/32
 128        check_err $? "Could not leave $TEST_GROUP"
 129
 130        sleep 5
 131        bridge mdb show dev br0 | grep $TEST_GROUP 1>/dev/null
 132        check_fail $? "Leave didn't delete mdb entry for $TEST_GROUP"
 133
 134        mcast_packet_test $TEST_GROUP_MAC 192.0.2.1 $TEST_GROUP $h1 $h2
 135        check_err $? "Traffic to $TEST_GROUP was forwarded without mdb entry"
 136
 137        log_test "IGMPv2 leave $TEST_GROUP"
 138}
 139
 140v3include_prepare()
 141{
 142        local host1_if=$1
 143        local mac=$2
 144        local group=$3
 145        local X=("192.0.2.1" "192.0.2.2" "192.0.2.3")
 146
 147        ip link set dev br0 type bridge mcast_igmp_version 3
 148        check_err $? "Could not change bridge IGMP version to 3"
 149
 150        $MZ $host1_if -b $mac -c 1 -B $group -t ip "proto=2,p=$MZPKT_IS_INC" -q
 151        sleep 1
 152        bridge -j -d -s mdb show dev br0 \
 153                | jq -e ".[].mdb[] | \
 154                         select(.grp == \"$TEST_GROUP\" and .source_list != null)" &>/dev/null
 155        check_err $? "Missing *,G entry with source list"
 156        bridge -j -d -s mdb show dev br0 \
 157                | jq -e ".[].mdb[] | \
 158                         select(.grp == \"$TEST_GROUP\" and \
 159                                .source_list != null and .filter_mode == \"include\")" &>/dev/null
 160        check_err $? "Wrong *,G entry filter mode"
 161        brmcast_check_sg_entries "is_include" "${X[@]}"
 162}
 163
 164v3exclude_prepare()
 165{
 166        local host1_if=$1
 167        local mac=$2
 168        local group=$3
 169        local pkt=$4
 170        local X=("192.0.2.1" "192.0.2.2")
 171        local Y=("192.0.2.20" "192.0.2.21")
 172
 173        v3include_prepare $host1_if $mac $group
 174
 175        $MZ $host1_if -c 1 -b $mac -B $group -t ip "proto=2,p=$MZPKT_IS_EXC" -q
 176        sleep 1
 177        bridge -j -d -s mdb show dev br0 \
 178                | jq -e ".[].mdb[] | \
 179                         select(.grp == \"$TEST_GROUP\" and \
 180                                .source_list != null and .filter_mode == \"exclude\")" &>/dev/null
 181        check_err $? "Wrong *,G entry filter mode"
 182
 183        brmcast_check_sg_entries "is_exclude" "${X[@]}" "${Y[@]}"
 184
 185        brmcast_check_sg_state 0 "${X[@]}"
 186        brmcast_check_sg_state 1 "${Y[@]}"
 187
 188        bridge -j -d -s mdb show dev br0 \
 189                | jq -e ".[].mdb[] | \
 190                         select(.grp == \"$TEST_GROUP\" and \
 191                                .source_list != null and
 192                                .source_list[].address == \"192.0.2.3\")" &>/dev/null
 193        check_fail $? "Wrong *,G entry source list, 192.0.2.3 entry still exists"
 194}
 195
 196v3cleanup()
 197{
 198        local port=$1
 199        local group=$2
 200
 201        bridge mdb del dev br0 port $port grp $group
 202        ip link set dev br0 type bridge mcast_igmp_version 2
 203}
 204
 205v3include_test()
 206{
 207        RET=0
 208        local X=("192.0.2.1" "192.0.2.2" "192.0.2.3")
 209
 210        v3include_prepare $h1 $ALL_MAC $ALL_GROUP
 211
 212        brmcast_check_sg_state 0 "${X[@]}"
 213
 214        brmcast_check_sg_fwding 1 "${X[@]}"
 215        brmcast_check_sg_fwding 0 "192.0.2.100"
 216
 217        log_test "IGMPv3 report $TEST_GROUP is_include"
 218
 219        v3cleanup $swp1 $TEST_GROUP
 220}
 221
 222v3inc_allow_test()
 223{
 224        RET=0
 225        local X=("192.0.2.10" "192.0.2.11" "192.0.2.12")
 226
 227        v3include_prepare $h1 $ALL_MAC $ALL_GROUP
 228
 229        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW" -q
 230        sleep 1
 231        brmcast_check_sg_entries "allow" "${X[@]}"
 232
 233        brmcast_check_sg_state 0 "${X[@]}"
 234
 235        brmcast_check_sg_fwding 1 "${X[@]}"
 236        brmcast_check_sg_fwding 0 "192.0.2.100"
 237
 238        log_test "IGMPv3 report $TEST_GROUP include -> allow"
 239
 240        v3cleanup $swp1 $TEST_GROUP
 241}
 242
 243v3inc_is_include_test()
 244{
 245        RET=0
 246        local X=("192.0.2.10" "192.0.2.11" "192.0.2.12")
 247
 248        v3include_prepare $h1 $ALL_MAC $ALL_GROUP
 249
 250        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_INC2" -q
 251        sleep 1
 252        brmcast_check_sg_entries "is_include" "${X[@]}"
 253
 254        brmcast_check_sg_state 0 "${X[@]}"
 255
 256        brmcast_check_sg_fwding 1 "${X[@]}"
 257        brmcast_check_sg_fwding 0 "192.0.2.100"
 258
 259        log_test "IGMPv3 report $TEST_GROUP include -> is_include"
 260
 261        v3cleanup $swp1 $TEST_GROUP
 262}
 263
 264v3inc_is_exclude_test()
 265{
 266        RET=0
 267
 268        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 269
 270        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 271        brmcast_check_sg_fwding 0 "${Y[@]}"
 272
 273        log_test "IGMPv3 report $TEST_GROUP include -> is_exclude"
 274
 275        v3cleanup $swp1 $TEST_GROUP
 276}
 277
 278v3inc_to_exclude_test()
 279{
 280        RET=0
 281        local X=("192.0.2.1")
 282        local Y=("192.0.2.20" "192.0.2.30")
 283
 284        v3include_prepare $h1 $ALL_MAC $ALL_GROUP
 285
 286        ip link set dev br0 type bridge mcast_last_member_interval 500
 287        check_err $? "Could not change mcast_last_member_interval to 5s"
 288
 289        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_TO_EXC" -q
 290        sleep 1
 291        bridge -j -d -s mdb show dev br0 \
 292                | jq -e ".[].mdb[] | \
 293                         select(.grp == \"$TEST_GROUP\" and \
 294                                .source_list != null and .filter_mode == \"exclude\")" &>/dev/null
 295        check_err $? "Wrong *,G entry filter mode"
 296
 297        brmcast_check_sg_entries "to_exclude" "${X[@]}" "${Y[@]}"
 298
 299        brmcast_check_sg_state 0 "${X[@]}"
 300        brmcast_check_sg_state 1 "${Y[@]}"
 301
 302        bridge -j -d -s mdb show dev br0 \
 303                | jq -e ".[].mdb[] | \
 304                         select(.grp == \"$TEST_GROUP\" and \
 305                                .source_list != null and
 306                                .source_list[].address == \"192.0.2.2\")" &>/dev/null
 307        check_fail $? "Wrong *,G entry source list, 192.0.2.2 entry still exists"
 308        bridge -j -d -s mdb show dev br0 \
 309                | jq -e ".[].mdb[] | \
 310                         select(.grp == \"$TEST_GROUP\" and \
 311                                .source_list != null and
 312                                .source_list[].address == \"192.0.2.21\")" &>/dev/null
 313        check_fail $? "Wrong *,G entry source list, 192.0.2.21 entry still exists"
 314
 315        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 316        brmcast_check_sg_fwding 0 "${Y[@]}"
 317
 318        log_test "IGMPv3 report $TEST_GROUP include -> to_exclude"
 319
 320        ip link set dev br0 type bridge mcast_last_member_interval 100
 321
 322        v3cleanup $swp1 $TEST_GROUP
 323}
 324
 325v3exc_allow_test()
 326{
 327        RET=0
 328        local X=("192.0.2.1" "192.0.2.2" "192.0.2.20" "192.0.2.30")
 329        local Y=("192.0.2.21")
 330
 331        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 332
 333        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW2" -q
 334        sleep 1
 335        brmcast_check_sg_entries "allow" "${X[@]}" "${Y[@]}"
 336
 337        brmcast_check_sg_state 0 "${X[@]}"
 338        brmcast_check_sg_state 1 "${Y[@]}"
 339
 340        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 341        brmcast_check_sg_fwding 0 "${Y[@]}"
 342
 343        log_test "IGMPv3 report $TEST_GROUP exclude -> allow"
 344
 345        v3cleanup $swp1 $TEST_GROUP
 346}
 347
 348v3exc_is_include_test()
 349{
 350        RET=0
 351        local X=("192.0.2.1" "192.0.2.2" "192.0.2.20" "192.0.2.30")
 352        local Y=("192.0.2.21")
 353
 354        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 355
 356        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_INC3" -q
 357        sleep 1
 358        brmcast_check_sg_entries "is_include" "${X[@]}" "${Y[@]}"
 359
 360        brmcast_check_sg_state 0 "${X[@]}"
 361        brmcast_check_sg_state 1 "${Y[@]}"
 362
 363        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 364        brmcast_check_sg_fwding 0 "${Y[@]}"
 365
 366        log_test "IGMPv3 report $TEST_GROUP exclude -> is_include"
 367
 368        v3cleanup $swp1 $TEST_GROUP
 369}
 370
 371v3exc_is_exclude_test()
 372{
 373        RET=0
 374        local X=("192.0.2.30")
 375        local Y=("192.0.2.20")
 376
 377        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 378
 379        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_EXC2" -q
 380        sleep 1
 381        brmcast_check_sg_entries "is_exclude" "${X[@]}" "${Y[@]}"
 382
 383        brmcast_check_sg_state 0 "${X[@]}"
 384        brmcast_check_sg_state 1 "${Y[@]}"
 385
 386        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 387        brmcast_check_sg_fwding 0 "${Y[@]}"
 388
 389        log_test "IGMPv3 report $TEST_GROUP exclude -> is_exclude"
 390
 391        v3cleanup $swp1 $TEST_GROUP
 392}
 393
 394v3exc_to_exclude_test()
 395{
 396        RET=0
 397        local X=("192.0.2.1" "192.0.2.30")
 398        local Y=("192.0.2.20")
 399
 400        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 401
 402        ip link set dev br0 type bridge mcast_last_member_interval 500
 403        check_err $? "Could not change mcast_last_member_interval to 5s"
 404
 405        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_TO_EXC" -q
 406        sleep 1
 407        brmcast_check_sg_entries "to_exclude" "${X[@]}" "${Y[@]}"
 408
 409        brmcast_check_sg_state 0 "${X[@]}"
 410        brmcast_check_sg_state 1 "${Y[@]}"
 411
 412        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 413        brmcast_check_sg_fwding 0 "${Y[@]}"
 414
 415        log_test "IGMPv3 report $TEST_GROUP exclude -> to_exclude"
 416
 417        ip link set dev br0 type bridge mcast_last_member_interval 100
 418
 419        v3cleanup $swp1 $TEST_GROUP
 420}
 421
 422v3inc_block_test()
 423{
 424        RET=0
 425        local X=("192.0.2.2" "192.0.2.3")
 426
 427        v3include_prepare $h1 $ALL_MAC $ALL_GROUP
 428
 429        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_BLOCK" -q
 430        # make sure the lowered timers have expired (by default 2 seconds)
 431        sleep 3
 432        brmcast_check_sg_entries "block" "${X[@]}"
 433
 434        brmcast_check_sg_state 0 "${X[@]}"
 435
 436        bridge -j -d -s mdb show dev br0 \
 437                | jq -e ".[].mdb[] | \
 438                         select(.grp == \"$TEST_GROUP\" and \
 439                                .source_list != null and
 440                                .source_list[].address == \"192.0.2.1\")" &>/dev/null
 441        check_fail $? "Wrong *,G entry source list, 192.0.2.1 entry still exists"
 442
 443        brmcast_check_sg_fwding 1 "${X[@]}"
 444        brmcast_check_sg_fwding 0 "192.0.2.100"
 445
 446        log_test "IGMPv3 report $TEST_GROUP include -> block"
 447
 448        v3cleanup $swp1 $TEST_GROUP
 449}
 450
 451v3exc_block_test()
 452{
 453        RET=0
 454        local X=("192.0.2.1" "192.0.2.2" "192.0.2.30")
 455        local Y=("192.0.2.20" "192.0.2.21")
 456
 457        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 458
 459        ip link set dev br0 type bridge mcast_last_member_interval 500
 460        check_err $? "Could not change mcast_last_member_interval to 5s"
 461
 462        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_BLOCK" -q
 463        sleep 1
 464        brmcast_check_sg_entries "block" "${X[@]}" "${Y[@]}"
 465
 466        brmcast_check_sg_state 0 "${X[@]}"
 467        brmcast_check_sg_state 1 "${Y[@]}"
 468
 469        brmcast_check_sg_fwding 1 "${X[@]}" 192.0.2.100
 470        brmcast_check_sg_fwding 0 "${Y[@]}"
 471
 472        log_test "IGMPv3 report $TEST_GROUP exclude -> block"
 473
 474        ip link set dev br0 type bridge mcast_last_member_interval 100
 475
 476        v3cleanup $swp1 $TEST_GROUP
 477}
 478
 479v3exc_timeout_test()
 480{
 481        RET=0
 482        local X=("192.0.2.20" "192.0.2.30")
 483
 484        # GMI should be 3 seconds
 485        ip link set dev br0 type bridge mcast_query_interval 100 mcast_query_response_interval 100
 486
 487        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 488        ip link set dev br0 type bridge mcast_query_interval 500 mcast_query_response_interval 500
 489        $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW2" -q
 490        sleep 3
 491        bridge -j -d -s mdb show dev br0 \
 492                | jq -e ".[].mdb[] | \
 493                         select(.grp == \"$TEST_GROUP\" and \
 494                                .source_list != null and .filter_mode == \"include\")" &>/dev/null
 495        check_err $? "Wrong *,G entry filter mode"
 496
 497        bridge -j -d -s mdb show dev br0 \
 498                | jq -e ".[].mdb[] | \
 499                         select(.grp == \"$TEST_GROUP\" and \
 500                                .source_list != null and
 501                                .source_list[].address == \"192.0.2.1\")" &>/dev/null
 502        check_fail $? "Wrong *,G entry source list, 192.0.2.1 entry still exists"
 503        bridge -j -d -s mdb show dev br0 \
 504                | jq -e ".[].mdb[] | \
 505                         select(.grp == \"$TEST_GROUP\" and \
 506                                .source_list != null and
 507                                .source_list[].address == \"192.0.2.2\")" &>/dev/null
 508        check_fail $? "Wrong *,G entry source list, 192.0.2.2 entry still exists"
 509
 510        brmcast_check_sg_entries "allow" "${X[@]}"
 511
 512        brmcast_check_sg_state 0 "${X[@]}"
 513
 514        brmcast_check_sg_fwding 1 "${X[@]}"
 515        brmcast_check_sg_fwding 0 192.0.2.100
 516
 517        log_test "IGMPv3 group $TEST_GROUP exclude timeout"
 518
 519        ip link set dev br0 type bridge mcast_query_interval 12500 \
 520                                        mcast_query_response_interval 1000
 521
 522        v3cleanup $swp1 $TEST_GROUP
 523}
 524
 525v3star_ex_auto_add_test()
 526{
 527        RET=0
 528
 529        v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP
 530
 531        $MZ $h2 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_IS_INC" -q
 532        sleep 1
 533        bridge -j -d -s mdb show dev br0 \
 534                | jq -e ".[].mdb[] | \
 535                         select(.grp == \"$TEST_GROUP\" and .src == \"192.0.2.3\" and \
 536                                .port == \"$swp1\")" &>/dev/null
 537        check_err $? "S,G entry for *,G port doesn't exist"
 538
 539        bridge -j -d -s mdb show dev br0 \
 540                | jq -e ".[].mdb[] | \
 541                         select(.grp == \"$TEST_GROUP\" and .src == \"192.0.2.3\" and \
 542                                .port == \"$swp1\" and \
 543                                .flags[] == \"added_by_star_ex\")" &>/dev/null
 544        check_err $? "Auto-added S,G entry doesn't have added_by_star_ex flag"
 545
 546        brmcast_check_sg_fwding 1 192.0.2.3
 547
 548        log_test "IGMPv3 S,G port entry automatic add to a *,G port"
 549
 550        v3cleanup $swp1 $TEST_GROUP
 551        v3cleanup $swp2 $TEST_GROUP
 552}
 553
 554trap cleanup EXIT
 555
 556setup_prepare
 557setup_wait
 558
 559tests_run
 560
 561exit $EXIT_STATUS
 562