t_ndp.sh revision 303980
1303980Sngie#	$NetBSD: t_ndp.sh,v 1.13 2016/08/10 23:07:57 kre Exp $
2303980Sngie#
3303980Sngie# Copyright (c) 2015 The NetBSD Foundation, Inc.
4303980Sngie# All rights reserved.
5303980Sngie#
6303980Sngie# Redistribution and use in source and binary forms, with or without
7303980Sngie# modification, are permitted provided that the following conditions
8303980Sngie# are met:
9303980Sngie# 1. Redistributions of source code must retain the above copyright
10303980Sngie#    notice, this list of conditions and the following disclaimer.
11303980Sngie# 2. Redistributions in binary form must reproduce the above copyright
12303980Sngie#    notice, this list of conditions and the following disclaimer in the
13303980Sngie#    documentation and/or other materials provided with the distribution.
14303980Sngie#
15303980Sngie# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16303980Sngie# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17303980Sngie# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18303980Sngie# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19303980Sngie# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20303980Sngie# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21303980Sngie# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22303980Sngie# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23303980Sngie# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24303980Sngie# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25303980Sngie# POSSIBILITY OF SUCH DAMAGE.
26303980Sngie#
27303980Sngie
28303980Sngieinetserver="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet"
29303980Sngieinetserver="$inetserver -lrumpnet_netinet6 -lrumpnet_shmif"
30303980Sngieinetserver="$inetserver -lrumpdev"
31303980SngieHIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=sysctl=yes"
32303980Sngie
33303980SngieSOCKSRC=unix://commsock1
34303980SngieSOCKDST=unix://commsock2
35303980SngieIP6SRC=fc00::1
36303980SngieIP6DST=fc00::2
37303980Sngie
38303980SngieDEBUG=true
39303980SngieTIMEOUT=1
40303980Sngie
41303980Sngieatf_test_case ndp_cache_expiration cleanup
42303980Sngieatf_test_case ndp_commands cleanup
43303980Sngieatf_test_case ndp_cache_overwriting cleanup
44303980Sngieatf_test_case ndp_neighborgcthresh cleanup
45303980Sngieatf_test_case ndp_link_activation cleanup
46303980Sngie
47303980Sngiendp_cache_expiration_head()
48303980Sngie{
49303980Sngie	atf_set "descr" "Tests for NDP cache expiration"
50303980Sngie	atf_set "require.progs" "rump_server"
51303980Sngie}
52303980Sngie
53303980Sngiendp_commands_head()
54303980Sngie{
55303980Sngie	atf_set "descr" "Tests for commands of ndp(8)"
56303980Sngie	atf_set "require.progs" "rump_server"
57303980Sngie}
58303980Sngie
59303980Sngiendp_cache_overwriting_head()
60303980Sngie{
61303980Sngie	atf_set "descr" "Tests for behavior of overwriting NDP caches"
62303980Sngie	atf_set "require.progs" "rump_server"
63303980Sngie}
64303980Sngie
65303980Sngiendp_neighborgcthresh_head()
66303980Sngie{
67303980Sngie	atf_set "descr" "Tests for GC of neighbor caches"
68303980Sngie	atf_set "require.progs" "rump_server"
69303980Sngie}
70303980Sngie
71303980Sngiendp_link_activation_head()
72303980Sngie{
73303980Sngie	atf_set "descr" "Tests for activating a new MAC address"
74303980Sngie	atf_set "require.progs" "rump_server"
75303980Sngie}
76303980Sngie
77303980Sngiesetup_dst_server()
78303980Sngie{
79303980Sngie	local assign_ip=$1
80303980Sngie
81303980Sngie	export RUMP_SERVER=$SOCKDST
82303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 create
83303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
84303980Sngie	if [ "$assign_ip" != no ]; then
85303980Sngie		atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST
86303980Sngie	fi
87303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 up
88303980Sngie	atf_check -s exit:0 rump.ifconfig -w 10
89303980Sngie
90303980Sngie	$DEBUG && rump.ifconfig shmif0
91303980Sngie	$DEBUG && rump.ndp -n -a
92303980Sngie}
93303980Sngie
94303980Sngiesetup_src_server()
95303980Sngie{
96303980Sngie	$DEBUG && ulimit -c unlimited
97303980Sngie	export RUMP_SERVER=$SOCKSRC
98303980Sngie
99303980Sngie	# Setup an interface
100303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 create
101303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
102303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC
103303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 up
104303980Sngie	atf_check -s exit:0 rump.ifconfig -w 10
105303980Sngie
106303980Sngie	# Sanity check
107303980Sngie	$DEBUG && rump.ifconfig shmif0
108303980Sngie	$DEBUG && rump.ndp -n -a
109303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -n $IP6SRC
110303980Sngie	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
111303980Sngie}
112303980Sngie
113303980Sngieget_timeout()
114303980Sngie{
115303980Sngie	local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}')
116303980Sngie	timeout=${timeout%s}
117303980Sngie	echo $timeout
118303980Sngie}
119303980Sngie
120303980Sngiendp_cache_expiration_body()
121303980Sngie{
122303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKSRC
123303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKDST
124303980Sngie
125303980Sngie	setup_dst_server
126303980Sngie	setup_src_server
127303980Sngie
128303980Sngie	#
129303980Sngie	# Check if a cache is expired expectedly
130303980Sngie	#
131303980Sngie	export RUMP_SERVER=$SOCKSRC
132303980Sngie	atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
133303980Sngie
134303980Sngie	$DEBUG && rump.ndp -n -a
135303980Sngie	atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC
136303980Sngie	# Should be cached
137303980Sngie	atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
138303980Sngie
139303980Sngie	timeout=$(get_timeout $IP6DST)
140303980Sngie
141303980Sngie	atf_check -s exit:0 sleep $(($timeout + 1))
142303980Sngie
143303980Sngie	$DEBUG && rump.ndp -n -a
144303980Sngie	atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC
145303980Sngie	# Expired but remains until GC sweaps it (1 day)
146303980Sngie	atf_check -s exit:0 -o match:'(1d0h0m|23h59m)' rump.ndp -n $IP6DST
147303980Sngie}
148303980Sngie
149303980Sngieifdown_dst_server()
150303980Sngie{
151303980Sngie	export RUMP_SERVER=$SOCKDST
152303980Sngie	atf_check -s exit:0 rump.ifconfig shmif0 down
153303980Sngie	export RUMP_SERVER=$SOCKSRC
154303980Sngie}
155303980Sngie
156303980Sngiendp_commands_body()
157303980Sngie{
158303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKSRC
159303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKDST
160303980Sngie
161303980Sngie	setup_dst_server
162303980Sngie	setup_src_server
163303980Sngie
164303980Sngie	export RUMP_SERVER=$SOCKSRC
165303980Sngie
166303980Sngie	# We can delete the entry for the interface's IP address
167303980Sngie	atf_check -s exit:0 -o match:"$IP6SRC" rump.ndp -d $IP6SRC
168303980Sngie
169303980Sngie	# Add and delete a static entry
170303980Sngie	$DEBUG && rump.ndp -n -a
171303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10
172303980Sngie	$DEBUG && rump.ndp -n -a
173303980Sngie	atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10
174303980Sngie	atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10
175303980Sngie	$DEBUG && rump.ndp -n -a
176303980Sngie	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10
177303980Sngie
178303980Sngie	# Add multiple entries via a file (XXX not implemented)
179303980Sngie	#cat - > ./list <<-EOF
180303980Sngie	#fc00::11 b2:a0:20:00:00:11
181303980Sngie	#fc00::12 b2:a0:20:00:00:12
182303980Sngie	#fc00::13 b2:a0:20:00:00:13
183303980Sngie	#fc00::14 b2:a0:20:00:00:14
184303980Sngie	#fc00::15 b2:a0:20:00:00:15
185303980Sngie	#EOF
186303980Sngie	#$DEBUG && rump.ndp -n -a
187303980Sngie	#atf_check -s exit:0 -o ignore rump.ndp -f ./list
188303980Sngie	#$DEBUG && rump.ndp -n -a
189303980Sngie
190303980Sngie	atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
191303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11
192303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12
193303980Sngie
194303980Sngie	atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
195303980Sngie	atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11
196303980Sngie	atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12
197303980Sngie
198303980Sngie	# Test ndp -a
199303980Sngie	atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a
200303980Sngie	atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a
201303980Sngie
202303980Sngie	# Ensure no packet upsets the src server
203303980Sngie	ifdown_dst_server
204303980Sngie
205303980Sngie	# Flush all entries (-c)
206303980Sngie	$DEBUG && rump.ndp -n -a
207303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -c
208303980Sngie	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC
209303980Sngie	atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
210303980Sngie	# Only the static caches are not deleted
211303980Sngie	atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11
212303980Sngie	atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12
213303980Sngie
214303980Sngie	$DEBUG && rump.ndp -n -a
215303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
216303980Sngie	rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
217303980Sngie	$DEBUG && rump.ndp -n -a
218303980Sngie	atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
219303980Sngie
220303980Sngie	return 0
221303980Sngie}
222303980Sngie
223303980Sngiendp_cache_overwriting_body()
224303980Sngie{
225303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKSRC
226303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKDST
227303980Sngie
228303980Sngie	setup_dst_server
229303980Sngie	setup_src_server
230303980Sngie
231303980Sngie	export RUMP_SERVER=$SOCKSRC
232303980Sngie
233303980Sngie	# Cannot overwrite a permanent cache
234303980Sngie	atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
235303980Sngie	$DEBUG && rump.ndp -n -a
236303980Sngie
237303980Sngie	atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
238303980Sngie	$DEBUG && rump.ndp -n -a
239303980Sngie	# Can overwrite a dynamic cache
240303980Sngie	atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00
241303980Sngie	$DEBUG && rump.ndp -n -a
242303980Sngie	atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST
243303980Sngie
244303980Sngie	# Test temp option (XXX it doesn't work; expire time isn't set)
245303980Sngie	#atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
246303980Sngie	#$DEBUG && rump.ndp -n -a
247303980Sngie	#atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
248303980Sngie	# Cannot overwrite a temp cache
249303980Sngie	#atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff
250303980Sngie	#$DEBUG && rump.ndp -n -a
251303980Sngie
252303980Sngie	return 0
253303980Sngie}
254303980Sngie
255303980Sngieget_n_caches()
256303980Sngie{
257303980Sngie
258303980Sngie	echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l)
259303980Sngie}
260303980Sngie
261303980Sngiendp_neighborgcthresh_body()
262303980Sngie{
263303980Sngie
264303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKSRC
265303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKDST
266303980Sngie
267303980Sngie	setup_dst_server no
268303980Sngie	setup_src_server
269303980Sngie
270303980Sngie	export RUMP_SERVER=$SOCKDST
271303980Sngie	for i in $(seq 0 9); do
272303980Sngie		atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i
273303980Sngie	done
274303980Sngie
275303980Sngie	export RUMP_SERVER=$SOCKSRC
276303980Sngie
277303980Sngie	# ping to 3 destinations
278303980Sngie	$DEBUG && rump.ndp -n -a
279303980Sngie	for i in $(seq 0 2); do
280303980Sngie		atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
281303980Sngie		    ${IP6DST}$i
282303980Sngie	done
283303980Sngie	$DEBUG && rump.ndp -n -a
284303980Sngie
285303980Sngie	# 3 caches should be created
286303980Sngie	atf_check_equal $(get_n_caches) 3
287303980Sngie
288303980Sngie	# ping to additional 3 destinations
289303980Sngie	for i in $(seq 3 5); do
290303980Sngie		atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
291303980Sngie		    ${IP6DST}$i
292303980Sngie	done
293303980Sngie	$DEBUG && rump.ndp -n -a
294303980Sngie
295303980Sngie	# 6 caches should be created in total
296303980Sngie	atf_check_equal $(get_n_caches) 6
297303980Sngie
298303980Sngie	# Limit the number of neighbor caches to 5
299303980Sngie	atf_check -s exit:0 -o ignore rump.sysctl -w \
300303980Sngie	    net.inet6.ip6.neighborgcthresh=5
301303980Sngie
302303980Sngie	# ping to additional 4 destinations
303303980Sngie	for i in $(seq 6 9); do
304303980Sngie		atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
305303980Sngie		    ${IP6DST}$i
306303980Sngie	done
307303980Sngie
308303980Sngie	# More than 5 caches should be created in total, but exceeded caches
309303980Sngie	# should be GC-ed
310303980Sngie	if [ "$(get_n_caches)" -gt 5 ]; then
311303980Sngie		atf_fail "Neighbor caches are not GC-ed"
312303980Sngie	fi
313303980Sngie
314303980Sngie	return 0
315303980Sngie}
316303980Sngie
317303980Sngiemake_pkt_str_na()
318303980Sngie{
319303980Sngie	local ip=$1
320303980Sngie	local mac=$2
321303980Sngie	local pkt=
322303980Sngie	pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:"
323303980Sngie	pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement"
324303980Sngie	echo $pkt
325303980Sngie}
326303980Sngie
327303980Sngieextract_new_packets()
328303980Sngie{
329303980Sngie	local old=./old
330303980Sngie
331303980Sngie	if [ ! -f $old ]; then
332303980Sngie		old=/dev/null
333303980Sngie	fi
334303980Sngie
335303980Sngie	shmif_dumpbus -p - bus1 2>/dev/null| \
336303980Sngie	    tcpdump -n -e -r - 2>/dev/null > ./new
337303980Sngie	diff -u $old ./new |grep '^+' |cut -d '+' -f 2 > ./diff
338303980Sngie	mv -f ./new ./old
339303980Sngie	cat ./diff
340303980Sngie}
341303980Sngie
342303980Sngiendp_link_activation_body()
343303980Sngie{
344303980Sngie	local linklocal=
345303980Sngie
346303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKSRC
347303980Sngie	atf_check -s exit:0 ${inetserver} $SOCKDST
348303980Sngie
349303980Sngie	setup_dst_server
350303980Sngie	setup_src_server
351303980Sngie
352303980Sngie	# flush old packets
353303980Sngie	extract_new_packets > ./out
354303980Sngie
355303980Sngie	export RUMP_SERVER=$SOCKSRC
356303980Sngie
357303980Sngie	atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
358303980Sngie	    b2:a1:00:00:00:01
359303980Sngie
360303980Sngie	atf_check -s exit:0 sleep 1
361303980Sngie	extract_new_packets > ./out
362303980Sngie	$DEBUG && cat ./out
363303980Sngie
364303980Sngie	linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
365303980Sngie	$DEBUG && echo $linklocal
366303980Sngie
367303980Sngie	pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01)
368303980Sngie	atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
369303980Sngie
370303980Sngie	atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
371303980Sngie	    b2:a1:00:00:00:02 active
372303980Sngie
373303980Sngie	atf_check -s exit:0 sleep 1
374303980Sngie	extract_new_packets > ./out
375303980Sngie	$DEBUG && cat ./out
376303980Sngie
377303980Sngie	linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
378303980Sngie	$DEBUG && echo $linklocal
379303980Sngie
380303980Sngie	pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02)
381303980Sngie	atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
382303980Sngie}
383303980Sngie
384303980Sngiecleanup()
385303980Sngie{
386303980Sngie	env RUMP_SERVER=$SOCKSRC rump.halt
387303980Sngie	env RUMP_SERVER=$SOCKDST rump.halt
388303980Sngie}
389303980Sngie
390303980Sngiedump_src()
391303980Sngie{
392303980Sngie	export RUMP_SERVER=$SOCKSRC
393303980Sngie	rump.netstat -nr
394303980Sngie	rump.ndp -n -a
395303980Sngie	rump.ifconfig
396303980Sngie	$HIJACKING dmesg
397303980Sngie}
398303980Sngie
399303980Sngiedump_dst()
400303980Sngie{
401303980Sngie	export RUMP_SERVER=$SOCKDST
402303980Sngie	rump.netstat -nr
403303980Sngie	rump.ndp -n -a
404303980Sngie	rump.ifconfig
405303980Sngie	$HIJACKING dmesg
406303980Sngie}
407303980Sngie
408303980Sngiedump()
409303980Sngie{
410303980Sngie	dump_src
411303980Sngie	dump_dst
412303980Sngie	shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
413303980Sngie	$DEBUG && gdb -ex bt /usr/bin/rump_server rump_server.core
414303980Sngie	$DEBUG && gdb -ex bt /usr/sbin/rump.ndp rump.ndp.core
415303980Sngie}
416303980Sngie
417303980Sngiendp_cache_expiration_cleanup()
418303980Sngie{
419303980Sngie	$DEBUG && dump
420303980Sngie	cleanup
421303980Sngie}
422303980Sngie
423303980Sngiendp_commands_cleanup()
424303980Sngie{
425303980Sngie	$DEBUG && dump
426303980Sngie	cleanup
427303980Sngie}
428303980Sngie
429303980Sngiendp_cache_overwriting_cleanup()
430303980Sngie{
431303980Sngie	$DEBUG && dump
432303980Sngie	cleanup
433303980Sngie}
434303980Sngie
435303980Sngiendp_neighborgcthresh_cleanup()
436303980Sngie{
437303980Sngie	$DEBUG && dump
438303980Sngie	cleanup
439303980Sngie}
440303980Sngie
441303980Sngiendp_link_activation_cleanup()
442303980Sngie{
443303980Sngie	$DEBUG && dump
444303980Sngie	cleanup
445303980Sngie}
446303980Sngie
447303980Sngieatf_init_test_cases()
448303980Sngie{
449303980Sngie	atf_add_test_case ndp_cache_expiration
450303980Sngie	atf_add_test_case ndp_commands
451303980Sngie	atf_add_test_case ndp_cache_overwriting
452303980Sngie	atf_add_test_case ndp_neighborgcthresh
453303980Sngie	atf_add_test_case ndp_link_activation
454303980Sngie}
455