xref: /netbsd-src/tests/net/arp/t_arp.sh (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1#	$NetBSD: t_arp.sh,v 1.36 2018/04/06 09:23:36 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
28SOCKSRC=unix://commsock1
29SOCKDST=unix://commsock2
30IP4SRC=10.0.1.1
31IP4SRC2=10.0.1.5
32IP4NET=10.0.1.0
33IP4DST=10.0.1.2
34IP4DST_PROXYARP1=10.0.1.3
35IP4DST_PROXYARP2=10.0.1.4
36
37DEBUG=${DEBUG:-false}
38TIMEOUT=1
39
40atf_test_case arp_cache_expiration_5s cleanup
41atf_test_case arp_cache_expiration_10s cleanup
42atf_test_case arp_command cleanup
43atf_test_case arp_garp cleanup
44atf_test_case arp_garp_without_dad cleanup
45atf_test_case arp_cache_overwriting cleanup
46atf_test_case arp_proxy_arp_pub cleanup
47atf_test_case arp_proxy_arp_pubproxy cleanup
48atf_test_case arp_link_activation cleanup
49atf_test_case arp_static cleanup
50
51arp_cache_expiration_5s_head()
52{
53	atf_set "descr" "Tests for ARP cache expiration (5s)"
54	atf_set "require.progs" "rump_server"
55}
56
57arp_cache_expiration_10s_head()
58{
59	atf_set "descr" "Tests for ARP cache expiration (10s)"
60	atf_set "require.progs" "rump_server"
61}
62
63arp_command_head()
64{
65	atf_set "descr" "Tests for arp_commands of arp(8)"
66	atf_set "require.progs" "rump_server"
67}
68
69arp_garp_head()
70{
71	atf_set "descr" "Tests for GARP"
72	atf_set "require.progs" "rump_server"
73}
74
75arp_garp_without_dad_head()
76{
77
78	atf_set "descr" "Tests for GARP with DAD disabled"
79	atf_set "require.progs" "rump_server"
80}
81
82arp_cache_overwriting_head()
83{
84	atf_set "descr" "Tests for behavior of overwriting ARP caches"
85	atf_set "require.progs" "rump_server"
86}
87
88arp_proxy_arp_pub_head()
89{
90	atf_set "descr" "Tests for Proxy ARP (pub)"
91	atf_set "require.progs" "rump_server"
92}
93
94arp_proxy_arp_pubproxy_head()
95{
96	atf_set "descr" "Tests for Proxy ARP (pub proxy)"
97	atf_set "require.progs" "rump_server"
98}
99
100arp_link_activation_head()
101{
102	atf_set "descr" "Tests for activating a new MAC address"
103	atf_set "require.progs" "rump_server"
104}
105
106arp_static_head()
107{
108
109	atf_set "descr" "Tests for static ARP entries"
110	atf_set "require.progs" "rump_server"
111}
112
113setup_dst_server()
114{
115
116	rump_server_add_iface $SOCKDST shmif0 bus1
117	export RUMP_SERVER=$SOCKDST
118	atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4DST/24
119	atf_check -s exit:0 rump.ifconfig shmif0 up
120	atf_check -s exit:0 rump.ifconfig -w 10
121
122	$DEBUG && rump.ifconfig shmif0
123	$DEBUG && rump.arp -n -a
124	$DEBUG && rump.netstat -nr -f inet
125}
126
127setup_src_server()
128{
129	local keep=${1:-0}
130
131	export RUMP_SERVER=$SOCKSRC
132
133	# Adjust ARP parameters
134	if [ $keep != 0 ]; then
135		atf_check -s exit:0 -o ignore \
136		    rump.sysctl -w net.inet.arp.keep=$keep
137	fi
138
139	# Setup an interface
140	rump_server_add_iface $SOCKSRC shmif0 bus1
141	atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4SRC/24
142	atf_check -s exit:0 rump.ifconfig shmif0 up
143	atf_check -s exit:0 rump.ifconfig -w 10
144
145	# Sanity check
146	$DEBUG && rump.ifconfig shmif0
147	$DEBUG && rump.arp -n -a
148	$DEBUG && rump.netstat -nr -f inet
149	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4SRC
150	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
151}
152
153test_cache_expiration()
154{
155	local arp_keep=$1
156	local bonus=2
157
158	rump_server_start $SOCKSRC
159	rump_server_start $SOCKDST
160
161	setup_dst_server
162	setup_src_server $arp_keep
163
164	#
165	# Check if a cache is expired expectedly
166	#
167	export RUMP_SERVER=$SOCKSRC
168	atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
169
170	$DEBUG && rump.arp -n -a
171	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4SRC
172	# Should be cached
173	atf_check -s exit:0 -o ignore rump.arp -n $IP4DST
174	$DEBUG && rump.netstat -nr -f inet
175	atf_check -s exit:0 -o match:"$IP4DST" rump.netstat -nr -f inet
176
177	atf_check -s exit:0 sleep $(($arp_keep + $bonus))
178
179	$DEBUG && rump.arp -n -a
180	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4SRC
181	# Should be expired
182	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
183}
184
185arp_cache_expiration_5s_body()
186{
187
188	test_cache_expiration 5
189	rump_server_destroy_ifaces
190}
191
192arp_cache_expiration_10s_body()
193{
194
195	test_cache_expiration 10
196	rump_server_destroy_ifaces
197}
198
199check_arp_static_entry()
200{
201	local ip=$1
202	local mac=$2
203	local type=$3
204	local flags=
205
206	atf_check -s exit:0 -o match:"$mac" rump.arp -n $ip
207	if [ $type = 'permanent' ]; then
208		atf_check -s exit:0 -o match:'permanent' rump.arp -n $ip
209		check_route $ip "$mac" UHLS shmif0
210	else
211		atf_check -s exit:0 -o not-match:'permanent' rump.arp -n $ip
212		check_route $ip "$mac" UHL shmif0
213	fi
214}
215
216arp_command_body()
217{
218	local arp_keep=5
219	local bonus=2
220
221	rump_server_start $SOCKSRC
222	rump_server_start $SOCKDST
223
224	setup_dst_server
225	setup_src_server $arp_keep
226
227	export RUMP_SERVER=$SOCKSRC
228
229	# Add and delete a static entry
230	$DEBUG && rump.arp -n -a
231	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10
232	$DEBUG && rump.arp -n -a
233	$DEBUG && rump.netstat -nr -f inet
234	check_arp_static_entry 10.0.1.10 'b2:a0:20:00:00:10' permanent
235	atf_check -s exit:0 -o ignore rump.arp -d 10.0.1.10
236	$DEBUG && rump.arp -n -a
237	$DEBUG && rump.netstat -nr -f inet
238	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10
239	check_route_no_entry 10.0.1.10
240
241	# Add multiple entries via a file
242	cat - > ./list <<-EOF
243	10.0.1.11 b2:a0:20:00:00:11
244	10.0.1.12 b2:a0:20:00:00:12
245	10.0.1.13 b2:a0:20:00:00:13
246	10.0.1.14 b2:a0:20:00:00:14
247	10.0.1.15 b2:a0:20:00:00:15
248	EOF
249	$DEBUG && rump.arp -n -a
250	$DEBUG && rump.netstat -nr -f inet
251	atf_check -s exit:0 -o ignore rump.arp -f ./list
252	$DEBUG && rump.arp -n -a
253	$DEBUG && rump.netstat -nr -f inet
254	check_arp_static_entry 10.0.1.11 'b2:a0:20:00:00:11' permanent
255	check_arp_static_entry 10.0.1.12 'b2:a0:20:00:00:12' permanent
256	check_arp_static_entry 10.0.1.13 'b2:a0:20:00:00:13' permanent
257	check_arp_static_entry 10.0.1.14 'b2:a0:20:00:00:14' permanent
258	check_arp_static_entry 10.0.1.15 'b2:a0:20:00:00:15' permanent
259
260	# Test arp -a
261	atf_check -s exit:0 -o match:'10.0.1.11' rump.arp -n -a
262	atf_check -s exit:0 -o match:'10.0.1.12' rump.arp -n -a
263	atf_check -s exit:0 -o match:'10.0.1.13' rump.arp -n -a
264	atf_check -s exit:0 -o match:'10.0.1.14' rump.arp -n -a
265	atf_check -s exit:0 -o match:'10.0.1.15' rump.arp -n -a
266
267	# Flush all entries
268	$DEBUG && rump.arp -n -a
269	$DEBUG && rump.netstat -nr -f inet
270	atf_check -s exit:0 -o ignore rump.arp -d -a
271	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.11
272	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.12
273	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.13
274	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.14
275	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.15
276	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.1
277	check_route_no_entry 10.0.1.11
278	check_route_no_entry 10.0.1.12
279	check_route_no_entry 10.0.1.13
280	check_route_no_entry 10.0.1.14
281	check_route_no_entry 10.0.1.15
282
283	# Test temp option
284	$DEBUG && rump.arp -n -a
285	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp
286	$DEBUG && rump.arp -n -a
287	$DEBUG && rump.netstat -nr -f inet
288	check_arp_static_entry 10.0.1.10 'b2:a0:20:00:00:10' temp
289
290	# Hm? the cache doesn't expire...
291	atf_check -s exit:0 sleep $(($arp_keep + $bonus))
292	$DEBUG && rump.arp -n -a
293	$DEBUG && rump.netstat -nr -f inet
294	#atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10
295
296	rump_server_destroy_ifaces
297}
298
299make_pkt_str_arpreq()
300{
301	local target=$1
302	local sender=$2
303	pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP \(0x0806\), length 42:"
304	pkt="$pkt Request who-has $target tell $sender, length 28"
305	echo $pkt
306}
307
308test_garp_common()
309{
310	local no_dad=$1
311	local pkt=
312
313	rump_server_start $SOCKSRC
314
315	export RUMP_SERVER=$SOCKSRC
316
317	if $no_dad; then
318		atf_check -s exit:0 -o match:'3 -> 0' \
319		    rump.sysctl -w net.inet.ip.dad_count=0
320	fi
321
322	# Setup an interface
323	rump_server_add_iface $SOCKSRC shmif0 bus1
324	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24
325	atf_check -s exit:0 rump.ifconfig shmif0 up
326	$DEBUG && rump.ifconfig shmif0
327
328	atf_check -s exit:0 sleep 1
329	extract_new_packets bus1 > ./out
330
331	#
332	# Assign an address to an interface without IFF_UP
333	#
334	# A GARP packet is sent for the primary address
335	pkt=$(make_pkt_str_arpreq 10.0.0.1 10.0.0.1)
336	atf_check -s exit:0 -o match:"$pkt" cat ./out
337
338	atf_check -s exit:0 rump.ifconfig shmif0 down
339	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias
340
341	atf_check -s exit:0 sleep 1
342	extract_new_packets bus1 > ./out
343
344	# A GARP packet is sent for the alias address
345	pkt=$(make_pkt_str_arpreq 10.0.0.2 10.0.0.2)
346	atf_check -s exit:0 -o match:"$pkt" cat ./out
347
348	# Clean up
349	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24 delete
350	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 delete
351
352	#
353	# Assign an address to an interface with IFF_UP
354	#
355	atf_check -s exit:0 rump.ifconfig shmif0 up
356
357	# Primary address
358	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24
359
360	atf_check -s exit:0 sleep 1
361	extract_new_packets bus1 > ./out
362
363	pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3)
364	if $no_dad; then
365		# A GARP packet is sent
366		atf_check -s exit:0 -o match:"$pkt" cat ./out
367	else
368		# No GARP packet is sent
369		atf_check -s exit:0 -o not-match:"$pkt" cat ./out
370	fi
371
372	# Alias address
373	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.4/24 alias
374
375	atf_check -s exit:0 sleep 1
376	extract_new_packets bus1 > ./out
377
378	pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4)
379	if $no_dad; then
380		# A GARP packet is sent
381		atf_check -s exit:0 -o match:"$pkt" cat ./out
382	else
383		# No GARP packet is sent
384		atf_check -s exit:0 -o not-match:"$pkt" cat ./out
385	fi
386
387	rump_server_destroy_ifaces
388}
389
390arp_garp_body()
391{
392
393	test_garp_common false
394}
395
396arp_garp_without_dad_body()
397{
398
399	test_garp_common true
400}
401
402arp_cache_overwriting_body()
403{
404	local bonus=2
405
406	rump_server_start $SOCKSRC
407	rump_server_start $SOCKDST
408
409	setup_dst_server
410	setup_src_server
411
412	export RUMP_SERVER=$SOCKSRC
413
414	# Cannot overwrite a permanent cache
415	atf_check -s exit:0 rump.arp -s $IP4DST b2:a0:20:00:00:ff
416	$DEBUG && rump.arp -n -a
417	atf_check -s not-exit:0 -e match:'File exists' \
418	    rump.arp -s $IP4DST b2:a0:20:00:00:fe
419	# cleanup
420	atf_check -s exit:0 rump.arp -d $IP4DST
421
422	atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
423	$DEBUG && rump.arp -n -a
424	# Can overwrite a dynamic cache
425	atf_check -s exit:0 -o ignore rump.arp -s $IP4DST b2:a0:20:00:00:00
426	$DEBUG && rump.arp -n -a
427	atf_check -s exit:0 -o match:'b2:a0:20:00:00:00' rump.arp -n $IP4DST
428	atf_check -s exit:0 -o match:'permanent' rump.arp -n $IP4DST
429
430	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp
431	$DEBUG && rump.arp -n -a
432	atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
433	atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10
434	# Can overwrite a temp cache
435	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:ff
436	atf_check -s exit:0 -o match:'b2:a0:20:00:00:ff' rump.arp -n 10.0.1.10
437	$DEBUG && rump.arp -n -a
438
439	rump_server_destroy_ifaces
440}
441
442make_pkt_str_arprep()
443{
444	local ip=$1
445	local mac=$2
446	pkt="ethertype ARP (0x0806), length 42: "
447	pkt="Reply $ip is-at $mac, length 28"
448	echo $pkt
449}
450
451make_pkt_str_garp()
452{
453	local ip=$1
454	local mac=$2
455	local pkt=
456	pkt="$mac > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806),"
457	pkt="$pkt length 42: Request who-has $ip tell $ip, length 28"
458	echo $pkt
459}
460
461test_proxy_arp()
462{
463	local opts= title= flags=
464	local type=$1
465
466	rump_server_start $SOCKSRC
467	rump_server_start $SOCKDST tap
468
469	setup_dst_server
470	setup_src_server
471
472	export RUMP_SERVER=$SOCKDST
473	atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1
474	macaddr_dst=$(get_macaddr $SOCKDST shmif0)
475
476	if [ "$type" = "pub" ]; then
477		opts="pub"
478	else
479		opts="pub proxy"
480	fi
481	# Always proxy only since migrating to lltable/llentry
482	title='permanent published \(proxy only\)'
483
484	#
485	# Test#1: First setup an endpoint then create proxy arp entry
486	#
487	export RUMP_SERVER=$SOCKDST
488	atf_check -s exit:0 rump.ifconfig tap1 create
489	atf_check -s exit:0 rump.ifconfig tap1 $IP4DST_PROXYARP1/24 up
490	atf_check -s exit:0 rump.ifconfig -w 10
491
492	# Try to ping (should fail w/o proxy arp)
493	export RUMP_SERVER=$SOCKSRC
494	atf_check -s not-exit:0 -o ignore -e ignore \
495	    rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1
496
497	# Flushing
498	extract_new_packets bus1 > ./out
499
500	# Set up proxy ARP entry
501	export RUMP_SERVER=$SOCKDST
502	atf_check -s exit:0 -o ignore \
503	    rump.arp -s $IP4DST_PROXYARP1 $macaddr_dst $opts
504	atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP1
505
506	# Try to ping
507	export RUMP_SERVER=$SOCKSRC
508	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1
509
510	extract_new_packets bus1 > ./out
511	$DEBUG && cat ./out
512
513	pkt1=$(make_pkt_str_arprep $IP4DST_PROXYARP1 $macaddr_dst)
514	pkt2=$(make_pkt_str_garp $IP4DST_PROXYARP1 $macaddr_dst)
515	atf_check -s exit:0 -x "cat ./out |grep -q -e '$pkt1' -e '$pkt2'"
516
517	#
518	# Test#2: Create proxy arp entry then set up an endpoint
519	#
520	export RUMP_SERVER=$SOCKDST
521	atf_check -s exit:0 -o ignore \
522	    rump.arp -s $IP4DST_PROXYARP2 $macaddr_dst $opts
523	atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP2
524	$DEBUG && rump.netstat -nr -f inet
525
526	# Try to ping (should fail because no endpoint exists)
527	export RUMP_SERVER=$SOCKSRC
528	atf_check -s not-exit:0 -o ignore -e ignore \
529	    rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2
530
531	extract_new_packets bus1 > ./out
532	$DEBUG && cat ./out
533
534	# ARP reply should be sent
535	pkt=$(make_pkt_str_arprep $IP4DST_PROXYARP2 $macaddr_dst)
536	atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
537
538	export RUMP_SERVER=$SOCKDST
539	atf_check -s exit:0 rump.ifconfig tap2 create
540	atf_check -s exit:0 rump.ifconfig tap2 $IP4DST_PROXYARP2/24 up
541	atf_check -s exit:0 rump.ifconfig -w 10
542
543	# Try to ping
544	export RUMP_SERVER=$SOCKSRC
545	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2
546}
547
548arp_proxy_arp_pub_body()
549{
550
551	test_proxy_arp pub
552	rump_server_destroy_ifaces
553}
554
555arp_proxy_arp_pubproxy_body()
556{
557
558	test_proxy_arp pubproxy
559	rump_server_destroy_ifaces
560}
561
562arp_link_activation_body()
563{
564	local bonus=2
565
566	rump_server_start $SOCKSRC
567	rump_server_start $SOCKDST
568
569	setup_dst_server
570	setup_src_server
571
572	# flush old packets
573	extract_new_packets bus1 > ./out
574
575	export RUMP_SERVER=$SOCKSRC
576
577	atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
578	    b2:a1:00:00:00:01
579
580	atf_check -s exit:0 sleep 1
581	extract_new_packets bus1 > ./out
582	$DEBUG && cat ./out
583
584	pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC)
585	atf_check -s exit:0 -o not-match:"$pkt" cat ./out
586
587	atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
588	    b2:a1:00:00:00:02 active
589
590	atf_check -s exit:0 sleep 1
591	extract_new_packets bus1 > ./out
592	$DEBUG && cat ./out
593
594	pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC)
595	atf_check -s exit:0 -o match:"b2:a1:00:00:00:02 $pkt" cat ./out
596
597	rump_server_destroy_ifaces
598}
599
600arp_static_body()
601{
602	local macaddr_src=
603
604	rump_server_start $SOCKSRC
605	rump_server_start $SOCKDST
606
607	setup_dst_server
608	setup_src_server
609
610	macaddr_src=$(get_macaddr $SOCKSRC shmif0)
611
612	# Set a (valid) static ARP entry for the src server
613	export RUMP_SERVER=$SOCKDST
614	$DEBUG && rump.arp -n -a
615	atf_check -s exit:0 -o ignore rump.arp -s $IP4SRC $macaddr_src
616	$DEBUG && rump.arp -n -a
617
618	# Test receiving an ARP request with the static ARP entry (as spa/sha)
619	export RUMP_SERVER=$SOCKSRC
620	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
621
622	rump_server_destroy_ifaces
623}
624
625arp_cache_expiration_5s_cleanup()
626{
627	$DEBUG && dump
628	cleanup
629}
630
631arp_cache_expiration_10s_cleanup()
632{
633	$DEBUG && dump
634	cleanup
635}
636
637arp_command_cleanup()
638{
639	$DEBUG && dump
640	cleanup
641}
642
643arp_garp_cleanup()
644{
645	$DEBUG && dump
646	cleanup
647}
648
649arp_garp_without_dad_cleanup()
650{
651
652	$DEBUG && dump
653	cleanup
654}
655
656arp_cache_overwriting_cleanup()
657{
658	$DEBUG && dump
659	cleanup
660}
661
662arp_proxy_arp_pub_cleanup()
663{
664	$DEBUG && dump
665	cleanup
666}
667
668arp_proxy_arp_pubproxy_cleanup()
669{
670	$DEBUG && dump
671	cleanup
672}
673
674arp_link_activation_cleanup()
675{
676	$DEBUG && dump
677	cleanup
678}
679
680arp_static_cleanup()
681{
682	$DEBUG && dump
683	cleanup
684}
685
686atf_test_case arp_rtm cleanup
687arp_rtm_head()
688{
689
690	atf_set "descr" "Tests for routing messages on operations of ARP entries"
691	atf_set "require.progs" "rump_server"
692}
693
694arp_rtm_body()
695{
696	local macaddr_src= macaddr_dst=
697	local file=./tmp
698	local pid= hdr= what= addr=
699
700	rump_server_start $SOCKSRC
701	rump_server_start $SOCKDST
702
703	setup_dst_server
704	setup_src_server
705
706	macaddr_src=$(get_macaddr $SOCKSRC shmif0)
707	macaddr_dst=$(get_macaddr $SOCKDST shmif0)
708
709	export RUMP_SERVER=$SOCKSRC
710
711	# Test ping and a resulting routing message (RTM_ADD)
712	rump.route -n monitor -c 1 > $file &
713	pid=$!
714	sleep 1
715	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
716	wait $pid
717	$DEBUG && cat $file
718
719	hdr="RTM_ADD.+<UP,HOST,DONE,LLINFO,CLONED>"
720	what="<DST,GATEWAY>"
721	addr="$IP4DST link#2"
722	atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
723		cat $file
724
725	# Test arp -d and resulting routing messages (RTM_DELETE)
726	rump.route -n monitor -c 1 > $file &
727	pid=$!
728	sleep 1
729	atf_check -s exit:0 -o ignore rump.arp -d $IP4DST
730	wait $pid
731	$DEBUG && cat $file
732
733	hdr="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>"
734	what="<DST,GATEWAY>"
735	addr="$IP4DST $macaddr_dst"
736	atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
737		grep -A 3 RTM_DELETE $file
738
739	rump_server_destroy_ifaces
740}
741
742arp_rtm_cleanup()
743{
744
745	$DEBUG && dump
746	cleanup
747}
748
749atf_test_case arp_purge_on_route_change cleanup
750arp_purge_on_route_change_head()
751{
752
753	atf_set "descr" "Tests if ARP entries are removed on route change"
754	atf_set "require.progs" "rump_server"
755}
756
757arp_purge_on_route_change_body()
758{
759
760	rump_server_start $SOCKSRC
761	rump_server_start $SOCKDST
762
763	setup_dst_server
764	setup_src_server
765
766	rump_server_add_iface $SOCKSRC shmif1 bus1
767	export RUMP_SERVER=$SOCKSRC
768	atf_check -s exit:0 rump.ifconfig shmif1 inet $IP4SRC2/24
769	atf_check -s exit:0 rump.ifconfig -w 10
770
771	$DEBUG && rump.netstat -nr -f inet
772	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
773	$DEBUG && rump.arp -na
774	atf_check -s exit:0 -o ignore \
775	    rump.route change -net $IP4NET -ifp shmif1
776	$DEBUG && rump.netstat -nr -f inet
777	$DEBUG && rump.arp -na
778	# The entry was already removed on route change
779	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
780
781	rump_server_destroy_ifaces
782}
783
784arp_purge_on_route_change_cleanup()
785{
786
787	$DEBUG && dump
788	cleanup
789}
790
791atf_test_case arp_purge_on_route_delete cleanup
792arp_purge_on_route_delete_head()
793{
794
795	atf_set "descr" "Tests if ARP entries are removed on route delete"
796	atf_set "require.progs" "rump_server"
797}
798
799arp_purge_on_route_delete_body()
800{
801
802	rump_server_start $SOCKSRC
803	rump_server_start $SOCKDST
804
805	setup_dst_server
806	setup_src_server
807
808	$DEBUG && rump.netstat -nr -f inet
809	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
810	$DEBUG && rump.arp -na
811
812	atf_check -s exit:0 -o ignore rump.route delete -net $IP4NET
813	$DEBUG && rump.netstat -nr -f inet
814	$DEBUG && rump.arp -na
815
816	# The entry was already removed on route delete
817	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
818
819	rump_server_destroy_ifaces
820}
821
822arp_purge_on_route_delete_cleanup()
823{
824
825	$DEBUG && dump
826	cleanup
827}
828
829atf_test_case arp_purge_on_ifdown cleanup
830arp_purge_on_ifdown_head()
831{
832
833	atf_set "descr" "Tests if ARP entries are removed on interface down"
834	atf_set "require.progs" "rump_server"
835}
836
837arp_purge_on_ifdown_body()
838{
839
840	rump_server_start $SOCKSRC
841	rump_server_start $SOCKDST
842
843	setup_dst_server
844	setup_src_server
845
846	$DEBUG && rump.netstat -nr -f inet
847	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
848	atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
849
850	# Shutdown the interface
851	atf_check -s exit:0 rump.ifconfig shmif0 down
852	$DEBUG && rump.netstat -nr -f inet
853	$DEBUG && rump.arp -na
854
855	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
856
857	rump_server_destroy_ifaces
858}
859
860arp_purge_on_ifdown_cleanup()
861{
862
863	$DEBUG && dump
864	cleanup
865}
866
867atf_test_case arp_stray_entries cleanup
868arp_stray_entries_head()
869{
870
871	atf_set "descr" "Tests if ARP entries are removed on route change"
872	atf_set "require.progs" "rump_server"
873}
874
875arp_stray_entries_body()
876{
877
878	rump_server_start $SOCKSRC
879	rump_server_start $SOCKDST
880
881	setup_dst_server
882	setup_src_server
883
884	rump_server_add_iface $SOCKSRC shmif1 bus1
885
886	export RUMP_SERVER=$SOCKSRC
887	atf_check -s exit:0 rump.ifconfig shmif1 inet $IP4SRC2/24
888	atf_check -s exit:0 rump.ifconfig -w 10
889
890	$DEBUG && rump.netstat -nr -f inet
891	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
892	$DEBUG && rump.arp -na
893	atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
894	atf_check -s exit:0 -o not-match:'shmif1' rump.arp -n $IP4DST
895
896	# Clean up
897	atf_check -s exit:0 -o ignore rump.arp -da
898	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
899
900	# ping from a different source address
901	atf_check -s exit:0 -o ignore \
902	    rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST
903	$DEBUG && rump.arp -na
904	atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
905	# ARP reply goes back via shmif1, so a cache is created on shmif1
906	atf_check -s exit:0 -o match:'shmif1' rump.arp -n $IP4DST
907
908	# Clean up by arp -da
909	atf_check -s exit:0 -o ignore rump.arp -da
910	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
911
912	# ping from a different source address again
913	atf_check -s exit:0 -o ignore \
914	    rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST
915	atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
916	# ARP reply doen't come
917	atf_check -s exit:0 -o not-match:'shmif1' rump.arp -n $IP4DST
918
919	# Cleanup caches on the destination
920	export RUMP_SERVER=$SOCKDST
921	atf_check -s exit:0 -o ignore rump.arp -da
922	export RUMP_SERVER=$SOCKSRC
923
924	# ping from a different source address again
925	atf_check -s exit:0 -o ignore \
926	    rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST
927	atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
928	# ARP reply goes back via shmif1
929	atf_check -s exit:0 -o match:'shmif1' rump.arp -n $IP4DST
930
931	# Clean up by arp -d <ip>
932	atf_check -s exit:0 -o ignore rump.arp -d $IP4DST
933	# Both entries should be deleted
934	atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
935
936	rump_server_destroy_ifaces
937}
938
939arp_stray_entries_cleanup()
940{
941
942	$DEBUG && dump
943	cleanup
944}
945
946atf_init_test_cases()
947{
948	atf_add_test_case arp_cache_expiration_5s
949	atf_add_test_case arp_cache_expiration_10s
950	atf_add_test_case arp_command
951	atf_add_test_case arp_garp
952	atf_add_test_case arp_garp_without_dad
953	atf_add_test_case arp_cache_overwriting
954	atf_add_test_case arp_proxy_arp_pub
955	atf_add_test_case arp_proxy_arp_pubproxy
956	atf_add_test_case arp_link_activation
957	atf_add_test_case arp_static
958	atf_add_test_case arp_rtm
959	atf_add_test_case arp_purge_on_route_change
960	atf_add_test_case arp_purge_on_route_delete
961	atf_add_test_case arp_purge_on_ifdown
962	atf_add_test_case arp_stray_entries
963}
964