net_common.sh revision 1.29 1 # $NetBSD: net_common.sh,v 1.29 2019/01/17 02:49:11 knakahara 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
32 HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so \
33 RUMPHIJACK=path=/rump,socket=all:nolocal,sysctl=yes"
34 ONEDAYISH="(23h5[0-9]m|1d0h0m)[0-9]+s ?"
35
36 extract_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
52 check_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
71 check_route_flags()
72 {
73
74 check_route "$1" "" "$2" ""
75 }
76
77 check_route_gw()
78 {
79
80 check_route "$1" "$2" "" ""
81 }
82
83 check_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
90 get_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
99 get_macaddr()
100 {
101
102 RUMP_SERVER=${1} rump.ifconfig ${2} | awk '/address/ {print $2;}'
103 }
104
105 HTTPD_PID=./.__httpd.pid
106 start_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
123 stop_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
133 NC_PID=./.__nc.pid
134 start_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
165 stop_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
175 BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev"
176 FS_LIBS="$BASIC_LIBS -lrumpvfs -lrumpfs_ffs"
177 CRYPTO_LIBS="$BASIC_LIBS -lrumpvfs -lrumpdev_opencrypto \
178 -lrumpkern_z -lrumpkern_crypto"
179 NPF_LIBS="$BASIC_LIBS -lrumpvfs -lrumpdev_bpf -lrumpnet_npf"
180 CRYPTO_NPF_LIBS="$CRYPTO_LIBS -lrumpdev_bpf -lrumpnet_npf"
181
182 # We cannot keep variables between test phases, so need to store in files
183 _rump_server_socks=./.__socks
184 _rump_server_ifaces=./.__ifaces
185 _rump_server_buses=./.__buses
186
187 DEBUG_SYSCTL_ENTRIES="net.inet.arp.debug net.inet6.icmp6.nd6_debug \
188 net.inet.ipsec.debug"
189
190 IPSEC_KEY_DEBUG=${IPSEC_KEY_DEBUG:-false}
191
192 _rump_server_start_common()
193 {
194 local sock=$1
195 local backup=$RUMP_SERVER
196
197 shift 1
198
199 atf_check -s exit:0 rump_server "$@" "$sock"
200
201 if $DEBUG; then
202 # Enable debugging features in the kernel
203 export RUMP_SERVER=$sock
204 for ent in $DEBUG_SYSCTL_ENTRIES; do
205 if rump.sysctl -q $ent; then
206 atf_check -s exit:0 rump.sysctl -q -w $ent=1
207 fi
208 done
209 export RUMP_SERVER=$backup
210 fi
211 if $IPSEC_KEY_DEBUG; then
212 # Enable debugging features in the kernel
213 export RUMP_SERVER=$sock
214 if rump.sysctl -q net.key.debug; then
215 atf_check -s exit:0 \
216 rump.sysctl -q -w net.key.debug=0xffff
217 fi
218 export RUMP_SERVER=$backup
219 fi
220
221 echo $sock >> $_rump_server_socks
222 $DEBUG && cat $_rump_server_socks
223 }
224
225 rump_server_start()
226 {
227 local sock=$1
228 local lib=
229 local libs="$BASIC_LIBS"
230
231 shift 1
232
233 for lib
234 do
235 libs="$libs -lrumpnet_$lib"
236 done
237
238 _rump_server_start_common $sock $libs
239
240 return 0
241 }
242
243 rump_server_fs_start()
244 {
245 local sock=$1
246 local lib=
247 local libs="$FS_LIBS"
248
249 shift 1
250
251 for lib
252 do
253 libs="$libs -lrumpnet_$lib"
254 done
255
256 _rump_server_start_common $sock $libs
257
258 return 0
259 }
260
261 rump_server_crypto_start()
262 {
263 local sock=$1
264 local lib=
265 local libs="$CRYPTO_LIBS"
266
267 shift 1
268
269 for lib
270 do
271 libs="$libs -lrumpnet_$lib"
272 done
273
274 _rump_server_start_common $sock $libs
275
276 return 0
277 }
278
279 rump_server_npf_start()
280 {
281 local sock=$1
282 local lib=
283 local libs="$NPF_LIBS"
284
285 shift 1
286
287 for lib
288 do
289 libs="$libs -lrumpnet_$lib"
290 done
291
292 _rump_server_start_common $sock $libs
293
294 return 0
295 }
296
297 rump_server_crypto_npf_start()
298 {
299 local sock=$1
300 local lib=
301 local libs="$CRYPTO_NPF_LIBS"
302
303 shift 1
304
305 for lib
306 do
307 libs="$libs -lrumpnet_$lib"
308 done
309
310 _rump_server_start_common $sock $libs
311
312 return 0
313 }
314
315 rump_server_add_iface()
316 {
317 local sock=$1
318 local ifname=$2
319 local bus=$3
320 local backup=$RUMP_SERVER
321
322 export RUMP_SERVER=$sock
323 atf_check -s exit:0 rump.ifconfig $ifname create
324 atf_check -s exit:0 rump.ifconfig $ifname linkstr $bus
325 export RUMP_SERVER=$backup
326
327 echo $sock $ifname >> $_rump_server_ifaces
328 $DEBUG && cat $_rump_server_ifaces
329
330 echo $bus >> $_rump_server_buses
331 cat $_rump_server_buses |sort -u >./.__tmp
332 mv -f ./.__tmp $_rump_server_buses
333 $DEBUG && cat $_rump_server_buses
334
335 return 0
336 }
337
338 rump_server_destroy_ifaces()
339 {
340 local backup=$RUMP_SERVER
341 local output=ignore
342
343 $DEBUG && cat $_rump_server_ifaces
344
345 # Try to dump states before destroying interfaces
346 for sock in $(cat $_rump_server_socks); do
347 export RUMP_SERVER=$sock
348 if $DEBUG; then
349 output=save:/dev/stdout
350 fi
351 atf_check -s exit:0 -o $output rump.ifconfig
352 atf_check -s exit:0 -o $output rump.netstat -nr
353 # XXX still need hijacking
354 atf_check -s exit:0 -o $output $HIJACKING rump.netstat -nai
355 atf_check -s exit:0 -o $output rump.arp -na
356 atf_check -s exit:0 -o $output rump.ndp -na
357 atf_check -s exit:0 -o $output $HIJACKING ifmcstat
358 done
359
360 # XXX using pipe doesn't work. See PR bin/51667
361 #cat $_rump_server_ifaces | while read sock ifname; do
362 while read sock ifname; do
363 export RUMP_SERVER=$sock
364 if rump.ifconfig -l |grep -q $ifname; then
365 atf_check -s exit:0 rump.ifconfig $ifname destroy
366 fi
367 atf_check -s exit:0 -o ignore rump.ifconfig
368 done < $_rump_server_ifaces
369 export RUMP_SERVER=$backup
370
371 return 0
372 }
373
374 rump_server_halt_servers()
375 {
376 local backup=$RUMP_SERVER
377
378 $DEBUG && cat $_rump_server_socks
379 for sock in $(cat $_rump_server_socks); do
380 env RUMP_SERVER=$sock rump.halt
381 done
382 export RUMP_SERVER=$backup
383
384 return 0
385 }
386
387 rump_server_dump_servers()
388 {
389 local backup=$RUMP_SERVER
390
391 $DEBUG && cat $_rump_server_socks
392 for sock in $(cat $_rump_server_socks); do
393 echo "### Dumping $sock"
394 export RUMP_SERVER=$sock
395 rump.ifconfig -av
396 rump.netstat -nr
397 # XXX still need hijacking
398 $HIJACKING rump.netstat -nai
399 rump.arp -na
400 rump.ndp -na
401 $HIJACKING ifmcstat
402 $HIJACKING dmesg
403 done
404 export RUMP_SERVER=$backup
405
406 if [ -f rump_server.core ]; then
407 gdb -ex bt /usr/bin/rump_server rump_server.core
408 strings rump_server.core |grep panic
409 fi
410 return 0
411 }
412
413 rump_server_dump_buses()
414 {
415
416 if [ ! -f $_rump_server_buses ]; then
417 return 0
418 fi
419
420 $DEBUG && cat $_rump_server_buses
421 for bus in $(cat $_rump_server_buses); do
422 echo "### Dumping $bus"
423 shmif_dumpbus -p - $bus 2>/dev/null| tcpdump -n -e -r -
424 done
425 return 0
426 }
427
428 cleanup()
429 {
430
431 rump_server_halt_servers
432 }
433
434 dump()
435 {
436
437 rump_server_dump_servers
438 rump_server_dump_buses
439 }
440
441 skip_if_qemu()
442 {
443 if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1
444 then
445 atf_skip "unreliable under qemu, skip until PR kern/43997 fixed"
446 fi
447 }
448
449 test_create_destroy_common()
450 {
451 local sock=$1
452 local ifname=$2
453 local test_address=${3:-false}
454 local ipv4="10.0.0.1/24"
455 local ipv6="fc00::1"
456
457 export RUMP_SERVER=$sock
458
459 atf_check -s exit:0 rump.ifconfig $ifname create
460 atf_check -s exit:0 rump.ifconfig $ifname destroy
461
462 atf_check -s exit:0 rump.ifconfig $ifname create
463 atf_check -s exit:0 rump.ifconfig $ifname up
464 atf_check -s exit:0 rump.ifconfig $ifname down
465 atf_check -s exit:0 rump.ifconfig $ifname destroy
466
467 # Destroy while UP
468 atf_check -s exit:0 rump.ifconfig $ifname create
469 atf_check -s exit:0 rump.ifconfig $ifname up
470 atf_check -s exit:0 rump.ifconfig $ifname destroy
471
472 if ! $test_address; then
473 return
474 fi
475
476 # With an IPv4 address
477 atf_check -s exit:0 rump.ifconfig $ifname create
478 atf_check -s exit:0 rump.ifconfig $ifname inet $ipv4
479 atf_check -s exit:0 rump.ifconfig $ifname up
480 atf_check -s exit:0 rump.ifconfig $ifname destroy
481
482 # With an IPv6 address
483 atf_check -s exit:0 rump.ifconfig $ifname create
484 atf_check -s exit:0 rump.ifconfig $ifname inet6 $ipv6
485 atf_check -s exit:0 rump.ifconfig $ifname up
486 atf_check -s exit:0 rump.ifconfig $ifname destroy
487
488 unset RUMP_SERVER
489 }
490