xref: /netbsd-src/tests/net/net_common.sh (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1#	$NetBSD: net_common.sh,v 1.28 2018/04/07 12:36:58 ozaki-r Exp $
2#
3# Copyright (c) 2016 Internet Initiative Japan Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27
28#
29# Common utility functions for tests/net
30#
31
32HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so \
33    RUMPHIJACK=path=/rump,socket=all:nolocal,sysctl=yes"
34ONEDAYISH="(23h5[0-9]m|1d0h0m)[0-9]+s ?"
35
36extract_new_packets()
37{
38	local bus=$1
39	local old=./.__old
40
41	if [ ! -f $old ]; then
42		old=/dev/null
43	fi
44
45	shmif_dumpbus -p - $bus 2>/dev/null |
46	    tcpdump -n -e -r - 2>/dev/null > ./.__new
47	diff -u $old ./.__new | grep '^+' | cut -d '+' -f 2   > ./.__diff
48	mv -f ./.__new ./.__old
49	cat ./.__diff
50}
51
52check_route()
53{
54	local target=$1
55	local gw=$2
56	local flags=${3:-\.\+}
57	local ifname=${4:-\.\+}
58
59	target=$(echo $target | sed 's/\./\\./g')
60	if [ "$gw" = "" ]; then
61		gw=".+"
62	else
63		gw=$(echo $gw | sed 's/\./\\./g')
64	fi
65
66	atf_check -s exit:0 -e ignore \
67	    -o match:"^$target +$gw +$flags +- +- +.+ +$ifname" \
68	    rump.netstat -rn
69}
70
71check_route_flags()
72{
73
74	check_route "$1" "" "$2" ""
75}
76
77check_route_gw()
78{
79
80	check_route "$1" "$2" "" ""
81}
82
83check_route_no_entry()
84{
85	local target=$(echo "$1" | sed 's/\./\\./g')
86
87	atf_check -s exit:0 -e ignore -o not-match:"^$target" rump.netstat -rn
88}
89
90get_linklocal_addr()
91{
92
93	RUMP_SERVER=${1} rump.ifconfig ${2} inet6 |
94	    awk "/fe80/ {sub(/%$2/, \"\"); sub(/\\/[0-9]*/, \"\"); print \$2;}"
95
96	return 0
97}
98
99get_macaddr()
100{
101
102	RUMP_SERVER=${1} rump.ifconfig ${2} | awk '/address/ {print $2;}'
103}
104
105HTTPD_PID=./.__httpd.pid
106start_httpd()
107{
108	local sock=$1
109	local ip=$2
110	local backup=$RUMP_SERVER
111
112	export RUMP_SERVER=$sock
113
114	# start httpd in daemon mode
115	atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
116	    /usr/libexec/httpd -P $HTTPD_PID -i $ip -b -s $(pwd)
117
118	export RUMP_SERVER=$backup
119
120	sleep 3
121}
122
123stop_httpd()
124{
125
126	if [ -f $HTTPD_PID ]; then
127		kill -9 $(cat $HTTPD_PID)
128		rm -f $HTTPD_PID
129		sleep 1
130	fi
131}
132
133NC_PID=./.__nc.pid
134start_nc_server()
135{
136	local sock=$1
137	local port=$2
138	local outfile=$3
139	local proto=${4:-ipv4}
140	local backup=$RUMP_SERVER
141	local opts=
142
143	export RUMP_SERVER=$sock
144
145	if [ $proto = ipv4 ]; then
146		opts="-l -4"
147	else
148		opts="-l -6"
149	fi
150
151	env LD_PRELOAD=/usr/lib/librumphijack.so nc $opts $port > $outfile &
152	echo $! > $NC_PID
153
154	if [ $proto = ipv4 ]; then
155		$DEBUG && rump.netstat -a -f inet
156	else
157		$DEBUG && rump.netstat -a -f inet6
158	fi
159
160	export RUMP_SERVER=$backup
161
162	sleep 1
163}
164
165stop_nc_server()
166{
167
168	if [ -f $NC_PID ]; then
169		kill -9 $(cat $NC_PID)
170		rm -f $NC_PID
171		sleep 1
172	fi
173}
174
175BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev"
176FS_LIBS="$BASIC_LIBS -lrumpvfs -lrumpfs_ffs"
177CRYPTO_LIBS="$BASIC_LIBS -lrumpvfs -lrumpdev_opencrypto \
178    -lrumpkern_z -lrumpkern_crypto"
179NPF_LIBS="$BASIC_LIBS -lrumpvfs -lrumpdev_bpf -lrumpnet_npf"
180
181# We cannot keep variables between test phases, so need to store in files
182_rump_server_socks=./.__socks
183_rump_server_ifaces=./.__ifaces
184_rump_server_buses=./.__buses
185
186DEBUG_SYSCTL_ENTRIES="net.inet.arp.debug net.inet6.icmp6.nd6_debug \
187    net.inet.ipsec.debug"
188
189IPSEC_KEY_DEBUG=${IPSEC_KEY_DEBUG:-false}
190
191_rump_server_start_common()
192{
193	local sock=$1
194	local backup=$RUMP_SERVER
195
196	shift 1
197
198	atf_check -s exit:0 rump_server "$@" "$sock"
199
200	if $DEBUG; then
201		# Enable debugging features in the kernel
202		export RUMP_SERVER=$sock
203		for ent in $DEBUG_SYSCTL_ENTRIES; do
204			if rump.sysctl -q $ent; then
205				atf_check -s exit:0 rump.sysctl -q -w $ent=1
206			fi
207		done
208		export RUMP_SERVER=$backup
209	fi
210	if $IPSEC_KEY_DEBUG; then
211		# Enable debugging features in the kernel
212		export RUMP_SERVER=$sock
213		if rump.sysctl -q net.key.debug; then
214			atf_check -s exit:0 \
215			    rump.sysctl -q -w net.key.debug=0xffff
216		fi
217		export RUMP_SERVER=$backup
218	fi
219
220	echo $sock >> $_rump_server_socks
221	$DEBUG && cat $_rump_server_socks
222}
223
224rump_server_start()
225{
226	local sock=$1
227	local lib=
228	local libs="$BASIC_LIBS"
229
230	shift 1
231
232	for lib
233	do
234		libs="$libs -lrumpnet_$lib"
235	done
236
237	_rump_server_start_common $sock $libs
238
239	return 0
240}
241
242rump_server_fs_start()
243{
244	local sock=$1
245	local lib=
246	local libs="$FS_LIBS"
247
248	shift 1
249
250	for lib
251	do
252		libs="$libs -lrumpnet_$lib"
253	done
254
255	_rump_server_start_common $sock $libs
256
257	return 0
258}
259
260rump_server_crypto_start()
261{
262	local sock=$1
263	local lib=
264	local libs="$CRYPTO_LIBS"
265
266	shift 1
267
268	for lib
269	do
270		libs="$libs -lrumpnet_$lib"
271	done
272
273	_rump_server_start_common $sock $libs
274
275	return 0
276}
277
278rump_server_npf_start()
279{
280	local sock=$1
281	local lib=
282	local libs="$NPF_LIBS"
283
284	shift 1
285
286	for lib
287	do
288		libs="$libs -lrumpnet_$lib"
289	done
290
291	_rump_server_start_common $sock $libs
292
293	return 0
294}
295
296rump_server_add_iface()
297{
298	local sock=$1
299	local ifname=$2
300	local bus=$3
301	local backup=$RUMP_SERVER
302
303	export RUMP_SERVER=$sock
304	atf_check -s exit:0 rump.ifconfig $ifname create
305	atf_check -s exit:0 rump.ifconfig $ifname linkstr $bus
306	export RUMP_SERVER=$backup
307
308	echo $sock $ifname >> $_rump_server_ifaces
309	$DEBUG && cat $_rump_server_ifaces
310
311	echo $bus >> $_rump_server_buses
312	cat $_rump_server_buses |sort -u >./.__tmp
313	mv -f ./.__tmp $_rump_server_buses
314	$DEBUG && cat $_rump_server_buses
315
316	return 0
317}
318
319rump_server_destroy_ifaces()
320{
321	local backup=$RUMP_SERVER
322	local output=ignore
323
324	$DEBUG && cat $_rump_server_ifaces
325
326	# Try to dump states before destroying interfaces
327	for sock in $(cat $_rump_server_socks); do
328		export RUMP_SERVER=$sock
329		if $DEBUG; then
330			output=save:/dev/stdout
331		fi
332		atf_check -s exit:0 -o $output rump.ifconfig
333		atf_check -s exit:0 -o $output rump.netstat -nr
334		# XXX still need hijacking
335		atf_check -s exit:0 -o $output $HIJACKING rump.netstat -nai
336		atf_check -s exit:0 -o $output rump.arp -na
337		atf_check -s exit:0 -o $output rump.ndp -na
338		atf_check -s exit:0 -o $output $HIJACKING ifmcstat
339	done
340
341	# XXX using pipe doesn't work. See PR bin/51667
342	#cat $_rump_server_ifaces | while read sock ifname; do
343	while read sock ifname; do
344		export RUMP_SERVER=$sock
345		if rump.ifconfig -l |grep -q $ifname; then
346			atf_check -s exit:0 rump.ifconfig $ifname destroy
347		fi
348		atf_check -s exit:0 -o ignore rump.ifconfig
349	done < $_rump_server_ifaces
350	export RUMP_SERVER=$backup
351
352	return 0
353}
354
355rump_server_halt_servers()
356{
357	local backup=$RUMP_SERVER
358
359	$DEBUG && cat $_rump_server_socks
360	for sock in $(cat $_rump_server_socks); do
361		env RUMP_SERVER=$sock rump.halt
362	done
363	export RUMP_SERVER=$backup
364
365	return 0
366}
367
368rump_server_dump_servers()
369{
370	local backup=$RUMP_SERVER
371
372	$DEBUG && cat $_rump_server_socks
373	for sock in $(cat $_rump_server_socks); do
374		echo "### Dumping $sock"
375		export RUMP_SERVER=$sock
376		rump.ifconfig -av
377		rump.netstat -nr
378		# XXX still need hijacking
379		$HIJACKING rump.netstat -nai
380		rump.arp -na
381		rump.ndp -na
382		$HIJACKING ifmcstat
383		$HIJACKING dmesg
384	done
385	export RUMP_SERVER=$backup
386
387	if [ -f rump_server.core ]; then
388		gdb -ex bt /usr/bin/rump_server rump_server.core
389		strings rump_server.core |grep panic
390	fi
391	return 0
392}
393
394rump_server_dump_buses()
395{
396
397	if [ ! -f $_rump_server_buses ]; then
398		return 0
399	fi
400
401	$DEBUG && cat $_rump_server_buses
402	for bus in $(cat $_rump_server_buses); do
403		echo "### Dumping $bus"
404		shmif_dumpbus -p - $bus 2>/dev/null| tcpdump -n -e -r -
405	done
406	return 0
407}
408
409cleanup()
410{
411
412	rump_server_halt_servers
413}
414
415dump()
416{
417
418	rump_server_dump_servers
419	rump_server_dump_buses
420}
421
422skip_if_qemu()
423{
424	if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1
425	then
426	    atf_skip "unreliable under qemu, skip until PR kern/43997 fixed"
427	fi
428}
429
430test_create_destroy_common()
431{
432	local sock=$1
433	local ifname=$2
434	local test_address=${3:-false}
435	local ipv4="10.0.0.1/24"
436	local ipv6="fc00::1"
437
438	export RUMP_SERVER=$sock
439
440	atf_check -s exit:0 rump.ifconfig $ifname create
441	atf_check -s exit:0 rump.ifconfig $ifname destroy
442
443	atf_check -s exit:0 rump.ifconfig $ifname create
444	atf_check -s exit:0 rump.ifconfig $ifname up
445	atf_check -s exit:0 rump.ifconfig $ifname down
446	atf_check -s exit:0 rump.ifconfig $ifname destroy
447
448	# Destroy while UP
449	atf_check -s exit:0 rump.ifconfig $ifname create
450	atf_check -s exit:0 rump.ifconfig $ifname up
451	atf_check -s exit:0 rump.ifconfig $ifname destroy
452
453	if ! $test_address; then
454		return
455	fi
456
457	# With an IPv4 address
458	atf_check -s exit:0 rump.ifconfig $ifname create
459	atf_check -s exit:0 rump.ifconfig $ifname inet $ipv4
460	atf_check -s exit:0 rump.ifconfig $ifname up
461	atf_check -s exit:0 rump.ifconfig $ifname destroy
462
463	# With an IPv6 address
464	atf_check -s exit:0 rump.ifconfig $ifname create
465	atf_check -s exit:0 rump.ifconfig $ifname inet6 $ipv6
466	atf_check -s exit:0 rump.ifconfig $ifname up
467	atf_check -s exit:0 rump.ifconfig $ifname destroy
468
469	unset RUMP_SERVER
470}
471