1#	$NetBSD: t_ipsec_tunnel_odd.sh,v 1.5 2023/06/19 08:28:09 knakahara 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_TUNNEL_LOCAL=unix://ipsec_tunel_local
30SOCK_TUNNEL_REMOTE=unix://ipsec_tunnel_remote
31SOCK_REMOTE=unix://ipsec_remote
32BUS_LOCAL=./bus_ipsec_local
33BUS_TUNNEL=./bus_ipsec_tunnel
34BUS_REMOTE=./bus_ipsec_remote
35
36DEBUG=${DEBUG:-false}
37
38setup_servers()
39{
40
41	# See https://www.netbsd.org/docs/network/ipsec/#sample_vpn
42	rump_server_crypto_start $SOCK_LOCAL netinet6
43	rump_server_crypto_start $SOCK_TUNNEL_LOCAL netipsec netinet6
44	rump_server_crypto_start $SOCK_TUNNEL_REMOTE netipsec netinet6
45	rump_server_crypto_start $SOCK_REMOTE netinet6
46	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL
47	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif0 $BUS_LOCAL
48	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif1 $BUS_TUNNEL
49	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif0 $BUS_REMOTE
50	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif1 $BUS_TUNNEL
51	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE
52}
53
54check_tunnel_packets()
55{
56	local outfile=$1
57	local src=$2
58	local dst=$3
59	local proto=$4
60
61	atf_check -s exit:0 -o match:"$src > $dst: $proto" cat $outfile
62	atf_check -s exit:0 -o match:"$dst > $src: $proto" cat $outfile
63}
64
65test_ipsec46_tunnel()
66{
67	local proto=$1
68	local algo=$2
69	local ip_local=10.0.1.2
70	local ip_gw_local=10.0.1.1
71	local ip_gw_local_tunnel=20.0.0.1
72	local ip_gw_remote_tunnel=20.0.0.2
73	local ip6_gw_local_tunnel=fc00::1
74	local ip6_gw_remote_tunnel=fc00::2
75	local ip_gw_remote=10.0.2.1
76	local ip_remote=10.0.2.2
77	local subnet_local=10.0.1.0
78	local subnet_remote=10.0.2.0
79	local tmpfile=./tmp
80	local outfile=./out
81	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
82	local algo_args="$(generate_algo_args $proto $algo)"
83
84	setup_servers
85
86	export RUMP_SERVER=$SOCK_LOCAL
87	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
88	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
89	atf_check -s exit:0 -o ignore \
90	    rump.route -n add -net $subnet_remote $ip_gw_local
91
92	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
93	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
94	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
95	atf_check -s exit:0 rump.ifconfig shmif0 $ip_gw_local/24
96	atf_check -s exit:0 rump.ifconfig shmif1 $ip_gw_local_tunnel/24
97	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip6_gw_local_tunnel/24
98	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
99	atf_check -s exit:0 -o ignore \
100	    rump.route -n add -net $subnet_remote $ip_gw_remote_tunnel
101
102	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
103	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
104	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
105	atf_check -s exit:0 rump.ifconfig shmif0 $ip_gw_remote/24
106	atf_check -s exit:0 rump.ifconfig shmif1 $ip_gw_remote_tunnel/24
107	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip6_gw_remote_tunnel/24
108	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
109	atf_check -s exit:0 -o ignore \
110	    rump.route -n add -net $subnet_local $ip_gw_local_tunnel
111
112	export RUMP_SERVER=$SOCK_REMOTE
113	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
114	atf_check -s exit:0 rump.ifconfig shmif0 $ip_remote/24
115	atf_check -s exit:0 -o ignore \
116	    rump.route -n add -net $subnet_local $ip_gw_remote
117
118	extract_new_packets $BUS_TUNNEL > $outfile
119
120	export RUMP_SERVER=$SOCK_LOCAL
121	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_remote
122
123	extract_new_packets $BUS_TUNNEL > $outfile
124	atf_check -s exit:0 \
125	    -o match:"$ip_local > $ip_remote: ICMP echo request" \
126	    cat $outfile
127	atf_check -s exit:0 \
128	    -o match:"$ip_remote > $ip_local: ICMP echo reply" \
129	    cat $outfile
130
131	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
132	# from https://www.netbsd.org/docs/network/ipsec/
133	cat > $tmpfile <<-EOF
134	add $ip6_gw_local_tunnel $ip6_gw_remote_tunnel $proto 10000 $algo_args;
135	add $ip6_gw_remote_tunnel $ip6_gw_local_tunnel $proto 10001 $algo_args;
136	spdadd $subnet_local/24 $subnet_remote/24 any -P out ipsec
137	    $proto/tunnel/$ip6_gw_local_tunnel-$ip6_gw_remote_tunnel/require;
138	spdadd $subnet_remote/24 $subnet_local/24 any -P in ipsec
139	    $proto/tunnel/$ip6_gw_remote_tunnel-$ip6_gw_local_tunnel/require;
140	EOF
141	$DEBUG && cat $tmpfile
142	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
143	check_sa_entries $SOCK_TUNNEL_LOCAL $ip6_gw_local_tunnel \
144	    $ip6_gw_remote_tunnel
145
146	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
147	cat > $tmpfile <<-EOF
148	add $ip6_gw_local_tunnel $ip6_gw_remote_tunnel $proto 10000 $algo_args;
149	add $ip6_gw_remote_tunnel $ip6_gw_local_tunnel $proto 10001 $algo_args;
150	spdadd $subnet_remote/24 $subnet_local/24 any -P out ipsec
151	    $proto/tunnel/$ip6_gw_remote_tunnel-$ip6_gw_local_tunnel/require;
152	spdadd $subnet_local/24 $subnet_remote/24 any -P in ipsec
153	    $proto/tunnel/$ip6_gw_local_tunnel-$ip6_gw_remote_tunnel/require;
154	EOF
155	$DEBUG && cat $tmpfile
156	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
157	check_sa_entries $SOCK_TUNNEL_REMOTE $ip6_gw_local_tunnel \
158	    $ip6_gw_remote_tunnel
159
160	export RUMP_SERVER=$SOCK_LOCAL
161	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_remote
162
163	extract_new_packets $BUS_TUNNEL > $outfile
164	check_tunnel_packets $outfile $ip6_gw_local_tunnel $ip6_gw_remote_tunnel \
165	    $proto_cap
166
167	test_flush_entries $SOCK_TUNNEL_LOCAL
168	test_flush_entries $SOCK_TUNNEL_REMOTE
169}
170
171test_ipsec64_tunnel()
172{
173	local proto=$1
174	local algo=$2
175	local ip_local=fd00:1::2
176	local ip_gw_local=fd00:1::1
177	local ip_gw_local_tunnel=fc00::1
178	local ip_gw_remote_tunnel=fc00::2
179	local ip4_gw_local_tunnel=20.0.0.1
180	local ip4_gw_remote_tunnel=20.0.0.2
181	local ip_gw_remote=fd00:2::1
182	local ip_remote=fd00:2::2
183	local subnet_local=fd00:1::
184	local subnet_remote=fd00:2::
185	local tmpfile=./tmp
186	local outfile=./out
187	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
188	local algo_args="$(generate_algo_args $proto $algo)"
189
190	setup_servers
191
192	export RUMP_SERVER=$SOCK_LOCAL
193	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
194	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local/64
195	atf_check -s exit:0 -o ignore \
196	    rump.route -n add -inet6 -net $subnet_remote/64 $ip_gw_local
197
198	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
199	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
200	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
201	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_gw_local/64
202	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_gw_local_tunnel/64
203	atf_check -s exit:0 rump.ifconfig shmif1 $ip4_gw_local_tunnel
204	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
205	atf_check -s exit:0 -o ignore \
206	    rump.route -n add -inet6 -net $subnet_remote/64 $ip_gw_remote_tunnel
207
208	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
209	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
210	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
211	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_gw_remote/64
212	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_gw_remote_tunnel/64
213	atf_check -s exit:0 rump.ifconfig shmif1 $ip4_gw_remote_tunnel
214	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
215	atf_check -s exit:0 -o ignore \
216	    rump.route -n add -inet6 -net $subnet_local/64 $ip_gw_local_tunnel
217
218	export RUMP_SERVER=$SOCK_REMOTE
219	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0
220	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_remote
221	atf_check -s exit:0 -o ignore \
222	    rump.route -n add -inet6 -net $subnet_local/64 $ip_gw_remote
223
224	extract_new_packets $BUS_TUNNEL > $outfile
225
226	export RUMP_SERVER=$SOCK_LOCAL
227	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_remote
228
229	extract_new_packets $BUS_TUNNEL > $outfile
230	atf_check -s exit:0 \
231	    -o match:"$ip_local > $ip_remote: ICMP6, echo request" \
232	    cat $outfile
233	atf_check -s exit:0 \
234	    -o match:"$ip_remote > $ip_local: ICMP6, echo reply" \
235	    cat $outfile
236
237	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
238	# from https://www.netbsd.org/docs/network/ipsec/
239	cat > $tmpfile <<-EOF
240	add $ip4_gw_local_tunnel $ip4_gw_remote_tunnel $proto 10000 $algo_args;
241	add $ip4_gw_remote_tunnel $ip4_gw_local_tunnel $proto 10001 $algo_args;
242	spdadd $subnet_local/64 $subnet_remote/64 any -P out ipsec
243	    $proto/tunnel/$ip4_gw_local_tunnel-$ip4_gw_remote_tunnel/require;
244	spdadd $subnet_remote/64 $subnet_local/64 any -P in ipsec
245	    $proto/tunnel/$ip4_gw_remote_tunnel-$ip4_gw_local_tunnel/require;
246	EOF
247	$DEBUG && cat $tmpfile
248	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
249	check_sa_entries $SOCK_TUNNEL_LOCAL $ip4_gw_local_tunnel \
250	    $ip4_gw_remote_tunnel
251
252	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
253	cat > $tmpfile <<-EOF
254	add $ip4_gw_local_tunnel $ip4_gw_remote_tunnel $proto 10000 $algo_args;
255	add $ip4_gw_remote_tunnel $ip4_gw_local_tunnel $proto 10001 $algo_args;
256	spdadd $subnet_remote/64 $subnet_local/64 any -P out ipsec
257	    $proto/tunnel/$ip4_gw_remote_tunnel-$ip4_gw_local_tunnel/require;
258	spdadd $subnet_local/64 $subnet_remote/64 any -P in ipsec
259	    $proto/tunnel/$ip4_gw_local_tunnel-$ip4_gw_remote_tunnel/require;
260	EOF
261	$DEBUG && cat $tmpfile
262	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
263	check_sa_entries $SOCK_TUNNEL_REMOTE $ip4_gw_local_tunnel \
264	    $ip4_gw_remote_tunnel
265
266	export RUMP_SERVER=$SOCK_LOCAL
267	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_remote
268
269	extract_new_packets $BUS_TUNNEL > $outfile
270	check_tunnel_packets $outfile $ip4_gw_local_tunnel $ip4_gw_remote_tunnel \
271	    $proto_cap
272
273	test_flush_entries $SOCK_TUNNEL_LOCAL
274	test_flush_entries $SOCK_TUNNEL_REMOTE
275}
276
277test_tunnel_common()
278{
279	local ipproto=$1
280	local proto=$2
281	local algo=$3
282
283	if [ $ipproto = v4v6 ]; then
284		test_ipsec46_tunnel $proto $algo
285	else
286		test_ipsec64_tunnel $proto $algo
287	fi
288}
289
290add_test_tunnel_mode()
291{
292	local ipproto=$1
293	local proto=$2
294	local algo=$3
295	local _algo=$(echo $algo | sed 's/-//g')
296	local name= desc=
297
298	name="ipsec_tunnel_${ipproto}_${proto}_${_algo}"
299	if [ $ipproto = v4v6 ]; then
300		desc="Tests of IPsec tunnel mode (IPv4 over IPv6) with $proto ($algo)"
301	else
302		desc="Tests of IPsec tunnel mode (IPv6 over IPv4) with $proto ($algo)"
303	fi
304
305	atf_test_case ${name} cleanup
306	eval "
307	    ${name}_head() {
308	        atf_set descr \"$desc\"
309	        atf_set require.progs rump_server setkey
310	    }
311	    ${name}_body() {
312	        test_tunnel_common $ipproto $proto $algo
313	        rump_server_destroy_ifaces
314	    }
315	    ${name}_cleanup() {
316	        \$DEBUG && dump
317	        cleanup
318	    }
319	"
320	atf_add_test_case ${name}
321}
322
323atf_init_test_cases()
324{
325	local algo=
326
327	for algo in $ESP_ENCRYPTION_ALGORITHMS; do
328		add_test_tunnel_mode v4v6 esp $algo
329		add_test_tunnel_mode v6v4 esp $algo
330	done
331
332	for algo in $AH_AUTHENTICATION_ALGORITHMS; do
333		add_test_tunnel_mode v4v6 ah $algo
334		add_test_tunnel_mode v6v4 ah $algo
335	done
336}
337