t_ndp.sh revision 1.10 1 # $NetBSD: t_ndp.sh,v 1.10 2016/04/04 07:37:08 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 inetserver="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet"
29 inetserver="$inetserver -lrumpnet_netinet6 -lrumpnet_shmif"
30 HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=sysctl=yes"
31
32 SOCKSRC=unix://commsock1
33 SOCKDST=unix://commsock2
34 IP6SRC=fc00::1
35 IP6DST=fc00::2
36
37 DEBUG=true
38 TIMEOUT=1
39
40 atf_test_case cache_expiration cleanup
41 atf_test_case command cleanup
42 atf_test_case cache_overwriting cleanup
43 atf_test_case neighborgcthresh cleanup
44 atf_test_case link_activation cleanup
45
46 cache_expiration_head()
47 {
48 atf_set "descr" "Tests for NDP cache expiration"
49 atf_set "require.progs" "rump_server"
50 }
51
52 command_head()
53 {
54 atf_set "descr" "Tests for commands of ndp(8)"
55 atf_set "require.progs" "rump_server"
56 }
57
58 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 neighborgcthresh_head()
65 {
66 atf_set "descr" "Tests for GC of neighbor caches"
67 atf_set "require.progs" "rump_server"
68 }
69
70 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 export RUMP_SERVER=$SOCKDST
81 atf_check -s exit:0 rump.ifconfig shmif0 create
82 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
83 if [ "$assign_ip" != no ]; then
84 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST
85 fi
86 atf_check -s exit:0 rump.ifconfig shmif0 up
87 atf_check -s exit:0 rump.ifconfig -w 10
88
89 $DEBUG && rump.ifconfig shmif0
90 $DEBUG && rump.ndp -n -a
91 }
92
93 setup_src_server()
94 {
95 $DEBUG && ulimit -c unlimited
96 export RUMP_SERVER=$SOCKSRC
97
98 # Setup an interface
99 atf_check -s exit:0 rump.ifconfig shmif0 create
100 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
101 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC
102 atf_check -s exit:0 rump.ifconfig shmif0 up
103 atf_check -s exit:0 rump.ifconfig -w 10
104
105 # Sanity check
106 $DEBUG && rump.ifconfig shmif0
107 $DEBUG && rump.ndp -n -a
108 atf_check -s exit:0 -o ignore rump.ndp -n $IP6SRC
109 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
110 }
111
112 get_timeout()
113 {
114 local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}')
115 timeout=${timeout%s}
116 echo $timeout
117 }
118
119 cache_expiration_body()
120 {
121 atf_check -s exit:0 ${inetserver} $SOCKSRC
122 atf_check -s exit:0 ${inetserver} $SOCKDST
123
124 setup_dst_server
125 setup_src_server
126
127 #
128 # Check if a cache is expired expectedly
129 #
130 export RUMP_SERVER=$SOCKSRC
131 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
132
133 $DEBUG && rump.ndp -n -a
134 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC
135 # Should be cached
136 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
137
138 timeout=$(get_timeout $IP6DST)
139
140 atf_check -s exit:0 sleep $(($timeout + 1))
141
142 $DEBUG && rump.ndp -n -a
143 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC
144 # Expired but remains until GC sweaps it (1 day)
145 atf_check -s exit:0 -o match:'(1d0h0m|23h59m)' rump.ndp -n $IP6DST
146 }
147
148 ifdown_dst_server()
149 {
150 export RUMP_SERVER=$SOCKDST
151 atf_check -s exit:0 rump.ifconfig shmif0 down
152 export RUMP_SERVER=$SOCKSRC
153 }
154
155 command_body()
156 {
157 atf_check -s exit:0 ${inetserver} $SOCKSRC
158 atf_check -s exit:0 ${inetserver} $SOCKDST
159
160 setup_dst_server
161 setup_src_server
162
163 export RUMP_SERVER=$SOCKSRC
164
165 # We can delete the entry for the interface's IP address
166 atf_check -s exit:0 -o match:"$IP6SRC" rump.ndp -d $IP6SRC
167
168 # Add and delete a static entry
169 $DEBUG && rump.ndp -n -a
170 atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10
171 $DEBUG && rump.ndp -n -a
172 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10
173 atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10
174 $DEBUG && rump.ndp -n -a
175 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10
176
177 # Add multiple entries via a file (XXX not implemented)
178 #cat - > ./list <<-EOF
179 #fc00::11 b2:a0:20:00:00:11
180 #fc00::12 b2:a0:20:00:00:12
181 #fc00::13 b2:a0:20:00:00:13
182 #fc00::14 b2:a0:20:00:00:14
183 #fc00::15 b2:a0:20:00:00:15
184 #EOF
185 #$DEBUG && rump.ndp -n -a
186 #atf_check -s exit:0 -o ignore rump.ndp -f ./list
187 #$DEBUG && rump.ndp -n -a
188
189 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
190 atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11
191 atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12
192
193 atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
194 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11
195 atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12
196
197 # Test ndp -a
198 atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a
199 atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a
200
201 # Ensure no packet upsets the src server
202 ifdown_dst_server
203
204 # Flush all entries (-c)
205 $DEBUG && rump.ndp -n -a
206 atf_check -s exit:0 -o ignore rump.ndp -c
207 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC
208 atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
209 # Only the static caches are not deleted
210 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11
211 atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12
212
213 # Test temp option (XXX it doesn't work; expire time isn't set)
214 $DEBUG && rump.ndp -n -a
215 #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
216 rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
217 $DEBUG && rump.ndp -n -a
218 #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
219
220 return 0
221 }
222
223 cache_overwriting_body()
224 {
225 atf_check -s exit:0 ${inetserver} $SOCKSRC
226 atf_check -s exit:0 ${inetserver} $SOCKDST
227
228 setup_dst_server
229 setup_src_server
230
231 export RUMP_SERVER=$SOCKSRC
232
233 # Cannot overwrite a permanent cache
234 atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
235 $DEBUG && rump.ndp -n -a
236
237 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
238 $DEBUG && rump.ndp -n -a
239 # Can overwrite a dynamic cache
240 atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00
241 $DEBUG && rump.ndp -n -a
242 atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST
243
244 # Test temp option (XXX it doesn't work; expire time isn't set)
245 #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
246 #$DEBUG && rump.ndp -n -a
247 #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
248 # Cannot overwrite a temp cache
249 #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff
250 #$DEBUG && rump.ndp -n -a
251
252 return 0
253 }
254
255 get_n_caches()
256 {
257
258 echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l)
259 }
260
261 neighborgcthresh_body()
262 {
263
264 atf_check -s exit:0 ${inetserver} $SOCKSRC
265 atf_check -s exit:0 ${inetserver} $SOCKDST
266
267 setup_dst_server no
268 setup_src_server
269
270 export RUMP_SERVER=$SOCKDST
271 for i in $(seq 0 9); do
272 atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i
273 done
274
275 export RUMP_SERVER=$SOCKSRC
276
277 # ping to 3 destinations
278 $DEBUG && rump.ndp -n -a
279 for i in $(seq 0 2); do
280 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
281 ${IP6DST}$i
282 done
283 $DEBUG && rump.ndp -n -a
284
285 # 3 caches should be created
286 atf_check_equal $(get_n_caches) 3
287
288 # ping to additional 3 destinations
289 for i in $(seq 3 5); do
290 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
291 ${IP6DST}$i
292 done
293 $DEBUG && rump.ndp -n -a
294
295 # 6 caches should be created in total
296 atf_check_equal $(get_n_caches) 6
297
298 # Limit the number of neighbor caches to 5
299 atf_check -s exit:0 -o ignore rump.sysctl -w \
300 net.inet6.ip6.neighborgcthresh=5
301
302 # ping to additional 4 destinations
303 for i in $(seq 6 9); do
304 atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
305 ${IP6DST}$i
306 done
307
308 # More than 5 caches should be created in total, but exceeded caches
309 # should be GC-ed
310 if [ "$(get_n_caches)" -gt 5 ]; then
311 atf_fail "Neighbor caches are not GC-ed"
312 fi
313
314 return 0
315 }
316
317 make_pkt_str_na()
318 {
319 local ip=$1
320 local mac=$2
321 local pkt=
322 pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:"
323 pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement"
324 echo $pkt
325 }
326
327 extract_new_packets()
328 {
329 local old=./old
330
331 if [ ! -f $old ]; then
332 old=/dev/null
333 fi
334
335 shmif_dumpbus -p - bus1 2>/dev/null| \
336 tcpdump -n -e -r - 2>/dev/null > ./new
337 diff -u $old ./new |grep '^+' |cut -d '+' -f 2 > ./diff
338 mv -f ./new ./old
339 cat ./diff
340 }
341
342 link_activation_body()
343 {
344 local linklocal=
345
346 atf_check -s exit:0 ${inetserver} $SOCKSRC
347 atf_check -s exit:0 ${inetserver} $SOCKDST
348
349 setup_dst_server
350 setup_src_server
351
352 # flush old packets
353 extract_new_packets > ./out
354
355 export RUMP_SERVER=$SOCKSRC
356
357 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
358 b2:a1:00:00:00:01
359
360 atf_check -s exit:0 sleep 1
361 extract_new_packets > ./out
362 $DEBUG && cat ./out
363
364 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
365 $DEBUG && echo $linklocal
366
367 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01)
368 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
369
370 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
371 b2:a1:00:00:00:02 active
372
373 atf_check -s exit:0 sleep 1
374 extract_new_packets > ./out
375 $DEBUG && cat ./out
376
377 linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
378 $DEBUG && echo $linklocal
379
380 pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02)
381 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
382 }
383
384 cleanup()
385 {
386 env RUMP_SERVER=$SOCKSRC rump.halt
387 env RUMP_SERVER=$SOCKDST rump.halt
388 }
389
390 dump_src()
391 {
392 export RUMP_SERVER=$SOCKSRC
393 rump.netstat -nr
394 rump.ndp -n -a
395 rump.ifconfig
396 $HIJACKING dmesg
397 }
398
399 dump_dst()
400 {
401 export RUMP_SERVER=$SOCKDST
402 rump.netstat -nr
403 rump.ndp -n -a
404 rump.ifconfig
405 $HIJACKING dmesg
406 }
407
408 dump()
409 {
410 dump_src
411 dump_dst
412 shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
413 $DEBUG && gdb -ex bt /usr/bin/rump_server rump_server.core
414 $DEBUG && gdb -ex bt /usr/sbin/rump.ndp rump.ndp.core
415 }
416
417 cache_expiration_cleanup()
418 {
419 $DEBUG && dump
420 cleanup
421 }
422
423 command_cleanup()
424 {
425 $DEBUG && dump
426 cleanup
427 }
428
429 cache_overwriting_cleanup()
430 {
431 $DEBUG && dump
432 cleanup
433 }
434
435 neighborgcthresh_cleanup()
436 {
437 $DEBUG && dump
438 cleanup
439 }
440
441 link_activation_cleanup()
442 {
443 $DEBUG && dump
444 cleanup
445 }
446
447 atf_init_test_cases()
448 {
449 atf_add_test_case cache_expiration
450 atf_add_test_case command
451 atf_add_test_case cache_overwriting
452 atf_add_test_case neighborgcthresh
453 atf_add_test_case link_activation
454 }
455