1# 2# Copyright (c) 2014 Spectra Logic Corporation 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions, and the following disclaimer, 10# without modification. 11# 2. Redistributions in binary form must reproduce at minimum a disclaimer 12# substantially similar to the "NO WARRANTY" disclaimer below 13# ("Disclaimer") and any redistribution must be conditioned upon 14# including a substantially similar Disclaimer requirement for further 15# binary redistribution. 16# 17# NO WARRANTY 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28# POSSIBILITY OF SUCH DAMAGES. 29# 30# Authors: Alan Somers (Spectra Logic Corporation) 31# 32 33# Outline: 34# For each cloned interface type, do three tests 35# 1) Create and destroy it 36# 2) Create, up, and destroy it 37# 3) Create, disable IPv6 auto address assignment, up, and destroy it 38 39TESTLEN=10 # seconds 40 41atf_test_case epair_stress cleanup 42epair_stress_head() 43{ 44 atf_set "descr" "Simultaneously create and destroy an epair(4)" 45 atf_set "require.user" "root" 46} 47epair_stress_body() 48{ 49 do_stress "epair" 50} 51epair_stress_cleanup() 52{ 53 cleanup_ifaces 54} 55 56atf_test_case epair_up_stress cleanup 57epair_up_stress_head() 58{ 59 atf_set "descr" "Simultaneously up and detroy an epair(4)" 60 atf_set "require.user" "root" 61} 62epair_up_stress_body() 63{ 64 do_up_stress "epair" "" "" 65} 66epair_up_stress_cleanup() 67{ 68 cleanup_ifaces 69} 70 71atf_test_case epair_destroy_race cleanup 72epair_destroy_race_head() 73{ 74 atf_set "descr" "Race if_detach() and if_vmove()" 75 atf_set "require.user" "root" 76} 77epair_destroy_race_body() 78{ 79 for i in `seq 1 10` 80 do 81 epair_a=$(ifconfig epair create) 82 echo $epair_a >> devices_to_cleanup 83 epair_b=${epair_a%a}b 84 85 jail -c vnet name="epair_destroy" nopersist path=/ \ 86 host.hostname="epair_destroy" vnet.interface="$epair_b" \ 87 command=sh -c "ifconfig $epair_b 192.0.2.1/24; sleep 0.1"& 88 pid=$! 89 ifconfig "$epair_a" destroy 90 wait $pid 91 done 92 true 93} 94epair_destroy_race_cleanup() 95{ 96 cleanup_ifaces 97} 98 99atf_test_case epair_ipv6_up_stress cleanup 100epair_ipv6_up_stress_head() 101{ 102 atf_set "descr" "Simultaneously up and destroy an epair(4) with IPv6" 103 atf_set "require.user" "root" 104} 105epair_ipv6_up_stress_body() 106{ 107 do_up_stress "epair" "6" "" 108} 109epair_ipv6_up_stress_cleanup() 110{ 111 cleanup_ifaces 112} 113 114atf_test_case faith_stress cleanup 115faith_stress_head() 116{ 117 atf_set "descr" "Simultaneously create and destroy a faith(4)" 118 atf_set "require.user" "root" 119} 120faith_stress_body() 121{ 122 do_stress "faith" 123} 124faith_stress_cleanup() 125{ 126 cleanup_ifaces 127} 128 129atf_test_case faith_up_stress cleanup 130faith_up_stress_head() 131{ 132 atf_set "descr" "Simultaneously up and destroy a faith(4)" 133 atf_set "require.user" "root" 134} 135faith_up_stress_body() 136{ 137 do_up_stress "faith" "" "" 138} 139faith_up_stress_cleanup() 140{ 141 cleanup_ifaces 142} 143 144atf_test_case faith_ipv6_up_stress cleanup 145faith_ipv6_up_stress_head() 146{ 147 atf_set "descr" "Simultaneously up and destroy a faith(4) with IPv6" 148 atf_set "require.user" "root" 149} 150faith_ipv6_up_stress_body() 151{ 152 do_up_stress "faith" "6" "" 153} 154faith_ipv6_up_stress_cleanup() 155{ 156 cleanup_ifaces 157} 158 159atf_test_case gif_stress cleanup 160gif_stress_head() 161{ 162 atf_set "descr" "Simultaneously create and destroy a gif(4)" 163 atf_set "require.user" "root" 164} 165gif_stress_body() 166{ 167 do_stress "gif" 168} 169gif_stress_cleanup() 170{ 171 cleanup_ifaces 172} 173 174atf_test_case gif_up_stress cleanup 175gif_up_stress_head() 176{ 177 atf_set "descr" "Simultaneously up and destroy a gif(4)" 178 atf_set "require.user" "root" 179} 180gif_up_stress_body() 181{ 182 do_up_stress "gif" "" "p2p" 183} 184gif_up_stress_cleanup() 185{ 186 cleanup_ifaces 187} 188 189atf_test_case gif_ipv6_up_stress cleanup 190gif_ipv6_up_stress_head() 191{ 192 atf_set "descr" "Simultaneously up and destroy a gif(4) with IPv6" 193 atf_set "require.user" "root" 194} 195gif_ipv6_up_stress_body() 196{ 197 do_up_stress "gif" "6" "p2p" 198} 199gif_ipv6_up_stress_cleanup() 200{ 201 cleanup_ifaces 202} 203 204atf_test_case lo_stress cleanup 205lo_stress_head() 206{ 207 atf_set "descr" "Simultaneously create and destroy an lo(4)" 208 atf_set "require.user" "root" 209} 210lo_stress_body() 211{ 212 do_stress "lo" 213} 214lo_stress_cleanup() 215{ 216 cleanup_ifaces 217} 218 219atf_test_case lo_up_stress cleanup 220lo_up_stress_head() 221{ 222 atf_set "descr" "Simultaneously up and destroy an lo(4)" 223 atf_set "require.user" "root" 224} 225lo_up_stress_body() 226{ 227 do_up_stress "lo" "" "" 228} 229lo_up_stress_cleanup() 230{ 231 cleanup_ifaces 232} 233 234atf_test_case lo_ipv6_up_stress cleanup 235lo_ipv6_up_stress_head() 236{ 237 atf_set "descr" "Simultaneously up and destroy an lo(4) with IPv6" 238 atf_set "require.user" "root" 239} 240lo_ipv6_up_stress_body() 241{ 242 do_up_stress "lo" "6" "" 243} 244lo_ipv6_up_stress_cleanup() 245{ 246 cleanup_ifaces 247} 248 249atf_test_case tap_stress cleanup 250tap_stress_head() 251{ 252 atf_set "descr" "Simultaneously create and destroy a tap(4)" 253 atf_set "require.user" "root" 254} 255tap_stress_body() 256{ 257 do_stress "tap" 258} 259tap_stress_cleanup() 260{ 261 cleanup_ifaces 262} 263 264atf_test_case tap_up_stress cleanup 265tap_up_stress_head() 266{ 267 atf_set "descr" "Simultaneously up and destroy a tap(4)" 268 atf_set "require.user" "root" 269} 270tap_up_stress_body() 271{ 272 do_up_stress "tap" "" "" 273} 274tap_up_stress_cleanup() 275{ 276 cleanup_ifaces 277} 278 279atf_test_case tap_ipv6_up_stress cleanup 280tap_ipv6_up_stress_head() 281{ 282 atf_set "descr" "Simultaneously up and destroy a tap(4) with IPv6" 283 atf_set "require.user" "root" 284} 285tap_ipv6_up_stress_body() 286{ 287 atf_skip "Quickly panics: if_delmulti_locked: inconsistent ifp 0xfffff80150e44000" 288 do_up_stress "tap" "6" "" 289} 290tap_ipv6_up_stress_cleanup() 291{ 292 cleanup_ifaces 293} 294 295atf_test_case tun_stress cleanup 296tun_stress_head() 297{ 298 atf_set "descr" "Simultaneously create and destroy a tun(4)" 299 atf_set "require.user" "root" 300} 301tun_stress_body() 302{ 303 do_stress "tun" 304} 305tun_stress_cleanup() 306{ 307 cleanup_ifaces 308} 309 310atf_test_case tun_up_stress cleanup 311tun_up_stress_head() 312{ 313 atf_set "descr" "Simultaneously up and destroy a tun(4)" 314 atf_set "require.user" "root" 315} 316tun_up_stress_body() 317{ 318 do_up_stress "tun" "" "p2p" 319} 320tun_up_stress_cleanup() 321{ 322 cleanup_ifaces 323} 324 325atf_test_case tun_ipv6_up_stress cleanup 326tun_ipv6_up_stress_head() 327{ 328 atf_set "descr" "Simultaneously up and destroy a tun(4) with IPv6" 329 atf_set "require.user" "root" 330} 331tun_ipv6_up_stress_body() 332{ 333 do_up_stress "tun" "6" "p2p" 334} 335tun_ipv6_up_stress_cleanup() 336{ 337 cleanup_ifaces 338} 339 340atf_test_case vlan_stress cleanup 341vlan_stress_head() 342{ 343 atf_set "descr" "Simultaneously create and destroy a vlan(4)" 344 atf_set "require.user" "root" 345} 346vlan_stress_body() 347{ 348 do_stress "vlan" 349} 350vlan_stress_cleanup() 351{ 352 cleanup_ifaces 353} 354 355atf_test_case vlan_up_stress cleanup 356vlan_up_stress_head() 357{ 358 atf_set "descr" "Simultaneously up and destroy a vlan(4)" 359 atf_set "require.user" "root" 360} 361vlan_up_stress_body() 362{ 363 do_up_stress "vlan" "" "" 364} 365vlan_up_stress_cleanup() 366{ 367 cleanup_ifaces 368} 369 370atf_test_case vlan_ipv6_up_stress cleanup 371vlan_ipv6_up_stress_head() 372{ 373 atf_set "descr" "Simultaneously up and destroy a vlan(4) with IPv6" 374 atf_set "require.user" "root" 375} 376vlan_ipv6_up_stress_body() 377{ 378 do_up_stress "vlan" "6" "" 379} 380vlan_ipv6_up_stress_cleanup() 381{ 382 cleanup_ifaces 383} 384 385atf_test_case vmnet_stress cleanup 386vmnet_stress_head() 387{ 388 atf_set "descr" "Simultaneously create and destroy a vmnet(4)" 389 atf_set "require.user" "root" 390} 391vmnet_stress_body() 392{ 393 do_stress "vmnet" 394} 395vmnet_stress_cleanup() 396{ 397 cleanup_ifaces 398} 399 400atf_test_case vmnet_up_stress cleanup 401vmnet_up_stress_head() 402{ 403 atf_set "descr" "Simultaneously up and destroy a vmnet(4)" 404 atf_set "require.user" "root" 405} 406vmnet_up_stress_body() 407{ 408 do_up_stress "vmnet" "" "" 409} 410vmnet_up_stress_cleanup() 411{ 412 cleanup_ifaces 413} 414 415atf_test_case vmnet_ipv6_up_stress cleanup 416vmnet_ipv6_up_stress_head() 417{ 418 atf_set "descr" "Simultaneously up and destroy a vmnet(4) with IPv6" 419 atf_set "require.user" "root" 420} 421vmnet_ipv6_up_stress_body() 422{ 423 do_up_stress "vmnet" "6" "" 424} 425vmnet_ipv6_up_stress_cleanup() 426{ 427 cleanup_ifaces 428} 429 430atf_init_test_cases() 431{ 432 atf_add_test_case epair_ipv6_up_stress 433 atf_add_test_case epair_stress 434 atf_add_test_case epair_up_stress 435 atf_add_test_case epair_destroy_race 436 atf_add_test_case faith_ipv6_up_stress 437 atf_add_test_case faith_stress 438 atf_add_test_case faith_up_stress 439 atf_add_test_case gif_ipv6_up_stress 440 atf_add_test_case gif_stress 441 atf_add_test_case gif_up_stress 442 # Don't test lagg; it has its own test program 443 atf_add_test_case lo_ipv6_up_stress 444 atf_add_test_case lo_stress 445 atf_add_test_case lo_up_stress 446 atf_add_test_case tap_ipv6_up_stress 447 atf_add_test_case tap_stress 448 atf_add_test_case tap_up_stress 449 atf_add_test_case tun_ipv6_up_stress 450 atf_add_test_case tun_stress 451 atf_add_test_case tun_up_stress 452 atf_add_test_case vlan_ipv6_up_stress 453 atf_add_test_case vlan_stress 454 atf_add_test_case vlan_up_stress 455 atf_add_test_case vmnet_ipv6_up_stress 456 atf_add_test_case vmnet_stress 457 atf_add_test_case vmnet_up_stress 458} 459 460do_stress() 461{ 462 local IFACE CREATOR_PID DESTROYER_PID 463 464 IFACE=`get_iface $1` 465 466 # First thread: create the interface 467 while true; do 468 ifconfig ${IFACE%a} create 2>/dev/null && \ 469 echo -n . >> creator_count.txt 470 done & 471 CREATOR_PID=$! 472 473 # Second thread: destroy the lagg 474 while true; do 475 ifconfig $IFACE destroy 2>/dev/null && \ 476 echo -n . >> destroyer_count.txt 477 done & 478 DESTROYER_PID=$! 479 480 sleep ${TESTLEN} 481 kill $CREATOR_PID 482 kill $DESTROYER_PID 483 echo "Created ${IFACE%a} `stat -f %z creator_count.txt` times." 484 echo "Destroyed it `stat -f %z destroyer_count.txt` times." 485} 486 487# Implement the up stress tests 488# Parameters 489# $1 Interface class, etc "lo" or "tap" 490# $2 "6" to enable IPv6 auto address assignment, anything else otherwise 491# $3 p2p for point to point interfaces, anything else for normal interfaces 492do_up_stress() 493{ 494 local ADDR DSTADDR MASK MEAN_SLEEP_SECONDS MAX_SLEEP_USECS \ 495 IFACE IPV6 P2P SRCDIR LOOP_PID ipv6_cmd up_cmd 496 497 # Configure the interface to use an RFC5737 nonrouteable addresses 498 ADDR="192.0.2.2" 499 DSTADDR="192.0.2.3" 500 MASK="24" 501 # ifconfig takes about 10ms to run. To increase race coverage, 502 # randomly delay the two commands relative to each other by 5ms either 503 # way. 504 MEAN_SLEEP_SECONDS=.005 505 MAX_SLEEP_USECS=10000 506 507 IFACE=`get_iface $1` 508 IPV6=$2 509 P2P=$3 510 511 SRCDIR=$( atf_get_srcdir ) 512 if [ "$IPV6" = 6 ]; then 513 ipv6_cmd="true" 514 else 515 ipv6_cmd="ifconfig $IFACE inet6 ifdisabled" 516 fi 517 if [ "$P2P" = "p2p" ]; then 518 up_cmd="ifconfig $IFACE up ${ADDR}/${MASK} ${DSTADDR}" 519 else 520 up_cmd="ifconfig $IFACE up ${ADDR}/${MASK}" 521 fi 522 while true; do 523 eval "$ipv6_cmd" 524 { sleep ${MEAN_SLEEP_SECONDS} && \ 525 eval "$up_cmd" 2> /dev/null && 526 echo -n . >> up_count.txt ; } & 527 { ${SRCDIR}/randsleep ${MAX_SLEEP_USECS} && \ 528 ifconfig $IFACE destroy && 529 echo -n . >> destroy_count.txt ; } & 530 wait 531 ifconfig ${IFACE%a} create 532 done & 533 LOOP_PID=$! 534 535 sleep ${TESTLEN} 536 kill $LOOP_PID 537 echo "Upped ${IFACE} `stat -f %z up_count.txt` times." 538 echo "Destroyed it `stat -f %z destroy_count.txt` times." 539} 540 541# Creates a new cloned interface, registers it for cleanup, and echoes it 542# params: $1 Interface class name (tap, gif, etc) 543get_iface() 544{ 545 local CLASS DEV N 546 547 CLASS=$1 548 N=0 549 while ! ifconfig ${CLASS}${N} create > /dev/null 2>&1; do 550 if [ "$N" -ge 8 ]; then 551 atf_skip "Could not create a ${CLASS} interface" 552 else 553 N=$(($N + 1)) 554 fi 555 done 556 if [ ${CLASS} = "epair" ]; then 557 DEV=${CLASS}${N}a 558 else 559 DEV=${CLASS}${N} 560 fi 561 # Record the device so we can clean it up later 562 echo ${DEV} >> "devices_to_cleanup" 563 echo ${DEV} 564} 565 566 567cleanup_ifaces() 568{ 569 local DEV 570 571 for DEV in `cat "devices_to_cleanup"`; do 572 ifconfig ${DEV} destroy 573 done 574 true 575} 576