1313680Sngie# $NetBSD: t_ndp.sh,v 1.17 2016/11/25 08:51:17 ozaki-r Exp $ 2303980Sngie# 3303980Sngie# Copyright (c) 2015 The NetBSD Foundation, Inc. 4303980Sngie# All rights reserved. 5303980Sngie# 6303980Sngie# Redistribution and use in source and binary forms, with or without 7303980Sngie# modification, are permitted provided that the following conditions 8303980Sngie# are met: 9303980Sngie# 1. Redistributions of source code must retain the above copyright 10303980Sngie# notice, this list of conditions and the following disclaimer. 11303980Sngie# 2. Redistributions in binary form must reproduce the above copyright 12303980Sngie# notice, this list of conditions and the following disclaimer in the 13303980Sngie# documentation and/or other materials provided with the distribution. 14303980Sngie# 15303980Sngie# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16303980Sngie# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17303980Sngie# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18303980Sngie# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19303980Sngie# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20303980Sngie# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21303980Sngie# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22303980Sngie# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23303980Sngie# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24303980Sngie# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25303980Sngie# POSSIBILITY OF SUCH DAMAGE. 26303980Sngie# 27303980Sngie 28303980SngieSOCKSRC=unix://commsock1 29303980SngieSOCKDST=unix://commsock2 30303980SngieIP6SRC=fc00::1 31303980SngieIP6DST=fc00::2 32303980Sngie 33313680SngieDEBUG=${DEBUG:-true} 34303980SngieTIMEOUT=1 35303980Sngie 36303980Sngieatf_test_case ndp_cache_expiration cleanup 37303980Sngieatf_test_case ndp_commands cleanup 38303980Sngieatf_test_case ndp_cache_overwriting cleanup 39303980Sngieatf_test_case ndp_neighborgcthresh cleanup 40303980Sngieatf_test_case ndp_link_activation cleanup 41303980Sngie 42303980Sngiendp_cache_expiration_head() 43303980Sngie{ 44303980Sngie atf_set "descr" "Tests for NDP cache expiration" 45303980Sngie atf_set "require.progs" "rump_server" 46303980Sngie} 47303980Sngie 48303980Sngiendp_commands_head() 49303980Sngie{ 50303980Sngie atf_set "descr" "Tests for commands of ndp(8)" 51303980Sngie atf_set "require.progs" "rump_server" 52303980Sngie} 53303980Sngie 54303980Sngiendp_cache_overwriting_head() 55303980Sngie{ 56303980Sngie atf_set "descr" "Tests for behavior of overwriting NDP caches" 57303980Sngie atf_set "require.progs" "rump_server" 58303980Sngie} 59303980Sngie 60303980Sngiendp_neighborgcthresh_head() 61303980Sngie{ 62303980Sngie atf_set "descr" "Tests for GC of neighbor caches" 63303980Sngie atf_set "require.progs" "rump_server" 64303980Sngie} 65303980Sngie 66303980Sngiendp_link_activation_head() 67303980Sngie{ 68303980Sngie atf_set "descr" "Tests for activating a new MAC address" 69303980Sngie atf_set "require.progs" "rump_server" 70303980Sngie} 71303980Sngie 72303980Sngiesetup_dst_server() 73303980Sngie{ 74303980Sngie local assign_ip=$1 75303980Sngie 76313680Sngie rump_server_add_iface $SOCKDST shmif0 bus1 77303980Sngie export RUMP_SERVER=$SOCKDST 78303980Sngie if [ "$assign_ip" != no ]; then 79303980Sngie atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST 80303980Sngie fi 81303980Sngie atf_check -s exit:0 rump.ifconfig shmif0 up 82303980Sngie atf_check -s exit:0 rump.ifconfig -w 10 83303980Sngie 84303980Sngie $DEBUG && rump.ifconfig shmif0 85303980Sngie $DEBUG && rump.ndp -n -a 86303980Sngie} 87303980Sngie 88303980Sngiesetup_src_server() 89303980Sngie{ 90303980Sngie $DEBUG && ulimit -c unlimited 91303980Sngie export RUMP_SERVER=$SOCKSRC 92303980Sngie 93303980Sngie # Setup an interface 94313680Sngie rump_server_add_iface $SOCKSRC shmif0 bus1 95303980Sngie atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC 96303980Sngie atf_check -s exit:0 rump.ifconfig shmif0 up 97303980Sngie atf_check -s exit:0 rump.ifconfig -w 10 98303980Sngie 99303980Sngie # Sanity check 100303980Sngie $DEBUG && rump.ifconfig shmif0 101303980Sngie $DEBUG && rump.ndp -n -a 102303980Sngie atf_check -s exit:0 -o ignore rump.ndp -n $IP6SRC 103303980Sngie atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST 104303980Sngie} 105303980Sngie 106303980Sngieget_timeout() 107303980Sngie{ 108303980Sngie local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}') 109303980Sngie timeout=${timeout%s} 110303980Sngie echo $timeout 111303980Sngie} 112303980Sngie 113303980Sngiendp_cache_expiration_body() 114303980Sngie{ 115303980Sngie 116313680Sngie rump_server_start $SOCKSRC netinet6 117313680Sngie rump_server_start $SOCKDST netinet6 118313680Sngie 119303980Sngie setup_dst_server 120303980Sngie setup_src_server 121303980Sngie 122303980Sngie # 123303980Sngie # Check if a cache is expired expectedly 124303980Sngie # 125303980Sngie export RUMP_SERVER=$SOCKSRC 126303980Sngie atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST 127303980Sngie 128303980Sngie $DEBUG && rump.ndp -n -a 129303980Sngie atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC 130303980Sngie # Should be cached 131303980Sngie atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST 132303980Sngie 133303980Sngie timeout=$(get_timeout $IP6DST) 134303980Sngie 135303980Sngie atf_check -s exit:0 sleep $(($timeout + 1)) 136303980Sngie 137303980Sngie $DEBUG && rump.ndp -n -a 138303980Sngie atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC 139303980Sngie # Expired but remains until GC sweaps it (1 day) 140303980Sngie atf_check -s exit:0 -o match:'(1d0h0m|23h59m)' rump.ndp -n $IP6DST 141313680Sngie 142313680Sngie rump_server_destroy_ifaces 143303980Sngie} 144303980Sngie 145303980Sngieifdown_dst_server() 146303980Sngie{ 147303980Sngie export RUMP_SERVER=$SOCKDST 148303980Sngie atf_check -s exit:0 rump.ifconfig shmif0 down 149303980Sngie export RUMP_SERVER=$SOCKSRC 150303980Sngie} 151303980Sngie 152303980Sngiendp_commands_body() 153303980Sngie{ 154303980Sngie 155313680Sngie rump_server_start $SOCKSRC netinet6 156313680Sngie rump_server_start $SOCKDST netinet6 157313680Sngie 158303980Sngie setup_dst_server 159303980Sngie setup_src_server 160303980Sngie 161303980Sngie export RUMP_SERVER=$SOCKSRC 162303980Sngie 163303980Sngie # We can delete the entry for the interface's IP address 164303980Sngie atf_check -s exit:0 -o match:"$IP6SRC" rump.ndp -d $IP6SRC 165303980Sngie 166303980Sngie # Add and delete a static entry 167303980Sngie $DEBUG && rump.ndp -n -a 168303980Sngie atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 169303980Sngie $DEBUG && rump.ndp -n -a 170303980Sngie atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10 171303980Sngie atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10 172303980Sngie $DEBUG && rump.ndp -n -a 173303980Sngie atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10 174303980Sngie 175303980Sngie # Add multiple entries via a file (XXX not implemented) 176303980Sngie #cat - > ./list <<-EOF 177303980Sngie #fc00::11 b2:a0:20:00:00:11 178303980Sngie #fc00::12 b2:a0:20:00:00:12 179303980Sngie #fc00::13 b2:a0:20:00:00:13 180303980Sngie #fc00::14 b2:a0:20:00:00:14 181303980Sngie #fc00::15 b2:a0:20:00:00:15 182303980Sngie #EOF 183303980Sngie #$DEBUG && rump.ndp -n -a 184303980Sngie #atf_check -s exit:0 -o ignore rump.ndp -f ./list 185303980Sngie #$DEBUG && rump.ndp -n -a 186303980Sngie 187303980Sngie atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST 188303980Sngie atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11 189303980Sngie atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12 190303980Sngie 191303980Sngie atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST 192303980Sngie atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11 193303980Sngie atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12 194303980Sngie 195303980Sngie # Test ndp -a 196303980Sngie atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a 197303980Sngie atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a 198303980Sngie 199303980Sngie # Ensure no packet upsets the src server 200303980Sngie ifdown_dst_server 201303980Sngie 202303980Sngie # Flush all entries (-c) 203303980Sngie $DEBUG && rump.ndp -n -a 204303980Sngie atf_check -s exit:0 -o ignore rump.ndp -c 205303980Sngie atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC 206303980Sngie atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST 207303980Sngie # Only the static caches are not deleted 208303980Sngie atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11 209303980Sngie atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12 210303980Sngie 211303980Sngie $DEBUG && rump.ndp -n -a 212303980Sngie atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp 213303980Sngie rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp 214303980Sngie $DEBUG && rump.ndp -n -a 215303980Sngie atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10 216303980Sngie 217313680Sngie rump_server_destroy_ifaces 218303980Sngie} 219303980Sngie 220303980Sngiendp_cache_overwriting_body() 221303980Sngie{ 222303980Sngie 223313680Sngie rump_server_start $SOCKSRC netinet6 224313680Sngie rump_server_start $SOCKDST netinet6 225313680Sngie 226303980Sngie setup_dst_server 227303980Sngie setup_src_server 228303980Sngie 229303980Sngie export RUMP_SERVER=$SOCKSRC 230303980Sngie 231303980Sngie # Cannot overwrite a permanent cache 232303980Sngie atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:ff 233303980Sngie $DEBUG && rump.ndp -n -a 234303980Sngie 235303980Sngie atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST 236303980Sngie $DEBUG && rump.ndp -n -a 237303980Sngie # Can overwrite a dynamic cache 238303980Sngie atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00 239303980Sngie $DEBUG && rump.ndp -n -a 240303980Sngie atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST 241303980Sngie 242303980Sngie # Test temp option (XXX it doesn't work; expire time isn't set) 243303980Sngie #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp 244303980Sngie #$DEBUG && rump.ndp -n -a 245303980Sngie #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10 246303980Sngie # Cannot overwrite a temp cache 247303980Sngie #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff 248303980Sngie #$DEBUG && rump.ndp -n -a 249303980Sngie 250313680Sngie rump_server_destroy_ifaces 251303980Sngie} 252303980Sngie 253303980Sngieget_n_caches() 254303980Sngie{ 255303980Sngie 256303980Sngie echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l) 257303980Sngie} 258303980Sngie 259303980Sngiendp_neighborgcthresh_body() 260303980Sngie{ 261303980Sngie 262313680Sngie rump_server_start $SOCKSRC netinet6 263313680Sngie rump_server_start $SOCKDST netinet6 264303980Sngie 265303980Sngie setup_dst_server no 266303980Sngie setup_src_server 267303980Sngie 268303980Sngie export RUMP_SERVER=$SOCKDST 269303980Sngie for i in $(seq 0 9); do 270303980Sngie atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i 271303980Sngie done 272303980Sngie 273303980Sngie export RUMP_SERVER=$SOCKSRC 274303980Sngie 275303980Sngie # ping to 3 destinations 276303980Sngie $DEBUG && rump.ndp -n -a 277303980Sngie for i in $(seq 0 2); do 278303980Sngie atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ 279303980Sngie ${IP6DST}$i 280303980Sngie done 281303980Sngie $DEBUG && rump.ndp -n -a 282303980Sngie 283303980Sngie # 3 caches should be created 284303980Sngie atf_check_equal $(get_n_caches) 3 285303980Sngie 286303980Sngie # ping to additional 3 destinations 287303980Sngie for i in $(seq 3 5); do 288303980Sngie atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ 289303980Sngie ${IP6DST}$i 290303980Sngie done 291303980Sngie $DEBUG && rump.ndp -n -a 292303980Sngie 293303980Sngie # 6 caches should be created in total 294303980Sngie atf_check_equal $(get_n_caches) 6 295303980Sngie 296303980Sngie # Limit the number of neighbor caches to 5 297303980Sngie atf_check -s exit:0 -o ignore rump.sysctl -w \ 298303980Sngie net.inet6.ip6.neighborgcthresh=5 299303980Sngie 300303980Sngie # ping to additional 4 destinations 301303980Sngie for i in $(seq 6 9); do 302303980Sngie atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ 303303980Sngie ${IP6DST}$i 304303980Sngie done 305303980Sngie 306303980Sngie # More than 5 caches should be created in total, but exceeded caches 307303980Sngie # should be GC-ed 308303980Sngie if [ "$(get_n_caches)" -gt 5 ]; then 309303980Sngie atf_fail "Neighbor caches are not GC-ed" 310303980Sngie fi 311303980Sngie 312313680Sngie rump_server_destroy_ifaces 313303980Sngie} 314303980Sngie 315303980Sngiemake_pkt_str_na() 316303980Sngie{ 317303980Sngie local ip=$1 318303980Sngie local mac=$2 319303980Sngie local pkt= 320303980Sngie pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:" 321303980Sngie pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement" 322303980Sngie echo $pkt 323303980Sngie} 324303980Sngie 325303980Sngiendp_link_activation_body() 326303980Sngie{ 327303980Sngie local linklocal= 328303980Sngie 329313680Sngie rump_server_start $SOCKSRC netinet6 330313680Sngie rump_server_start $SOCKDST netinet6 331303980Sngie 332303980Sngie setup_dst_server 333303980Sngie setup_src_server 334303980Sngie 335303980Sngie # flush old packets 336313680Sngie extract_new_packets bus1 > ./out 337303980Sngie 338303980Sngie export RUMP_SERVER=$SOCKSRC 339303980Sngie 340303980Sngie atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 341303980Sngie b2:a1:00:00:00:01 342303980Sngie 343303980Sngie atf_check -s exit:0 sleep 1 344313680Sngie extract_new_packets bus1 > ./out 345303980Sngie $DEBUG && cat ./out 346303980Sngie 347303980Sngie linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}') 348303980Sngie $DEBUG && echo $linklocal 349303980Sngie 350303980Sngie pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01) 351303980Sngie atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" 352303980Sngie 353303980Sngie atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 354303980Sngie b2:a1:00:00:00:02 active 355303980Sngie 356303980Sngie atf_check -s exit:0 sleep 1 357313680Sngie extract_new_packets bus1 > ./out 358303980Sngie $DEBUG && cat ./out 359303980Sngie 360303980Sngie linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}') 361303980Sngie $DEBUG && echo $linklocal 362303980Sngie 363303980Sngie pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02) 364303980Sngie atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" 365303980Sngie 366313680Sngie rump_server_destroy_ifaces 367303980Sngie} 368303980Sngie 369303980Sngiendp_cache_expiration_cleanup() 370303980Sngie{ 371303980Sngie $DEBUG && dump 372303980Sngie cleanup 373303980Sngie} 374303980Sngie 375303980Sngiendp_commands_cleanup() 376303980Sngie{ 377303980Sngie $DEBUG && dump 378303980Sngie cleanup 379303980Sngie} 380303980Sngie 381303980Sngiendp_cache_overwriting_cleanup() 382303980Sngie{ 383303980Sngie $DEBUG && dump 384303980Sngie cleanup 385303980Sngie} 386303980Sngie 387303980Sngiendp_neighborgcthresh_cleanup() 388303980Sngie{ 389303980Sngie $DEBUG && dump 390303980Sngie cleanup 391303980Sngie} 392303980Sngie 393303980Sngiendp_link_activation_cleanup() 394303980Sngie{ 395303980Sngie $DEBUG && dump 396303980Sngie cleanup 397303980Sngie} 398303980Sngie 399303980Sngieatf_init_test_cases() 400303980Sngie{ 401303980Sngie atf_add_test_case ndp_cache_expiration 402303980Sngie atf_add_test_case ndp_commands 403303980Sngie atf_add_test_case ndp_cache_overwriting 404303980Sngie atf_add_test_case ndp_neighborgcthresh 405303980Sngie atf_add_test_case ndp_link_activation 406303980Sngie} 407