xref: /freebsd/tests/sys/net/if_clone_test.sh (revision 069ac184)
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