Home | History | Annotate | Line # | Download | only in ndp
t_ndp.sh revision 1.26
      1 #	$NetBSD: t_ndp.sh,v 1.26 2017/06/26 03:16:28 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 
     28 SOCKSRC=unix://commsock1
     29 SOCKDST=unix://commsock2
     30 IP6SRC=fc00::1
     31 IP6SRC2=fc00::3
     32 IP6DST=fc00::2
     33 IP6NET=fc00::0
     34 
     35 DEBUG=${DEBUG:-false}
     36 TIMEOUT=1
     37 
     38 atf_test_case ndp_cache_expiration cleanup
     39 atf_test_case ndp_commands cleanup
     40 atf_test_case ndp_cache_overwriting cleanup
     41 atf_test_case ndp_neighborgcthresh cleanup
     42 atf_test_case ndp_link_activation cleanup
     43 
     44 ndp_cache_expiration_head()
     45 {
     46 	atf_set "descr" "Tests for NDP cache expiration"
     47 	atf_set "require.progs" "rump_server"
     48 }
     49 
     50 ndp_commands_head()
     51 {
     52 	atf_set "descr" "Tests for commands of ndp(8)"
     53 	atf_set "require.progs" "rump_server"
     54 }
     55 
     56 ndp_cache_overwriting_head()
     57 {
     58 	atf_set "descr" "Tests for behavior of overwriting NDP caches"
     59 	atf_set "require.progs" "rump_server"
     60 }
     61 
     62 ndp_neighborgcthresh_head()
     63 {
     64 	atf_set "descr" "Tests for GC of neighbor caches"
     65 	atf_set "require.progs" "rump_server"
     66 }
     67 
     68 ndp_link_activation_head()
     69 {
     70 	atf_set "descr" "Tests for activating a new MAC address"
     71 	atf_set "require.progs" "rump_server"
     72 }
     73 
     74 setup_dst_server()
     75 {
     76 	local assign_ip=$1
     77 
     78 	rump_server_add_iface $SOCKDST shmif0 bus1
     79 	export RUMP_SERVER=$SOCKDST
     80 	if [ "$assign_ip" != no ]; then
     81 		atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST
     82 	fi
     83 	atf_check -s exit:0 rump.ifconfig shmif0 up
     84 	atf_check -s exit:0 rump.ifconfig -w 10
     85 
     86 	$DEBUG && rump.ifconfig shmif0
     87 	$DEBUG && rump.ndp -n -a
     88 }
     89 
     90 setup_src_server()
     91 {
     92 	$DEBUG && ulimit -c unlimited
     93 	export RUMP_SERVER=$SOCKSRC
     94 
     95 	# Setup an interface
     96 	rump_server_add_iface $SOCKSRC shmif0 bus1
     97 	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC
     98 	atf_check -s exit:0 rump.ifconfig shmif0 up
     99 	atf_check -s exit:0 rump.ifconfig -w 10
    100 
    101 	# Sanity check
    102 	$DEBUG && rump.ifconfig shmif0
    103 	$DEBUG && rump.ndp -n -a
    104 	atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
    105 	atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
    106 }
    107 
    108 get_timeout()
    109 {
    110 	local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}')
    111 	timeout=${timeout%s}
    112 	echo $timeout
    113 }
    114 
    115 ndp_cache_expiration_body()
    116 {
    117 
    118 	rump_server_start $SOCKSRC netinet6
    119 	rump_server_start $SOCKDST netinet6
    120 
    121 	setup_dst_server
    122 	setup_src_server
    123 
    124 	#
    125 	# Check if a cache is expired expectedly
    126 	#
    127 	export RUMP_SERVER=$SOCKSRC
    128 	atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
    129 
    130 	$DEBUG && rump.ndp -n -a
    131 	atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
    132 	# Should be cached
    133 	atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
    134 
    135 	timeout=$(get_timeout $IP6DST)
    136 
    137 	atf_check -s exit:0 sleep $(($timeout + 1))
    138 
    139 	$DEBUG && rump.ndp -n -a
    140 	atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
    141 	# Expired but remains until GC sweaps it (1 day)
    142 	atf_check -s exit:0 -o match:"$ONEDAYISH" rump.ndp -n $IP6DST
    143 
    144 	rump_server_destroy_ifaces
    145 }
    146 
    147 ifdown_dst_server()
    148 {
    149 	export RUMP_SERVER=$SOCKDST
    150 	atf_check -s exit:0 rump.ifconfig shmif0 down
    151 	export RUMP_SERVER=$SOCKSRC
    152 }
    153 
    154 ndp_commands_body()
    155 {
    156 
    157 	rump_server_start $SOCKSRC netinet6
    158 	rump_server_start $SOCKDST netinet6
    159 
    160 	setup_dst_server
    161 	setup_src_server
    162 
    163 	export RUMP_SERVER=$SOCKSRC
    164 
    165 	# Add and delete a static entry
    166 	$DEBUG && rump.ndp -n -a
    167 	atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10
    168 	$DEBUG && rump.ndp -n -a
    169 	atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10
    170 	atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10
    171 	$DEBUG && rump.ndp -n -a
    172 	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10
    173 
    174 	# Add multiple entries via a file (XXX not implemented)
    175 	#cat - > ./list <<-EOF
    176 	#fc00::11 b2:a0:20:00:00:11
    177 	#fc00::12 b2:a0:20:00:00:12
    178 	#fc00::13 b2:a0:20:00:00:13
    179 	#fc00::14 b2:a0:20:00:00:14
    180 	#fc00::15 b2:a0:20:00:00:15
    181 	#EOF
    182 	#$DEBUG && rump.ndp -n -a
    183 	#atf_check -s exit:0 -o ignore rump.ndp -f ./list
    184 	#$DEBUG && rump.ndp -n -a
    185 
    186 	atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
    187 	atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11
    188 	atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12
    189 
    190 	atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
    191 	atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11
    192 	atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12
    193 
    194 	# Test ndp -a
    195 	atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a
    196 	atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a
    197 
    198 	# Ensure no packet upsets the src server
    199 	ifdown_dst_server
    200 
    201 	# Flush all entries (-c)
    202 	$DEBUG && rump.ndp -n -a
    203 	atf_check -s exit:0 -o ignore rump.ndp -c
    204 	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC
    205 	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
    206 	# Only the static caches are not deleted
    207 	atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11
    208 	atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12
    209 
    210 	$DEBUG && rump.ndp -n -a
    211 	atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
    212 	rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
    213 	$DEBUG && rump.ndp -n -a
    214 	atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
    215 
    216 	rump_server_destroy_ifaces
    217 }
    218 
    219 ndp_cache_overwriting_body()
    220 {
    221 
    222 	rump_server_start $SOCKSRC netinet6
    223 	rump_server_start $SOCKDST netinet6
    224 
    225 	setup_dst_server
    226 	setup_src_server
    227 
    228 	export RUMP_SERVER=$SOCKSRC
    229 
    230 	# Cannot overwrite a permanent cache
    231 	atf_check -s exit:0 rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
    232 	$DEBUG && rump.ndp -n -a
    233 	atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:fe
    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 
    253 get_n_caches()
    254 {
    255 
    256 	echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l)
    257 }
    258 
    259 ndp_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 
    315 make_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 
    325 ndp_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 
    369 ndp_cache_expiration_cleanup()
    370 {
    371 	$DEBUG && dump
    372 	cleanup
    373 }
    374 
    375 ndp_commands_cleanup()
    376 {
    377 	$DEBUG && dump
    378 	cleanup
    379 }
    380 
    381 ndp_cache_overwriting_cleanup()
    382 {
    383 	$DEBUG && dump
    384 	cleanup
    385 }
    386 
    387 ndp_neighborgcthresh_cleanup()
    388 {
    389 	$DEBUG && dump
    390 	cleanup
    391 }
    392 
    393 ndp_link_activation_cleanup()
    394 {
    395 	$DEBUG && dump
    396 	cleanup
    397 }
    398 
    399 atf_test_case ndp_rtm cleanup
    400 ndp_rtm_head()
    401 {
    402 
    403 	atf_set "descr" "Tests for routing messages on operations of NDP entries"
    404 	atf_set "require.progs" "rump_server"
    405 }
    406 
    407 ndp_rtm_body()
    408 {
    409 	local macaddr_src= macaddr_dst=
    410 	local file=./tmp
    411 	local pid= str=
    412 
    413 	rump_server_start $SOCKSRC netinet6
    414 	rump_server_start $SOCKDST netinet6
    415 
    416 	setup_dst_server
    417 	setup_src_server
    418 
    419 	macaddr_src=$(get_macaddr $SOCKSRC shmif0)
    420 	macaddr_dst=$(get_macaddr $SOCKDST shmif0)
    421 
    422 	export RUMP_SERVER=$SOCKSRC
    423 
    424 	# Test ping and a resulting routing message (RTM_ADD)
    425 	rump.route -n monitor -c 1 > $file &
    426 	pid=$?
    427 	sleep 1
    428 	atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
    429 	wait $pid
    430 	$DEBUG && cat $file
    431 
    432 	str="RTM_ADD.+<UP,HOST,DONE,LLINFO,CLONED>"
    433 	atf_check -s exit:0 -o match:"$str" cat $file
    434 	str="<DST,GATEWAY>"
    435 	atf_check -s exit:0 -o match:"$str" cat $file
    436 	str="$IP6DST link#2"
    437 	atf_check -s exit:0 -o match:"$str" cat $file
    438 
    439 	# Test ndp -d and resulting routing messages (RTM_GET and RTM_DELETE)
    440 	rump.route -n monitor -c 2 > $file &
    441 	pid=$?
    442 	sleep 1
    443 	atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
    444 	wait $pid
    445 	$DEBUG && cat $file
    446 
    447 	str="RTM_GET.+<UP,DONE,LLINFO>"
    448 	atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
    449 	str="<DST,GATEWAY>"
    450 	atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
    451 	str="$IP6DST $macaddr_dst"
    452 	atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
    453 	str="RTM_DELETE.+<UP,DONE,LLINFO>"
    454 	atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
    455 	str="<DST,GATEWAY>"
    456 	atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
    457 	str="$IP6DST $macaddr_dst"
    458 	atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
    459 
    460 	rump_server_destroy_ifaces
    461 }
    462 
    463 ndp_rtm_cleanup()
    464 {
    465 
    466 	$DEBUG && dump
    467 	cleanup
    468 }
    469 
    470 atf_test_case ndp_purge_on_route_change cleanup
    471 ndp_purge_on_route_change_head()
    472 {
    473 
    474 	atf_set "descr" "Tests if NDP entries are removed on route change"
    475 	atf_set "require.progs" "rump_server"
    476 }
    477 
    478 ndp_purge_on_route_change_body()
    479 {
    480 
    481 	rump_server_start $SOCKSRC netinet6
    482 	rump_server_start $SOCKDST netinet6
    483 
    484 	setup_dst_server
    485 	setup_src_server
    486 
    487 	rump_server_add_iface $SOCKSRC shmif1 bus1
    488 	export RUMP_SERVER=$SOCKSRC
    489 	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6SRC2
    490 	atf_check -s exit:0 rump.ifconfig -w 10
    491 
    492 	$DEBUG && rump.netstat -nr -f inet6
    493 	atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
    494 	atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
    495 
    496 	atf_check -s exit:0 -o ignore \
    497 	    rump.route change -inet6 -net $IP6NET/64 -ifp shmif1
    498 	$DEBUG && rump.netstat -nr -f inet6
    499 	$DEBUG && rump.ndp -na
    500 	# The entry was already removed on route change
    501 	atf_check -s not-exit:0 -o ignore -e match:'no entry' \
    502 	    rump.ndp -n $IP6DST
    503 
    504 	rump_server_destroy_ifaces
    505 }
    506 
    507 ndp_purge_on_route_change_cleanup()
    508 {
    509 
    510 	$DEBUG && dump
    511 	cleanup
    512 }
    513 
    514 atf_test_case ndp_purge_on_route_delete cleanup
    515 ndp_purge_on_route_delete_head()
    516 {
    517 
    518 	atf_set "descr" "Tests if NDP entries are removed on route delete"
    519 	atf_set "require.progs" "rump_server"
    520 }
    521 
    522 ndp_purge_on_route_delete_body()
    523 {
    524 
    525 	rump_server_start $SOCKSRC netinet6
    526 	rump_server_start $SOCKDST netinet6
    527 
    528 	setup_dst_server
    529 	setup_src_server
    530 
    531 	$DEBUG && rump.netstat -nr -f inet6
    532 	atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
    533 	atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
    534 
    535 	atf_check -s exit:0 -o ignore rump.route delete -inet6 -net $IP6NET/64
    536 	$DEBUG && rump.netstat -nr -f inet6
    537 	$DEBUG && rump.ndp -na
    538 
    539 	# The entry was already removed on route delete
    540 	atf_check -s not-exit:0 -o ignore -e match:'no entry' \
    541 	    rump.ndp -n $IP6DST
    542 
    543 	rump_server_destroy_ifaces
    544 }
    545 
    546 ndp_purge_on_route_delete_cleanup()
    547 {
    548 
    549 	$DEBUG && dump
    550 	cleanup
    551 }
    552 
    553 atf_test_case ndp_purge_on_ifdown cleanup
    554 ndp_purge_on_ifdown_head()
    555 {
    556 
    557 	atf_set "descr" "Tests if NDP entries are removed on interface down"
    558 	atf_set "require.progs" "rump_server"
    559 }
    560 
    561 ndp_purge_on_ifdown_body()
    562 {
    563 
    564 	rump_server_start $SOCKSRC netinet6
    565 	rump_server_start $SOCKDST netinet6
    566 
    567 	setup_dst_server
    568 	setup_src_server
    569 
    570 	$DEBUG && rump.netstat -nr -f inet6
    571 	atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
    572 	atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
    573 
    574 	# Shutdown the interface
    575 	atf_check -s exit:0 rump.ifconfig shmif0 down
    576 	$DEBUG && rump.netstat -nr -f inet6
    577 	$DEBUG && rump.ndp -na
    578 
    579 	# The entry was already removed on ifconfig down
    580 	atf_check -s not-exit:0 -o ignore -e match:'no entry' \
    581 	    rump.ndp -n $IP6DST
    582 
    583 	rump_server_destroy_ifaces
    584 }
    585 
    586 ndp_purge_on_ifdown_cleanup()
    587 {
    588 
    589 	$DEBUG && dump
    590 	cleanup
    591 }
    592 
    593 atf_init_test_cases()
    594 {
    595 	atf_add_test_case ndp_cache_expiration
    596 	atf_add_test_case ndp_commands
    597 	atf_add_test_case ndp_cache_overwriting
    598 	atf_add_test_case ndp_neighborgcthresh
    599 	atf_add_test_case ndp_link_activation
    600 	atf_add_test_case ndp_rtm
    601 	atf_add_test_case ndp_purge_on_route_change
    602 	atf_add_test_case ndp_purge_on_route_delete
    603 	atf_add_test_case ndp_purge_on_ifdown
    604 }
    605