t_ndp.sh revision 1.22 1 # $NetBSD: t_ndp.sh,v 1.22 2017/06/21 09:05:31 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 IP6DST=fc00::2
32
33 DEBUG=${DEBUG:-false}
34 TIMEOUT=1
35
36 atf_test_case ndp_cache_expiration cleanup
37 atf_test_case ndp_commands cleanup
38 atf_test_case ndp_cache_overwriting cleanup
39 atf_test_case ndp_neighborgcthresh cleanup
40 atf_test_case ndp_link_activation cleanup
41
42 ndp_cache_expiration_head()
43 {
44 atf_set "descr" "Tests for NDP cache expiration"
45 atf_set "require.progs" "rump_server"
46 }
47
48 ndp_commands_head()
49 {
50 atf_set "descr" "Tests for commands of ndp(8)"
51 atf_set "require.progs" "rump_server"
52 }
53
54 ndp_cache_overwriting_head()
55 {
56 atf_set "descr" "Tests for behavior of overwriting NDP caches"
57 atf_set "require.progs" "rump_server"
58 }
59
60 ndp_neighborgcthresh_head()
61 {
62 atf_set "descr" "Tests for GC of neighbor caches"
63 atf_set "require.progs" "rump_server"
64 }
65
66 ndp_link_activation_head()
67 {
68 atf_set "descr" "Tests for activating a new MAC address"
69 atf_set "require.progs" "rump_server"
70 }
71
72 setup_dst_server()
73 {
74 local assign_ip=$1
75
76 rump_server_add_iface $SOCKDST shmif0 bus1
77 export RUMP_SERVER=$SOCKDST
78 if [ "$assign_ip" != no ]; then
79 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST
80 fi
81 atf_check -s exit:0 rump.ifconfig shmif0 up
82 atf_check -s exit:0 rump.ifconfig -w 10
83
84 $DEBUG && rump.ifconfig shmif0
85 $DEBUG && rump.ndp -n -a
86 }
87
88 setup_src_server()
89 {
90 $DEBUG && ulimit -c unlimited
91 export RUMP_SERVER=$SOCKSRC
92
93 # Setup an interface
94 rump_server_add_iface $SOCKSRC shmif0 bus1
95 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC
96 atf_check -s exit:0 rump.ifconfig shmif0 up
97 atf_check -s exit:0 rump.ifconfig -w 10
98
99 # Sanity check
100 $DEBUG && rump.ifconfig shmif0
101 $DEBUG && rump.ndp -n -a
102 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
103 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
104 }
105
106 get_timeout()
107 {
108 local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}')
109 timeout=${timeout%s}
110 echo $timeout
111 }
112
113 ndp_cache_expiration_body()
114 {
115
116 rump_server_start $SOCKSRC netinet6
117 rump_server_start $SOCKDST netinet6
118
119 setup_dst_server
120 setup_src_server
121
122 #
123 # Check if a cache is expired expectedly
124 #
125 export RUMP_SERVER=$SOCKSRC
126 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
127
128 $DEBUG && rump.ndp -n -a
129 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
130 # Should be cached
131 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
132
133 timeout=$(get_timeout $IP6DST)
134
135 atf_check -s exit:0 sleep $(($timeout + 1))
136
137 $DEBUG && rump.ndp -n -a
138 atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
139 # Expired but remains until GC sweaps it (1 day)
140 atf_check -s exit:0 -o match:"$ONEDAYISH" rump.ndp -n $IP6DST
141
142 rump_server_destroy_ifaces
143 }
144
145 ifdown_dst_server()
146 {
147 export RUMP_SERVER=$SOCKDST
148 atf_check -s exit:0 rump.ifconfig shmif0 down
149 export RUMP_SERVER=$SOCKSRC
150 }
151
152 ndp_commands_body()
153 {
154
155 rump_server_start $SOCKSRC netinet6
156 rump_server_start $SOCKDST netinet6
157
158 setup_dst_server
159 setup_src_server
160
161 export RUMP_SERVER=$SOCKSRC
162
163 # Add and delete a static entry
164 $DEBUG && rump.ndp -n -a
165 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10
166 $DEBUG && rump.ndp -n -a
167 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10
168 atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10
169 $DEBUG && rump.ndp -n -a
170 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10
171
172 # Add multiple entries via a file (XXX not implemented)
173 #cat - > ./list <<-EOF
174 #fc00::11 b2:a0:20:00:00:11
175 #fc00::12 b2:a0:20:00:00:12
176 #fc00::13 b2:a0:20:00:00:13
177 #fc00::14 b2:a0:20:00:00:14
178 #fc00::15 b2:a0:20:00:00:15
179 #EOF
180 #$DEBUG && rump.ndp -n -a
181 #atf_check -s exit:0 -o ignore rump.ndp -f ./list
182 #$DEBUG && rump.ndp -n -a
183
184 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
185 atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11
186 atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12
187
188 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
189 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11
190 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12
191
192 # Test ndp -a
193 atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a
194 atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a
195
196 # Ensure no packet upsets the src server
197 ifdown_dst_server
198
199 # Flush all entries (-c)
200 $DEBUG && rump.ndp -n -a
201 atf_check -s exit:0 -o ignore rump.ndp -c
202 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC
203 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
204 # Only the static caches are not deleted
205 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11
206 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12
207
208 $DEBUG && rump.ndp -n -a
209 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
210 rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
211 $DEBUG && rump.ndp -n -a
212 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
213
214 rump_server_destroy_ifaces
215 }
216
217 ndp_cache_overwriting_body()
218 {
219
220 rump_server_start $SOCKSRC netinet6
221 rump_server_start $SOCKDST netinet6
222
223 setup_dst_server
224 setup_src_server
225
226 export RUMP_SERVER=$SOCKSRC
227
228 # Cannot overwrite a permanent cache
229 atf_check -s exit:0 rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
230 $DEBUG && rump.ndp -n -a
231 atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:fe
232
233 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
234 $DEBUG && rump.ndp -n -a
235 # Can overwrite a dynamic cache
236 atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00
237 $DEBUG && rump.ndp -n -a
238 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST
239
240 # Test temp option (XXX it doesn't work; expire time isn't set)
241 #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
242 #$DEBUG && rump.ndp -n -a
243 #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
244 # Cannot overwrite a temp cache
245 #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff
246 #$DEBUG && rump.ndp -n -a
247
248 rump_server_destroy_ifaces
249 }
250
251 get_n_caches()
252 {
253
254 echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l)
255 }
256
257 ndp_neighborgcthresh_body()
258 {
259
260 rump_server_start $SOCKSRC netinet6
261 rump_server_start $SOCKDST netinet6
262
263 setup_dst_server no
264 setup_src_server
265
266 export RUMP_SERVER=$SOCKDST
267 for i in $(seq 0 9); do
268 atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i
269 done
270
271 export RUMP_SERVER=$SOCKSRC
272
273 # ping to 3 destinations
274 $DEBUG && rump.ndp -n -a
275 for i in $(seq 0 2); do
276 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
277 ${IP6DST}$i
278 done
279 $DEBUG && rump.ndp -n -a
280
281 # 3 caches should be created
282 atf_check_equal $(get_n_caches) 3
283
284 # ping to additional 3 destinations
285 for i in $(seq 3 5); do
286 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
287 ${IP6DST}$i
288 done
289 $DEBUG && rump.ndp -n -a
290
291 # 6 caches should be created in total
292 atf_check_equal $(get_n_caches) 6
293
294 # Limit the number of neighbor caches to 5
295 atf_check -s exit:0 -o ignore rump.sysctl -w \
296 net.inet6.ip6.neighborgcthresh=5
297
298 # ping to additional 4 destinations
299 for i in $(seq 6 9); do
300 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
301 ${IP6DST}$i
302 done
303
304 # More than 5 caches should be created in total, but exceeded caches
305 # should be GC-ed
306 if [ "$(get_n_caches)" -gt 5 ]; then
307 atf_fail "Neighbor caches are not GC-ed"
308 fi
309
310 rump_server_destroy_ifaces
311 }
312
313 make_pkt_str_na()
314 {
315 local ip=$1
316 local mac=$2
317 local pkt=
318 pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:"
319 pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement"
320 echo $pkt
321 }
322
323 ndp_link_activation_body()
324 {
325 local linklocal=
326
327 rump_server_start $SOCKSRC netinet6
328 rump_server_start $SOCKDST netinet6
329
330 setup_dst_server
331 setup_src_server
332
333 # flush old packets
334 extract_new_packets bus1 > ./out
335
336 export RUMP_SERVER=$SOCKSRC
337
338 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
339 b2:a1:00:00:00:01
340
341 atf_check -s exit:0 sleep 1
342 extract_new_packets bus1 > ./out
343 $DEBUG && cat ./out
344
345 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
346 $DEBUG && echo $linklocal
347
348 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01)
349 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
350
351 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
352 b2:a1:00:00:00:02 active
353
354 atf_check -s exit:0 sleep 1
355 extract_new_packets bus1 > ./out
356 $DEBUG && cat ./out
357
358 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
359 $DEBUG && echo $linklocal
360
361 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02)
362 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
363
364 rump_server_destroy_ifaces
365 }
366
367 ndp_cache_expiration_cleanup()
368 {
369 $DEBUG && dump
370 cleanup
371 }
372
373 ndp_commands_cleanup()
374 {
375 $DEBUG && dump
376 cleanup
377 }
378
379 ndp_cache_overwriting_cleanup()
380 {
381 $DEBUG && dump
382 cleanup
383 }
384
385 ndp_neighborgcthresh_cleanup()
386 {
387 $DEBUG && dump
388 cleanup
389 }
390
391 ndp_link_activation_cleanup()
392 {
393 $DEBUG && dump
394 cleanup
395 }
396
397 atf_test_case ndp_rtm cleanup
398 ndp_rtm_head()
399 {
400
401 atf_set "descr" "Tests for routing messages on operations of ARP entries"
402 atf_set "require.progs" "rump_server"
403 }
404
405 ndp_rtm_body()
406 {
407 local macaddr_src= macaddr_dst=
408 local file=./tmp
409 local pid= str=
410
411 rump_server_start $SOCKSRC netinet6
412 rump_server_start $SOCKDST netinet6
413
414 setup_dst_server
415 setup_src_server
416
417 macaddr_src=$(get_macaddr $SOCKSRC shmif0)
418 macaddr_dst=$(get_macaddr $SOCKDST shmif0)
419
420 export RUMP_SERVER=$SOCKSRC
421
422 # Test ping and a resulting routing message (RTM_ADD)
423 rump.route -n monitor -c 1 > $file &
424 pid=$?
425 sleep 1
426 atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
427 wait $pid
428 $DEBUG && cat $file
429
430 str="RTM_ADD.+<UP,HOST,DONE,LLINFO,CLONED>"
431 atf_check -s exit:0 -o match:"$str" cat $file
432 str="<DST,GATEWAY,IFP,IFA>"
433 atf_check -s exit:0 -o match:"$str" cat $file
434 str="$IP6DST link#2 $macaddr_src $IP6SRC"
435 atf_check -s exit:0 -o match:"$str" cat $file
436
437 # Test ndp -d and resulting routing messages (RTM_GET and RTM_DELETE)
438 rump.route -n monitor -c 2 > $file &
439 pid=$?
440 sleep 1
441 atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
442 wait $pid
443 $DEBUG && cat $file
444
445 str="RTM_GET.+<UP,DONE,LLINFO>"
446 atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
447 str="<DST,GATEWAY,IFP,IFA>"
448 atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
449 str="$IP6DST $macaddr_dst $macaddr_src $IP6SRC"
450 atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
451 str="RTM_DELETE.+<UP,DONE,LLINFO>"
452 atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
453 str="<DST,GATEWAY,IFP,IFA>"
454 atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
455 str="$IP6DST $macaddr_dst $macaddr_src $IP6SRC"
456 atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
457
458 rump_server_destroy_ifaces
459 }
460
461 ndp_rtm_cleanup()
462 {
463
464 $DEBUG && dump
465 cleanup
466 }
467
468 atf_init_test_cases()
469 {
470 atf_add_test_case ndp_cache_expiration
471 atf_add_test_case ndp_commands
472 atf_add_test_case ndp_cache_overwriting
473 atf_add_test_case ndp_neighborgcthresh
474 atf_add_test_case ndp_link_activation
475 atf_add_test_case ndp_rtm
476 }
477