1329874Sasomers# 2329874Sasomers# Copyright (c) 2014 Spectra Logic Corporation 3329874Sasomers# All rights reserved. 4329874Sasomers# 5329874Sasomers# Redistribution and use in source and binary forms, with or without 6329874Sasomers# modification, are permitted provided that the following conditions 7329874Sasomers# are met: 8329874Sasomers# 1. Redistributions of source code must retain the above copyright 9329874Sasomers# notice, this list of conditions, and the following disclaimer, 10329874Sasomers# without modification. 11329874Sasomers# 2. Redistributions in binary form must reproduce at minimum a disclaimer 12329874Sasomers# substantially similar to the "NO WARRANTY" disclaimer below 13329874Sasomers# ("Disclaimer") and any redistribution must be conditioned upon 14329874Sasomers# including a substantially similar Disclaimer requirement for further 15329874Sasomers# binary redistribution. 16329874Sasomers# 17329874Sasomers# NO WARRANTY 18329874Sasomers# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19329874Sasomers# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20329874Sasomers# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21329874Sasomers# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22329874Sasomers# HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23329874Sasomers# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24329874Sasomers# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25329874Sasomers# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26329874Sasomers# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27329874Sasomers# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28329874Sasomers# POSSIBILITY OF SUCH DAMAGES. 29329874Sasomers# 30329874Sasomers# Authors: Alan Somers (Spectra Logic Corporation) 31329874Sasomers# 32329874Sasomers# $FreeBSD: stable/11/tests/sys/net/if_lagg_test.sh 329874 2018-02-23 18:18:42Z asomers $ 33329874Sasomers 34329874Sasomersatf_test_case create cleanup 35329874Sasomerscreate_head() 36329874Sasomers{ 37329874Sasomers atf_set "descr" "Create a lagg and assign an address" 38329874Sasomers atf_set "require.user" "root" 39329874Sasomers} 40329874Sasomerscreate_body() 41329874Sasomers{ 42329874Sasomers local TAP0 TAP1 LAGG MAC 43329874Sasomers 44329874Sasomers # Configure the lagg interface to use an RFC5737 nonrouteable addresses 45329874Sasomers ADDR="192.0.2.2" 46329874Sasomers MASK="24" 47329874Sasomers 48329874Sasomers TAP0=`get_tap` 49329874Sasomers TAP1=`get_tap` 50329874Sasomers LAGG=`get_lagg` 51329874Sasomers 52329874Sasomers # Create the lagg 53329874Sasomers ifconfig $TAP0 up 54329874Sasomers ifconfig $TAP1 up 55329874Sasomers atf_check ifconfig $LAGG up laggport $TAP0 laggport $TAP1 \ 56329874Sasomers ${ADDR}/${MASK} 57329874Sasomers atf_check -o match:"inet ${ADDR}" ifconfig $LAGG 58329874Sasomers atf_check -o match:"laggport: ${TAP0}" ifconfig $LAGG 59329874Sasomers atf_check -o match:"laggport: ${TAP1}" ifconfig $LAGG 60329874Sasomers 61329874Sasomers # Check that all members have the same MAC 62329874Sasomers MAC=`ifconfig $LAGG | awk '/ether/ {print $2}'` 63329874Sasomers atf_check -o match:"ether ${MAC}" ifconfig $TAP0 64329874Sasomers atf_check -o match:"ether ${MAC}" ifconfig $TAP1 65329874Sasomers 66329874Sasomers # Check that no members have an IPv6 link-local address. IPv6 67329874Sasomers # link-local addresses should never be merged in any way to prevent 68329874Sasomers # scope violation. 69329874Sasomers atf_check -o not-match:"inet6 fe80:" ifconfig $TAP0 70329874Sasomers atf_check -o not-match:"inet6 fe80:" ifconfig $TAP1 71329874Sasomers} 72329874Sasomerscreate_cleanup() 73329874Sasomers{ 74329874Sasomers cleanup_tap_and_lagg 75329874Sasomers} 76329874Sasomers 77329874Sasomersatf_test_case status_stress cleanup 78329874Sasomersstatus_stress_head() 79329874Sasomers{ 80329874Sasomers atf_set "descr" "Simultaneously query a lagg while also creating or destroying it." 81329874Sasomers atf_set "require.user" "root" 82329874Sasomers} 83329874Sasomersstatus_stress_body() 84329874Sasomers{ 85329874Sasomers local TAP0 TAP1 LAGG MAC 86329874Sasomers 87329874Sasomers # Configure the lagg interface to use an RFC5737 nonrouteable addresses 88329874Sasomers ADDR="192.0.2.2" 89329874Sasomers MASK="24" 90329874Sasomers 91329874Sasomers TAP0=`get_tap` 92329874Sasomers TAP1=`get_tap` 93329874Sasomers TAP2=`get_tap` 94329874Sasomers TAP3=`get_tap` 95329874Sasomers LAGG=`get_lagg` 96329874Sasomers 97329874Sasomers # Up the lagg's children 98329874Sasomers ifconfig $TAP0 inet6 ifdisabled up 99329874Sasomers ifconfig $TAP1 inet6 ifdisabled up 100329874Sasomers ifconfig $TAP2 inet6 ifdisabled up 101329874Sasomers ifconfig $TAP3 inet6 ifdisabled up 102329874Sasomers 103329874Sasomers # First thread: create and destroy the lagg 104329874Sasomers while true; do 105329874Sasomers ifconfig $LAGG destroy 2>&1 106329874Sasomers ifconfig $LAGG create 2>/dev/null 107329874Sasomers ifconfig $LAGG inet6 ifdisabled 108329874Sasomers ifconfig $LAGG up laggport $TAP0 laggport $TAP1 laggport $TAP2\ 109329874Sasomers laggport $TAP3 ${ADDR}/${MASK} 2>/dev/null 110329874Sasomers echo -n . >> creator_count.txt 111329874Sasomers done & 112329874Sasomers CREATOR_PID=$! 113329874Sasomers 114329874Sasomers # Second thread: Query the lagg's status 115329874Sasomers while true; do 116329874Sasomers ifconfig -am 2> /dev/null > /dev/null 117329874Sasomers echo -n . >> querier_count.txt 118329874Sasomers done & 119329874Sasomers QUERIER_PID=$! 120329874Sasomers 121329874Sasomers sleep 60 122329874Sasomers kill $CREATOR_PID 123329874Sasomers kill $QUERIER_PID 124329874Sasomers echo "Created the lagg `stat -f %z creator_count.txt` times." 125329874Sasomers echo "Queried its status `stat -f %z querier_count.txt` times" 126329874Sasomers} 127329874Sasomersstatus_stress_cleanup() 128329874Sasomers{ 129329874Sasomers cleanup_tap_and_lagg 130329874Sasomers} 131329874Sasomers 132329874Sasomersatf_test_case create_destroy_stress cleanup 133329874Sasomerscreate_destroy_stress_head() 134329874Sasomers{ 135329874Sasomers atf_set "descr" "Simultaneously create and destroy a lagg" 136329874Sasomers atf_set "require.user" "root" 137329874Sasomers} 138329874Sasomerscreate_destroy_stress_body() 139329874Sasomers{ 140329874Sasomers local TAP0 TAP1 LAGG MAC 141329874Sasomers 142329874Sasomers atf_skip "Skipping this test because it easily panics the machine" 143329874Sasomers 144329874Sasomers TAP0=`get_tap` 145329874Sasomers TAP1=`get_tap` 146329874Sasomers TAP2=`get_tap` 147329874Sasomers TAP3=`get_tap` 148329874Sasomers LAGG=`get_lagg` 149329874Sasomers 150329874Sasomers # Up the lagg's children 151329874Sasomers ifconfig $TAP0 inet6 ifdisabled up 152329874Sasomers ifconfig $TAP1 inet6 ifdisabled up 153329874Sasomers ifconfig $TAP2 inet6 ifdisabled up 154329874Sasomers ifconfig $TAP3 inet6 ifdisabled up 155329874Sasomers 156329874Sasomers # First thread: create the lagg 157329874Sasomers while true; do 158329874Sasomers ifconfig $LAGG create 2>/dev/null && \ 159329874Sasomers echo -n . >> creator_count.txt 160329874Sasomers done & 161329874Sasomers CREATOR_PID=$! 162329874Sasomers 163329874Sasomers # Second thread: destroy the lagg 164329874Sasomers while true; do 165329874Sasomers ifconfig $LAGG destroy 2>/dev/null && \ 166329874Sasomers echo -n . >> destroyer_count.txt 167329874Sasomers done & 168329874Sasomers DESTROYER_PID=$! 169329874Sasomers 170329874Sasomers sleep 60 171329874Sasomers kill $CREATOR_PID 172329874Sasomers kill $DESTROYER_PID 173329874Sasomers echo "Created the lagg `stat -f %z creator_count.txt` times." 174329874Sasomers echo "Destroyed it `stat -f %z destroyer_count.txt` times." 175329874Sasomers} 176329874Sasomerscreate_destroy_stress_cleanup() 177329874Sasomers{ 178329874Sasomers cleanup_tap_and_lagg 179329874Sasomers} 180329874Sasomers 181329874Sasomers# This test regresses a panic that is particular to LACP. If the child's link 182329874Sasomers# state changes while the lagg is being destroyed, lacp_linkstate can 183329874Sasomers# use-after-free. The problem is compounded by two factors: 184329874Sasomers# 1) In SpectraBSD, downing the parent will also down the child 185329874Sasomers# 2) The cxgbe driver will show the link state as "no carrier" as soon as you 186329874Sasomers# down the interface. 187329874Sasomers# TeamTrack: P2_30328 188329874Sasomersatf_test_case lacp_linkstate_destroy_stress cleanup 189329874Sasomerslacp_linkstate_destroy_stress_head() 190329874Sasomers{ 191329874Sasomers atf_set "descr" "Simultaneously destroy an LACP lagg and change its childrens link states" 192329874Sasomers atf_set "require.user" "root" 193329874Sasomers} 194329874Sasomerslacp_linkstate_destroy_stress_body() 195329874Sasomers{ 196329874Sasomers local TAP0 TAP1 LAGG MAC SRCDIR 197329874Sasomers 198329874Sasomers # Configure the lagg interface to use an RFC5737 nonrouteable addresses 199329874Sasomers ADDR="192.0.2.2" 200329874Sasomers MASK="24" 201329874Sasomers # ifconfig takes about 10ms to run. To increase race coverage, 202329874Sasomers # randomly delay the two commands relative to each other by 5ms either 203329874Sasomers # way. 204329874Sasomers MEAN_SLEEP_SECONDS=.005 205329874Sasomers MAX_SLEEP_USECS=10000 206329874Sasomers 207329874Sasomers TAP0=`get_tap` 208329874Sasomers TAP1=`get_tap` 209329874Sasomers LAGG=`get_lagg` 210329874Sasomers 211329874Sasomers # Up the lagg's children 212329874Sasomers ifconfig $TAP0 inet6 ifdisabled up 213329874Sasomers ifconfig $TAP1 inet6 ifdisabled up 214329874Sasomers 215329874Sasomers SRCDIR=$( atf_get_srcdir ) 216329874Sasomers while true; do 217329874Sasomers ifconfig $LAGG inet6 ifdisabled 218329874Sasomers # We must open the tap devices to change their link states 219329874Sasomers cat /dev/$TAP0 > /dev/null & 220329874Sasomers CAT0_PID=$! 221329874Sasomers cat /dev/$TAP1 > /dev/null & 222329874Sasomers CAT1_PID=$! 223329874Sasomers ifconfig $LAGG up laggport $TAP0 laggport $TAP1 \ 224329874Sasomers ${ADDR}/${MASK} 2> /dev/null && 225329874Sasomers { sleep ${MEAN_SLEEP_SECONDS} && \ 226329874Sasomers kill $CAT0_PID && 227329874Sasomers kill $CAT1_PID && 228329874Sasomers echo -n . >> linkstate_count.txt ; } & 229329874Sasomers { ${SRCDIR}/randsleep ${MAX_SLEEP_USECS} && \ 230329874Sasomers ifconfig $LAGG destroy && 231329874Sasomers echo -n . >> destroy_count.txt ; } & 232329874Sasomers wait 233329874Sasomers ifconfig $LAGG create 234329874Sasomers done & 235329874Sasomers LOOP_PID=$! 236329874Sasomers 237329874Sasomers sleep 60 238329874Sasomers kill $LOOP_PID 239329874Sasomers echo "Disconnected the children `stat -f %z linkstate_count.txt` times." 240329874Sasomers echo "Destroyed the lagg `stat -f %z destroy_count.txt` times." 241329874Sasomers} 242329874Sasomerslacp_linkstate_destroy_stress_cleanup() 243329874Sasomers{ 244329874Sasomers cleanup_tap_and_lagg 245329874Sasomers} 246329874Sasomers 247329874Sasomersatf_test_case up_destroy_stress cleanup 248329874Sasomersup_destroy_stress_head() 249329874Sasomers{ 250329874Sasomers atf_set "descr" "Simultaneously up and destroy a lagg" 251329874Sasomers atf_set "require.user" "root" 252329874Sasomers} 253329874Sasomersup_destroy_stress_body() 254329874Sasomers{ 255329874Sasomers local TAP0 TAP1 LAGG MAC SRCDIR 256329874Sasomers 257329874Sasomers atf_skip "Skipping this test because it panics the machine fairly often" 258329874Sasomers 259329874Sasomers # Configure the lagg interface to use an RFC5737 nonrouteable addresses 260329874Sasomers ADDR="192.0.2.2" 261329874Sasomers MASK="24" 262329874Sasomers # ifconfig takes about 10ms to run. To increase race coverage, 263329874Sasomers # randomly delay the two commands relative to each other by 5ms either 264329874Sasomers # way. 265329874Sasomers MEAN_SLEEP_SECONDS=.005 266329874Sasomers MAX_SLEEP_USECS=10000 267329874Sasomers 268329874Sasomers TAP0=`get_tap` 269329874Sasomers TAP1=`get_tap` 270329874Sasomers TAP2=`get_tap` 271329874Sasomers TAP3=`get_tap` 272329874Sasomers LAGG=`get_lagg` 273329874Sasomers 274329874Sasomers # Up the lagg's children 275329874Sasomers ifconfig $TAP0 inet6 ifdisabled up 276329874Sasomers ifconfig $TAP1 inet6 ifdisabled up 277329874Sasomers ifconfig $TAP2 inet6 ifdisabled up 278329874Sasomers ifconfig $TAP3 inet6 ifdisabled up 279329874Sasomers 280329874Sasomers SRCDIR=$( atf_get_srcdir ) 281329874Sasomers while true; do 282329874Sasomers ifconfig $LAGG inet6 ifdisabled 283329874Sasomers { sleep ${MEAN_SLEEP_SECONDS} && \ 284329874Sasomers ifconfig $LAGG up laggport $TAP0 laggport $TAP1 \ 285329874Sasomers laggport $TAP2 laggport $TAP3 \ 286329874Sasomers ${ADDR}/${MASK} 2> /dev/null && 287329874Sasomers echo -n . >> up_count.txt ; } & 288329874Sasomers { ${SRCDIR}/randsleep ${MAX_SLEEP_USECS} && \ 289329874Sasomers ifconfig $LAGG destroy && 290329874Sasomers echo -n . >> destroy_count.txt ; } & 291329874Sasomers wait 292329874Sasomers ifconfig $LAGG create 293329874Sasomers done & 294329874Sasomers LOOP_PID=$! 295329874Sasomers 296329874Sasomers sleep 60 297329874Sasomers kill $LOOP_PID 298329874Sasomers echo "Upped the lagg `stat -f %z up_count.txt` times." 299329874Sasomers echo "Destroyed it `stat -f %z destroy_count.txt` times." 300329874Sasomers} 301329874Sasomersup_destroy_stress_cleanup() 302329874Sasomers{ 303329874Sasomers cleanup_tap_and_lagg 304329874Sasomers} 305329874Sasomers 306329874Sasomersatf_test_case set_ether cleanup 307329874Sasomersset_ether_head() 308329874Sasomers{ 309329874Sasomers atf_set "descr" "Set a lagg's ethernet address" 310329874Sasomers atf_set "require.user" "root" 311329874Sasomers} 312329874Sasomersset_ether_body() 313329874Sasomers{ 314329874Sasomers local TAP0 TAP1 LAGG MAC 315329874Sasomers 316329874Sasomers # Configure the lagg interface to use an RFC5737 nonrouteable addresses 317329874Sasomers ADDR="192.0.2.2" 318329874Sasomers MASK="24" 319329874Sasomers MAC="00:11:22:33:44:55" 320329874Sasomers 321329874Sasomers TAP0=`get_tap` 322329874Sasomers TAP1=`get_tap` 323329874Sasomers LAGG=`get_lagg` 324329874Sasomers 325329874Sasomers # Create the lagg 326329874Sasomers ifconfig $TAP0 up 327329874Sasomers ifconfig $TAP1 up 328329874Sasomers atf_check ifconfig $LAGG up laggport $TAP0 laggport $TAP1 \ 329329874Sasomers ${ADDR}/${MASK} 330329874Sasomers 331329874Sasomers # Change the lagg's ethernet address 332329874Sasomers atf_check ifconfig $LAGG ether ${MAC} 333329874Sasomers 334329874Sasomers # Check that all members have the same MAC 335329874Sasomers atf_check -o match:"ether ${MAC}" ifconfig $LAGG 336329874Sasomers atf_check -o match:"ether ${MAC}" ifconfig $TAP0 337329874Sasomers atf_check -o match:"ether ${MAC}" ifconfig $TAP1 338329874Sasomers} 339329874Sasomersset_ether_cleanup() 340329874Sasomers{ 341329874Sasomers cleanup_tap_and_lagg 342329874Sasomers} 343329874Sasomers 344329874Sasomersatf_test_case updown cleanup 345329874Sasomersupdown_head() 346329874Sasomers{ 347329874Sasomers atf_set "descr" "upping or downing a lagg ups or downs its children" 348329874Sasomers atf_set "require.user" "root" 349329874Sasomers} 350329874Sasomersupdown_body() 351329874Sasomers{ 352329874Sasomers local TAP0 TAP1 LAGG MAC 353329874Sasomers 354329874Sasomers atf_expect_fail "PR 226144 Upping a lagg interrface should automatically up its children" 355329874Sasomers # Configure the lagg interface to use an RFC5737 nonrouteable addresses 356329874Sasomers ADDR="192.0.2.2" 357329874Sasomers MASK="24" 358329874Sasomers MAC="00:11:22:33:44:55" 359329874Sasomers 360329874Sasomers TAP0=`get_tap` 361329874Sasomers TAP1=`get_tap` 362329874Sasomers LAGG=`get_lagg` 363329874Sasomers 364329874Sasomers # Create the lagg 365329874Sasomers ifconfig $TAP0 up 366329874Sasomers ifconfig $TAP1 up 367329874Sasomers atf_check ifconfig $LAGG up laggport $TAP0 laggport $TAP1 \ 368329874Sasomers ${ADDR}/${MASK} 369329874Sasomers 370329874Sasomers # Down the lagg 371329874Sasomers ifconfig $LAGG down 372329874Sasomers atf_check -o not-match:"flags=.*\<UP\>" ifconfig $LAGG 373329874Sasomers atf_check -o not-match:"flags=.*\<UP\>" ifconfig $TAP0 374329874Sasomers atf_check -o not-match:"flags=.*\<UP\>" ifconfig $TAP1 375329874Sasomers # Up the lagg again 376329874Sasomers ifconfig $LAGG up 377329874Sasomers atf_check -o match:"flags=.*\<UP\>" ifconfig $LAGG 378329874Sasomers atf_check -o match:"flags=.*\<UP\>" ifconfig $TAP0 379329874Sasomers atf_check -o match:"flags=.*\<UP\>" ifconfig $TAP1 380329874Sasomers 381329874Sasomers # Check that no members have acquired an IPv6 link-local address by 382329874Sasomers # virtue of being upped. IPv6 link-local addresses should never be 383329874Sasomers # merged in any way to prevent scope violation. 384329874Sasomers atf_check -o not-match:"inet6 fe80:" ifconfig $TAP0 385329874Sasomers atf_check -o not-match:"inet6 fe80:" ifconfig $TAP1 386329874Sasomers} 387329874Sasomersupdown_cleanup() 388329874Sasomers{ 389329874Sasomers cleanup_tap_and_lagg 390329874Sasomers} 391329874Sasomers 392329874Sasomers# Check for lock-order reversals. For best results, this test should be run 393329874Sasomers# last. 394329874Sasomersatf_test_case witness 395329874Sasomerswitness_head() 396329874Sasomers{ 397329874Sasomers atf_set "descr" "Check witness(4) for lock-order reversals in if_lagg" 398329874Sasomers} 399329874Sasomerswitness_body() 400329874Sasomers{ 401329874Sasomers if [ `sysctl -n debug.witness.watch` -ne 1 ]; then 402329874Sasomers atf_skip "witness(4) is not enabled" 403329874Sasomers fi 404329874Sasomers if `sysctl -n debug.witness.badstacks | grep -q 'at lagg_'`; then 405329874Sasomers sysctl debug.witness.badstacks 406329874Sasomers atf_fail "Lock-order reversals involving if_lagg.c detected" 407329874Sasomers fi 408329874Sasomers} 409329874Sasomers 410329874Sasomersatf_init_test_cases() 411329874Sasomers{ 412329874Sasomers atf_add_test_case create 413329874Sasomers atf_add_test_case create_destroy_stress 414329874Sasomers atf_add_test_case lacp_linkstate_destroy_stress 415329874Sasomers atf_add_test_case set_ether 416329874Sasomers atf_add_test_case status_stress 417329874Sasomers atf_add_test_case up_destroy_stress 418329874Sasomers atf_add_test_case updown 419329874Sasomers # For best results, keep the witness test last 420329874Sasomers atf_add_test_case witness 421329874Sasomers} 422329874Sasomers 423329874Sasomers 424329874Sasomers# Creates a new tap(4) interface, registers it for cleanup, and echoes it 425329874Sasomersget_tap() 426329874Sasomers{ 427329874Sasomers local TAPN=0 428329874Sasomers while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do 429329874Sasomers if [ "$TAPN" -ge 8 ]; then 430329874Sasomers atf_skip "Could not create a tap(4) interface" 431329874Sasomers else 432329874Sasomers TAPN=$(($TAPN + 1)) 433329874Sasomers fi 434329874Sasomers done 435329874Sasomers local TAPD=tap${TAPN} 436329874Sasomers # Record the TAP device so we can clean it up later 437329874Sasomers echo ${TAPD} >> "devices_to_cleanup" 438329874Sasomers echo ${TAPD} 439329874Sasomers} 440329874Sasomers 441329874Sasomers# Creates a new lagg(4) interface, registers it for cleanup, and echoes it 442329874Sasomersget_lagg() 443329874Sasomers{ 444329874Sasomers local LAGGN=0 445329874Sasomers while ! ifconfig lagg${LAGGN} create > /dev/null 2>&1; do 446329874Sasomers if [ "$LAGGN" -ge 8 ]; then 447329874Sasomers atf_skip "Could not create a lagg(4) interface" 448329874Sasomers else 449329874Sasomers LAGGN=$(($LAGGN + 1)) 450329874Sasomers fi 451329874Sasomers done 452329874Sasomers local LAGGD=lagg${LAGGN} 453329874Sasomers # Record the lagg device so we can clean it up later 454329874Sasomers echo ${LAGGD} >> "devices_to_cleanup" 455329874Sasomers echo ${LAGGD} 456329874Sasomers} 457329874Sasomers 458329874Sasomerscleanup_tap_and_lagg() 459329874Sasomers{ 460329874Sasomers local DEV 461329874Sasomers 462329874Sasomers for DEV in `cat "devices_to_cleanup"`; do 463329874Sasomers ifconfig ${DEV} destroy 464329874Sasomers done 465329874Sasomers true 466329874Sasomers} 467