xref: /netbsd-src/tests/net/ipsec/t_ipsec_forwarding.sh (revision 708e59eb6f2c07b965ba8f065614e64ace68c843)
1#       $NetBSD: t_ipsec_forwarding.sh,v 1.2 2022/11/24 02:58:28 knakahara Exp $
2#
3# Copyright (c) 2022 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_FORWARD=unix://ipsec_forward
30SOCK_REMOTE=unix://ipsec_remote
31BUS_LOCAL_I=./bus_ipsec_local
32BUS_LOCAL_F=./bus_ipsec_local_forward
33BUS_REMOTE_F=./bus_ipsec_remote_forward
34BUS_REMOTE_I=./bus_ipsec_remote
35
36DEBUG=${DEBUG:-false}
37
38setup_servers_ipv4()
39{
40
41	rump_server_crypto_start $SOCK_LOCAL netipsec
42	rump_server_crypto_start $SOCK_FORWARD netipsec
43	rump_server_crypto_start $SOCK_REMOTE netipsec
44	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL_F
45	rump_server_add_iface $SOCK_LOCAL shmif1 $BUS_LOCAL_I
46	rump_server_add_iface $SOCK_FORWARD shmif0 $BUS_LOCAL_F
47	rump_server_add_iface $SOCK_FORWARD shmif1 $BUS_REMOTE_F
48	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE_F
49	rump_server_add_iface $SOCK_REMOTE shmif1 $BUS_REMOTE_I
50}
51
52setup_servers_ipv6()
53{
54
55	rump_server_crypto_start $SOCK_LOCAL netipsec netinet6
56	rump_server_crypto_start $SOCK_FORWARD netipsec netinet6
57	rump_server_crypto_start $SOCK_REMOTE netipsec netinet6
58	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL_F
59	rump_server_add_iface $SOCK_LOCAL shmif1 $BUS_LOCAL_I
60	rump_server_add_iface $SOCK_FORWARD shmif0 $BUS_LOCAL_F
61	rump_server_add_iface $SOCK_FORWARD shmif1 $BUS_REMOTE_F
62	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE_F
63	rump_server_add_iface $SOCK_REMOTE shmif1 $BUS_REMOTE_I
64}
65
66setup_servers()
67{
68	local proto=$1
69
70	setup_servers_$proto
71}
72
73setup_sp_port()
74{
75	local proto=$1
76	local algo_args="$2"
77	local tunnel_src=$3
78	local tunnel_dst=$4
79	local subnet_src=$5
80	local subnet_dst=$6
81	local port_src=$7
82	local port_dst=$8
83	local tmpfile=./tmp
84
85	export RUMP_SERVER=$SOCK_LOCAL
86	cat > $tmpfile <<-EOF
87	spdadd $subnet_src[$port_src] $subnet_dst[$port_dst] tcp -P out ipsec $proto/tunnel/$tunnel_src-$tunnel_dst/require;
88	spdadd $subnet_dst[$port_dst] $subnet_src[$port_src] tcp -P in ipsec $proto/tunnel/$tunnel_dst-$tunnel_src/require;
89	EOF
90	$DEBUG && cat $tmpfile
91	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
92	$DEBUG && $HIJACKING setkey -DP
93
94	export RUMP_SERVER=$SOCK_FORWARD
95	cat > $tmpfile <<-EOF
96	spdadd $subnet_dst[$port_dst] $subnet_src[$port_src] tcp -P out ipsec $proto/tunnel/$tunnel_dst-$tunnel_src/require;
97	spdadd $subnet_src[$port_src] $subnet_dst[$port_dst] tcp -P in ipsec $proto/tunnel/$tunnel_src-$tunnel_dst/require;
98	EOF
99	$DEBUG && cat $tmpfile
100	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
101	$DEBUG && $HIJACKING setkey -DP
102}
103
104add_sa()
105{
106	local proto=$1
107	local algo_args="$2"
108	local tunnel_src=$3
109	local tunnel_dst=$4
110	local spi=$5
111	local port_src=$6
112	local port_dst=$7
113	local tmpfile=./tmp
114
115	export RUMP_SERVER=$SOCK_LOCAL
116	cat > $tmpfile <<-EOF
117	add $tunnel_src [$port_src] $tunnel_dst [$port_dst] $proto $((spi)) $algo_args;
118	add $tunnel_dst [$port_dst] $tunnel_src [$port_src] $proto $((spi + 1)) $algo_args;
119	EOF
120	$DEBUG && cat $tmpfile
121	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
122	$DEBUG && $HIJACKING setkey -D
123	# XXX it can be expired if $lifetime is very short
124	#check_sa_entries $SOCK_LOCAL $ip_local $ip_remote
125
126	export RUMP_SERVER=$SOCK_FORWARD
127	cat > $tmpfile <<-EOF
128	add $tunnel_src [$port_src] $tunnel_dst [$port_dst] $proto $((spi)) $algo_args;
129	add $tunnel_dst [$port_dst] $tunnel_src [$port_src] $proto $((spi + 1)) $algo_args;
130	EOF
131	$DEBUG && cat $tmpfile
132	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
133	$DEBUG && $HIJACKING setkey -D
134}
135
136prepare_file()
137{
138	local file=$1
139	local data="0123456789"
140
141	touch $file
142	for i in `seq 1 512`
143	do
144		echo $data >> $file
145	done
146}
147
148test_ipsec_sp_port_ipv4()
149{
150
151	local algo=$1
152	local ip_local_i=192.168.11.1
153	local ip_local_i_subnet=192.168.11.0/24
154	local ip_local_f=10.22.22.2
155	local ip_local_f_subnet=10.22.22.0/24
156	local ip_forward_l=10.22.22.1
157	local ip_forward_l_subnet=10.22.22.0/24
158	local ip_forward_r=10.33.33.1
159	local ip_forward_r_subnet=10.33.33.0/24
160	local ip_remote_f=10.33.33.2
161	local ip_remote_f_subnet=10.33.33.0/24
162	local ip_remote_i=192.168.44.1
163	local ip_remote_i_subnet=192.168.44.0/24
164	local port=1234
165	local loutfile=./out_local
166	local routfile=./out_remote
167	local file_send=./file.send
168	local file_recv=./file.recv
169	local algo_args="$(generate_algo_args esp $algo)"
170	local pid=
171
172	setup_servers ipv4
173
174	export RUMP_SERVER=$SOCK_LOCAL
175	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
176	atf_check -s exit:0 rump.ifconfig shmif0 inet $ip_local_f/24
177	atf_check -s exit:0 rump.ifconfig shmif1 inet $ip_local_i/24
178	atf_check -s exit:0 -o ignore \
179	    rump.route add -inet default $ip_forward_l
180
181	export RUMP_SERVER=$SOCK_FORWARD
182	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
183	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
184	atf_check -s exit:0 rump.ifconfig shmif0 inet $ip_forward_l/24
185	atf_check -s exit:0 rump.ifconfig shmif1 inet $ip_forward_r/24
186	atf_check -s exit:0 -o ignore \
187	    rump.route add -inet $ip_local_i_subnet $ip_local_f
188	atf_check -s exit:0 -o ignore \
189	    rump.route add -inet $ip_remote_i_subnet $ip_remote_f
190
191	export RUMP_SERVER=$SOCK_REMOTE
192	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
193	atf_check -s exit:0 rump.ifconfig shmif0 inet $ip_remote_f/24
194	atf_check -s exit:0 rump.ifconfig shmif1 inet $ip_remote_i/24
195	atf_check -s exit:0 -o ignore \
196	    rump.route add -inet default $ip_forward_r
197
198	extract_new_packets $BUS_LOCAL_F > $loutfile
199	extract_new_packets $BUS_REMOTE_F > $routfile
200
201	export RUMP_SERVER=$SOCK_LOCAL
202	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 -I $ip_local_i \
203		  $ip_remote_i
204
205	extract_new_packets $BUS_LOCAL_F > $loutfile
206	extract_new_packets $BUS_REMOTE_F > $routfile
207	$DEBUG && cat $loutfile
208	atf_check -s exit:0 \
209	    -o match:"$ip_local_i > $ip_remote_i: ICMP echo request" \
210	    cat $loutfile
211	atf_check -s exit:0 \
212	    -o match:"$ip_remote_i > $ip_local_i: ICMP echo reply" \
213	    cat $loutfile
214	$DEBUG && cat $routfile
215	atf_check -s exit:0 \
216	    -o match:"$ip_local_i > $ip_remote_i: ICMP echo request" \
217	    cat $routfile
218	atf_check -s exit:0 \
219	    -o match:"$ip_remote_i > $ip_local_i: ICMP echo reply" \
220	    cat $routfile
221
222	# Try TCP communications just in case
223	start_nc_server $SOCK_REMOTE $port $file_recv ipv4
224	prepare_file $file_send
225	export RUMP_SERVER=$SOCK_LOCAL
226	atf_check -s exit:0 $HIJACKING nc -w 7 -s $ip_local_i \
227		  $ip_remote_i $port < $file_send
228	atf_check -s exit:0 diff -q $file_send $file_recv
229	stop_nc_server
230
231	extract_new_packets $BUS_LOCAL_F > $loutfile
232	extract_new_packets $BUS_REMOTE_F > $routfile
233	$DEBUG && cat $loutfile
234	atf_check -s exit:0 \
235	    -o match:"${ip_local_i}\.[0-9]+ > ${ip_remote_i}\.$port" \
236	    cat $loutfile
237	atf_check -s exit:0 \
238	    -o match:"${ip_remote_i}\.$port > ${ip_local_i}\.[0-9]+" \
239	    cat $loutfile
240	$DEBUG && cat $routfile
241	atf_check -s exit:0 \
242	    -o match:"${ip_local_i}\.[0-9]+ > ${ip_remote_i}\.$port" \
243	    cat $routfile
244	atf_check -s exit:0 \
245	    -o match:"${ip_remote_i}\.$port > ${ip_local_i}\.[0-9]+" \
246	    cat $routfile
247
248	# Create IPsec connections
249	setup_sp_port esp "$algo_args" $ip_local_i $ip_forward_r \
250		      $ip_local_i_subnet $ip_remote_i_subnet any $port
251	add_sa esp "$algo_args" $ip_local_i $ip_forward_r \
252	       10000 any $port
253
254	extract_new_packets $BUS_LOCAL_F > $loutfile
255	extract_new_packets $BUS_REMOTE_F > $routfile
256
257	export RUMP_SERVER=$SOCK_LOCAL
258	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 -I $ip_local_i \
259		  $ip_remote_i
260
261	extract_new_packets $BUS_LOCAL_F > $loutfile
262	extract_new_packets $BUS_REMOTE_F > $routfile
263	$DEBUG && cat $loutfile
264	atf_check -s exit:0 \
265	    -o match:"$ip_local_i > $ip_remote_i: ICMP echo request" \
266	    cat $loutfile
267	atf_check -s exit:0 \
268	    -o match:"$ip_remote_i > $ip_local_i: ICMP echo reply" \
269	    cat $loutfile
270	$DEBUG && cat $routfile
271	atf_check -s exit:0 \
272	    -o match:"$ip_local_i > $ip_remote_i: ICMP echo request" \
273	    cat $routfile
274	atf_check -s exit:0 \
275	    -o match:"$ip_remote_i > $ip_local_i: ICMP echo reply" \
276	    cat $routfile
277
278	# Check TCP communications from local to remote
279	start_nc_server $SOCK_REMOTE $port $file_recv ipv4
280	prepare_file $file_send
281	export RUMP_SERVER=$SOCK_LOCAL
282	atf_check -s exit:0 $HIJACKING nc -w 15 -s $ip_local_i \
283		  $ip_remote_i $port < $file_send
284	atf_check -s exit:0 diff -q $file_send $file_recv
285	stop_nc_server
286
287	extract_new_packets $BUS_LOCAL_F > $loutfile
288	extract_new_packets $BUS_REMOTE_F > $routfile
289	$DEBUG && cat $loutfile
290	atf_check -s exit:0 \
291	    -o match:"${ip_local_i} > ${ip_forward_r}: ESP" \
292	    cat $loutfile
293	atf_check -s exit:0 \
294	    -o match:"${ip_forward_r} > ${ip_local_i}: ESP" \
295	    cat $loutfile
296	$DEBUG && cat $routfile
297	atf_check -s exit:0 \
298	    -o match:"${ip_local_i}\.[0-9]+ > ${ip_remote_i}\.$port" \
299	    cat $routfile
300	atf_check -s exit:0 \
301	    -o match:"${ip_remote_i}\.$port > ${ip_local_i}\.[0-9]+" \
302	    cat $routfile
303}
304
305test_ipsec_sp_port_ipv6()
306{
307	local algo=$1
308	local ip_local_i=fc00:1111::1
309	local ip_local_i_subnet=fc00:1111::/64
310	local ip_local_f=fc00:2222::2
311	local ip_local_f_subnet=fc00:2222::/64
312	local ip_forward_l=fc00:2222::1
313	local ip_forward_l_subnet=fc00:2222::/64
314	local ip_forward_r=fc00:3333::1
315	local ip_forward_r_subnet=fc00:3333::/64
316	local ip_remote_f=fc00:3333::2
317	local ip_remote_f_subnet=fc00:3333::/64
318	local ip_remote_i=fc00:4444::1
319	local ip_remote_i_subnet=fc00:4444::/64
320	local port=1234
321	local loutfile=./out_local
322	local routfile=./out_remote
323	local file_send=./file.send
324	local file_recv=./file.recv
325	local algo_args="$(generate_algo_args esp $algo)"
326	local pid=
327
328	setup_servers ipv6
329
330	export RUMP_SERVER=$SOCK_LOCAL
331	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
332	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local_f/64
333	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_local_i/64
334	atf_check -s exit:0 -o ignore \
335	    rump.route add -inet6 default $ip_forward_l
336
337	export RUMP_SERVER=$SOCK_FORWARD
338	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
339	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
340	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_forward_l/64
341	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_forward_r/64
342	atf_check -s exit:0 -o ignore \
343	    rump.route add -inet6 $ip_local_i_subnet $ip_local_f
344	atf_check -s exit:0 -o ignore \
345	    rump.route add -inet6 $ip_remote_i_subnet $ip_remote_f
346
347	export RUMP_SERVER=$SOCK_REMOTE
348	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
349	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_remote_f/64
350	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_remote_i/64
351	atf_check -s exit:0 -o ignore \
352	    rump.route add -inet6 default $ip_forward_r
353
354	extract_new_packets $BUS_LOCAL_F > $loutfile
355	extract_new_packets $BUS_REMOTE_F > $routfile
356
357	export RUMP_SERVER=$SOCK_LOCAL
358	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 -S $ip_local_i \
359		  $ip_remote_i
360
361	extract_new_packets $BUS_LOCAL_F > $loutfile
362	extract_new_packets $BUS_REMOTE_F > $routfile
363	$DEBUG && cat $loutfile
364	atf_check -s exit:0 \
365	    -o match:"$ip_local_i > $ip_remote_i: ICMP6, echo request" \
366	    cat $loutfile
367	atf_check -s exit:0 \
368	    -o match:"$ip_remote_i > $ip_local_i: ICMP6, echo reply" \
369	    cat $loutfile
370	$DEBUG && cat $routfile
371	atf_check -s exit:0 \
372	    -o match:"$ip_local_i > $ip_remote_i: ICMP6, echo request" \
373	    cat $routfile
374	atf_check -s exit:0 \
375	    -o match:"$ip_remote_i > $ip_local_i: ICMP6, echo reply" \
376	    cat $routfile
377
378	# Try TCP communications just in case
379	start_nc_server $SOCK_REMOTE $port $file_recv ipv6
380	prepare_file $file_send
381	export RUMP_SERVER=$SOCK_LOCAL
382	atf_check -s exit:0 $HIJACKING nc -w 7 -s $ip_local_i \
383		  $ip_remote_i $port < $file_send
384	atf_check -s exit:0 diff -q $file_send $file_recv
385	stop_nc_server
386
387	extract_new_packets $BUS_LOCAL_F > $loutfile
388	extract_new_packets $BUS_REMOTE_F > $routfile
389	$DEBUG && cat $loutfile
390	atf_check -s exit:0 \
391	    -o match:"${ip_local_i}\.[0-9]+ > ${ip_remote_i}\.$port" \
392	    cat $loutfile
393	atf_check -s exit:0 \
394	    -o match:"${ip_remote_i}\.$port > ${ip_local_i}\.[0-9]+" \
395	    cat $loutfile
396	$DEBUG && cat $routfile
397	atf_check -s exit:0 \
398	    -o match:"${ip_local_i}\.[0-9]+ > ${ip_remote_i}\.$port" \
399	    cat $routfile
400	atf_check -s exit:0 \
401	    -o match:"${ip_remote_i}\.$port > ${ip_local_i}\.[0-9]+" \
402	    cat $routfile
403
404	# Create IPsec connections
405	setup_sp_port esp "$algo_args" $ip_local_i $ip_forward_r \
406		      $ip_local_i_subnet $ip_remote_i_subnet any $port
407	add_sa esp "$algo_args" $ip_local_i $ip_forward_r \
408	       10000 any $port
409
410	extract_new_packets $BUS_LOCAL_F > $loutfile
411	extract_new_packets $BUS_REMOTE_F > $routfile
412
413	export RUMP_SERVER=$SOCK_LOCAL
414	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 -S $ip_local_i \
415		  $ip_remote_i
416
417	extract_new_packets $BUS_LOCAL_F > $loutfile
418	extract_new_packets $BUS_REMOTE_F > $routfile
419	$DEBUG && cat $loutfile
420	atf_check -s exit:0 \
421	    -o match:"$ip_local_i > $ip_remote_i: ICMP6, echo request" \
422	    cat $loutfile
423	atf_check -s exit:0 \
424	    -o match:"$ip_remote_i > $ip_local_i: ICMP6, echo reply" \
425	    cat $loutfile
426	$DEBUG && cat $routfile
427	atf_check -s exit:0 \
428	    -o match:"$ip_local_i > $ip_remote_i: ICMP6, echo request" \
429	    cat $routfile
430	atf_check -s exit:0 \
431	    -o match:"$ip_remote_i > $ip_local_i: ICMP6, echo reply" \
432	    cat $routfile
433
434	# Check TCP communications from local to remote
435	start_nc_server $SOCK_REMOTE $port $file_recv ipv6
436	prepare_file $file_send
437	export RUMP_SERVER=$SOCK_LOCAL
438	atf_check -s exit:0 $HIJACKING nc -w 7 -s $ip_local_i \
439		  $ip_remote_i $port < $file_send
440	atf_check -s exit:0 diff -q $file_send $file_recv
441	stop_nc_server
442
443	extract_new_packets $BUS_LOCAL_F > $loutfile
444	extract_new_packets $BUS_REMOTE_F > $routfile
445	$DEBUG && cat $loutfile
446	atf_check -s exit:0 \
447	    -o match:"${ip_local_i} > ${ip_forward_r}: ESP" \
448	    cat $loutfile
449	atf_check -s exit:0 \
450	    -o match:"${ip_forward_r} > ${ip_local_i}: ESP" \
451	    cat $loutfile
452	$DEBUG && cat $routfile
453	atf_check -s exit:0 \
454	    -o match:"${ip_local_i}\.[0-9]+ > ${ip_remote_i}\.$port" \
455	    cat $routfile
456	atf_check -s exit:0 \
457	    -o match:"${ip_remote_i}\.$port > ${ip_local_i}\.[0-9]+" \
458	    cat $routfile
459}
460
461add_test_ipsec_sp_port()
462{
463	local proto=$1
464	local algo=$2
465	local _algo=$(echo $algo | sed 's/-//g')
466	local name= desc=
467
468	desc="Test IPsec $proto forwarding SP port ($algo)"
469	name="ipsec_sp_port_${proto}_${_algo}"
470
471	atf_test_case ${name} cleanup
472	eval "
473	    ${name}_head() {
474	        atf_set descr \"$desc\"
475	        atf_set require.progs rump_server setkey nc
476	    }
477	    ${name}_body() {
478	        test_ipsec_sp_port_$proto $algo
479	        rump_server_destroy_ifaces
480	    }
481	    ${name}_cleanup() {
482	    	stop_nc_server
483	        \$DEBUG && dump
484	        cleanup
485	    }
486	"
487	atf_add_test_case ${name}
488}
489
490atf_init_test_cases()
491{
492	local algo=
493
494	for algo in $ESP_ENCRYPTION_ALGORITHMS_MINIMUM; do
495		add_test_ipsec_sp_port ipv4 $algo
496		add_test_ipsec_sp_port ipv6 $algo
497	done
498}
499