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