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