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 # Add entries with arbitrary destination IP. Verify that packets are 544 # not duplicated (this can happen if hardware floods the packets, and 545 # then traps them due to misconfiguration, so software data path repeats 546 # flooding and resends packets). 547 bridge fdb append dev vx10 00:00:00:00:00:00 dst 203.0.113.1 self 548 bridge fdb append dev vx20 00:00:00:00:00:00 dst 203.0.113.2 self 549 550 __test_flood de:ad:be:ef:13:37 192.0.2.100 10 \ 551 "flood vlan 10, unresolved FDB entry" 10 10 0 10 0 552 __test_flood ca:fe:be:ef:13:37 198.51.100.100 20 \ 553 "flood vlan 20, unresolved FDB entry" 10 0 10 0 10 554 555 bridge fdb del dev vx20 00:00:00:00:00:00 dst 203.0.113.2 self 556 bridge fdb del dev vx10 00:00:00:00:00:00 dst 203.0.113.1 self 557} 558 559vxlan_fdb_add_del() 560{ 561 local add_del=$1; shift 562 local vid=$1; shift 563 local mac=$1; shift 564 local dev=$1; shift 565 local dst=$1; shift 566 567 bridge fdb $add_del dev $dev $mac self static permanent \ 568 ${dst:+dst} $dst 2>/dev/null 569 bridge fdb $add_del dev $dev $mac master static vlan $vid 2>/dev/null 570} 571 572__test_unicast() 573{ 574 local mac=$1; shift 575 local dst=$1; shift 576 local hit_idx=$1; shift 577 local vid=$1; shift 578 local what=$1; shift 579 580 RET=0 581 582 local -a expects=(0 0 0 0 0) 583 expects[$hit_idx]=10 584 585 vxlan_flood_test $mac $dst $vid "${expects[@]}" 586 587 log_test "VXLAN: $what" 588} 589 590test_unicast() 591{ 592 local -a targets=("$h2_mac $h2" 593 "$r1_mac vx10 192.0.2.34" 594 "$r2_mac vx10 192.0.2.50") 595 local target 596 597 log_info "unicast vlan 10" 598 599 for target in "${targets[@]}"; do 600 vxlan_fdb_add_del add 10 $target 601 done 602 603 __test_unicast $h2_mac 192.0.2.2 0 10 "local MAC unicast" 604 __test_unicast $r1_mac 192.0.2.3 1 10 "remote MAC 1 unicast" 605 __test_unicast $r2_mac 192.0.2.4 3 10 "remote MAC 2 unicast" 606 607 for target in "${targets[@]}"; do 608 vxlan_fdb_add_del del 10 $target 609 done 610 611 log_info "unicast vlan 20" 612 613 targets=("$h2_mac $h2" "$r1_mac vx20 192.0.2.34" \ 614 "$r2_mac vx20 192.0.2.50") 615 616 for target in "${targets[@]}"; do 617 vxlan_fdb_add_del add 20 $target 618 done 619 620 __test_unicast $h2_mac 198.51.100.2 0 20 "local MAC unicast" 621 __test_unicast $r1_mac 198.51.100.3 2 20 "remote MAC 1 unicast" 622 __test_unicast $r2_mac 198.51.100.4 4 20 "remote MAC 2 unicast" 623 624 for target in "${targets[@]}"; do 625 vxlan_fdb_add_del del 20 $target 626 done 627} 628 629test_pvid() 630{ 631 local -a expects=(0 0 0 0 0) 632 local mac=de:ad:be:ef:13:37 633 local dst=192.0.2.100 634 local vid=10 635 636 # Check that flooding works 637 RET=0 638 639 expects[0]=10; expects[1]=10; expects[3]=10 640 vxlan_flood_test $mac $dst $vid "${expects[@]}" 641 642 log_test "VXLAN: flood before pvid off" 643 644 # Toggle PVID off and test that flood to remote hosts does not work 645 RET=0 646 647 bridge vlan add vid 10 dev vx10 648 649 expects[0]=10; expects[1]=0; expects[3]=0 650 vxlan_flood_test $mac $dst $vid "${expects[@]}" 651 652 log_test "VXLAN: flood after pvid off" 653 654 # Toggle PVID on and test that flood to remote hosts does work 655 RET=0 656 657 bridge vlan add vid 10 dev vx10 pvid untagged 658 659 expects[0]=10; expects[1]=10; expects[3]=10 660 vxlan_flood_test $mac $dst $vid "${expects[@]}" 661 662 log_test "VXLAN: flood after pvid on" 663 664 # Add a new VLAN and test that it does not affect flooding 665 RET=0 666 667 bridge vlan add vid 30 dev vx10 668 669 expects[0]=10; expects[1]=10; expects[3]=10 670 vxlan_flood_test $mac $dst $vid "${expects[@]}" 671 672 bridge vlan del vid 30 dev vx10 673 674 log_test "VXLAN: flood after vlan add" 675 676 # Remove currently mapped VLAN and test that flood to remote hosts does 677 # not work 678 RET=0 679 680 bridge vlan del vid 10 dev vx10 681 682 expects[0]=10; expects[1]=0; expects[3]=0 683 vxlan_flood_test $mac $dst $vid "${expects[@]}" 684 685 log_test "VXLAN: flood after vlan delete" 686 687 # Re-add the VLAN and test that flood to remote hosts does work 688 RET=0 689 690 bridge vlan add vid 10 dev vx10 pvid untagged 691 692 expects[0]=10; expects[1]=10; expects[3]=10 693 vxlan_flood_test $mac $dst $vid "${expects[@]}" 694 695 log_test "VXLAN: flood after vlan re-add" 696} 697 698__test_learning() 699{ 700 local -a expects=(0 0 0 0 0) 701 local mac=$1; shift 702 local dst=$1; shift 703 local vid=$1; shift 704 local idx1=$1; shift 705 local idx2=$1; shift 706 local vx=vx$vid 707 708 # Check that flooding works 709 RET=0 710 711 expects[0]=10; expects[$idx1]=10; expects[$idx2]=10 712 vxlan_flood_test $mac $dst $vid "${expects[@]}" 713 714 log_test "VXLAN: flood before learning" 715 716 # Send a packet with source mac set to $mac from host w2 and check that 717 # a corresponding entry is created in the VxLAN device 718 RET=0 719 720 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 721 -B $dst -t icmp -q 722 sleep 1 723 724 bridge fdb show brport $vx | grep $mac | grep -q self 725 check_err $? 726 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 727 | grep -q -v self 728 check_err $? 729 730 log_test "VXLAN: show learned FDB entry" 731 732 # Repeat first test and check that packets only reach host w2 in ns1 733 RET=0 734 735 expects[0]=0; expects[$idx1]=10; expects[$idx2]=0 736 vxlan_flood_test $mac $dst $vid "${expects[@]}" 737 738 log_test "VXLAN: learned FDB entry" 739 740 # Delete the learned FDB entry from the VxLAN and bridge devices and 741 # check that packets are flooded 742 RET=0 743 744 bridge fdb del dev $vx $mac master self vlan $vid 745 sleep 1 746 747 expects[0]=10; expects[$idx1]=10; expects[$idx2]=10 748 vxlan_flood_test $mac $dst $vid "${expects[@]}" 749 750 log_test "VXLAN: deletion of learned FDB entry" 751 752 # Re-learn the first FDB entry and check that it is correctly aged-out 753 RET=0 754 755 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 756 -B $dst -t icmp -q 757 sleep 1 758 759 bridge fdb show brport $vx | grep $mac | grep -q self 760 check_err $? 761 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 762 | grep -q -v self 763 check_err $? 764 765 expects[0]=0; expects[$idx1]=10; expects[$idx2]=0 766 vxlan_flood_test $mac $dst $vid "${expects[@]}" 767 768 sleep 60 769 770 bridge fdb show brport $vx | grep $mac | grep -q self 771 check_fail $? 772 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 773 | grep -q -v self 774 check_fail $? 775 776 expects[0]=10; expects[$idx1]=10; expects[$idx2]=10 777 vxlan_flood_test $mac $dst $vid "${expects[@]}" 778 779 log_test "VXLAN: Ageing of learned FDB entry" 780 781 # Toggle learning on the bridge port and check that the bridge's FDB 782 # is populated only when it should 783 RET=0 784 785 ip link set dev $vx type bridge_slave learning off 786 787 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 788 -B $dst -t icmp -q 789 sleep 1 790 791 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 792 | grep -q -v self 793 check_fail $? 794 795 ip link set dev $vx type bridge_slave learning on 796 797 in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \ 798 -B $dst -t icmp -q 799 sleep 1 800 801 bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \ 802 | grep -q -v self 803 check_err $? 804 805 log_test "VXLAN: learning toggling on bridge port" 806} 807 808test_learning() 809{ 810 local mac=de:ad:be:ef:13:37 811 local dst=192.0.2.100 812 local vid=10 813 814 # Enable learning on the VxLAN devices and set ageing time to 30 seconds 815 ip link set dev br1 type bridge ageing_time 3000 816 ip link set dev vx10 type vxlan ageing 30 817 ip link set dev vx10 type vxlan learning 818 ip link set dev vx20 type vxlan ageing 30 819 ip link set dev vx20 type vxlan learning 820 reapply_config 821 822 log_info "learning vlan 10" 823 824 __test_learning $mac $dst $vid 1 3 825 826 log_info "learning vlan 20" 827 828 mac=ca:fe:be:ef:13:37 829 dst=198.51.100.100 830 vid=20 831 832 __test_learning $mac $dst $vid 2 4 833 834 # Restore previous settings 835 ip link set dev vx20 type vxlan nolearning 836 ip link set dev vx20 type vxlan ageing 300 837 ip link set dev vx10 type vxlan nolearning 838 ip link set dev vx10 type vxlan ageing 300 839 ip link set dev br1 type bridge ageing_time 30000 840 reapply_config 841} 842 843test_all() 844{ 845 log_info "Running tests with UDP port $VXPORT" 846 tests_run 847} 848 849trap cleanup EXIT 850 851setup_prepare 852setup_wait 853test_all 854 855exit $EXIT_STATUS 856