net_common.sh revision 1.21 1 # $NetBSD: net_common.sh,v 1.21 2017/10/20 03:42:53 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
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" \
88 rump.netstat -rn
89 }
90
91 get_linklocal_addr()
92 {
93
94 export RUMP_SERVER=${1}
95 rump.ifconfig ${2} inet6 |
96 awk "/fe80/ {sub(/%$2/, \"\"); sub(/\\/[0-9]*/, \"\"); print \$2;}"
97 unset RUMP_SERVER
98
99 return 0
100 }
101
102 get_macaddr()
103 {
104
105 env RUMP_SERVER=${1} \
106 rump.ifconfig ${2} |awk '/address/ {print $2;}'
107 }
108
109 HTTPD_PID=./.__httpd.pid
110 start_httpd()
111 {
112 local sock=$1
113 local ip=$2
114 local backup=$RUMP_SERVER
115
116 export RUMP_SERVER=$sock
117
118 # start httpd in daemon mode
119 atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
120 /usr/libexec/httpd -P $HTTPD_PID -i $ip -b -s $(pwd)
121
122 export RUMP_SERVER=$backup
123
124 sleep 3
125 }
126
127 stop_httpd()
128 {
129
130 if [ -f $HTTPD_PID ]; then
131 kill -9 $(cat $HTTPD_PID)
132 rm -f $HTTPD_PID
133 sleep 1
134 fi
135 }
136
137 NC_PID=./.__nc.pid
138 start_nc_server()
139 {
140 local sock=$1
141 local port=$2
142 local outfile=$3
143 local proto=${4:-ipv4}
144 local backup=$RUMP_SERVER
145 local pid= opts=
146
147 export RUMP_SERVER=$sock
148
149 if [ $proto = ipv4 ]; then
150 opts="-l -4"
151 else
152 opts="-l -6"
153 fi
154
155 env LD_PRELOAD=/usr/lib/librumphijack.so \
156 nc $opts $port > $outfile &
157 pid=$!
158 echo $pid > $NC_PID
159
160 if [ $proto = ipv4 ]; then
161 $DEBUG && rump.netstat -a -f inet
162 else
163 $DEBUG && rump.netstat -a -f inet6
164 fi
165
166 export RUMP_SERVER=$backup
167
168 sleep 1
169 }
170
171 stop_nc_server()
172 {
173
174 if [ -f $NC_PID ]; then
175 kill -9 $(cat $NC_PID)
176 rm -f $NC_PID
177 sleep 1
178 fi
179 }
180
181 BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \
182 -lrumpnet_shmif -lrumpdev"
183 FS_LIBS="$BASIC_LIBS -lrumpvfs -lrumpfs_ffs"
184 CRYPTO_LIBS="$BASIC_LIBS -lrumpvfs -lrumpdev_opencrypto \
185 -lrumpkern_z -lrumpkern_crypto"
186
187 # We cannot keep variables between test phases, so need to store in files
188 _rump_server_socks=./.__socks
189 _rump_server_ifaces=./.__ifaces
190 _rump_server_buses=./.__buses
191
192 DEBUG_SYSCTL_ENTRIES="net.inet.arp.debug net.inet6.icmp6.nd6_debug \
193 net.inet.ipsec.debug"
194
195 IPSEC_KEY_DEBUG=${IPSEC_KEY_DEBUG:-false}
196
197 _rump_server_start_common()
198 {
199 local sock=$1
200 local libs=
201 local backup=$RUMP_SERVER
202
203 shift 1
204 libs="$*"
205
206 atf_check -s exit:0 rump_server $libs $sock
207
208 if $DEBUG; then
209 # Enable debugging features in the kernel
210 export RUMP_SERVER=$sock
211 for ent in $DEBUG_SYSCTL_ENTRIES; do
212 if rump.sysctl -q $ent; then
213 atf_check -s exit:0 rump.sysctl -q -w $ent=1
214 fi
215 done
216 export RUMP_SERVER=$backup
217 fi
218 if $IPSEC_KEY_DEBUG; then
219 # Enable debugging features in the kernel
220 export RUMP_SERVER=$sock
221 if rump.sysctl -q net.key.debug; then
222 atf_check -s exit:0 \
223 rump.sysctl -q -w net.key.debug=0xffff
224 fi
225 export RUMP_SERVER=$backup
226 fi
227
228 echo $sock >> $_rump_server_socks
229 $DEBUG && cat $_rump_server_socks
230 }
231
232 rump_server_start()
233 {
234 local sock=$1
235 local _libs=
236 local libs="$BASIC_LIBS"
237
238 shift 1
239 _libs="$*"
240
241 for lib in $_libs; do
242 libs="$libs -lrumpnet_$lib"
243 done
244
245 _rump_server_start_common $sock $libs
246
247 return 0
248 }
249
250 rump_server_fs_start()
251 {
252 local sock=$1
253 local _libs=
254 local libs="$FS_LIBS"
255
256 shift 1
257 _libs="$*"
258
259 for lib in $_libs; do
260 libs="$libs -lrumpnet_$lib"
261 done
262
263 _rump_server_start_common $sock $libs
264
265 return 0
266 }
267
268 rump_server_crypto_start()
269 {
270 local sock=$1
271 local _libs=
272 local libs="$CRYPTO_LIBS"
273
274 shift 1
275 _libs="$*"
276
277 for lib in $_libs; do
278 libs="$libs -lrumpnet_$lib"
279 done
280
281 _rump_server_start_common $sock $libs
282
283 return 0
284 }
285
286 rump_server_add_iface()
287 {
288 local sock=$1
289 local ifname=$2
290 local bus=$3
291 local backup=$RUMP_SERVER
292
293 export RUMP_SERVER=$sock
294 atf_check -s exit:0 rump.ifconfig $ifname create
295 atf_check -s exit:0 rump.ifconfig $ifname linkstr $bus
296 export RUMP_SERVER=$backup
297
298 echo $sock $ifname >> $_rump_server_ifaces
299 $DEBUG && cat $_rump_server_ifaces
300
301 echo $bus >> $_rump_server_buses
302 cat $_rump_server_buses |sort -u >./.__tmp
303 mv -f ./.__tmp $_rump_server_buses
304 $DEBUG && cat $_rump_server_buses
305
306 return 0
307 }
308
309 rump_server_destroy_ifaces()
310 {
311 local backup=$RUMP_SERVER
312
313 $DEBUG && cat $_rump_server_ifaces
314
315 # Try to dump states before destroying interfaces
316 for sock in $(cat $_rump_server_socks); do
317 export RUMP_SERVER=$sock
318 atf_check -s exit:0 -o ignore rump.ifconfig
319 atf_check -s exit:0 -o ignore rump.netstat -nr
320 # XXX still need hijacking
321 atf_check -s exit:0 -o ignore $HIJACKING rump.netstat -i -a
322 atf_check -s exit:0 -o ignore rump.arp -na
323 atf_check -s exit:0 -o ignore rump.ndp -na
324 atf_check -s exit:0 -o ignore $HIJACKING ifmcstat
325 done
326
327 # XXX using pipe doesn't work. See PR bin/51667
328 #cat $_rump_server_ifaces | while read sock ifname; do
329 while read sock ifname; do
330 export RUMP_SERVER=$sock
331 if rump.ifconfig -l |grep -q $ifname; then
332 atf_check -s exit:0 rump.ifconfig $ifname destroy
333 fi
334 atf_check -s exit:0 -o ignore rump.ifconfig
335 done < $_rump_server_ifaces
336 export RUMP_SERVER=$backup
337
338 return 0
339 }
340
341 rump_server_halt_servers()
342 {
343 local backup=$RUMP_SERVER
344
345 $DEBUG && cat $_rump_server_socks
346 for sock in $(cat $_rump_server_socks); do
347 env RUMP_SERVER=$sock rump.halt
348 done
349 export RUMP_SERVER=$backup
350
351 return 0
352 }
353
354 rump_server_dump_servers()
355 {
356 local backup=$RUMP_SERVER
357
358 $DEBUG && cat $_rump_server_socks
359 for sock in $(cat $_rump_server_socks); do
360 echo "### Dumping $sock"
361 export RUMP_SERVER=$sock
362 rump.ifconfig -av
363 rump.netstat -nr
364 # XXX still need hijacking
365 $HIJACKING rump.netstat -i -a
366 rump.arp -na
367 rump.ndp -na
368 $HIJACKING ifmcstat
369 $HIJACKING dmesg
370 done
371 export RUMP_SERVER=$backup
372
373 if [ -f rump_server.core ]; then
374 gdb -ex bt /usr/bin/rump_server rump_server.core
375 strings rump_server.core |grep panic
376 fi
377 return 0
378 }
379
380 rump_server_dump_buses()
381 {
382
383 if [ ! -f $_rump_server_buses ]; then
384 return 0
385 fi
386
387 $DEBUG && cat $_rump_server_buses
388 for bus in $(cat $_rump_server_buses); do
389 echo "### Dumping $bus"
390 shmif_dumpbus -p - $bus 2>/dev/null| tcpdump -n -e -r -
391 done
392 return 0
393 }
394
395 cleanup()
396 {
397
398 rump_server_halt_servers
399 }
400
401 dump()
402 {
403
404 rump_server_dump_servers
405 rump_server_dump_buses
406 }
407
408 skip_if_qemu()
409 {
410 if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1
411 then
412 atf_skip "unreliable under qemu, skip until PR kern/43997 fixed"
413 fi
414 }
415