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