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