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