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