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 do_up_stress "tap" "6" "" 288} 289tap_ipv6_up_stress_cleanup() 290{ 291 cleanup_ifaces 292} 293 294atf_test_case tun_stress cleanup 295tun_stress_head() 296{ 297 atf_set "descr" "Simultaneously create and destroy a tun(4)" 298 atf_set "require.user" "root" 299} 300tun_stress_body() 301{ 302 do_stress "tun" 303} 304tun_stress_cleanup() 305{ 306 cleanup_ifaces 307} 308 309atf_test_case tun_up_stress cleanup 310tun_up_stress_head() 311{ 312 atf_set "descr" "Simultaneously up and destroy a tun(4)" 313 atf_set "require.user" "root" 314} 315tun_up_stress_body() 316{ 317 do_up_stress "tun" "" "p2p" 318} 319tun_up_stress_cleanup() 320{ 321 cleanup_ifaces 322} 323 324atf_test_case tun_ipv6_up_stress cleanup 325tun_ipv6_up_stress_head() 326{ 327 atf_set "descr" "Simultaneously up and destroy a tun(4) with IPv6" 328 atf_set "require.user" "root" 329} 330tun_ipv6_up_stress_body() 331{ 332 do_up_stress "tun" "6" "p2p" 333} 334tun_ipv6_up_stress_cleanup() 335{ 336 cleanup_ifaces 337} 338 339atf_test_case vlan_stress cleanup 340vlan_stress_head() 341{ 342 atf_set "descr" "Simultaneously create and destroy a vlan(4)" 343 atf_set "require.user" "root" 344} 345vlan_stress_body() 346{ 347 do_stress "vlan" 348} 349vlan_stress_cleanup() 350{ 351 cleanup_ifaces 352} 353 354atf_test_case vlan_up_stress cleanup 355vlan_up_stress_head() 356{ 357 atf_set "descr" "Simultaneously up and destroy a vlan(4)" 358 atf_set "require.user" "root" 359} 360vlan_up_stress_body() 361{ 362 do_up_stress "vlan" "" "" 363} 364vlan_up_stress_cleanup() 365{ 366 cleanup_ifaces 367} 368 369atf_test_case vlan_ipv6_up_stress cleanup 370vlan_ipv6_up_stress_head() 371{ 372 atf_set "descr" "Simultaneously up and destroy a vlan(4) with IPv6" 373 atf_set "require.user" "root" 374} 375vlan_ipv6_up_stress_body() 376{ 377 do_up_stress "vlan" "6" "" 378} 379vlan_ipv6_up_stress_cleanup() 380{ 381 cleanup_ifaces 382} 383 384atf_test_case vmnet_stress cleanup 385vmnet_stress_head() 386{ 387 atf_set "descr" "Simultaneously create and destroy a vmnet(4)" 388 atf_set "require.user" "root" 389} 390vmnet_stress_body() 391{ 392 do_stress "vmnet" 393} 394vmnet_stress_cleanup() 395{ 396 cleanup_ifaces 397} 398 399atf_test_case vmnet_up_stress cleanup 400vmnet_up_stress_head() 401{ 402 atf_set "descr" "Simultaneously up and destroy a vmnet(4)" 403 atf_set "require.user" "root" 404} 405vmnet_up_stress_body() 406{ 407 do_up_stress "vmnet" "" "" 408} 409vmnet_up_stress_cleanup() 410{ 411 cleanup_ifaces 412} 413 414atf_test_case vmnet_ipv6_up_stress cleanup 415vmnet_ipv6_up_stress_head() 416{ 417 atf_set "descr" "Simultaneously up and destroy a vmnet(4) with IPv6" 418 atf_set "require.user" "root" 419} 420vmnet_ipv6_up_stress_body() 421{ 422 do_up_stress "vmnet" "6" "" 423} 424vmnet_ipv6_up_stress_cleanup() 425{ 426 cleanup_ifaces 427} 428 429atf_init_test_cases() 430{ 431 atf_add_test_case epair_ipv6_up_stress 432 atf_add_test_case epair_stress 433 atf_add_test_case epair_up_stress 434 atf_add_test_case epair_destroy_race 435 atf_add_test_case faith_ipv6_up_stress 436 atf_add_test_case faith_stress 437 atf_add_test_case faith_up_stress 438 atf_add_test_case gif_ipv6_up_stress 439 atf_add_test_case gif_stress 440 atf_add_test_case gif_up_stress 441 # Don't test lagg; it has its own test program 442 atf_add_test_case lo_ipv6_up_stress 443 atf_add_test_case lo_stress 444 atf_add_test_case lo_up_stress 445 atf_add_test_case tap_ipv6_up_stress 446 atf_add_test_case tap_stress 447 atf_add_test_case tap_up_stress 448 atf_add_test_case tun_ipv6_up_stress 449 atf_add_test_case tun_stress 450 atf_add_test_case tun_up_stress 451 atf_add_test_case vlan_ipv6_up_stress 452 atf_add_test_case vlan_stress 453 atf_add_test_case vlan_up_stress 454 atf_add_test_case vmnet_ipv6_up_stress 455 atf_add_test_case vmnet_stress 456 atf_add_test_case vmnet_up_stress 457} 458 459do_stress() 460{ 461 local IFACE CREATOR_PID DESTROYER_PID 462 463 IFACE=`get_iface $1` 464 465 # First thread: create the interface 466 while true; do 467 ifconfig ${IFACE%a} create 2>/dev/null && \ 468 echo -n . >> creator_count.txt 469 done & 470 CREATOR_PID=$! 471 472 # Second thread: destroy the lagg 473 while true; do 474 ifconfig $IFACE destroy 2>/dev/null && \ 475 echo -n . >> destroyer_count.txt 476 done & 477 DESTROYER_PID=$! 478 479 sleep ${TESTLEN} 480 kill $CREATOR_PID 481 kill $DESTROYER_PID 482 echo "Created ${IFACE%a} `stat -f %z creator_count.txt` times." 483 echo "Destroyed it `stat -f %z destroyer_count.txt` times." 484} 485 486# Implement the up stress tests 487# Parameters 488# $1 Interface class, etc "lo" or "tap" 489# $2 "6" to enable IPv6 auto address assignment, anything else otherwise 490# $3 p2p for point to point interfaces, anything else for normal interfaces 491do_up_stress() 492{ 493 local ADDR DSTADDR MASK MEAN_SLEEP_SECONDS MAX_SLEEP_USECS \ 494 IFACE IPV6 P2P SRCDIR LOOP_PID ipv6_cmd up_cmd 495 496 # Configure the interface to use an RFC5737 nonrouteable addresses 497 ADDR="192.0.2.2" 498 DSTADDR="192.0.2.3" 499 MASK="24" 500 # ifconfig takes about 10ms to run. To increase race coverage, 501 # randomly delay the two commands relative to each other by 5ms either 502 # way. 503 MEAN_SLEEP_SECONDS=.005 504 MAX_SLEEP_USECS=10000 505 506 IFACE=`get_iface $1` 507 IPV6=$2 508 P2P=$3 509 510 SRCDIR=$( atf_get_srcdir ) 511 if [ "$IPV6" = 6 ]; then 512 ipv6_cmd="true" 513 else 514 ipv6_cmd="ifconfig $IFACE inet6 ifdisabled" 515 fi 516 if [ "$P2P" = "p2p" ]; then 517 up_cmd="ifconfig $IFACE up ${ADDR}/${MASK} ${DSTADDR}" 518 else 519 up_cmd="ifconfig $IFACE up ${ADDR}/${MASK}" 520 fi 521 while true; do 522 eval "$ipv6_cmd" 523 { sleep ${MEAN_SLEEP_SECONDS} && \ 524 eval "$up_cmd" 2> /dev/null && 525 echo -n . >> up_count.txt ; } & 526 { ${SRCDIR}/randsleep ${MAX_SLEEP_USECS} && \ 527 ifconfig $IFACE destroy && 528 echo -n . >> destroy_count.txt ; } & 529 wait 530 ifconfig ${IFACE%a} create 531 done & 532 LOOP_PID=$! 533 534 sleep ${TESTLEN} 535 kill $LOOP_PID 536 echo "Upped ${IFACE} `stat -f %z up_count.txt` times." 537 echo "Destroyed it `stat -f %z destroy_count.txt` times." 538} 539 540# Creates a new cloned interface, registers it for cleanup, and echoes it 541# params: $1 Interface class name (tap, gif, etc) 542get_iface() 543{ 544 local CLASS DEV N 545 546 CLASS=$1 547 N=0 548 while ! ifconfig ${CLASS}${N} create > /dev/null 2>&1; do 549 if [ "$N" -ge 8 ]; then 550 atf_skip "Could not create a ${CLASS} interface" 551 else 552 N=$(($N + 1)) 553 fi 554 done 555 if [ ${CLASS} = "epair" ]; then 556 DEV=${CLASS}${N}a 557 else 558 DEV=${CLASS}${N} 559 fi 560 # Record the device so we can clean it up later 561 echo ${DEV} >> "devices_to_cleanup" 562 echo ${DEV} 563} 564 565 566cleanup_ifaces() 567{ 568 local DEV 569 570 for DEV in `cat "devices_to_cleanup"`; do 571 ifconfig ${DEV} destroy 572 done 573 true 574} 575