t_ndp.sh revision 1.33 1 # $NetBSD: t_ndp.sh,v 1.33 2019/07/18 04:00:09 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 export RUMP_SERVER=$SOCKSRC
125
126 # Shorten the expire time of cache entries
127 atf_check -s exit:0 -o match:'basereachable=7s0ms' \
128 rump.ndp -i shmif0 basereachable=7000
129
130 #
131 # Check if a cache is expired expectedly
132 #
133 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
134
135 $DEBUG && rump.ndp -n -a
136 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
137 # Should be cached
138 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
139
140 timeout=$(get_timeout $IP6DST)
141
142 atf_check -s exit:0 sleep $(($timeout + 1))
143
144 $DEBUG && rump.ndp -n -a
145 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
146 # Expired but remains until GC sweaps it (1 day)
147 atf_check -s exit:0 -o match:"$ONEDAYISH" rump.ndp -n $IP6DST
148
149 rump_server_destroy_ifaces
150 }
151
152 ifdown_dst_server()
153 {
154 export RUMP_SERVER=$SOCKDST
155 atf_check -s exit:0 rump.ifconfig shmif0 down
156 export RUMP_SERVER=$SOCKSRC
157 }
158
159 ndp_commands_body()
160 {
161
162 rump_server_start $SOCKSRC netinet6
163 rump_server_start $SOCKDST netinet6
164
165 setup_dst_server
166 setup_src_server
167
168 export RUMP_SERVER=$SOCKSRC
169
170 # Add and delete a static entry
171 $DEBUG && rump.ndp -n -a
172 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10
173 $DEBUG && rump.ndp -n -a
174 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10
175 check_route fc00::10 'b2:a0:20:00:00:10' UHLS shmif0
176 atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10
177 $DEBUG && rump.ndp -n -a
178 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10
179 check_route_no_entry fc00::10
180
181 # Add multiple entries via a file (XXX not implemented)
182 #cat - > ./list <<-EOF
183 #fc00::11 b2:a0:20:00:00:11
184 #fc00::12 b2:a0:20:00:00:12
185 #fc00::13 b2:a0:20:00:00:13
186 #fc00::14 b2:a0:20:00:00:14
187 #fc00::15 b2:a0:20:00:00:15
188 #EOF
189 #$DEBUG && rump.ndp -n -a
190 #atf_check -s exit:0 -o ignore rump.ndp -f ./list
191 #$DEBUG && rump.ndp -n -a
192
193 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
194 atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11
195 atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12
196
197 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
198 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11
199 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12
200 check_route_flags $IP6DST UHL
201 check_route_flags fc00::11 UHLS
202 check_route_flags fc00::12 UHLS
203
204 # Test ndp -a
205 atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a
206 atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a
207
208 # Ensure no packet upsets the src server
209 ifdown_dst_server
210
211 # Flush all entries (-c)
212 $DEBUG && rump.ndp -n -a
213 atf_check -s exit:0 -o ignore rump.ndp -c
214 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC
215 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
216 #check_route_no_entry $IP6SRC
217 check_route_no_entry $IP6DST
218 # Only the static caches are not deleted
219 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11
220 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12
221 check_route_flags fc00::11 UHLS
222 check_route_flags fc00::12 UHLS
223
224 $DEBUG && rump.ndp -n -a
225 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
226 rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
227 $DEBUG && rump.ndp -n -a
228 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
229 check_route fc00::10 'b2:a0:20:00:00:10' UHL shmif0
230
231 rump_server_destroy_ifaces
232 }
233
234 ndp_cache_overwriting_body()
235 {
236
237 rump_server_start $SOCKSRC netinet6
238 rump_server_start $SOCKDST netinet6
239
240 setup_dst_server
241 setup_src_server
242
243 export RUMP_SERVER=$SOCKSRC
244
245 # Cannot overwrite a permanent cache
246 atf_check -s exit:0 rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
247 $DEBUG && rump.ndp -n -a
248 atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:fe
249
250 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
251 $DEBUG && rump.ndp -n -a
252 # Can overwrite a dynamic cache
253 atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00
254 $DEBUG && rump.ndp -n -a
255 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST
256
257 # Test temp option (XXX it doesn't work; expire time isn't set)
258 #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
259 #$DEBUG && rump.ndp -n -a
260 #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
261 # Cannot overwrite a temp cache
262 #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff
263 #$DEBUG && rump.ndp -n -a
264
265 rump_server_destroy_ifaces
266 }
267
268 get_n_caches()
269 {
270
271 echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l)
272 }
273
274 ndp_neighborgcthresh_body()
275 {
276
277 rump_server_start $SOCKSRC netinet6
278 rump_server_start $SOCKDST netinet6
279
280 setup_dst_server no
281 setup_src_server
282
283 export RUMP_SERVER=$SOCKDST
284 for i in $(seq 0 9); do
285 atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i
286 done
287
288 export RUMP_SERVER=$SOCKSRC
289
290 # ping to 3 destinations
291 $DEBUG && rump.ndp -n -a
292 for i in $(seq 0 2); do
293 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
294 ${IP6DST}$i
295 done
296 $DEBUG && rump.ndp -n -a
297
298 # 3 caches should be created
299 atf_check_equal $(get_n_caches) 3
300
301 # ping to additional 3 destinations
302 for i in $(seq 3 5); do
303 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
304 ${IP6DST}$i
305 done
306 $DEBUG && rump.ndp -n -a
307
308 # 6 caches should be created in total
309 atf_check_equal $(get_n_caches) 6
310
311 # Limit the number of neighbor caches to 5
312 atf_check -s exit:0 -o ignore rump.sysctl -w \
313 net.inet6.ip6.neighborgcthresh=5
314
315 # ping to additional 4 destinations
316 for i in $(seq 6 9); do
317 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
318 ${IP6DST}$i
319 done
320
321 # More than 5 caches should be created in total, but exceeded caches
322 # should be GC-ed
323 if [ "$(get_n_caches)" -gt 5 ]; then
324 atf_fail "Neighbor caches are not GC-ed"
325 fi
326
327 rump_server_destroy_ifaces
328 }
329
330 make_pkt_str_na()
331 {
332 local ip=$1
333 local mac=$2
334 local pkt=
335 pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:"
336 pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement"
337 echo $pkt
338 }
339
340 ndp_link_activation_body()
341 {
342 local linklocal=
343
344 rump_server_start $SOCKSRC netinet6
345 rump_server_start $SOCKDST netinet6
346
347 setup_dst_server
348 setup_src_server
349
350 # flush old packets
351 extract_new_packets bus1 > ./out
352
353 export RUMP_SERVER=$SOCKSRC
354
355 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
356 b2:a1:00:00:00:01
357
358 atf_check -s exit:0 sleep 1
359 extract_new_packets bus1 > ./out
360 $DEBUG && cat ./out
361
362 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
363 $DEBUG && echo $linklocal
364
365 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01)
366 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
367
368 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
369 b2:a1:00:00:00:02 active
370
371 atf_check -s exit:0 sleep 1
372 extract_new_packets bus1 > ./out
373 $DEBUG && cat ./out
374
375 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
376 $DEBUG && echo $linklocal
377
378 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02)
379 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
380
381 rump_server_destroy_ifaces
382 }
383
384 ndp_cache_expiration_cleanup()
385 {
386 $DEBUG && dump
387 cleanup
388 }
389
390 ndp_commands_cleanup()
391 {
392 $DEBUG && dump
393 cleanup
394 }
395
396 ndp_cache_overwriting_cleanup()
397 {
398 $DEBUG && dump
399 cleanup
400 }
401
402 ndp_neighborgcthresh_cleanup()
403 {
404 $DEBUG && dump
405 cleanup
406 }
407
408 ndp_link_activation_cleanup()
409 {
410 $DEBUG && dump
411 cleanup
412 }
413
414 atf_test_case ndp_rtm cleanup
415 ndp_rtm_head()
416 {
417
418 atf_set "descr" "Tests for routing messages on operations of NDP entries"
419 atf_set "require.progs" "rump_server"
420 }
421
422 ndp_rtm_body()
423 {
424 local macaddr_src= macaddr_dst=
425 local file=./tmp
426 local pid= hdr= what= addr=
427
428 rump_server_start $SOCKSRC netinet6
429 rump_server_start $SOCKDST netinet6
430
431 setup_dst_server
432 setup_src_server
433
434 macaddr_src=$(get_macaddr $SOCKSRC shmif0)
435 macaddr_dst=$(get_macaddr $SOCKDST shmif0)
436
437 export RUMP_SERVER=$SOCKSRC
438
439 # Test ping and a resulting routing message (RTM_ADD)
440 rump.route -n monitor -c 1 > $file &
441 pid=$!
442 sleep 1
443 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
444 wait $pid
445 $DEBUG && cat $file
446
447 hdr="RTM_ADD.+<UP,HOST,DONE,LLINFO,CLONED>"
448 what="<DST,GATEWAY>"
449 addr="$IP6DST link#2"
450 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
451 cat $file
452
453 # Test ndp -d and resulting routing messages (RTM_DELETE)
454 rump.route -n monitor -c 1 > $file &
455 pid=$!
456 sleep 1
457 atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
458 wait $pid
459 $DEBUG && cat $file
460
461 hdr="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>"
462 what="<DST,GATEWAY>"
463 addr="$IP6DST $macaddr_dst"
464 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
465 grep -A 3 RTM_DELETE $file
466
467 rump_server_destroy_ifaces
468 }
469
470 ndp_rtm_cleanup()
471 {
472
473 $DEBUG && dump
474 cleanup
475 }
476
477 atf_test_case ndp_purge_on_route_change cleanup
478 ndp_purge_on_route_change_head()
479 {
480
481 atf_set "descr" "Tests if NDP entries are removed on route change"
482 atf_set "require.progs" "rump_server"
483 }
484
485 ndp_purge_on_route_change_body()
486 {
487
488 rump_server_start $SOCKSRC netinet6
489 rump_server_start $SOCKDST netinet6
490
491 setup_dst_server
492 setup_src_server
493
494 rump_server_add_iface $SOCKSRC shmif1 bus1
495 export RUMP_SERVER=$SOCKSRC
496 atf_check -s exit:0 rump.ifconfig shmif1 inet6 fc00:1::1
497 atf_check -s exit:0 rump.ifconfig -w 10
498
499 $DEBUG && rump.netstat -nr -f inet6
500 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
501 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
502
503 atf_check -s exit:0 -o ignore \
504 rump.route change -inet6 -net $IP6NET/64 -ifp shmif1
505 $DEBUG && rump.netstat -nr -f inet6
506 $DEBUG && rump.ndp -na
507 # The entry was already removed on route change
508 atf_check -s not-exit:0 -o ignore -e match:'no entry' \
509 rump.ndp -n $IP6DST
510
511 rump_server_destroy_ifaces
512 }
513
514 ndp_purge_on_route_change_cleanup()
515 {
516
517 $DEBUG && dump
518 cleanup
519 }
520
521 atf_test_case ndp_purge_on_route_delete cleanup
522 ndp_purge_on_route_delete_head()
523 {
524
525 atf_set "descr" "Tests if NDP entries are removed on route delete"
526 atf_set "require.progs" "rump_server"
527 }
528
529 ndp_purge_on_route_delete_body()
530 {
531
532 rump_server_start $SOCKSRC netinet6
533 rump_server_start $SOCKDST netinet6
534
535 setup_dst_server
536 setup_src_server
537
538 $DEBUG && rump.netstat -nr -f inet6
539 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
540 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
541
542 atf_check -s exit:0 -o ignore rump.route delete -inet6 -net $IP6NET/64
543 $DEBUG && rump.netstat -nr -f inet6
544 $DEBUG && rump.ndp -na
545
546 # The entry was already removed on route delete
547 atf_check -s not-exit:0 -o ignore -e match:'no entry' \
548 rump.ndp -n $IP6DST
549
550 rump_server_destroy_ifaces
551 }
552
553 ndp_purge_on_route_delete_cleanup()
554 {
555
556 $DEBUG && dump
557 cleanup
558 }
559
560 atf_test_case ndp_purge_on_ifdown cleanup
561 ndp_purge_on_ifdown_head()
562 {
563
564 atf_set "descr" "Tests if NDP entries are removed on interface down"
565 atf_set "require.progs" "rump_server"
566 }
567
568 ndp_purge_on_ifdown_body()
569 {
570
571 rump_server_start $SOCKSRC netinet6
572 rump_server_start $SOCKDST netinet6
573
574 setup_dst_server
575 setup_src_server
576
577 $DEBUG && rump.netstat -nr -f inet6
578 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
579 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
580
581 # Shutdown the interface
582 atf_check -s exit:0 rump.ifconfig shmif0 down
583 $DEBUG && rump.netstat -nr -f inet6
584 $DEBUG && rump.ndp -na
585
586 # The entry was already removed on ifconfig down
587 atf_check -s not-exit:0 -o ignore -e match:'no entry' \
588 rump.ndp -n $IP6DST
589
590 rump_server_destroy_ifaces
591 }
592
593 ndp_purge_on_ifdown_cleanup()
594 {
595
596 $DEBUG && dump
597 cleanup
598 }
599
600 atf_test_case ndp_stray_entries cleanup
601 ndp_stray_entries_head()
602 {
603
604 atf_set "descr" "Tests if NDP entries are removed on route change"
605 atf_set "require.progs" "rump_server"
606 }
607
608 ndp_stray_entries_body()
609 {
610
611 rump_server_start $SOCKSRC netinet6
612 rump_server_start $SOCKDST netinet6
613
614 setup_dst_server
615 setup_src_server
616
617 rump_server_add_iface $SOCKSRC shmif1 bus1
618
619 export RUMP_SERVER=$SOCKSRC
620 atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6SRC2/64
621 atf_check -s exit:0 rump.ifconfig -w 10
622
623 $DEBUG && rump.netstat -nr -f inet6
624 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
625 $DEBUG && rump.ndp -na
626 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
627 atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
628
629 # Clean up
630 atf_check -s exit:0 -o ignore rump.ndp -c
631 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
632
633 # ping from a different source address
634 atf_check -s exit:0 -o ignore \
635 rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
636 $DEBUG && rump.ndp -na
637 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
638 # ARP reply goes back via shmif1, so a cache is created on shmif1
639 atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
640
641 # Clean up by ndp -c
642 atf_check -s exit:0 -o ignore rump.ndp -c
643 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
644
645 # ping from a different source address again
646 atf_check -s exit:0 -o ignore \
647 rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
648 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
649 # ARP reply doen't come
650 atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
651
652 # Cleanup caches on the destination
653 export RUMP_SERVER=$SOCKDST
654 $DEBUG && rump.ndp -na
655 atf_check -s exit:0 -o ignore rump.ndp -c
656 $DEBUG && rump.ndp -na
657 export RUMP_SERVER=$SOCKSRC
658
659 # ping from a different source address again
660 atf_check -s exit:0 -o ignore \
661 rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
662 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
663 # ARP reply goes back via shmif1
664 atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
665
666 # Clean up by ndp -d <ip>
667 atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
668 # Both entries should be deleted
669 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
670
671 rump_server_destroy_ifaces
672 }
673
674 ndp_stray_entries_cleanup()
675 {
676
677 $DEBUG && dump
678 cleanup
679 }
680
681 atf_test_case ndp_cache_state cleanup
682 ndp_stray_entries_head()
683 {
684
685 atf_set "descr" "Tests states of neighbor cache entries"
686 atf_set "require.progs" "rump_server"
687 }
688
689 check_cache_state()
690 {
691 local dst=$1
692 local state=$2
693
694 $DEBUG && rump.ndp -n $dst
695 atf_check -s exit:0 -o match:"^$dst.*$state " rump.ndp -n $dst
696 }
697
698 wait_until_stalled()
699 {
700 local dst=$1
701 local state=$2
702
703 $DEBUG && rump.ndp -n $dst
704 while true; do
705 rump.ndp -n $dst | grep -q "^$dst.*S " && break
706 sleep 1
707 done
708 $DEBUG && rump.ndp -n $dst
709 }
710
711 ndp_cache_state_body()
712 {
713
714 rump_server_start $SOCKSRC netinet6
715 rump_server_start $SOCKDST netinet6
716
717 setup_dst_server
718 setup_src_server
719
720 export RUMP_SERVER=$SOCKSRC
721
722 # Shorten the expire time of cache entries
723 atf_check -s exit:0 -o match:'basereachable=7s0ms' \
724 rump.ndp -i shmif0 basereachable=7000
725
726 #
727 # Reachability confirmation (RFC 4861 7.3.3)
728 #
729 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
730
731 # Receiving a solicited NA packet changes the state of the cache to REACHABLE
732 check_cache_state $IP6DST R
733
734 # The state of the cache transits to STALE after a while
735 wait_until_stalled $IP6DST
736
737 # Sending a packet on the cache will run a reachability confirmation
738 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
739
740 sleep 1
741
742 # The state of the cache is changed to DELAY and stay for 5s, then
743 # send a NS packet and change the state to PROBE
744 check_cache_state $IP6DST D
745
746 sleep $((5 + 1))
747
748 # If the reachability confirmation is success, the state of the cache
749 # is changed to REACHABLE
750 check_cache_state $IP6DST R
751 }
752
753 ndp_cache_state_cleanup()
754 {
755
756 $DEBUG && dump
757 cleanup
758 }
759
760 atf_init_test_cases()
761 {
762 atf_add_test_case ndp_cache_expiration
763 atf_add_test_case ndp_commands
764 atf_add_test_case ndp_cache_overwriting
765 atf_add_test_case ndp_neighborgcthresh
766 atf_add_test_case ndp_link_activation
767 atf_add_test_case ndp_rtm
768 atf_add_test_case ndp_purge_on_route_change
769 atf_add_test_case ndp_purge_on_route_delete
770 atf_add_test_case ndp_purge_on_ifdown
771 atf_add_test_case ndp_stray_entries
772 atf_add_test_case ndp_cache_state
773 }
774