798 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# +--------------------+ +----------------------+5# | H1 (vrf) | | H2 (vrf) |6# | + $h1 | | + $h2 |7# | | 192.0.2.1/28 | | | 192.0.2.2/28 |8# +----|---------------+ +--|-------------------+9# | |10# +----|--------------------------------------------------|-------------------+11# | SW | | |12# | +--|--------------------------------------------------|-----------------+ |13# | | + $swp1 BR1 (802.1d) + $swp2 | |14# | | | |15# | | + vx1 (vxlan) | |16# | | local 192.0.2.17 | |17# | | remote 192.0.2.34 192.0.2.50 | |18# | | id 1000 dstport $VXPORT | |19# | +-----------------------------------------------------------------------+ |20# | |21# | 192.0.2.32/28 via 192.0.2.18 |22# | 192.0.2.48/28 via 192.0.2.18 |23# | |24# | + $rp1 |25# | | 192.0.2.17/28 |26# +----|----------------------------------------------------------------------+27# |28# +----|--------------------------------------------------------+29# | | VRP2 (vrf) |30# | + $rp2 |31# | 192.0.2.18/28 |32# | | (maybe) HW33# =============================================================================34# | | (likely) SW35# | + v1 (veth) + v3 (veth) |36# | | 192.0.2.33/28 | 192.0.2.49/28 |37# +----|---------------------------------------|----------------+38# | |39# +----|------------------------------+ +----|------------------------------+40# | + v2 (veth) NS1 (netns) | | + v4 (veth) NS2 (netns) |41# | 192.0.2.34/28 | | 192.0.2.50/28 |42# | | | |43# | 192.0.2.16/28 via 192.0.2.33 | | 192.0.2.16/28 via 192.0.2.49 |44# | 192.0.2.50/32 via 192.0.2.33 | | 192.0.2.34/32 via 192.0.2.49 |45# | | | |46# | +-------------------------------+ | | +-------------------------------+ |47# | | BR2 (802.1d) | | | | BR2 (802.1d) | |48# | | + vx2 (vxlan) | | | | + vx2 (vxlan) | |49# | | local 192.0.2.34 | | | | local 192.0.2.50 | |50# | | remote 192.0.2.17 | | | | remote 192.0.2.17 | |51# | | remote 192.0.2.50 | | | | remote 192.0.2.34 | |52# | | id 1000 dstport $VXPORT | | | | id 1000 dstport $VXPORT | |53# | | | | | | | |54# | | + w1 (veth) | | | | + w1 (veth) | |55# | +--|----------------------------+ | | +--|----------------------------+ |56# | | | | | |57# | +--|----------------------------+ | | +--|----------------------------+ |58# | | | VW2 (vrf) | | | | | VW2 (vrf) | |59# | | + w2 (veth) | | | | + w2 (veth) | |60# | | 192.0.2.3/28 | | | | 192.0.2.4/28 | |61# | +-------------------------------+ | | +-------------------------------+ |62# +-----------------------------------+ +-----------------------------------+63 64: ${VXPORT:=4789}65export VXPORT66 67: ${ALL_TESTS:="68 ping_ipv469 test_flood70 test_unicast71 test_ttl72 test_tos73 test_ecn_encap74 test_ecn_decap75 reapply_config76 ping_ipv477 test_flood78 test_unicast79 test_learning80 "}81 82NUM_NETIFS=683source lib.sh84 85h1_create()86{87 simple_if_init $h1 192.0.2.1/2888 tc qdisc add dev $h1 clsact89}90 91h1_destroy()92{93 tc qdisc del dev $h1 clsact94 simple_if_fini $h1 192.0.2.1/2895}96 97h2_create()98{99 simple_if_init $h2 192.0.2.2/28100 tc qdisc add dev $h2 clsact101}102 103h2_destroy()104{105 tc qdisc del dev $h2 clsact106 simple_if_fini $h2 192.0.2.2/28107}108 109rp1_set_addr()110{111 ip address add dev $rp1 192.0.2.17/28112 113 ip route add 192.0.2.32/28 nexthop via 192.0.2.18114 ip route add 192.0.2.48/28 nexthop via 192.0.2.18115}116 117rp1_unset_addr()118{119 ip route del 192.0.2.48/28 nexthop via 192.0.2.18120 ip route del 192.0.2.32/28 nexthop via 192.0.2.18121 122 ip address del dev $rp1 192.0.2.17/28123}124 125switch_create()126{127 ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0128 # Make sure the bridge uses the MAC address of the local port and not129 # that of the VxLAN's device.130 ip link set dev br1 address $(mac_get $swp1)131 ip link set dev br1 up132 133 ip link set dev $rp1 up134 rp1_set_addr135 136 ip link add name vx1 type vxlan id 1000 \137 local 192.0.2.17 dstport "$VXPORT" \138 nolearning noudpcsum tos inherit ttl 100139 ip link set dev vx1 up140 141 ip link set dev vx1 master br1142 ip link set dev $swp1 master br1143 ip link set dev $swp1 up144 145 ip link set dev $swp2 master br1146 ip link set dev $swp2 up147 148 bridge fdb append dev vx1 00:00:00:00:00:00 dst 192.0.2.34 self149 bridge fdb append dev vx1 00:00:00:00:00:00 dst 192.0.2.50 self150}151 152switch_destroy()153{154 rp1_unset_addr155 ip link set dev $rp1 down156 157 bridge fdb del dev vx1 00:00:00:00:00:00 dst 192.0.2.50 self158 bridge fdb del dev vx1 00:00:00:00:00:00 dst 192.0.2.34 self159 160 ip link set dev vx1 nomaster161 ip link set dev vx1 down162 ip link del dev vx1163 164 ip link set dev $swp2 down165 ip link set dev $swp2 nomaster166 167 ip link set dev $swp1 down168 ip link set dev $swp1 nomaster169 170 ip link set dev br1 down171 ip link del dev br1172}173 174vrp2_create()175{176 simple_if_init $rp2 192.0.2.18/28177 __simple_if_init v1 v$rp2 192.0.2.33/28178 __simple_if_init v3 v$rp2 192.0.2.49/28179 tc qdisc add dev v1 clsact180}181 182vrp2_destroy()183{184 tc qdisc del dev v1 clsact185 __simple_if_fini v3 192.0.2.49/28186 __simple_if_fini v1 192.0.2.33/28187 simple_if_fini $rp2 192.0.2.18/28188}189 190ns_init_common()191{192 local in_if=$1; shift193 local in_addr=$1; shift194 local other_in_addr=$1; shift195 local nh_addr=$1; shift196 local host_addr=$1; shift197 198 ip link set dev $in_if up199 ip address add dev $in_if $in_addr/28200 tc qdisc add dev $in_if clsact201 202 ip link add name br2 type bridge vlan_filtering 0203 ip link set dev br2 up204 205 ip link add name w1 type veth peer name w2206 207 ip link set dev w1 master br2208 ip link set dev w1 up209 210 ip link add name vx2 type vxlan id 1000 local $in_addr dstport "$VXPORT"211 ip link set dev vx2 up212 bridge fdb append dev vx2 00:00:00:00:00:00 dst 192.0.2.17 self213 bridge fdb append dev vx2 00:00:00:00:00:00 dst $other_in_addr self214 215 ip link set dev vx2 master br2216 tc qdisc add dev vx2 clsact217 218 simple_if_init w2 $host_addr/28219 220 ip route add 192.0.2.16/28 nexthop via $nh_addr221 ip route add $other_in_addr/32 nexthop via $nh_addr222}223export -f ns_init_common224 225ns1_create()226{227 ip netns add ns1228 ip link set dev v2 netns ns1229 in_ns ns1 \230 ns_init_common v2 192.0.2.34 192.0.2.50 192.0.2.33 192.0.2.3231}232 233ns1_destroy()234{235 ip netns exec ns1 ip link set dev v2 netns 1236 ip netns del ns1237}238 239ns2_create()240{241 ip netns add ns2242 ip link set dev v4 netns ns2243 in_ns ns2 \244 ns_init_common v4 192.0.2.50 192.0.2.34 192.0.2.49 192.0.2.4245}246 247ns2_destroy()248{249 ip netns exec ns2 ip link set dev v4 netns 1250 ip netns del ns2251}252 253setup_prepare()254{255 h1=${NETIFS[p1]}256 swp1=${NETIFS[p2]}257 258 swp2=${NETIFS[p3]}259 h2=${NETIFS[p4]}260 261 rp1=${NETIFS[p5]}262 rp2=${NETIFS[p6]}263 264 vrf_prepare265 forwarding_enable266 267 h1_create268 h2_create269 switch_create270 271 ip link add name v1 type veth peer name v2272 ip link add name v3 type veth peer name v4273 vrp2_create274 ns1_create275 ns2_create276 277 r1_mac=$(in_ns ns1 mac_get w2)278 r2_mac=$(in_ns ns2 mac_get w2)279 h2_mac=$(mac_get $h2)280}281 282cleanup()283{284 pre_cleanup285 286 ns2_destroy287 ns1_destroy288 vrp2_destroy289 ip link del dev v3290 ip link del dev v1291 292 switch_destroy293 h2_destroy294 h1_destroy295 296 forwarding_restore297 vrf_cleanup298}299 300# For the first round of tests, vx1 is the first device to get attached to the301# bridge, and that at the point that the local IP is already configured. Try the302# other scenario of attaching the device to an already-offloaded bridge, and303# only then attach the local IP.304reapply_config()305{306 echo "Reapplying configuration"307 308 bridge fdb del dev vx1 00:00:00:00:00:00 dst 192.0.2.50 self309 bridge fdb del dev vx1 00:00:00:00:00:00 dst 192.0.2.34 self310 rp1_unset_addr311 ip link set dev vx1 nomaster312 sleep 5313 314 ip link set dev vx1 master br1315 bridge fdb append dev vx1 00:00:00:00:00:00 dst 192.0.2.34 self316 bridge fdb append dev vx1 00:00:00:00:00:00 dst 192.0.2.50 self317 sleep 1318 rp1_set_addr319 sleep 5320}321 322ping_ipv4()323{324 ping_test $h1 192.0.2.2 ": local->local"325 ping_test $h1 192.0.2.3 ": local->remote 1"326 ping_test $h1 192.0.2.4 ": local->remote 2"327}328 329maybe_in_ns()330{331 echo ${1:+in_ns} $1332}333 334__flood_counter_add_del()335{336 local add_del=$1; shift337 local dev=$1; shift338 local ns=$1; shift339 340 # Putting the ICMP capture both to HW and to SW will end up341 # double-counting the packets that are trapped to slow path, such as for342 # the unicast test. Adding either skip_hw or skip_sw fixes this problem,343 # but with skip_hw, the flooded packets are not counted at all, because344 # those are dropped due to MAC address mismatch; and skip_sw is a no-go345 # for veth-based topologies.346 #347 # So try to install with skip_sw and fall back to skip_sw if that fails.348 349 $(maybe_in_ns $ns) __icmp_capture_add_del \350 $add_del 100 "" $dev skip_sw 2>/dev/null || \351 $(maybe_in_ns $ns) __icmp_capture_add_del \352 $add_del 100 "" $dev skip_hw353}354 355flood_counter_install()356{357 __flood_counter_add_del add "$@"358}359 360flood_counter_uninstall()361{362 __flood_counter_add_del del "$@"363}364 365flood_fetch_stat()366{367 local dev=$1; shift368 local ns=$1; shift369 370 $(maybe_in_ns $ns) tc_rule_stats_get $dev 100 ingress371}372 373flood_fetch_stats()374{375 local counters=("${@}")376 local counter377 378 for counter in "${counters[@]}"; do379 flood_fetch_stat $counter380 done381}382 383vxlan_flood_test()384{385 local mac=$1; shift386 local dst=$1; shift387 local -a expects=("${@}")388 389 local -a counters=($h2 "vx2 ns1" "vx2 ns2")390 local counter391 local key392 393 for counter in "${counters[@]}"; do394 flood_counter_install $counter395 done396 397 local -a t0s=($(flood_fetch_stats "${counters[@]}"))398 $MZ $h1 -c 10 -d 100msec -p 64 -b $mac -B $dst -t icmp -q399 sleep 1400 local -a t1s=($(flood_fetch_stats "${counters[@]}"))401 402 for key in ${!t0s[@]}; do403 local delta=$((t1s[$key] - t0s[$key]))404 local expect=${expects[$key]}405 406 ((expect == delta))407 check_err $? "${counters[$key]}: Expected to capture $expect packets, got $delta."408 done409 410 for counter in "${counters[@]}"; do411 flood_counter_uninstall $counter412 done413}414 415__test_flood()416{417 local mac=$1; shift418 local dst=$1; shift419 local what=$1; shift420 421 RET=0422 423 vxlan_flood_test $mac $dst 10 10 10424 425 log_test "VXLAN: $what"426}427 428test_flood()429{430 __test_flood de:ad:be:ef:13:37 192.0.2.100 "flood"431}432 433vxlan_fdb_add_del()434{435 local add_del=$1; shift436 local mac=$1; shift437 local dev=$1; shift438 local dst=$1; shift439 440 bridge fdb $add_del dev $dev $mac self static permanent \441 ${dst:+dst} $dst 2>/dev/null442 bridge fdb $add_del dev $dev $mac master static 2>/dev/null443}444 445__test_unicast()446{447 local mac=$1; shift448 local dst=$1; shift449 local hit_idx=$1; shift450 local what=$1; shift451 452 RET=0453 454 local -a expects=(0 0 0)455 expects[$hit_idx]=10456 457 vxlan_flood_test $mac $dst "${expects[@]}"458 459 log_test "VXLAN: $what"460}461 462test_unicast()463{464 local -a targets=("$h2_mac $h2"465 "$r1_mac vx1 192.0.2.34"466 "$r2_mac vx1 192.0.2.50")467 local target468 469 for target in "${targets[@]}"; do470 vxlan_fdb_add_del add $target471 done472 473 __test_unicast $h2_mac 192.0.2.2 0 "local MAC unicast"474 __test_unicast $r1_mac 192.0.2.3 1 "remote MAC 1 unicast"475 __test_unicast $r2_mac 192.0.2.4 2 "remote MAC 2 unicast"476 477 for target in "${targets[@]}"; do478 vxlan_fdb_add_del del $target479 done480}481 482vxlan_ping_test()483{484 local ping_dev=$1; shift485 local ping_dip=$1; shift486 local ping_args=$1; shift487 local capture_dev=$1; shift488 local capture_dir=$1; shift489 local capture_pref=$1; shift490 local expect=$1; shift491 492 local t0=$(tc_rule_stats_get $capture_dev $capture_pref $capture_dir)493 ping_do $ping_dev $ping_dip "$ping_args"494 local t1=$(tc_rule_stats_get $capture_dev $capture_pref $capture_dir)495 local delta=$((t1 - t0))496 497 # Tolerate a couple stray extra packets.498 ((expect <= delta && delta <= expect + 5))499 check_err $? "$capture_dev: Expected to capture $expect packets, got $delta."500}501 502test_ttl()503{504 RET=0505 506 tc filter add dev v1 egress pref 77 prot ip \507 flower ip_ttl 99 action pass508 vxlan_ping_test $h1 192.0.2.3 "" v1 egress 77 10509 tc filter del dev v1 egress pref 77 prot ip510 511 log_test "VXLAN: envelope TTL"512}513 514test_tos()515{516 RET=0517 518 tc filter add dev v1 egress pref 77 prot ip \519 flower ip_tos 0x14 action pass520 vxlan_ping_test $h1 192.0.2.3 "-Q 0x14" v1 egress 77 10521 vxlan_ping_test $h1 192.0.2.3 "-Q 0x18" v1 egress 77 0522 tc filter del dev v1 egress pref 77 prot ip523 524 log_test "VXLAN: envelope TOS inheritance"525}526 527__test_ecn_encap()528{529 local q=$1; shift530 local tos=$1; shift531 532 RET=0533 534 tc filter add dev v1 egress pref 77 prot ip \535 flower ip_tos $tos ip_proto udp dst_port $VXPORT action pass536 sleep 1537 vxlan_ping_test $h1 192.0.2.3 "-Q $q" v1 egress 77 10538 tc filter del dev v1 egress pref 77 prot ip539 540 log_test "VXLAN: ECN encap: $q->$tos"541}542 543test_ecn_encap()544{545 # In accordance with INET_ECN_encapsulate()546 __test_ecn_encap 0x00 0x00547 __test_ecn_encap 0x01 0x01548 __test_ecn_encap 0x02 0x02549 __test_ecn_encap 0x03 0x02550}551 552vxlan_encapped_ping_do()553{554 local count=$1; shift555 local dev=$1; shift556 local next_hop_mac=$1; shift557 local dest_ip=$1; shift558 local dest_mac=$1; shift559 local inner_tos=$1; shift560 local outer_tos=$1; shift561 562 $MZ $dev -c $count -d 100msec -q \563 -b $next_hop_mac -B $dest_ip \564 -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:565 )"08:"$( : VXLAN flags566 )"00:00:00:"$( : VXLAN reserved567 )"00:03:e8:"$( : VXLAN VNI568 )"00:"$( : VXLAN reserved569 )"$dest_mac:"$( : ETH daddr570 )"$(mac_get w2):"$( : ETH saddr571 )"08:00:"$( : ETH type572 )"45:"$( : IP version + IHL573 )"$inner_tos:"$( : IP TOS574 )"00:54:"$( : IP total length575 )"99:83:"$( : IP identification576 )"40:00:"$( : IP flags + frag off577 )"40:"$( : IP TTL578 )"01:"$( : IP proto579 )"00:00:"$( : IP header csum580 )"c0:00:02:03:"$( : IP saddr: 192.0.2.3581 )"c0:00:02:01:"$( : IP daddr: 192.0.2.1582 )"08:"$( : ICMP type583 )"00:"$( : ICMP code584 )"8b:f2:"$( : ICMP csum585 )"1f:6a:"$( : ICMP request identifier586 )"00:01:"$( : ICMP request sequence number587 )"4f:ff:c5:5b:00:00:00:00:"$( : ICMP payload588 )"6d:74:0b:00:00:00:00:00:"$( :589 )"10:11:12:13:14:15:16:17:"$( :590 )"18:19:1a:1b:1c:1d:1e:1f:"$( :591 )"20:21:22:23:24:25:26:27:"$( :592 )"28:29:2a:2b:2c:2d:2e:2f:"$( :593 )"30:31:32:33:34:35:36:37"594}595export -f vxlan_encapped_ping_do596 597vxlan_encapped_ping_test()598{599 local ping_dev=$1; shift600 local nh_dev=$1; shift601 local ping_dip=$1; shift602 local inner_tos=$1; shift603 local outer_tos=$1; shift604 local stat_get=$1; shift605 local expect=$1; shift606 607 local t0=$($stat_get)608 609 in_ns ns1 \610 vxlan_encapped_ping_do 10 $ping_dev $(mac_get $nh_dev) \611 $ping_dip $(mac_get $h1) \612 $inner_tos $outer_tos613 614 local t1=$($stat_get)615 local delta=$((t1 - t0))616 617 # Tolerate a couple stray extra packets.618 ((expect <= delta && delta <= expect + 2))619 check_err $? "Expected to capture $expect packets, got $delta."620}621export -f vxlan_encapped_ping_test622 623__test_ecn_decap()624{625 local orig_inner_tos=$1; shift626 local orig_outer_tos=$1; shift627 local decapped_tos=$1; shift628 629 RET=0630 631 tc filter add dev $h1 ingress pref 77 prot ip \632 flower ip_tos $decapped_tos action drop633 sleep 1634 vxlan_encapped_ping_test v2 v1 192.0.2.17 \635 $orig_inner_tos $orig_outer_tos \636 "tc_rule_stats_get $h1 77 ingress" 10637 tc filter del dev $h1 ingress pref 77638 639 log_test "VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->$decapped_tos"640}641 642test_ecn_decap_error()643{644 local orig_inner_tos=00645 local orig_outer_tos=03646 647 RET=0648 649 vxlan_encapped_ping_test v2 v1 192.0.2.17 \650 $orig_inner_tos $orig_outer_tos \651 "link_stats_rx_errors_get vx1" 10652 653 log_test "VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->error"654}655 656test_ecn_decap()657{658 # In accordance with INET_ECN_decapsulate()659 __test_ecn_decap 00 00 0x00660 __test_ecn_decap 00 01 0x00661 __test_ecn_decap 00 02 0x00662 # 00 03 is tested in test_ecn_decap_error()663 __test_ecn_decap 01 00 0x01664 __test_ecn_decap 01 01 0x01665 __test_ecn_decap 01 02 0x01666 __test_ecn_decap 01 03 0x03667 __test_ecn_decap 02 00 0x02668 __test_ecn_decap 02 01 0x01669 __test_ecn_decap 02 02 0x02670 __test_ecn_decap 02 03 0x03671 __test_ecn_decap 03 00 0x03672 __test_ecn_decap 03 01 0x03673 __test_ecn_decap 03 02 0x03674 __test_ecn_decap 03 03 0x03675 test_ecn_decap_error676}677 678test_learning()679{680 local mac=de:ad:be:ef:13:37681 local dst=192.0.2.100682 683 # Enable learning on the VxLAN device and set ageing time to 30 seconds684 ip link set dev br1 type bridge ageing_time 3000685 ip link set dev vx1 type vxlan ageing 30686 ip link set dev vx1 type vxlan learning687 reapply_config688 689 # Check that flooding works690 RET=0691 692 vxlan_flood_test $mac $dst 10 10 10693 694 log_test "VXLAN: flood before learning"695 696 # Send a packet with source mac set to $mac from host w2 and check that697 # a corresponding entry is created in VxLAN device vx1698 RET=0699 700 in_ns ns1 $MZ w2 -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff -B $dst \701 -t icmp -q702 sleep 1703 704 bridge fdb show brport vx1 | grep $mac | grep -q self705 check_err $?706 bridge fdb show brport vx1 | grep $mac | grep -q -v self707 check_err $?708 709 log_test "VXLAN: show learned FDB entry"710 711 # Repeat first test and check that packets only reach host w2 in ns1712 RET=0713 714 vxlan_flood_test $mac $dst 0 10 0715 716 log_test "VXLAN: learned FDB entry"717 718 # Delete the learned FDB entry from the VxLAN and bridge devices and719 # check that packets are flooded720 RET=0721 722 bridge fdb del dev vx1 $mac master self723 sleep 1724 725 vxlan_flood_test $mac $dst 10 10 10726 727 log_test "VXLAN: deletion of learned FDB entry"728 729 # Re-learn the first FDB entry and check that it is correctly aged-out730 RET=0731 732 in_ns ns1 $MZ w2 -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff -B $dst \733 -t icmp -q734 sleep 1735 736 bridge fdb show brport vx1 | grep $mac | grep -q self737 check_err $?738 bridge fdb show brport vx1 | grep $mac | grep -q -v self739 check_err $?740 741 vxlan_flood_test $mac $dst 0 10 0742 743 sleep 60744 745 bridge fdb show brport vx1 | grep $mac | grep -q self746 check_fail $?747 bridge fdb show brport vx1 | grep $mac | grep -q -v self748 check_fail $?749 750 vxlan_flood_test $mac $dst 10 10 10751 752 log_test "VXLAN: Ageing of learned FDB entry"753 754 # Toggle learning on the bridge port and check that the bridge's FDB755 # is populated only when it should756 RET=0757 758 ip link set dev vx1 type bridge_slave learning off759 760 in_ns ns1 $MZ w2 -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff -B $dst \761 -t icmp -q762 sleep 1763 764 bridge fdb show brport vx1 | grep $mac | grep -q -v self765 check_fail $?766 767 ip link set dev vx1 type bridge_slave learning on768 769 in_ns ns1 $MZ w2 -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff -B $dst \770 -t icmp -q771 sleep 1772 773 bridge fdb show brport vx1 | grep $mac | grep -q -v self774 check_err $?775 776 log_test "VXLAN: learning toggling on bridge port"777 778 # Restore previous settings779 ip link set dev vx1 type vxlan nolearning780 ip link set dev vx1 type vxlan ageing 300781 ip link set dev br1 type bridge ageing_time 30000782 reapply_config783}784 785test_all()786{787 echo "Running tests with UDP port $VXPORT"788 tests_run789}790 791trap cleanup EXIT792 793setup_prepare794setup_wait795test_all796 797exit $EXIT_STATUS798