xref: /netbsd-src/tests/net/ipsec/t_ipsec_misc.sh (revision b2a8932dbe9fdfd3d41d60d0a04b9a3ba294763d)
1#	$NetBSD: t_ipsec_misc.sh,v 1.22 2017/11/09 04:51:07 ozaki-r Exp $
2#
3# Copyright (c) 2017 Internet Initiative Japan 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
28SOCK_LOCAL=unix://ipsec_local
29SOCK_PEER=unix://ipsec_peer
30BUS=./bus_ipsec
31
32DEBUG=${DEBUG:-true}
33
34setup_sasp()
35{
36	local proto=$1
37	local algo_args="$2"
38	local ip_local=$3
39	local ip_peer=$4
40	local lifetime=$5
41	local update=$6
42	local tmpfile=./tmp
43	local extra=
44
45	if [ "$update" = sa ]; then
46		extra="update $ip_local $ip_peer $proto 10000 $algo_args;
47		       update $ip_peer $ip_local $proto 10001 $algo_args;"
48	elif [ "$update" = sp ]; then
49		extra="spdupdate $ip_local $ip_peer any -P out ipsec $proto/transport//require;"
50	fi
51
52	export RUMP_SERVER=$SOCK_LOCAL
53	cat > $tmpfile <<-EOF
54	add $ip_local $ip_peer $proto 10000 -lh $lifetime -ls $lifetime $algo_args;
55	add $ip_peer $ip_local $proto 10001 -lh $lifetime -ls $lifetime $algo_args;
56	spdadd $ip_local $ip_peer any -P out ipsec $proto/transport//require;
57	$extra
58	EOF
59	$DEBUG && cat $tmpfile
60	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
61	# XXX it can be expired if $lifetime is very short
62	#check_sa_entries $SOCK_LOCAL $ip_local $ip_peer
63
64	if [ "$update" = sp ]; then
65		extra="spdupdate $ip_peer $ip_local any -P out ipsec $proto/transport//require;"
66	fi
67
68	export RUMP_SERVER=$SOCK_PEER
69	cat > $tmpfile <<-EOF
70	add $ip_local $ip_peer $proto 10000 -lh $lifetime -ls $lifetime $algo_args;
71	add $ip_peer $ip_local $proto 10001 -lh $lifetime -ls $lifetime $algo_args;
72	spdadd $ip_peer $ip_local any -P out ipsec $proto/transport//require;
73	$extra
74	EOF
75	$DEBUG && cat $tmpfile
76	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
77	# XXX it can be expired if $lifetime is very short
78	#check_sa_entries $SOCK_PEER $ip_local $ip_peer
79}
80
81test_sad_disapper_until()
82{
83	local time=$1
84	local check_dead_sa=$2
85	local setkey_opts=
86	local n=$time
87	local tmpfile=./__tmp
88	local sock= ok=
89
90	if $check_dead_sa; then
91		setkey_opts="-D -a"
92	else
93		setkey_opts="-D"
94	fi
95
96	while [ $n -ne 0 ]; do
97		ok=0
98		sleep 1
99		for sock in $SOCK_LOCAL $SOCK_PEER; do
100			export RUMP_SERVER=$sock
101			$HIJACKING setkey $setkey_opts > $tmpfile
102			$DEBUG && cat $tmpfile
103			if grep -q 'No SAD entries.' $tmpfile; then
104				ok=$((ok + 1))
105			fi
106		done
107		if [ $ok -eq 2 ]; then
108			return
109		fi
110
111		n=$((n - 1))
112	done
113
114	atf_fail "SAs didn't disappear after $time sec."
115}
116
117test_ipsec4_lifetime()
118{
119	local proto=$1
120	local algo=$2
121	local ip_local=10.0.0.1
122	local ip_peer=10.0.0.2
123	local outfile=./out
124	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
125	local algo_args="$(generate_algo_args $proto $algo)"
126	local lifetime=3
127	local buffertime=2
128
129	rump_server_crypto_start $SOCK_LOCAL netipsec
130	rump_server_crypto_start $SOCK_PEER netipsec
131	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
132	rump_server_add_iface $SOCK_PEER shmif0 $BUS
133
134	export RUMP_SERVER=$SOCK_LOCAL
135	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
136	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
137	#atf_check -s exit:0 -o ignore rump.sysctl -w net.key.debug=0xff
138
139	export RUMP_SERVER=$SOCK_PEER
140	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
141	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
142	#atf_check -s exit:0 -o ignore rump.sysctl -w net.key.debug=0xff
143
144	extract_new_packets $BUS > $outfile
145
146	export RUMP_SERVER=$SOCK_LOCAL
147	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
148
149	extract_new_packets $BUS > $outfile
150	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: ICMP echo request" \
151	    cat $outfile
152	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: ICMP echo reply" \
153	    cat $outfile
154
155	# Set up SAs with lifetime 1 sec.
156	setup_sasp $proto "$algo_args" $ip_local $ip_peer 1
157
158	# Check the SAs have been expired
159	test_sad_disapper_until $((1 + $buffertime)) false
160
161	# Clean up SPs
162	export RUMP_SERVER=$SOCK_LOCAL
163	atf_check -s exit:0 -o empty $HIJACKING setkey -F -P
164	export RUMP_SERVER=$SOCK_PEER
165	atf_check -s exit:0 -o empty $HIJACKING setkey -F -P
166
167	# Set up SAs with lifetime with $lifetime
168	setup_sasp $proto "$algo_args" $ip_local $ip_peer $lifetime
169
170	# Use the SAs; this will create a reference from an SP to an SA
171	export RUMP_SERVER=$SOCK_LOCAL
172	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
173
174	extract_new_packets $BUS > $outfile
175	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: $proto_cap" \
176	    cat $outfile
177	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: $proto_cap" \
178	    cat $outfile
179
180	# Check the SAs have been expired
181	test_sad_disapper_until $((lifetime + $buffertime)) true
182
183	export RUMP_SERVER=$SOCK_LOCAL
184	atf_check -s not-exit:0 -o match:'0 packets received' \
185	    rump.ping -c 1 -n -w 1 $ip_peer
186
187	test_flush_entries $SOCK_LOCAL
188	test_flush_entries $SOCK_PEER
189}
190
191test_ipsec6_lifetime()
192{
193	local proto=$1
194	local algo=$2
195	local ip_local=fd00::1
196	local ip_peer=fd00::2
197	local outfile=./out
198	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
199	local algo_args="$(generate_algo_args $proto $algo)"
200	local lifetime=3
201	local buffertime=2
202
203	rump_server_crypto_start $SOCK_LOCAL netinet6 netipsec
204	rump_server_crypto_start $SOCK_PEER netinet6 netipsec
205	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
206	rump_server_add_iface $SOCK_PEER shmif0 $BUS
207
208	export RUMP_SERVER=$SOCK_LOCAL
209	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
210	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local
211
212	export RUMP_SERVER=$SOCK_PEER
213	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
214	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_peer
215
216	extract_new_packets $BUS > $outfile
217
218	export RUMP_SERVER=$SOCK_LOCAL
219	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_peer
220
221	extract_new_packets $BUS > $outfile
222	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: ICMP6, echo request" \
223	    cat $outfile
224	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: ICMP6, echo reply" \
225	    cat $outfile
226
227	# Set up SAs with lifetime 1 sec.
228	setup_sasp $proto "$algo_args" $ip_local $ip_peer 1
229
230	# Check the SAs have been expired
231	test_sad_disapper_until $((1 + $buffertime)) false
232
233	# Clean up SPs
234	export RUMP_SERVER=$SOCK_LOCAL
235	atf_check -s exit:0 -o empty $HIJACKING setkey -F -P
236	export RUMP_SERVER=$SOCK_PEER
237	atf_check -s exit:0 -o empty $HIJACKING setkey -F -P
238
239	# Set up SAs with lifetime with $lifetime
240	setup_sasp $proto "$algo_args" $ip_local $ip_peer $lifetime
241
242	# Use the SAs; this will create a reference from an SP to an SA
243	export RUMP_SERVER=$SOCK_LOCAL
244	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_peer
245
246	extract_new_packets $BUS > $outfile
247	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: $proto_cap" \
248	    cat $outfile
249	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: $proto_cap" \
250	    cat $outfile
251
252	# Check the SAs have been expired
253	test_sad_disapper_until $((lifetime + $buffertime)) true
254
255	export RUMP_SERVER=$SOCK_LOCAL
256	atf_check -s not-exit:0 -o match:'0 packets received' \
257	    rump.ping6 -c 1 -n -X 1 $ip_peer
258
259	test_flush_entries $SOCK_LOCAL
260	test_flush_entries $SOCK_PEER
261}
262
263test_lifetime_common()
264{
265	local ipproto=$1
266	local proto=$2
267	local algo=$3
268
269	if [ $ipproto = ipv4 ]; then
270		test_ipsec4_lifetime $proto $algo
271	else
272		test_ipsec6_lifetime $proto $algo
273	fi
274}
275
276add_test_lifetime()
277{
278	local ipproto=$1
279	local proto=$2
280	local algo=$3
281	local _algo=$(echo $algo | sed 's/-//g')
282	local name= desc=
283
284	name="ipsec_lifetime_${ipproto}_${proto}_${_algo}"
285	desc="Tests of lifetime of IPsec ($ipproto) with $proto ($algo)"
286
287	atf_test_case ${name} cleanup
288	eval "
289	    ${name}_head() {
290	        atf_set descr \"$desc\"
291	        atf_set require.progs rump_server setkey
292	    }
293	    ${name}_body() {
294	        test_lifetime_common $ipproto $proto $algo
295	        rump_server_destroy_ifaces
296	    }
297	    ${name}_cleanup() {
298	        \$DEBUG && dump
299	        cleanup
300	    }
301	"
302	atf_add_test_case ${name}
303}
304
305test_update()
306{
307	local proto=$1
308	local algo=$2
309	local update=$3
310	local ip_local=10.0.0.1
311	local ip_peer=10.0.0.2
312	local algo_args="$(generate_algo_args $proto $algo)"
313	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
314	local outfile=./out
315
316	rump_server_crypto_start $SOCK_LOCAL netipsec
317	rump_server_crypto_start $SOCK_PEER netipsec
318	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
319	rump_server_add_iface $SOCK_PEER shmif0 $BUS
320
321	export RUMP_SERVER=$SOCK_LOCAL
322	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
323	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
324
325	export RUMP_SERVER=$SOCK_PEER
326	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
327	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
328
329	setup_sasp $proto "$algo_args" $ip_local $ip_peer 100 $update
330
331	extract_new_packets $BUS > $outfile
332
333	export RUMP_SERVER=$SOCK_LOCAL
334	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
335
336	extract_new_packets $BUS > $outfile
337	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: $proto_cap" \
338	    cat $outfile
339	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: $proto_cap" \
340	    cat $outfile
341}
342
343add_test_update()
344{
345	local proto=$1
346	local algo=$2
347	local update=$3
348	local _update=$(echo $update |tr 'a-z' 'A-Z')
349	local _algo=$(echo $algo | sed 's/-//g')
350	local name= desc=
351
352	desc="Tests trying to udpate $_update of $proto ($algo)"
353	name="ipsec_update_${update}_${proto}_${_algo}"
354
355	atf_test_case ${name} cleanup
356	eval "
357	    ${name}_head() {
358	        atf_set descr \"$desc\"
359	        atf_set require.progs rump_server setkey
360	    }
361	    ${name}_body() {
362	        test_update $proto $algo $update
363	        rump_server_destroy_ifaces
364	    }
365	    ${name}_cleanup() {
366	        \$DEBUG && dump
367	        cleanup
368	    }
369	"
370	atf_add_test_case ${name}
371}
372
373add_sa()
374{
375	local proto=$1
376	local algo_args="$2"
377	local ip_local=$3
378	local ip_peer=$4
379	local lifetime=$5
380	local spi=$6
381	local tmpfile=./tmp
382	local extra=
383
384	export RUMP_SERVER=$SOCK_LOCAL
385	cat > $tmpfile <<-EOF
386	add $ip_local $ip_peer $proto $((spi)) -lh $lifetime -ls $lifetime $algo_args;
387	add $ip_peer $ip_local $proto $((spi + 1)) -lh $lifetime -ls $lifetime $algo_args;
388	$extra
389	EOF
390	$DEBUG && cat $tmpfile
391	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
392	$DEBUG && $HIJACKING setkey -D
393	# XXX it can be expired if $lifetime is very short
394	#check_sa_entries $SOCK_LOCAL $ip_local $ip_peer
395
396	export RUMP_SERVER=$SOCK_PEER
397	cat > $tmpfile <<-EOF
398	add $ip_local $ip_peer $proto $((spi)) -lh $lifetime -ls $lifetime $algo_args;
399	add $ip_peer $ip_local $proto $((spi + 1)) -lh $lifetime -ls $lifetime $algo_args;
400	$extra
401	EOF
402	$DEBUG && cat $tmpfile
403	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
404	$DEBUG && $HIJACKING setkey -D
405	# XXX it can be expired if $lifetime is very short
406	#check_sa_entries $SOCK_PEER $ip_local $ip_peer
407}
408
409delete_sa()
410{
411	local proto=$1
412	local ip_local=$2
413	local ip_peer=$3
414	local spi=$4
415	local tmpfile=./tmp
416	local extra=
417
418	export RUMP_SERVER=$SOCK_LOCAL
419	cat > $tmpfile <<-EOF
420	delete $ip_local $ip_peer $proto $((spi));
421	delete $ip_peer $ip_local $proto $((spi + 1));
422	EOF
423	$DEBUG && cat $tmpfile
424	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
425	$DEBUG && $HIJACKING setkey -D
426
427	export RUMP_SERVER=$SOCK_PEER
428	cat > $tmpfile <<-EOF
429	delete $ip_local $ip_peer $proto $((spi));
430	delete $ip_peer $ip_local $proto $((spi + 1));
431	EOF
432	$DEBUG && cat $tmpfile
433	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
434	$DEBUG && $HIJACKING setkey -D
435}
436
437check_packet_spi()
438{
439	local outfile=$1
440	local ip_local=$2
441	local ip_peer=$3
442	local proto=$4
443	local spi=$5
444	local spistr=
445
446	$DEBUG && cat $outfile
447	spistr=$(printf "%08x" $spi)
448	atf_check -s exit:0 \
449	    -o match:"$ip_local > $ip_peer: $proto_cap\(spi=0x$spistr," \
450	    cat $outfile
451	spistr=$(printf "%08x" $((spi + 1)))
452	atf_check -s exit:0 \
453	    -o match:"$ip_peer > $ip_local: $proto_cap\(spi=0x$spistr," \
454	    cat $outfile
455}
456
457wait_sa_disappeared()
458{
459	local spi=$1
460	local i=
461
462	export RUMP_SERVER=$SOCK_LOCAL
463	for i in $(seq 1 10); do
464		$HIJACKING setkey -D |grep -q "spi=$spi"
465		[ $? != 0 ] && break
466		sleep 1
467	done
468	if [ $i -eq 10 ]; then
469		atf_fail "SA (spi=$spi) didn't disappear in 10s"
470	fi
471	export RUMP_SERVER=$SOCK_PEER
472	for i in $(seq 1 10); do
473		$HIJACKING setkey -D |grep -q "spi=$spi"
474		[ $? != 0 ] && break
475		sleep 1
476	done
477	if [ $i -eq 10 ]; then
478		atf_fail "SA (spi=$spi) didn't disappear in 10s"
479	fi
480}
481
482test_spi()
483{
484	local proto=$1
485	local algo=$2
486	local preferred=$3
487	local method=$4
488	local ip_local=10.0.0.1
489	local ip_peer=10.0.0.2
490	local algo_args="$(generate_algo_args $proto $algo)"
491	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
492	local outfile=./out
493	local spistr=
494	local longtime= shorttime=
495
496	if [ $method = timeout -a $preferred = new ]; then
497		skip_if_qemu
498	fi
499
500	if [ $method = delete ]; then
501		shorttime=100
502		longtime=100
503	else
504		shorttime=3
505		longtime=6
506	fi
507
508	rump_server_crypto_start $SOCK_LOCAL netipsec
509	rump_server_crypto_start $SOCK_PEER netipsec
510	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
511	rump_server_add_iface $SOCK_PEER shmif0 $BUS
512
513	export RUMP_SERVER=$SOCK_LOCAL
514	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
515	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
516	if [ $preferred = old ]; then
517		atf_check -s exit:0 rump.sysctl -q -w net.key.prefered_oldsa=1
518	fi
519
520	export RUMP_SERVER=$SOCK_PEER
521	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
522	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
523	if [ $preferred = old ]; then
524		atf_check -s exit:0 rump.sysctl -q -w net.key.prefered_oldsa=1
525	fi
526
527	setup_sasp $proto "$algo_args" $ip_local $ip_peer 100
528
529	extract_new_packets $BUS > $outfile
530
531	export RUMP_SERVER=$SOCK_LOCAL
532	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
533	extract_new_packets $BUS > $outfile
534	check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10000
535
536	# Add a new SA with a different SPI
537	add_sa $proto "$algo_args" $ip_local $ip_peer $longtime 10010
538
539	export RUMP_SERVER=$SOCK_LOCAL
540	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
541	extract_new_packets $BUS > $outfile
542	if [ $preferred = old ]; then
543		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10000
544	else
545		# The new SA is preferred
546		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10010
547	fi
548
549	# Add another SA with a different SPI
550	add_sa $proto "$algo_args" $ip_local $ip_peer $shorttime 10020
551
552	export RUMP_SERVER=$SOCK_LOCAL
553	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
554	extract_new_packets $BUS > $outfile
555	if [ $preferred = old ]; then
556		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10000
557	else
558		# The newest SA is preferred
559		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10020
560	fi
561
562	if [ $method = delete ]; then
563		delete_sa $proto $ip_local $ip_peer 10020
564	else
565		wait_sa_disappeared 10020
566	fi
567
568	export RUMP_SERVER=$SOCK_LOCAL
569	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
570	extract_new_packets $BUS > $outfile
571	if [ $preferred = old ]; then
572		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10000
573	else
574		# The newest one is removed and the second one is used
575		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10010
576	fi
577
578	if [ $method = delete ]; then
579		delete_sa $proto $ip_local $ip_peer 10010
580	else
581		wait_sa_disappeared 10010
582	fi
583
584	export RUMP_SERVER=$SOCK_LOCAL
585	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
586	extract_new_packets $BUS > $outfile
587	if [ $preferred = old ]; then
588		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10000
589	else
590		# The second one is removed and the original one is used
591		check_packet_spi $outfile $ip_local $ip_peer $proto_cap 10000
592	fi
593}
594
595add_test_spi()
596{
597	local proto=$1
598	local algo=$2
599	local preferred=$3
600	local method=$4
601	local _algo=$(echo $algo | sed 's/-//g')
602	local name= desc=
603
604	desc="Tests SAs with different SPIs of $proto ($algo) ($preferred SA preferred) ($method)"
605	name="ipsec_spi_${proto}_${_algo}_preferred_${preferred}_${method}"
606
607	atf_test_case ${name} cleanup
608	eval "
609	    ${name}_head() {
610	        atf_set descr \"$desc\"
611	        atf_set require.progs rump_server setkey
612	    }
613	    ${name}_body() {
614	        test_spi $proto $algo $preferred $method
615	        rump_server_destroy_ifaces
616	    }
617	    ${name}_cleanup() {
618	        \$DEBUG && dump
619	        cleanup
620	    }
621	"
622	atf_add_test_case ${name}
623}
624
625setup_sp()
626{
627	local proto=$1
628	local algo_args="$2"
629	local ip_local=$3
630	local ip_peer=$4
631	local tmpfile=./tmp
632
633	export RUMP_SERVER=$SOCK_LOCAL
634	cat > $tmpfile <<-EOF
635	spdadd $ip_local $ip_peer any -P out ipsec $proto/transport//require;
636	spdadd $ip_peer $ip_local any -P in ipsec $proto/transport//require;
637	EOF
638	$DEBUG && cat $tmpfile
639	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
640	check_sp_entries $SOCK_LOCAL $ip_local $ip_peer
641
642	export RUMP_SERVER=$SOCK_PEER
643	cat > $tmpfile <<-EOF
644	spdadd $ip_peer $ip_local any -P out ipsec $proto/transport//require;
645	spdadd $ip_local $ip_peer any -P in ipsec $proto/transport//require;
646	EOF
647	$DEBUG && cat $tmpfile
648	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
649	check_sp_entries $SOCK_PEER $ip_peer $ip_local
650}
651
652test_nosa()
653{
654	local proto=$1
655	local algo=$2
656	local update=$3
657	local ip_local=10.0.0.1
658	local ip_peer=10.0.0.2
659	local algo_args="$(generate_algo_args $proto $algo)"
660	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
661	local outfile=./out
662
663	rump_server_crypto_start $SOCK_LOCAL netipsec
664	rump_server_crypto_start $SOCK_PEER netipsec
665	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
666	rump_server_add_iface $SOCK_PEER shmif0 $BUS
667
668	export RUMP_SERVER=$SOCK_LOCAL
669	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
670	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
671
672	export RUMP_SERVER=$SOCK_PEER
673	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
674	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
675
676	setup_sp $proto "$algo_args" $ip_local $ip_peer
677
678	extract_new_packets $BUS > $outfile
679
680	export RUMP_SERVER=$SOCK_LOCAL
681	# It doesn't work because there is no SA
682	atf_check -s not-exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
683}
684
685add_test_nosa()
686{
687	local proto=$1
688	local algo=$2
689	local _algo=$(echo $algo | sed 's/-//g')
690	local name= desc=
691
692	desc="Tests SPs with no relevant SAs with $proto ($algo)"
693	name="ipsec_nosa_${proto}_${_algo}"
694
695	atf_test_case ${name} cleanup
696	eval "
697	    ${name}_head() {
698	        atf_set descr \"$desc\"
699	        atf_set require.progs rump_server setkey
700	    }
701	    ${name}_body() {
702	        test_nosa $proto $algo
703	        rump_server_destroy_ifaces
704	    }
705	    ${name}_cleanup() {
706	        \$DEBUG && dump
707	        cleanup
708	    }
709	"
710	atf_add_test_case ${name}
711}
712
713test_multiple_sa()
714{
715	local proto=$1
716	local algo=$2
717	local update=$3
718	local ip_local=10.0.0.1
719	local ip_peer=10.0.0.2
720	local ip_peer2=10.0.0.3
721	local algo_args="$(generate_algo_args $proto $algo)"
722	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
723	local outfile=./out
724
725	rump_server_crypto_start $SOCK_LOCAL netipsec
726	rump_server_crypto_start $SOCK_PEER netipsec
727	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
728	rump_server_add_iface $SOCK_PEER shmif0 $BUS
729
730	export RUMP_SERVER=$SOCK_LOCAL
731	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
732	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
733
734	export RUMP_SERVER=$SOCK_PEER
735	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
736	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
737	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer2/24 alias
738
739	setup_sp $proto "$algo_args" "$ip_local" "0.0.0.0/0"
740
741	extract_new_packets $BUS > $outfile
742
743	export RUMP_SERVER=$SOCK_LOCAL
744	# There is no SA, so ping should fail
745	atf_check -s not-exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
746	atf_check -s not-exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer2
747
748	add_sa $proto "$algo_args" $ip_local $ip_peer 100 10000
749
750	export RUMP_SERVER=$SOCK_LOCAL
751	# There is only an SA for $ip_peer, so ping to $ip_peer2 should fail
752	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
753	atf_check -s not-exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer2
754
755	add_sa $proto "$algo_args" $ip_local $ip_peer2 100 10010
756
757	export RUMP_SERVER=$SOCK_LOCAL
758	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
759	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer2
760
761	export RUMP_SERVER=$SOCK_LOCAL
762	atf_check -s exit:0 -o match:"$proto/transport//require" \
763	    $HIJACKING setkey -D -P
764	# Check if the policy isn't modified accidentally
765	atf_check -s exit:0 -o not-match:"$proto/transport/.+\-.+/require" \
766	    $HIJACKING setkey -D -P
767	export RUMP_SERVER=$SOCK_PEER
768	atf_check -s exit:0 -o match:"$proto/transport//require" \
769	    $HIJACKING setkey -D -P
770	# Check if the policy isn't modified accidentally
771	atf_check -s exit:0 -o not-match:"$proto/transport/.+\-.+/require" \
772	    $HIJACKING setkey -D -P
773}
774
775add_test_multiple_sa()
776{
777	local proto=$1
778	local algo=$2
779	local _algo=$(echo $algo | sed 's/-//g')
780	local name= desc=
781
782	desc="Tests multiple SAs with $proto ($algo)"
783	name="ipsec_multiple_sa_${proto}_${_algo}"
784
785	atf_test_case ${name} cleanup
786	eval "
787	    ${name}_head() {
788	        atf_set descr \"$desc\"
789	        atf_set require.progs rump_server setkey
790	    }
791	    ${name}_body() {
792	        test_multiple_sa $proto $algo
793	        rump_server_destroy_ifaces
794	    }
795	    ${name}_cleanup() {
796	        \$DEBUG && dump
797	        cleanup
798	    }
799	"
800	atf_add_test_case ${name}
801}
802
803atf_init_test_cases()
804{
805	local algo=
806
807	for algo in $ESP_ENCRYPTION_ALGORITHMS_MINIMUM; do
808		add_test_lifetime ipv4 esp $algo
809		add_test_lifetime ipv6 esp $algo
810		add_test_update esp $algo sa
811		add_test_update esp $algo sp
812		add_test_spi esp $algo new delete
813		add_test_spi esp $algo old delete
814		add_test_spi esp $algo new timeout
815		add_test_spi esp $algo old timeout
816		add_test_nosa esp $algo
817		add_test_multiple_sa esp $algo
818	done
819	for algo in $AH_AUTHENTICATION_ALGORITHMS_MINIMUM; do
820		add_test_lifetime ipv4 ah $algo
821		add_test_lifetime ipv6 ah $algo
822		add_test_update ah $algo sa
823		add_test_update ah $algo sp
824		add_test_spi ah $algo new delete
825		add_test_spi ah $algo old delete
826		add_test_spi ah $algo new timeout
827		add_test_spi ah $algo old timeout
828		add_test_nosa ah $algo
829		add_test_multiple_sa ah $algo
830	done
831}
832