t_ndp.sh revision 1.40 1 # $NetBSD: t_ndp.sh,v 1.40 2022/01/07 03:07:41 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 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,AUTHOR>"
459 addr="$IP6DST $macaddr_dst $IP6DST"
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 atf_check -s exit:1 -o ignore -e ignore \
468 rump.ping6 -n -X 1 -c 1 $IP6DST_FAIL1
469 wait $pid
470 $DEBUG && cat $file
471
472 hdr="RTM_MISS.+<DONE>"
473 what="<DST,GATEWAY,AUTHOR>"
474 addr="$IP6DST_FAIL1 link#2 $IP6SRC"
475 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
476 cat $file
477
478 # Test ping and a resulting routing message (RTM_MISS) off subnet
479 rump.route -n monitor -c 1 > $file &
480 pid=$!
481 sleep 1
482 atf_check -s exit:1 -o ignore -e ignore \
483 rump.ping6 -n -X 1 -c 1 $IP6DST_FAIL2
484 wait $pid
485 $DEBUG && cat $file
486
487 hdr="RTM_MISS.+<DONE>"
488 what="<DST>"
489 addr="$IP6DST_FAIL2"
490 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
491 cat $file
492
493 # Test ndp -d and resulting routing messages (RTM_DELETE)
494 rump.route -n monitor -c 1 > $file &
495 pid=$!
496 sleep 1
497 atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
498 wait $pid
499 $DEBUG && cat $file
500
501 hdr="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>"
502 what="<DST,GATEWAY>"
503 addr="$IP6DST $macaddr_dst"
504 atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
505 grep -A 3 RTM_DELETE $file
506
507 rump_server_destroy_ifaces
508 }
509
510 ndp_rtm_cleanup()
511 {
512
513 $DEBUG && dump
514 cleanup
515 }
516
517 atf_test_case ndp_purge_on_route_change cleanup
518 ndp_purge_on_route_change_head()
519 {
520
521 atf_set "descr" "Tests if NDP entries are removed on route change"
522 atf_set "require.progs" "rump_server"
523 }
524
525 ndp_purge_on_route_change_body()
526 {
527
528 rump_server_start $SOCKSRC netinet6
529 rump_server_start $SOCKDST netinet6
530
531 setup_dst_server
532 setup_src_server
533
534 rump_server_add_iface $SOCKSRC shmif1 bus1
535 export RUMP_SERVER=$SOCKSRC
536 atf_check -s exit:0 rump.ifconfig shmif1 inet6 fc00:1::1
537 atf_check -s exit:0 rump.ifconfig -w 10
538
539 $DEBUG && rump.netstat -nr -f inet6
540 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
541 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
542
543 atf_check -s exit:0 -o ignore \
544 rump.route change -inet6 -net $IP6NET/64 -ifp shmif1
545 $DEBUG && rump.netstat -nr -f inet6
546 $DEBUG && rump.ndp -na
547 # The entry was already removed on route change
548 atf_check -s not-exit:0 -o ignore -e match:'no entry' \
549 rump.ndp -n $IP6DST
550
551 rump_server_destroy_ifaces
552 }
553
554 ndp_purge_on_route_change_cleanup()
555 {
556
557 $DEBUG && dump
558 cleanup
559 }
560
561 atf_test_case ndp_purge_on_route_delete cleanup
562 ndp_purge_on_route_delete_head()
563 {
564
565 atf_set "descr" "Tests if NDP entries are removed on route delete"
566 atf_set "require.progs" "rump_server"
567 }
568
569 ndp_purge_on_route_delete_body()
570 {
571
572 rump_server_start $SOCKSRC netinet6
573 rump_server_start $SOCKDST netinet6
574
575 setup_dst_server
576 setup_src_server
577
578 $DEBUG && rump.netstat -nr -f inet6
579 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
580 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
581
582 atf_check -s exit:0 -o ignore rump.route delete -inet6 -net $IP6NET/64
583 $DEBUG && rump.netstat -nr -f inet6
584 $DEBUG && rump.ndp -na
585
586 # The entry was already removed on route delete
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_route_delete_cleanup()
594 {
595
596 $DEBUG && dump
597 cleanup
598 }
599
600 atf_test_case ndp_purge_on_ifdown cleanup
601 ndp_purge_on_ifdown_head()
602 {
603
604 atf_set "descr" "Tests if NDP entries are removed on interface down"
605 atf_set "require.progs" "rump_server"
606 }
607
608 ndp_purge_on_ifdown_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 $DEBUG && rump.netstat -nr -f inet6
618 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
619 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
620
621 # Shutdown the interface
622 atf_check -s exit:0 rump.ifconfig shmif0 down
623 $DEBUG && rump.netstat -nr -f inet6
624 $DEBUG && rump.ndp -na
625
626 # The entry was already removed on ifconfig down
627 atf_check -s not-exit:0 -o ignore -e match:'no entry' \
628 rump.ndp -n $IP6DST
629
630 rump_server_destroy_ifaces
631 }
632
633 ndp_purge_on_ifdown_cleanup()
634 {
635
636 $DEBUG && dump
637 cleanup
638 }
639
640 atf_test_case ndp_stray_entries cleanup
641 ndp_stray_entries_head()
642 {
643
644 atf_set "descr" "Tests if NDP entries are removed on route change"
645 atf_set "require.progs" "rump_server"
646 }
647
648 ndp_stray_entries_body()
649 {
650
651 rump_server_start $SOCKSRC netinet6
652 rump_server_start $SOCKDST netinet6
653
654 setup_dst_server
655 setup_src_server
656
657 rump_server_add_iface $SOCKSRC shmif1 bus1
658
659 export RUMP_SERVER=$SOCKSRC
660 atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6SRC2/64
661 atf_check -s exit:0 rump.ifconfig -w 10
662
663 $DEBUG && rump.netstat -nr -f inet6
664 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
665 $DEBUG && rump.ndp -na
666 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
667 atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
668
669 # Clean up
670 atf_check -s exit:0 -o ignore rump.ndp -c
671 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
672
673 # ping from a different source address
674 atf_check -s exit:0 -o ignore \
675 rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
676 $DEBUG && rump.ndp -na
677 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
678 # ARP reply goes back via shmif1, so a cache is created on shmif1
679 atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
680
681 # Clean up by ndp -c
682 atf_check -s exit:0 -o ignore rump.ndp -c
683 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
684
685 # ping from a different source address again
686 atf_check -s exit:0 -o ignore \
687 rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
688 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
689 # ARP reply doen't come
690 atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
691
692 # Cleanup caches on the destination
693 export RUMP_SERVER=$SOCKDST
694 $DEBUG && rump.ndp -na
695 atf_check -s exit:0 -o ignore rump.ndp -c
696 $DEBUG && rump.ndp -na
697 export RUMP_SERVER=$SOCKSRC
698
699 # ping from a different source address again
700 atf_check -s exit:0 -o ignore \
701 rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
702 atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
703 # ARP reply goes back via shmif1
704 atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
705
706 # Clean up by ndp -d <ip>
707 atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
708 # Both entries should be deleted
709 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
710
711 rump_server_destroy_ifaces
712 }
713
714 ndp_stray_entries_cleanup()
715 {
716
717 $DEBUG && dump
718 cleanup
719 }
720
721 atf_test_case ndp_cache_state cleanup
722 ndp_cache_state_head()
723 {
724
725 atf_set "descr" "Tests states of neighbor cache entries"
726 atf_set "require.progs" "rump_server"
727 }
728
729 check_cache_state()
730 {
731 local dst=$1
732 local state=$2
733
734 $DEBUG && rump.ndp -n $dst
735 atf_check -s exit:0 -o match:"^$dst.*$state " rump.ndp -n $dst
736 }
737
738 wait_until_stalled()
739 {
740 local dst=$1
741 local state=$2
742
743 $DEBUG && rump.ndp -n $dst
744 while true; do
745 rump.ndp -n $dst | grep -q "^$dst.*S " && break
746 sleep 1
747 done
748 $DEBUG && rump.ndp -n $dst
749 }
750
751 ndp_cache_state_body()
752 {
753 local macaddr=
754
755 skip_if_qemu
756
757 rump_server_start $SOCKSRC netinet6
758 rump_server_start $SOCKDST netinet6
759
760 setup_dst_server
761 setup_src_server
762
763 # Shorten the expire time of cache entries
764 export RUMP_SERVER=$SOCKSRC
765 atf_check -s exit:0 -o match:'basereachable=7s0ms' \
766 rump.ndp -i shmif0 basereachable=7000
767
768 # Make a permanent cache entry to avoid sending an NS packet disturbing
769 # the test
770 macaddr=$(get_macaddr $SOCKSRC shmif0)
771 export RUMP_SERVER=$SOCKDST
772 atf_check -s exit:0 -o ignore rump.ndp -s $IP6SRC $macaddr
773
774 export RUMP_SERVER=$SOCKSRC
775
776 #
777 # Reachability confirmation (RFC 4861 7.3.3)
778 #
779 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
780
781 # Receiving a solicited NA packet changes the state of the cache to REACHABLE
782 check_cache_state $IP6DST R
783
784 # The state of the cache transits to STALE after a while
785 wait_until_stalled $IP6DST
786
787 # Sending a packet on the cache will run a reachability confirmation
788 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
789
790 sleep 1
791
792 # The state of the cache is changed to DELAY and stay for 5s, then
793 # send a NS packet and change the state to PROBE
794 check_cache_state $IP6DST D
795
796 sleep $((5 + 1))
797
798 # If the reachability confirmation is success, the state of the cache
799 # is changed to REACHABLE
800 check_cache_state $IP6DST R
801 }
802
803 ndp_cache_state_cleanup()
804 {
805
806 $DEBUG && dump
807 cleanup
808 }
809
810 atf_init_test_cases()
811 {
812 atf_add_test_case ndp_cache_expiration
813 atf_add_test_case ndp_commands
814 atf_add_test_case ndp_cache_overwriting
815 atf_add_test_case ndp_neighborgcthresh
816 atf_add_test_case ndp_link_activation
817 atf_add_test_case ndp_rtm
818 atf_add_test_case ndp_purge_on_route_change
819 atf_add_test_case ndp_purge_on_route_delete
820 atf_add_test_case ndp_purge_on_ifdown
821 atf_add_test_case ndp_stray_entries
822 atf_add_test_case ndp_cache_state
823 }
824