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