1# $NetBSD: t_ndp.sh,v 1.13 2016/08/10 23:07:57 kre Exp $ 2# 3# Copyright (c) 2015 The NetBSD Foundation, 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 28inetserver="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet" 29inetserver="$inetserver -lrumpnet_netinet6 -lrumpnet_shmif" 30inetserver="$inetserver -lrumpdev" 31HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=sysctl=yes" 32 33SOCKSRC=unix://commsock1 34SOCKDST=unix://commsock2 35IP6SRC=fc00::1 36IP6DST=fc00::2 37 38DEBUG=true 39TIMEOUT=1 40 41atf_test_case ndp_cache_expiration cleanup 42atf_test_case ndp_commands cleanup 43atf_test_case ndp_cache_overwriting cleanup 44atf_test_case ndp_neighborgcthresh cleanup 45atf_test_case ndp_link_activation cleanup 46 47ndp_cache_expiration_head() 48{ 49 atf_set "descr" "Tests for NDP cache expiration" 50 atf_set "require.progs" "rump_server" 51} 52 53ndp_commands_head() 54{ 55 atf_set "descr" "Tests for commands of ndp(8)" 56 atf_set "require.progs" "rump_server" 57} 58 59ndp_cache_overwriting_head() 60{ 61 atf_set "descr" "Tests for behavior of overwriting NDP caches" 62 atf_set "require.progs" "rump_server" 63} 64 65ndp_neighborgcthresh_head() 66{ 67 atf_set "descr" "Tests for GC of neighbor caches" 68 atf_set "require.progs" "rump_server" 69} 70 71ndp_link_activation_head() 72{ 73 atf_set "descr" "Tests for activating a new MAC address" 74 atf_set "require.progs" "rump_server" 75} 76 77setup_dst_server() 78{ 79 local assign_ip=$1 80 81 export RUMP_SERVER=$SOCKDST 82 atf_check -s exit:0 rump.ifconfig shmif0 create 83 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1 84 if [ "$assign_ip" != no ]; then 85 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST 86 fi 87 atf_check -s exit:0 rump.ifconfig shmif0 up 88 atf_check -s exit:0 rump.ifconfig -w 10 89 90 $DEBUG && rump.ifconfig shmif0 91 $DEBUG && rump.ndp -n -a 92} 93 94setup_src_server() 95{ 96 $DEBUG && ulimit -c unlimited 97 export RUMP_SERVER=$SOCKSRC 98 99 # Setup an interface 100 atf_check -s exit:0 rump.ifconfig shmif0 create 101 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1 102 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC 103 atf_check -s exit:0 rump.ifconfig shmif0 up 104 atf_check -s exit:0 rump.ifconfig -w 10 105 106 # Sanity check 107 $DEBUG && rump.ifconfig shmif0 108 $DEBUG && rump.ndp -n -a 109 atf_check -s exit:0 -o ignore rump.ndp -n $IP6SRC 110 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST 111} 112 113get_timeout() 114{ 115 local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}') 116 timeout=${timeout%s} 117 echo $timeout 118} 119 120ndp_cache_expiration_body() 121{ 122 atf_check -s exit:0 ${inetserver} $SOCKSRC 123 atf_check -s exit:0 ${inetserver} $SOCKDST 124 125 setup_dst_server 126 setup_src_server 127 128 # 129 # Check if a cache is expired expectedly 130 # 131 export RUMP_SERVER=$SOCKSRC 132 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST 133 134 $DEBUG && rump.ndp -n -a 135 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC 136 # Should be cached 137 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST 138 139 timeout=$(get_timeout $IP6DST) 140 141 atf_check -s exit:0 sleep $(($timeout + 1)) 142 143 $DEBUG && rump.ndp -n -a 144 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC 145 # Expired but remains until GC sweaps it (1 day) 146 atf_check -s exit:0 -o match:'(1d0h0m|23h59m)' rump.ndp -n $IP6DST 147} 148 149ifdown_dst_server() 150{ 151 export RUMP_SERVER=$SOCKDST 152 atf_check -s exit:0 rump.ifconfig shmif0 down 153 export RUMP_SERVER=$SOCKSRC 154} 155 156ndp_commands_body() 157{ 158 atf_check -s exit:0 ${inetserver} $SOCKSRC 159 atf_check -s exit:0 ${inetserver} $SOCKDST 160 161 setup_dst_server 162 setup_src_server 163 164 export RUMP_SERVER=$SOCKSRC 165 166 # We can delete the entry for the interface's IP address 167 atf_check -s exit:0 -o match:"$IP6SRC" rump.ndp -d $IP6SRC 168 169 # Add and delete a static entry 170 $DEBUG && rump.ndp -n -a 171 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 172 $DEBUG && rump.ndp -n -a 173 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10 174 atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10 175 $DEBUG && rump.ndp -n -a 176 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10 177 178 # Add multiple entries via a file (XXX not implemented) 179 #cat - > ./list <<-EOF 180 #fc00::11 b2:a0:20:00:00:11 181 #fc00::12 b2:a0:20:00:00:12 182 #fc00::13 b2:a0:20:00:00:13 183 #fc00::14 b2:a0:20:00:00:14 184 #fc00::15 b2:a0:20:00:00:15 185 #EOF 186 #$DEBUG && rump.ndp -n -a 187 #atf_check -s exit:0 -o ignore rump.ndp -f ./list 188 #$DEBUG && rump.ndp -n -a 189 190 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST 191 atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11 192 atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12 193 194 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST 195 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11 196 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12 197 198 # Test ndp -a 199 atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a 200 atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a 201 202 # Ensure no packet upsets the src server 203 ifdown_dst_server 204 205 # Flush all entries (-c) 206 $DEBUG && rump.ndp -n -a 207 atf_check -s exit:0 -o ignore rump.ndp -c 208 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC 209 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST 210 # Only the static caches are not deleted 211 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11 212 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12 213 214 $DEBUG && rump.ndp -n -a 215 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp 216 rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp 217 $DEBUG && rump.ndp -n -a 218 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10 219 220 return 0 221} 222 223ndp_cache_overwriting_body() 224{ 225 atf_check -s exit:0 ${inetserver} $SOCKSRC 226 atf_check -s exit:0 ${inetserver} $SOCKDST 227 228 setup_dst_server 229 setup_src_server 230 231 export RUMP_SERVER=$SOCKSRC 232 233 # Cannot overwrite a permanent cache 234 atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:ff 235 $DEBUG && rump.ndp -n -a 236 237 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST 238 $DEBUG && rump.ndp -n -a 239 # Can overwrite a dynamic cache 240 atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00 241 $DEBUG && rump.ndp -n -a 242 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST 243 244 # Test temp option (XXX it doesn't work; expire time isn't set) 245 #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp 246 #$DEBUG && rump.ndp -n -a 247 #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10 248 # Cannot overwrite a temp cache 249 #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff 250 #$DEBUG && rump.ndp -n -a 251 252 return 0 253} 254 255get_n_caches() 256{ 257 258 echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l) 259} 260 261ndp_neighborgcthresh_body() 262{ 263 264 atf_check -s exit:0 ${inetserver} $SOCKSRC 265 atf_check -s exit:0 ${inetserver} $SOCKDST 266 267 setup_dst_server no 268 setup_src_server 269 270 export RUMP_SERVER=$SOCKDST 271 for i in $(seq 0 9); do 272 atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i 273 done 274 275 export RUMP_SERVER=$SOCKSRC 276 277 # ping to 3 destinations 278 $DEBUG && rump.ndp -n -a 279 for i in $(seq 0 2); do 280 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ 281 ${IP6DST}$i 282 done 283 $DEBUG && rump.ndp -n -a 284 285 # 3 caches should be created 286 atf_check_equal $(get_n_caches) 3 287 288 # ping to additional 3 destinations 289 for i in $(seq 3 5); do 290 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ 291 ${IP6DST}$i 292 done 293 $DEBUG && rump.ndp -n -a 294 295 # 6 caches should be created in total 296 atf_check_equal $(get_n_caches) 6 297 298 # Limit the number of neighbor caches to 5 299 atf_check -s exit:0 -o ignore rump.sysctl -w \ 300 net.inet6.ip6.neighborgcthresh=5 301 302 # ping to additional 4 destinations 303 for i in $(seq 6 9); do 304 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ 305 ${IP6DST}$i 306 done 307 308 # More than 5 caches should be created in total, but exceeded caches 309 # should be GC-ed 310 if [ "$(get_n_caches)" -gt 5 ]; then 311 atf_fail "Neighbor caches are not GC-ed" 312 fi 313 314 return 0 315} 316 317make_pkt_str_na() 318{ 319 local ip=$1 320 local mac=$2 321 local pkt= 322 pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:" 323 pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement" 324 echo $pkt 325} 326 327extract_new_packets() 328{ 329 local old=./old 330 331 if [ ! -f $old ]; then 332 old=/dev/null 333 fi 334 335 shmif_dumpbus -p - bus1 2>/dev/null| \ 336 tcpdump -n -e -r - 2>/dev/null > ./new 337 diff -u $old ./new |grep '^+' |cut -d '+' -f 2 > ./diff 338 mv -f ./new ./old 339 cat ./diff 340} 341 342ndp_link_activation_body() 343{ 344 local linklocal= 345 346 atf_check -s exit:0 ${inetserver} $SOCKSRC 347 atf_check -s exit:0 ${inetserver} $SOCKDST 348 349 setup_dst_server 350 setup_src_server 351 352 # flush old packets 353 extract_new_packets > ./out 354 355 export RUMP_SERVER=$SOCKSRC 356 357 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 358 b2:a1:00:00:00:01 359 360 atf_check -s exit:0 sleep 1 361 extract_new_packets > ./out 362 $DEBUG && cat ./out 363 364 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}') 365 $DEBUG && echo $linklocal 366 367 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01) 368 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" 369 370 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 371 b2:a1:00:00:00:02 active 372 373 atf_check -s exit:0 sleep 1 374 extract_new_packets > ./out 375 $DEBUG && cat ./out 376 377 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}') 378 $DEBUG && echo $linklocal 379 380 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02) 381 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" 382} 383 384cleanup() 385{ 386 env RUMP_SERVER=$SOCKSRC rump.halt 387 env RUMP_SERVER=$SOCKDST rump.halt 388} 389 390dump_src() 391{ 392 export RUMP_SERVER=$SOCKSRC 393 rump.netstat -nr 394 rump.ndp -n -a 395 rump.ifconfig 396 $HIJACKING dmesg 397} 398 399dump_dst() 400{ 401 export RUMP_SERVER=$SOCKDST 402 rump.netstat -nr 403 rump.ndp -n -a 404 rump.ifconfig 405 $HIJACKING dmesg 406} 407 408dump() 409{ 410 dump_src 411 dump_dst 412 shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - 413 $DEBUG && gdb -ex bt /usr/bin/rump_server rump_server.core 414 $DEBUG && gdb -ex bt /usr/sbin/rump.ndp rump.ndp.core 415} 416 417ndp_cache_expiration_cleanup() 418{ 419 $DEBUG && dump 420 cleanup 421} 422 423ndp_commands_cleanup() 424{ 425 $DEBUG && dump 426 cleanup 427} 428 429ndp_cache_overwriting_cleanup() 430{ 431 $DEBUG && dump 432 cleanup 433} 434 435ndp_neighborgcthresh_cleanup() 436{ 437 $DEBUG && dump 438 cleanup 439} 440 441ndp_link_activation_cleanup() 442{ 443 $DEBUG && dump 444 cleanup 445} 446 447atf_init_test_cases() 448{ 449 atf_add_test_case ndp_cache_expiration 450 atf_add_test_case ndp_commands 451 atf_add_test_case ndp_cache_overwriting 452 atf_add_test_case ndp_neighborgcthresh 453 atf_add_test_case ndp_link_activation 454} 455