1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# +-----------------------+ +------------------------+ 5# | H1 (vrf) | | H2 (vrf) | 6# | + $h1.10 | | + $h2.10 | 7# | | 192.0.2.1/28 | | | 192.0.2.2/28 | 8# | | | | | | 9# | | + $h1.20 | | | + $h2.20 | 10# | \ | 198.51.100.1/24 | | \ | 198.51.100.2/24 | 11# | \| | | \| | 12# | + $h1 | | + $h2 | 13# +----|------------------+ +----|-------------------+ 14# | | 15# +----|--------------------------------------------------|-------------------+ 16# | SW | | | 17# | +--|--------------------------------------------------|-----------------+ | 18# | | + $swp1 BR1 (802.1q) + $swp2 | | 19# | | vid 10 vid 10 | | 20# | | vid 20 vid 20 | | 21# | | | | 22# | | + vx10 (vxlan) + vx20 (vxlan) | | 23# | | local 192.0.2.17 local 192.0.2.17 | | 24# | | remote 192.0.2.34 192.0.2.50 remote 192.0.2.34 192.0.2.50 | | 25# | | id 1000 dstport $VXPORT id 2000 dstport $VXPORT | | 26# | | vid 10 pvid untagged vid 20 pvid untagged | | 27# | +-----------------------------------------------------------------------+ | 28# | | 29# | 192.0.2.32/28 via 192.0.2.18 | 30# | 192.0.2.48/28 via 192.0.2.18 | 31# | | 32# | + $rp1 | 33# | | 192.0.2.17/28 | 34# +----|----------------------------------------------------------------------+ 35# | 36# +----|--------------------------------------------------------+ 37# | | VRP2 (vrf) | 38# | + $rp2 | 39# | 192.0.2.18/28 | 40# | | (maybe) HW 41# ============================================================================= 42# | | (likely) SW 43# | + v1 (veth) + v3 (veth) | 44# | | 192.0.2.33/28 | 192.0.2.49/28 | 45# +----|---------------------------------------|----------------+ 46# | | 47# +----|------------------------------+ +----|------------------------------+ 48# | + v2 (veth) NS1 (netns) | | + v4 (veth) NS2 (netns) | 49# | 192.0.2.34/28 | | 192.0.2.50/28 | 50# | | | | 51# | 192.0.2.16/28 via 192.0.2.33 | | 192.0.2.16/28 via 192.0.2.49 | 52# | 192.0.2.50/32 via 192.0.2.33 | | 192.0.2.34/32 via 192.0.2.49 | 53# | | | | 54# | +-------------------------------+ | | +-------------------------------+ | 55# | | BR2 (802.1q) | | | | BR2 (802.1q) | | 56# | | + vx10 (vxlan) | | | | + vx10 (vxlan) | | 57# | | local 192.0.2.34 | | | | local 192.0.2.50 | | 58# | | remote 192.0.2.17 | | | | remote 192.0.2.17 | | 59# | | remote 192.0.2.50 | | | | remote 192.0.2.34 | | 60# | | id 1000 dstport $VXPORT | | | | id 1000 dstport $VXPORT | | 61# | | vid 10 pvid untagged | | | | vid 10 pvid untagged | | 62# | | | | | | | | 63# | | + vx20 (vxlan) | | | | + vx20 (vxlan) | | 64# | | local 192.0.2.34 | | | | local 192.0.2.50 | | 65# | | remote 192.0.2.17 | | | | remote 192.0.2.17 | | 66# | | remote 192.0.2.50 | | | | remote 192.0.2.34 | | 67# | | id 2000 dstport $VXPORT | | | | id 2000 dstport $VXPORT | | 68# | | vid 20 pvid untagged | | | | vid 20 pvid untagged | | 69# | | | | | | | | 70# | | + w1 (veth) | | | | + w1 (veth) | | 71# | | | vid 10 | | | | | vid 10 | | 72# | | | vid 20 | | | | | vid 20 | | 73# | +--|----------------------------+ | | +--|----------------------------+ | 74# | | | | | | 75# | +--|----------------------------+ | | +--|----------------------------+ | 76# | | + w2 (veth) VW2 (vrf) | | | | + w2 (veth) VW2 (vrf) | | 77# | | |\ | | | | |\ | | 78# | | | + w2.10 | | | | | + w2.10 | | 79# | | | 192.0.2.3/28 | | | | | 192.0.2.4/28 | | 80# | | | | | | | | | | 81# | | + w2.20 | | | | + w2.20 | | 82# | | 198.51.100.3/24 | | | | 198.51.100.4/24 | | 83# | +-------------------------------+ | | +-------------------------------+ | 84# +-----------------------------------+ +-----------------------------------+ 85 86: ${VXPORT:=4789} 87export VXPORT 88 89: ${ALL_TESTS:=" 90 ping_ipv4 91 test_flood 92 test_unicast 93 reapply_config 94 ping_ipv4 95 test_flood 96 test_unicast 97 test_learning 98 test_pvid 99 "} 100 101NUM_NETIFS=6 102source lib.sh 103 104h1_create() 105{ 106 simple_if_init $h1 107 tc qdisc add dev $h1 clsact 108 vlan_create $h1 10 v$h1 192.0.2.1/28 109 vlan_create $h1 20 v$h1 198.51.100.1/24 110} 111 112h1_destroy() 113{ 114 vlan_destroy $h1 20 115 vlan_destroy $h1 10 116 tc qdisc del dev $h1 clsact 117 simple_if_fini $h1 118} 119 120h2_create() 121{ 122 simple_if_init $h2 123 tc qdisc add dev $h2 clsact 124 vlan_create $h2 10 v$h2 192.0.2.2/28 125 vlan_create $h2 20 v$h2 198.51.100.2/24 126} 127 128h2_destroy() 129{ 130 vlan_destroy $h2 20 131 vlan_destroy $h2 10 132 tc qdisc del dev $h2 clsact 133 simple_if_fini $h2 134} 135 136rp1_set_addr() 137{ 138 ip address add dev $rp1 192.0.2.17/28 139 140 ip route add 192.0.2.32/28 nexthop via 192.0.2.18 141 ip route add 192.0.2.48/28 nexthop via 192.0.2.18 142} 143 144rp1_unset_addr() 145{ 146 ip route del 192.0.2.48/28 nexthop via 192.0.2.18 147 ip route del 192.0.2.32/28 nexthop via 192.0.2.18 148 149 ip address del dev $rp1 192.0.2.17/28 150} 151 152switch_create() 153{ 154 ip link add name br1 type bridge vlan_filtering 1 vlan_default_pvid 0 \ 155 mcast_snooping 0 156 # Make sure the bridge uses the MAC address of the local port and not 157 # that of the VxLAN's device. 158 ip link set dev br1 address $(mac_get $swp1) 159 ip link set dev br1 up 160 161 ip link set dev $rp1 up 162 rp1_set_addr 163 164 ip link add name vx10 type vxlan id 1000 \ 165 local 192.0.2.17 dstport "$VXPORT" \ 166 nolearning noudpcsum tos inherit ttl 100 167 ip link set dev vx10 up 168 169 ip link set dev vx10 master br1 170 bridge vlan add vid 10 dev vx10 pvid untagged 171 172 ip link add name vx20 type vxlan id 2000 \ 173 local 192.0.2.17 dstport "$VXPORT" \ 174 nolearning noudpcsum tos inherit ttl 100 175 ip link set dev vx20 up 176 177 ip link set dev vx20 master br1 178 bridge vlan add vid 20 dev vx20 pvid untagged 179 180 ip link set dev $swp1 master br1 181 ip link set dev $swp1 up 182 bridge vlan add vid 10 dev $swp1 183 bridge vlan add vid 20 dev $swp1 184 185 ip link set dev $swp2 master br1 186 ip link set dev $swp2 up 187 bridge vlan add vid 10 dev $swp2 188 bridge vlan add vid 20 dev $swp2 189 190 bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self 191 bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self 192 193 bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self 194 bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self 195} 196 197switch_destroy() 198{ 199 bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self 200 bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self 201 202 bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self 203 bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self 204 205 bridge vlan del vid 20 dev $swp2 206 bridge vlan del vid 10 dev $swp2 207 ip link set dev $swp2 down 208 ip link set dev $swp2 nomaster 209 210 bridge vlan del vid 20 dev $swp1 211 bridge vlan del vid 10 dev $swp1 212 ip link set dev $swp1 down 213 ip link set dev $swp1 nomaster 214 215 bridge vlan del vid 20 dev vx20 216 ip link set dev vx20 nomaster 217 218 ip link set dev vx20 down 219 ip link del dev vx20 220 221 bridge vlan del vid 10 dev vx10 222 ip link set dev vx10 nomaster 223 224 ip link set dev vx10 down 225 ip link del dev vx10 226 227 rp1_unset_addr 228 ip link set dev $rp1 down 229 230 ip link set dev br1 down 231 ip link del dev br1 232} 233 234vrp2_create() 235{ 236 simple_if_init $rp2 192.0.2.18/28 237 __simple_if_init v1 v$rp2 192.0.2.33/28 238 __simple_if_init v3 v$rp2 192.0.2.49/28 239 tc qdisc add dev v1 clsact 240} 241 242vrp2_destroy() 243{ 244 tc qdisc del dev v1 clsact 245 __simple_if_fini v3 192.0.2.49/28 246 __simple_if_fini v1 192.0.2.33/28 247 simple_if_fini $rp2 192.0.2.18/28 248} 249 250ns_init_common() 251{ 252 local in_if=$1; shift 253 local in_addr=$1; shift 254 local other_in_addr=$1; shift 255 local nh_addr=$1; shift 256 local host_addr1=$1; shift 257 local host_addr2=$1; shift 258 259 ip link set dev $in_if up 260 ip address add dev $in_if $in_addr/28 261 tc qdisc add dev $in_if clsact 262 263 ip link add name br2 type bridge vlan_filtering 1 vlan_default_pvid 0 264 ip link set dev br2 up 265 266 ip link add name w1 type veth peer name w2 267 268 ip link set dev w1 master br2 269 ip link set dev w1 up 270 271 bridge vlan add vid 10 dev w1 272 bridge vlan add vid 20 dev w1 273 274 ip link add name vx10 type vxlan id 1000 local $in_addr \ 275 dstport "$VXPORT" 276 ip link set dev vx10 up 277 bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.17 self 278 bridge fdb append dev vx10 00:00:00:00:00:00 dst $other_in_addr self 279 280 ip link set dev vx10 master br2 281 tc qdisc add dev vx10 clsact 282 283 bridge vlan add vid 10 dev vx10 pvid untagged 284 285 ip link add name vx20 type vxlan id 2000 local $in_addr \ 286 dstport "$VXPORT" 287 ip link set dev vx20 up 288 bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.17 self 289 bridge fdb append dev vx20 00:00:00:00:00:00 dst $other_in_addr self 290 291 ip link set dev vx20 master br2 292 tc qdisc add dev vx20 clsact 293 294 bridge vlan add vid 20 dev vx20 pvid untagged 295 296 simple_if_init w2 297 vlan_create w2 10 vw2 $host_addr1/28 298 vlan_create w2 20 vw2 $host_addr2/24 299 300 ip route add 192.0.2.16/28 nexthop via $nh_addr 301 ip route add $other_in_addr/32 nexthop via $nh_addr 302} 303export -f ns_init_common 304 305ns1_create() 306{ 307 ip netns add ns1 308 ip link set dev v2 netns ns1 309 in_ns ns1 \ 310 ns_init_common v2 192.0.2.34 192.0.2.50 192.0.2.33 192.0.2.3 \ 311 198.51.100.3 312} 313 314ns1_destroy() 315{ 316 ip netns exec ns1 ip link set dev v2 netns 1 317 ip netns del ns1 318} 319 320ns2_create() 321{ 322 ip netns add ns2 323 ip link set dev v4 netns ns2 324 in_ns ns2 \ 325 ns_init_common v4 192.0.2.50 192.0.2.34 192.0.2.49 192.0.2.4 \ 326 198.51.100.4 327} 328 329ns2_destroy() 330{ 331 ip netns exec ns2 ip link set dev v4 netns 1 332 ip netns del ns2 333} 334 335setup_prepare() 336{ 337 h1=${NETIFS[p1]} 338 swp1=${NETIFS[p2]} 339 340 swp2=${NETIFS[p3]} 341 h2=${NETIFS[p4]} 342 343 rp1=${NETIFS[p5]} 344 rp2=${NETIFS[p6]} 345 346 vrf_prepare 347 forwarding_enable 348 349 h1_create 350 h2_create 351 switch_create 352 353 ip link add name v1 type veth peer name v2 354 ip link add name v3 type veth peer name v4 355 vrp2_create 356 ns1_create 357 ns2_create 358 359 r1_mac=$(in_ns ns1 mac_get w2) 360 r2_mac=$(in_ns ns2 mac_get w2) 361 h2_mac=$(mac_get $h2) 362} 363 364cleanup() 365{ 366 pre_cleanup 367 368 ns2_destroy 369 ns1_destroy 370 vrp2_destroy 371 ip link del dev v3 372 ip link del dev v1 373 374 switch_destroy 375 h2_destroy 376 h1_destroy 377 378 forwarding_restore 379 vrf_cleanup 380} 381 382# For the first round of tests, vx10 and vx20 were the first devices to get 383# attached to the bridge, and that at the point that the local IP is already 384# configured. Try the other scenario of attaching these devices to a bridge 385# that already has local ports members, and only then assign the local IP. 386reapply_config() 387{ 388 log_info "Reapplying configuration" 389 390 bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self 391 bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self 392 393 bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self 394 bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self 395 396 ip link set dev vx20 nomaster 397 ip link set dev vx10 nomaster 398 399 rp1_unset_addr 400 sleep 5 401 402 ip link set dev vx10 master br1 403 bridge vlan add vid 10 dev vx10 pvid untagged 404 405 ip link set dev vx20 master br1 406 bridge vlan add vid 20 dev vx20 pvid untagged 407 408 bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self 409 bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self 410 411 bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self 412 bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self 413 414 rp1_set_addr 415 sleep 5 416} 417 418ping_ipv4() 419{ 420 ping_test $h1.10 192.0.2.2 ": local->local vid 10" 421 ping_test $h1.20 198.51.100.2 ": local->local vid 20" 422 ping_test $h1.10 192.0.2.3 ": local->remote 1 vid 10" 423 ping_test $h1.10 192.0.2.4 ": local->remote 2 vid 10" 424 ping_test $h1.20 198.51.100.3 ": local->remote 1 vid 20" 425 ping_test $h1.20 198.51.100.4 ": local->remote 2 vid 20" 426} 427 428maybe_in_ns() 429{ 430 echo ${1:+in_ns} $1 431} 432 433__flood_counter_add_del() 434{ 435 local add_del=$1; shift 436 local dev=$1; shift 437 local ns=$1; shift 438 439 # Putting the ICMP capture both to HW and to SW will end up 440 # double-counting the packets that are trapped to slow path, such as for 441 # the unicast test. Adding either skip_hw or skip_sw fixes this problem, 442 # but with skip_hw, the flooded packets are not counted at all, because 443 # those are dropped due to MAC address mismatch; and skip_sw is a no-go 444 # for veth-based topologies. 445 # 446 # So try to install with skip_sw and fall back to skip_sw if that fails. 447 448 $(maybe_in_ns $ns) __icmp_capture_add_del \ 449 $add_del 100 "" $dev skip_sw 2>/dev/null || \ 450 $(maybe_in_ns $ns) __icmp_capture_add_del \ 451 $add_del 100 "" $dev skip_hw 452} 453 454flood_counter_install() 455{ 456 __flood_counter_add_del add "$@" 457} 458 459flood_counter_uninstall() 460{ 461 __flood_counter_add_del del "$@" 462} 463 464flood_fetch_stat() 465{ 466 local dev=$1; shift 467 local ns=$1; shift 468 469 $(maybe_in_ns $ns) tc_rule_stats_get $dev 100 ingress 470} 471 472flood_fetch_stats() 473{ 474 local counters=("${@}") 475 local counter 476 477 for counter in "${counters[@]}"; do 478 flood_fetch_stat $counter 479 done 480} 481 482vxlan_flood_test() 483{ 484 local mac=$1; shift 485 local dst=$1; shift 486 local vid=$1; shift 487 local -a expects=("${@}") 488 489 local -a counters=($h2 "vx10 ns1" "vx20 ns1" "vx10 ns2" "vx20 ns2") 490 local counter 491 local key 492 493 # Packets reach the local host tagged whereas they reach the VxLAN 494 # devices untagged. In order to be able to use the same filter for 495 # all counters, make sure the packets also reach the local host 496 # untagged 497 bridge vlan add vid $vid dev $swp2 untagged 498 for counter in "${counters[@]}"; do 499 flood_counter_install $counter 500 done 501 502 local -a t0s=($(flood_fetch_stats "${counters[@]}")) 503 $MZ $h1 -Q $vid -c 10 -d 100msec -p 64 -b $mac -B $dst -t icmp -q 504 sleep 1 505 local -a t1s=($(flood_fetch_stats "${counters[@]}")) 506 507 for key in ${!t0s[@]}; do 508 local delta=$((t1s[$key] - t0s[$key])) 509 local expect=${expects[$key]} 510 511 ((expect == delta)) 512 check_err $? "${counters[$key]}: Expected to capture $expect packets, got $delta." 513 done 514 515 for counter in "${counters[@]}"; do 516 flood_counter_uninstall $counter 517 done 518 bridge vlan add vid $vid dev $swp2 519} 520 521__test_flood() 522{ 523 local mac=$1; shift 524 local dst=$1; shift 525 local vid=$1; shift 526 local what=$1; shift 527 local -a expects=("${@}") 528 529 RET=0 530 531 vxlan_flood_test $mac $dst $vid "${expects[@]}" 532 533 log_test "VXLAN: $what" 534} 535 536test_flood() 537{ 538 __test_flood de:ad:be:ef:13:37 192.0.2.100 10 "flood vlan 10" \ 539 10 10 0 10 0 540 __test_flood ca:fe:be:ef:13:37 198.51.100.100 20 "flood vlan 20" \ 541 10 0 10 0 10 542} 543 544vxlan_fdb_add_del() 545{ 546 local add_del=$1; shift 547 local vid=$1; shift 548 local mac=$1; shift 549 local dev=$1; shift 550 local dst=$1; shift 551 552 bridge fdb $add_del dev $dev $mac self static permanent \ 553 ${dst:+dst} $dst 2>/dev/null 554 bridge fdb $add_del dev $dev $mac master static vlan $vid 2>/dev/null 555} 556 557__test_unicast() 558{ 559 local mac=$1; shift 560 local dst=$1; shift 561 local hit_idx=$1; shift 562 local vid=$1; shift 563 local what=$1; shift 564 565 RET=0 566 567 local -a expects=(0 0 0 0 0) 568 expects[$hit_idx]=10 569 570 vxlan_flood_test $mac $dst $vid "${expects[@]}" 571 572 log_test "VXLAN: $what" 573} 574 575test_unicast() 576{ 577 local -a targets=("$h2_mac $h2" 578 "$r1_mac vx10 192.0.2.34" 579 "$r2_mac vx10 192.0.2.50") 580 local target 581 582 log_info "unicast vlan 10" 583 584 for target in "${targets[@]}"; do 585 vxlan_fdb_add_del add 10 $target 586 done 587 588 __test_unicast $h2_mac 192.0.2.2 0 10 "local MAC unicast" 589 __test_unicast $r1_mac 192.0.2.3 1 10 "remote MAC 1 unicast" 590 __test_unicast $r2_mac 192.0.2.4 3 10 "remote MAC 2 unicast" 591 592 for target in "${targets[@]}"; do 593 vxlan_fdb_add_del del 10 $target 594 done 595 596 log_info "unicast vlan 20" 597 598 targets=("$h2_mac $h2" "$r1_mac vx20 192.0.2.34" \ 599 "$r2_mac vx20 192.0.2.50") 600 601 for target in "${targets[@]}"; do 602 vxlan_fdb_add_del add 20 $target 603 done 604 605 __test_unicast $h2_mac 198.51.100.2 0 20 "local MAC unicast" 606 __test_unicast $r1_mac 198.51.100.3 2 20 "remote MAC 1 unicast" 607 __test_unicast $r2_mac 198.51.100.4 4 20 "remote MAC 2 unicast" 608 609 for target in "${targets[@]}"; do 610 vxlan_fdb_add_del del 20 $target 611 done 612} 613 614test_pvid() 615{ 616 local -a expects=(0 0 0 0 0) 617 local mac=de:ad:be:ef:13:37 618 local dst=192.0.2.100 619 local vid=10 620 621 # Check that flooding works 622 RET=0 623 624 expects[0]=10; expects[1]=10; expects[3]=10 625 vxlan_flood_test $mac $dst $vid "${expects[@]}" 626 627 log_test "VXLAN: flood before pvid off" 628 629 # Toggle PVID off and test that flood to remote hosts does not work 630 RET=0 631 632 bridge vlan add vid 10 dev vx10 633 634 expects[0]=10; expects[1]=0; expects[3]=0 635 vxlan_flood_test $mac $dst $vid "${expects[@]}" 636 637 log_test "VXLAN: flood after pvid off" 638 639 # Toggle PVID on and test that flood to remote hosts does work 640 RET=0 641 642 bridge vlan add vid 10 dev vx10 pvid untagged 643 644 expects[0]=10; expects[1]=10; expects[3]=10 645 vxlan_flood_test $mac $dst $vid "${expects[@]}" 646 647 log_test "VXLAN: flood after pvid on" 648 649 # Add a new VLAN and test that it does not affect flooding 650 RET=0 651 652 bridge vlan add vid 30 dev vx10 653 654 expects[0]=10; expects[1]=10; expects[3]=10 655 vxlan_flood_test $mac $dst $vid "${expects[@]}" 656 657 bridge vlan del vid 30 dev vx10 658 659 log_test "VXLAN: flood after vlan add" 660 661 # Remove currently mapped VLAN and test that flood to remote hosts does 662 # not work 663 RET=0 664 665 bridge vlan del vid 10 dev vx10 666 667 expects[0]=10; expects[1]=0; expects[3]=0 668 vxlan_flood_test $mac $dst $vid "${expects[@]}" 669 670 log_test "VXLAN: flood after vlan delete" 671 672 # Re-add the VLAN and test that flood to remote hosts does work 673 RET=0 674 675 bridge vlan add vid 10 dev vx10 pvid untagged 676 677 expects[0]=10; expects[1]=10; expects[3]=10 678 vxlan_flood_test $mac $dst $vid "${expects[@]}" 679 680 log_test "VXLAN: flood after vlan re-add" 681} 682 683vxlan_ping_test() 684{ 685 local ping_dev=$1; shift 686 local ping_dip=$1; shift 687 local ping_args=$1; shift 688 local capture_dev=$1; shift 689 local capture_dir=$1; shift 690 local capture_pref=$1; shift 691 local expect=$1; shift 692 693 local t0=$(tc_rule_stats_get $capture_dev $capture_pref $capture_dir) 694 ping_do $ping_dev $ping_dip "$ping_args" 695 local t1=$(tc_rule_stats_get $capture_dev $capture_pref $capture_dir) 696 local delta=$((t1 - t0)) 697 698 # Tolerate a couple stray extra packets. 699 ((expect <= delta && delta <= expect + 2)) 700 check_err $? "$capture_dev: Expected to capture $expect packets, got $delta." 701} 702 703__test_learning() 704{ 705 local -a expects=(0 0 0 0 0) 706 local mac=$1; shift 707 local dst=$1; shift 708 local vid=$1; shift 709 local idx1=$1; shift 710 local idx2=$1; shift 711 local vx=vx$vid 712 713 # Check that flooding works 714 RET=0 715 716 expects[0]=10; expects[$idx1]=10; expects[$idx2]=10 717 vxlan_flood_test $mac $dst $vid "${expects[@]}" 718 719 log_test "VXLAN: flood before learning" 720 721 # Send a packet with source mac set to $mac from host w2 and check that 722 # a corresponding entry is created in the VxLAN device 723 RET=0 724 725 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 726 -B $dst -t icmp -q 727 sleep 1 728 729 bridge fdb show brport $vx | grep $mac | grep -q self 730 check_err $? 731 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 732 | grep -q -v self 733 check_err $? 734 735 log_test "VXLAN: show learned FDB entry" 736 737 # Repeat first test and check that packets only reach host w2 in ns1 738 RET=0 739 740 expects[0]=0; expects[$idx1]=10; expects[$idx2]=0 741 vxlan_flood_test $mac $dst $vid "${expects[@]}" 742 743 log_test "VXLAN: learned FDB entry" 744 745 # Delete the learned FDB entry from the VxLAN and bridge devices and 746 # check that packets are flooded 747 RET=0 748 749 bridge fdb del dev $vx $mac master self vlan $vid 750 sleep 1 751 752 expects[0]=10; expects[$idx1]=10; expects[$idx2]=10 753 vxlan_flood_test $mac $dst $vid "${expects[@]}" 754 755 log_test "VXLAN: deletion of learned FDB entry" 756 757 # Re-learn the first FDB entry and check that it is correctly aged-out 758 RET=0 759 760 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 761 -B $dst -t icmp -q 762 sleep 1 763 764 bridge fdb show brport $vx | grep $mac | grep -q self 765 check_err $? 766 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 767 | grep -q -v self 768 check_err $? 769 770 expects[0]=0; expects[$idx1]=10; expects[$idx2]=0 771 vxlan_flood_test $mac $dst $vid "${expects[@]}" 772 773 sleep 20 774 775 bridge fdb show brport $vx | grep $mac | grep -q self 776 check_fail $? 777 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 778 | grep -q -v self 779 check_fail $? 780 781 expects[0]=10; expects[$idx1]=10; expects[$idx2]=10 782 vxlan_flood_test $mac $dst $vid "${expects[@]}" 783 784 log_test "VXLAN: Ageing of learned FDB entry" 785 786 # Toggle learning on the bridge port and check that the bridge's FDB 787 # is populated only when it should 788 RET=0 789 790 ip link set dev $vx type bridge_slave learning off 791 792 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 793 -B $dst -t icmp -q 794 sleep 1 795 796 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 797 | grep -q -v self 798 check_fail $? 799 800 ip link set dev $vx type bridge_slave learning on 801 802 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 803 -B $dst -t icmp -q 804 sleep 1 805 806 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 807 | grep -q -v self 808 check_err $? 809 810 log_test "VXLAN: learning toggling on bridge port" 811} 812 813test_learning() 814{ 815 local mac=de:ad:be:ef:13:37 816 local dst=192.0.2.100 817 local vid=10 818 819 # Enable learning on the VxLAN devices and set ageing time to 10 seconds 820 ip link set dev br1 type bridge ageing_time 1000 821 ip link set dev vx10 type vxlan ageing 10 822 ip link set dev vx10 type vxlan learning 823 ip link set dev vx20 type vxlan ageing 10 824 ip link set dev vx20 type vxlan learning 825 reapply_config 826 827 log_info "learning vlan 10" 828 829 __test_learning $mac $dst $vid 1 3 830 831 log_info "learning vlan 20" 832 833 mac=ca:fe:be:ef:13:37 834 dst=198.51.100.100 835 vid=20 836 837 __test_learning $mac $dst $vid 2 4 838 839 # Restore previous settings 840 ip link set dev vx20 type vxlan nolearning 841 ip link set dev vx20 type vxlan ageing 300 842 ip link set dev vx10 type vxlan nolearning 843 ip link set dev vx10 type vxlan ageing 300 844 ip link set dev br1 type bridge ageing_time 30000 845 reapply_config 846} 847 848test_all() 849{ 850 log_info "Running tests with UDP port $VXPORT" 851 tests_run 852} 853 854trap cleanup EXIT 855 856setup_prepare 857setup_wait 858test_all 859 860exit $EXIT_STATUS 861