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