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