t_dad.sh revision 1.4.2.1 1 # $NetBSD: t_dad.sh,v 1.4.2.1 2016/11/04 14:49:24 pgoyette 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 SOCKLOCAL=unix://commsock1
33 SOCKPEER=unix://commsock2
34
35 DEBUG=false
36
37 duplicated="[Dd][Uu][Pp][Ll][Ii][Cc][Aa][Tt][Ee][Dd]"
38
39 atf_test_case dad_basic cleanup
40 atf_test_case dad_duplicated cleanup
41 atf_test_case dad_count cleanup
42
43 dad_basic_head()
44 {
45 atf_set "descr" "Tests for IPv6 DAD basic behavior"
46 atf_set "require.progs" "rump_server"
47 }
48
49 dad_duplicated_head()
50 {
51 atf_set "descr" "Tests for IPv6 DAD duplicated state"
52 atf_set "require.progs" "rump_server"
53 }
54
55 dad_count_head()
56 {
57 atf_set "descr" "Tests for IPv6 DAD count behavior"
58 atf_set "require.progs" "rump_server"
59 }
60
61 setup_server()
62 {
63 local sock=$1
64 local ip=$2
65
66 export RUMP_SERVER=$sock
67
68 atf_check -s exit:0 rump.ifconfig shmif0 create
69 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
70 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip
71 atf_check -s exit:0 rump.ifconfig shmif0 up
72 atf_check -s exit:0 rump.ifconfig -w 10
73
74 $DEBUG && rump.ifconfig shmif0
75 }
76
77 make_ns_pkt_str()
78 {
79 local id=$1
80 local target=$2
81 pkt="33:33:ff:00:00:0${id}, ethertype IPv6 (0x86dd), length 78: ::"
82 pkt="$pkt > ff02::1:ff00:${id}: ICMP6, neighbor solicitation,"
83 pkt="$pkt who has $target, length 24"
84 echo $pkt
85 }
86
87 extract_new_packets()
88 {
89 local old=./old
90
91 if [ ! -f $old ]; then
92 old=/dev/null
93 fi
94
95 shmif_dumpbus -p - bus1 2>/dev/null| \
96 tcpdump -n -e -r - 2>/dev/null > ./new
97 diff -u $old ./new |grep '^+' |cut -d '+' -f 2 > ./diff
98 mv -f ./new ./old
99 cat ./diff
100 }
101
102 dad_basic_body()
103 {
104 local pkt=
105 local localip1=fc00::1
106 local localip2=fc00::2
107 local localip3=fc00::3
108
109 atf_check -s exit:0 ${inetserver} $SOCKLOCAL
110 export RUMP_SERVER=$SOCKLOCAL
111
112 atf_check -s exit:0 rump.ifconfig shmif0 create
113 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
114 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip1
115 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip2
116 $DEBUG && rump.ifconfig shmif0
117
118 atf_check -s exit:0 rump.ifconfig shmif0 up
119 rump.ifconfig shmif0 > ./out
120 $DEBUG && cat ./out
121
122 # The primary address doesn't start with tentative state
123 atf_check -s not-exit:0 -x "cat ./out |grep $localip1 |grep -q tentative"
124 # The alias address starts with tentative state
125 # XXX we have no stable way to check this, so skip for now
126 #atf_check -s exit:0 -x "cat ./out |grep $localip2 |grep -q tentative"
127
128 atf_check -s exit:0 sleep 2
129 extract_new_packets > ./out
130 $DEBUG && cat ./out
131
132 # Check DAD probe packets (Neighbor Solicitation Message)
133 pkt=$(make_ns_pkt_str 2 $localip2)
134 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
135 # No DAD for the primary address
136 pkt=$(make_ns_pkt_str 1 $localip1)
137 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
138
139 # Waiting for DAD complete
140 atf_check -s exit:0 rump.ifconfig -w 10
141 extract_new_packets > ./out
142 $DEBUG && cat ./out
143
144 # IPv6 DAD doesn't announce (Neighbor Advertisement Message)
145
146 # The alias address left tentative
147 atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip2 |grep -q tentative"
148
149 #
150 # Add a new address on the fly
151 #
152 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip3
153
154 # The new address starts with tentative state
155 # XXX we have no stable way to check this, so skip for now
156 #atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep $localip3 |grep -q tentative"
157
158 # Check DAD probe packets (Neighbor Solicitation Message)
159 atf_check -s exit:0 sleep 2
160 extract_new_packets > ./out
161 $DEBUG && cat ./out
162 pkt=$(make_ns_pkt_str 3 $localip3)
163 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
164
165 # Waiting for DAD complete
166 atf_check -s exit:0 rump.ifconfig -w 10
167 extract_new_packets > ./out
168 $DEBUG && cat ./out
169
170 # IPv6 DAD doesn't announce (Neighbor Advertisement Message)
171
172 # The new address left tentative
173 atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip3 |grep -q tentative"
174 }
175
176 dad_duplicated_body()
177 {
178 local localip1=fc00::1
179 local localip2=fc00::11
180 local peerip=fc00::2
181
182 atf_check -s exit:0 ${inetserver} $SOCKLOCAL
183 atf_check -s exit:0 ${inetserver} $SOCKPEER
184
185 setup_server $SOCKLOCAL $localip1
186 setup_server $SOCKPEER $peerip
187
188 export RUMP_SERVER=$SOCKLOCAL
189
190 # The primary address isn't marked as duplicated
191 atf_check -s exit:0 -o not-match:"$localip1.+$duplicated" \
192 rump.ifconfig shmif0
193
194 #
195 # Add a new address duplicated with the peer server
196 #
197 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $peerip
198 atf_check -s exit:0 sleep 1
199
200 # The new address is marked as duplicated
201 atf_check -s exit:0 -o match:"$peerip.+$duplicated" \
202 rump.ifconfig shmif0
203
204 # A unique address isn't marked as duplicated
205 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip2
206 atf_check -s exit:0 sleep 1
207 atf_check -s exit:0 -o not-match:"$localip2.+$duplicated" \
208 rump.ifconfig shmif0
209 }
210
211 dad_count_test()
212 {
213 local pkt=
214 local count=$1
215 local id=$2
216 local target=$3
217
218 #
219 # Set DAD count to $count
220 #
221 atf_check -s exit:0 rump.sysctl -w -q net.inet6.ip6.dad_count=$count
222
223 # Add a new address
224 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $target
225
226 # Waiting for DAD complete
227 atf_check -s exit:0 rump.ifconfig -w 20
228
229 # Check the number of DAD probe packets (Neighbor Solicitation Message)
230 atf_check -s exit:0 sleep 2
231 extract_new_packets > ./out
232 $DEBUG && cat ./out
233 pkt=$(make_ns_pkt_str $id $target)
234 atf_check -s exit:0 -o match:"$count" \
235 -x "cat ./out |grep '$pkt' | wc -l | tr -d ' '"
236 }
237
238 dad_count_body()
239 {
240 local localip1=fc00::1
241 local localip2=fc00::2
242
243 atf_check -s exit:0 ${inetserver} $SOCKLOCAL
244 export RUMP_SERVER=$SOCKLOCAL
245
246 # Check default value
247 atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet6.ip6.dad_count
248
249 # Setup interface
250 atf_check -s exit:0 rump.ifconfig shmif0 create
251 atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
252 atf_check -s exit:0 rump.ifconfig shmif0 up
253 atf_check -s exit:0 sleep 2
254 rump.ifconfig shmif0 > ./out
255 $DEBUG && cat ./out
256
257 #
258 # Set and test DAD count (count=1)
259 #
260 dad_count_test 1 1 $localip1
261
262 #
263 # Set and test DAD count (count=8)
264 #
265 dad_count_test 8 2 $localip2
266 }
267
268 cleanup()
269 {
270 gdb -ex bt /usr/bin/rump_server rump_server.core
271 gdb -ex bt /usr/sbin/arp arp.core
272 env RUMP_SERVER=$SOCKLOCAL rump.halt
273 env RUMP_SERVER=$SOCKPEER rump.halt
274 }
275
276 dump_local()
277 {
278 export RUMP_SERVER=$SOCKLOCAL
279 rump.netstat -nr
280 rump.arp -n -a
281 rump.ifconfig
282 $HIJACKING dmesg
283 }
284
285 dump_peer()
286 {
287 export RUMP_SERVER=$SOCKPEER
288 rump.netstat -nr
289 rump.arp -n -a
290 rump.ifconfig
291 $HIJACKING dmesg
292 }
293
294 dump()
295 {
296 dump_local
297 dump_peer
298 shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
299 }
300
301 dad_basic_cleanup()
302 {
303 $DEBUG && dump_local
304 $DEBUG && shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
305 env RUMP_SERVER=$SOCKLOCAL rump.halt
306 }
307
308 dad_duplicated_cleanup()
309 {
310 $DEBUG && dump
311 cleanup
312 }
313
314 dad_count_cleanup()
315 {
316 $DEBUG && dump_local
317 $DEBUG && shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
318 env RUMP_SERVER=$SOCKLOCAL rump.halt
319 }
320
321 atf_init_test_cases()
322 {
323 atf_add_test_case dad_basic
324 atf_add_test_case dad_duplicated
325 atf_add_test_case dad_count
326 }
327