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