Module Name:    src
Committed By:   ozaki-r
Date:           Fri Apr 14 02:56:49 UTC 2017

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/etc/mtree: NetBSD.dist.tests
        src/tests/net: Makefile net_common.sh
Added Files:
        src/tests/net/ipsec: Makefile algorithms.sh t_ipsec_ah_keys.sh
            t_ipsec_esp_keys.sh t_ipsec_sysctl.sh t_ipsec_transport.sh
            t_ipsec_tunnel.sh

Log Message:
Add tests for ipsec

- Check if setkey correctly handles algorithms for AH/ESP
- Check IPsec of transport mode with AH/ESP over IPv4/IPv6
- Check IPsec of tunnel mode with AH/ESP over IPv4/IPv6


To generate a diff of this commit:
cvs rdiff -u -r1.733 -r1.734 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.144 -r1.145 src/etc/mtree/NetBSD.dist.tests
cvs rdiff -u -r1.31 -r1.32 src/tests/net/Makefile
cvs rdiff -u -r1.14 -r1.15 src/tests/net/net_common.sh
cvs rdiff -u -r0 -r1.1 src/tests/net/ipsec/Makefile \
    src/tests/net/ipsec/algorithms.sh src/tests/net/ipsec/t_ipsec_ah_keys.sh \
    src/tests/net/ipsec/t_ipsec_esp_keys.sh \
    src/tests/net/ipsec/t_ipsec_sysctl.sh \
    src/tests/net/ipsec/t_ipsec_transport.sh \
    src/tests/net/ipsec/t_ipsec_tunnel.sh

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.733 src/distrib/sets/lists/tests/mi:1.734
--- src/distrib/sets/lists/tests/mi:1.733	Mon Apr  3 05:06:28 2017
+++ src/distrib/sets/lists/tests/mi	Fri Apr 14 02:56:48 2017
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.733 2017/04/03 05:06:28 kamil Exp $
+# $NetBSD: mi,v 1.734 2017/04/14 02:56:48 ozaki-r Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -3293,6 +3293,14 @@
 ./usr/tests/net/in_cksum/Kyuafile		tests-net-tests		compattestfile,atf,kyua
 ./usr/tests/net/in_cksum/in_cksum		tests-net-tests		compattestfile,atf
 ./usr/tests/net/in_cksum/t_in_cksum		tests-net-tests		compattestfile,atf
+./usr/tests/net/ipsec				tests-net-tests		compattestfile,atf
+./usr/tests/net/ipsec/Atffile			tests-net-tests		atf,rump
+./usr/tests/net/ipsec/Kyuafile			tests-net-tests		atf,rump,kyua
+./usr/tests/net/ipsec/t_ipsec_ah_keys		tests-net-tests		atf,rump
+./usr/tests/net/ipsec/t_ipsec_esp_keys		tests-net-tests		atf,rump
+./usr/tests/net/ipsec/t_ipsec_sysctl		tests-net-tests		atf,rump
+./usr/tests/net/ipsec/t_ipsec_transport		tests-net-tests		atf,rump
+./usr/tests/net/ipsec/t_ipsec_tunnel		tests-net-tests		atf,rump
 ./usr/tests/net/mcast				tests-net-tests		compattestfile,atf
 ./usr/tests/net/mcast/Atffile			tests-net-tests		atf,rump
 ./usr/tests/net/mcast/Kyuafile			tests-net-tests		atf,rump,kyua

Index: src/etc/mtree/NetBSD.dist.tests
diff -u src/etc/mtree/NetBSD.dist.tests:1.144 src/etc/mtree/NetBSD.dist.tests:1.145
--- src/etc/mtree/NetBSD.dist.tests:1.144	Mon Apr  3 04:33:32 2017
+++ src/etc/mtree/NetBSD.dist.tests	Fri Apr 14 02:56:48 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: NetBSD.dist.tests,v 1.144 2017/04/03 04:33:32 kamil Exp $
+#	$NetBSD: NetBSD.dist.tests,v 1.145 2017/04/14 02:56:48 ozaki-r Exp $
 
 ./usr/libdata/debug/usr/tests
 ./usr/libdata/debug/usr/tests/atf
@@ -338,6 +338,7 @@
 ./usr/tests/net/if_tun
 ./usr/tests/net/if_vlan
 ./usr/tests/net/in_cksum
+./usr/tests/net/ipsec
 ./usr/tests/net/mcast
 ./usr/tests/net/mpls
 ./usr/tests/net/net

Index: src/tests/net/Makefile
diff -u src/tests/net/Makefile:1.31 src/tests/net/Makefile:1.32
--- src/tests/net/Makefile:1.31	Thu Feb 16 08:44:47 2017
+++ src/tests/net/Makefile	Fri Apr 14 02:56:48 2017
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.31 2017/02/16 08:44:47 knakahara Exp $
+# $NetBSD: Makefile,v 1.32 2017/04/14 02:56:48 ozaki-r Exp $
 
 .include <bsd.own.mk>
 
@@ -7,8 +7,8 @@ TESTSDIR=	${TESTSBASE}/net
 TESTS_SUBDIRS=		fdpass in_cksum net sys
 .if (${MKRUMP} != "no") && !defined(BSD_MK_COMPAT_FILE)
 TESTS_SUBDIRS+=		arp bpf bpfilter carp icmp if if_bridge if_gif if_l2tp
-TESTS_SUBDIRS+=		 if_loop if_pppoe if_tap if_tun mcast mpls ndp npf route
-TESTS_SUBDIRS+=		 if_vlan
+TESTS_SUBDIRS+=		 if_loop if_pppoe if_tap if_tun ipsec mcast mpls ndp npf
+TESTS_SUBDIRS+=		 route if_vlan
 .if (${MKSLJIT} != "no")
 TESTS_SUBDIRS+=		bpfjit
 .endif

Index: src/tests/net/net_common.sh
diff -u src/tests/net/net_common.sh:1.14 src/tests/net/net_common.sh:1.15
--- src/tests/net/net_common.sh:1.14	Mon Mar  6 07:15:47 2017
+++ src/tests/net/net_common.sh	Fri Apr 14 02:56:48 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: net_common.sh,v 1.14 2017/03/06 07:15:47 ozaki-r Exp $
+#	$NetBSD: net_common.sh,v 1.15 2017/04/14 02:56:48 ozaki-r Exp $
 #
 # Copyright (c) 2016 Internet Initiative Japan Inc.
 # All rights reserved.
@@ -170,6 +170,8 @@ stop_nc_server()
 BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \
     -lrumpnet_shmif -lrumpdev"
 FS_LIBS="$BASIC_LIBS -lrumpvfs -lrumpfs_ffs"
+CRYPTO_LIBS="$BASIC_LIBS -lrumpvfs -lrumpdev_opencrypto \
+    -lrumpkern_z -lrumpkern_crypto"
 
 # We cannot keep variables between test phases, so need to store in files
 _rump_server_socks=./.__socks
@@ -226,6 +228,24 @@ rump_server_fs_start()
 	return 0
 }
 
+rump_server_crypto_start()
+{
+	local sock=$1
+	local _libs=
+	local libs="$CRYPTO_LIBS"
+
+	shift 1
+	_libs="$*"
+
+	for lib in $_libs; do
+		libs="$libs -lrumpnet_$lib"
+	done
+
+	_rump_server_start_common $sock $libs
+
+	return 0
+}
+
 rump_server_add_iface()
 {
 	local sock=$1

Added files:

Index: src/tests/net/ipsec/Makefile
diff -u /dev/null src/tests/net/ipsec/Makefile:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/Makefile	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,14 @@
+# $NetBSD: Makefile,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+
+.include <bsd.own.mk>
+
+TESTSDIR=	${TESTSBASE}/net/ipsec
+
+.for name in ipsec_ah_keys ipsec_esp_keys ipsec_sysctl ipsec_transport \
+    ipsec_tunnel
+TESTS_SH+=		t_${name}
+TESTS_SH_SRC_t_${name}=	../net_common.sh ./algorithms.sh t_${name}.sh
+.endfor
+
+.include <bsd.test.mk>
Index: src/tests/net/ipsec/algorithms.sh
diff -u /dev/null src/tests/net/ipsec/algorithms.sh:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/algorithms.sh	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,160 @@
+#	$NetBSD: algorithms.sh,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+# Copyright (c) 2017 Internet Initiative Japan Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+ESP_ENCRYPTION_ALGORITHMS="des-cbc 3des-cbc null blowfish-cbc cast128-cbc \
+    des-deriv rijndael-cbc aes-ctr camellia-cbc aes-gcm-16 aes-gmac"
+
+# Valid key lengths of ESP encription algorithms
+#    des-cbc         64
+#    3des-cbc        192
+#    null            0 to 2048     XXX only accept 0 length
+#    blowfish-cbc    40 to 448
+#    cast128-cbc     40 to 128
+#    des-deriv       64
+#    3des-deriv      192           XXX not implemented
+#    rijndael-cbc    128/192/256
+#    twofish-cbc     0 to 256      XXX not supported
+#    aes-ctr         160/224/288
+#    camellia-cbc    128/192/256
+#    aes-gcm-16      160/224/288
+#    aes-gmac        160/224/288
+valid_keys_descbc="64"
+invalid_keys_descbc="56 72"
+valid_keys_3descbc="192"
+invalid_keys_3descbc="184 200"
+#valid_keys_null="0 2048"
+valid_keys_null="0"
+invalid_keys_null="8"
+valid_keys_blowfishcbc="40 448"
+invalid_keys_blowfishcbc="32 456"
+valid_keys_cast128cbc="40 128"
+invalid_keys_cast128cbc="32 136"
+valid_keys_desderiv="64"
+invalid_keys_desderiv="56 72"
+#valid_keys_3desderiv="192"
+#invalid_keys_3desderiv="184 200"
+valid_keys_rijndaelcbc="128 192 256"
+invalid_keys_rijndaelcbc="120 136 184 200 248 264"
+#valid_keys_twofishcbc="0 256"
+#invalid_keys_twofishcbc="264"
+valid_keys_aesctr="160 224 288"
+invalid_keys_aesctr="152 168 216 232 280 296"
+valid_keys_camelliacbc="128 192 256"
+invalid_keys_camelliacbc="120 136 184 200 248 264"
+valid_keys_aesgcm16="160 224 288"
+invalid_keys_aesgcm16="152 168 216 232 280 296"
+valid_keys_aesgmac="160 224 288"
+invalid_keys_aesgmac="152 168 216 232 280 296"
+
+AH_AUTHENTICATION_ALGORITHMS="hmac-md5 hmac-sha1 keyed-md5 keyed-sha1 null \
+    hmac-sha256 hmac-sha384 hmac-sha512 hmac-ripemd160 aes-xcbc-mac"
+
+# Valid key lengths of AH authentication algorithms
+#    hmac-md5        128
+#    hmac-sha1       160
+#    keyed-md5       128
+#    keyed-sha1      160
+#    null            0 to 2048
+#    hmac-sha256     256
+#    hmac-sha384     384
+#    hmac-sha512     512
+#    hmac-ripemd160  160
+#    aes-xcbc-mac    128
+#    tcp-md5         8 to 640  XXX not enabled in rump kernels
+valid_keys_hmacmd5="128"
+invalid_keys_hmacmd5="120 136"
+valid_keys_hmacsha1="160"
+invalid_keys_hmacsha1="152 168"
+valid_keys_keyedmd5="128"
+invalid_keys_keyedmd5="120 136"
+valid_keys_keyedsha1="160"
+invalid_keys_keyedsha1="152 168"
+#valid_keys_null="0 2048"
+valid_keys_null="0"
+invalid_keys_null="8"
+valid_keys_hmacsha256="256"
+invalid_keys_hmacsha256="248 264"
+valid_keys_hmacsha384="384"
+invalid_keys_hmacsha384="376 392"
+valid_keys_hmacsha512="512"
+invalid_keys_hmacsha512="504 520"
+valid_keys_hmacripemd160="160"
+invalid_keys_hmacripemd160="152 168"
+valid_keys_aesxcbcmac="128"
+invalid_keys_aesxcbcmac="120 136"
+#valid_keys_tcpmd5="8 640"
+#invalid_keys_tcpmd5="648"
+
+get_one_valid_keylen()
+{
+	local algo=$1
+	local _algo=$(echo $algo | sed 's/-//g')
+	local len=
+	local keylengths=
+
+	eval keylengths="\$valid_keys_${_algo}"
+
+	for len in $(echo $keylengths); do
+		break;
+	done
+
+	echo $len
+}
+
+get_valid_keylengths()
+{
+	local algo=$1
+	local _algo=$(echo $algo | sed 's/-//g')
+
+	eval keylengths="\$valid_keys_${_algo}"
+	echo $keylengths
+}
+
+get_invalid_keylengths()
+{
+	local algo=$1
+	local _algo=$(echo $algo | sed 's/-//g')
+
+	eval keylengths="\$invalid_keys_${_algo}"
+	echo $keylengths
+}
+
+generate_key()
+{
+	local keylen=$(($1 / 8))
+	local key=
+
+	while [ $keylen -gt 0 ]; do
+		key="${key}a"
+		keylen=$((keylen - 1))
+	done
+	if [ ! -z "$key" ]; then
+		key="\"$key\""
+	fi
+
+	echo $key
+}
Index: src/tests/net/ipsec/t_ipsec_ah_keys.sh
diff -u /dev/null src/tests/net/ipsec/t_ipsec_ah_keys.sh:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/t_ipsec_ah_keys.sh	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,159 @@
+#	$NetBSD: t_ipsec_ah_keys.sh,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+# Copyright (c) 2017 Internet Initiative Japan Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+SOCK_LOCAL=unix://ipsec_local
+
+DEBUG=${DEBUG:-false}
+
+test_ah_valid_keys_common()
+{
+	local aalgo=$1
+	local key=
+	local tmpfile=./tmp
+	local len=
+
+	rump_server_crypto_start $SOCK_LOCAL netipsec
+
+	export RUMP_SERVER=$SOCK_LOCAL
+
+	for len in $(get_valid_keylengths $aalgo); do
+		key=$(generate_key $len)
+		cat > $tmpfile <<-EOF
+		add 10.0.0.1 10.0.0.2 ah 10000 -A $aalgo $key;
+		EOF
+		$DEBUG && cat $tmpfile
+		atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+		atf_check -s exit:0 -o match:'10.0.0.1 10.0.0.2' \
+		    $HIJACKING setkey -D
+		# TODO: more detail checks
+
+		cat > $tmpfile <<-EOF
+		delete 10.0.0.1 10.0.0.2 ah 10000;
+		EOF
+		$DEBUG && cat $tmpfile
+		atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+		atf_check -s exit:0 -o match:'No SAD entries.' \
+		    $HIJACKING setkey -D
+	done
+
+	rm -f $tmpfile
+}
+
+add_test_valid_keys()
+{
+	local aalgo=$1
+	local _aalgo=$(echo $aalgo | sed 's/-//g')
+	local name= desc=
+
+	name="ipsec_ah_${_aalgo}_valid_keys"
+	desc="Tests AH ($aalgo) valid keys"
+
+	atf_test_case ${name} cleanup
+	eval "								\
+	    ${name}_head() {						\
+	        atf_set \"descr\" \"$desc\";				\
+	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
+	    };								\
+	    ${name}_body() {						\
+	        test_ah_valid_keys_common $aalgo;			\
+	    };								\
+	    ${name}_cleanup() {						\
+	        $DEBUG && dump;						\
+	        cleanup;						\
+	    }								\
+	"
+	atf_add_test_case ${name}
+}
+
+test_ah_invalid_keys_common()
+{
+	local aalgo=$1
+	local key=
+	local tmpfile=./tmp
+	local len=
+
+	rump_server_crypto_start $SOCK_LOCAL netipsec
+
+	export RUMP_SERVER=$SOCK_LOCAL
+
+	for len in $(get_invalid_keylengths $aalgo); do
+		key=$(generate_key $len)
+		cat > $tmpfile <<-EOF
+		add 10.0.0.1 10.0.0.2 ah 10000 -A $aalgo $key;
+		EOF
+		$DEBUG && cat $tmpfile
+		if [ $aalgo = null ]; then
+			# null doesn't accept any keys
+			atf_check -s exit:0 \
+			    -o match:'syntax error' -e ignore \
+			    $HIJACKING setkey -c < $tmpfile
+		else
+			atf_check -s exit:0 \
+			    -o match:'Invalid (key length|argument)' -e ignore \
+			    $HIJACKING setkey -c < $tmpfile
+		fi
+		atf_check -s exit:0 -o match:'No SAD entries.' \
+		    $HIJACKING setkey -D
+	done
+
+	rm -f $tmpfile
+}
+
+add_test_invalid_keys()
+{
+	local aalgo=$1
+	local _aalgo=$(echo $aalgo | sed 's/-//g')
+	local name= desc=
+
+	name="ipsec_ah_${_aalgo}_invalid_keys"
+	desc="Tests AH ($aalgo) invalid keys"
+
+	atf_test_case ${name} cleanup
+	eval "								\
+	    ${name}_head() {						\
+	        atf_set \"descr\" \"$desc\";				\
+	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
+	    };								\
+	    ${name}_body() {						\
+	        test_ah_invalid_keys_common $aalgo;			\
+	    };								\
+	    ${name}_cleanup() {						\
+	        $DEBUG && dump;						\
+	        cleanup;						\
+	    }								\
+	"
+	atf_add_test_case ${name}
+}
+
+atf_init_test_cases()
+{
+
+	for aalgo in $AH_AUTHENTICATION_ALGORITHMS; do
+		add_test_valid_keys $aalgo
+		add_test_invalid_keys $aalgo
+	done
+}
Index: src/tests/net/ipsec/t_ipsec_esp_keys.sh
diff -u /dev/null src/tests/net/ipsec/t_ipsec_esp_keys.sh:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/t_ipsec_esp_keys.sh	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,159 @@
+#	$NetBSD: t_ipsec_esp_keys.sh,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+# Copyright (c) 2017 Internet Initiative Japan Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+SOCK_LOCAL=unix://ipsec_local
+
+DEBUG=${DEBUG:-false}
+
+test_esp_valid_keys_common()
+{
+	local ealgo=$1
+	local key=
+	local tmpfile=./tmp
+	local len=
+
+	rump_server_crypto_start $SOCK_LOCAL netipsec
+
+	export RUMP_SERVER=$SOCK_LOCAL
+
+	for len in $(get_valid_keylengths $ealgo); do
+		key=$(generate_key $len)
+		cat > $tmpfile <<-EOF
+		add 10.0.0.1 10.0.0.2 esp 10000 -E $ealgo $key;
+		EOF
+		$DEBUG && cat $tmpfile
+		atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+		atf_check -s exit:0 -o match:'10.0.0.1 10.0.0.2' \
+		    $HIJACKING setkey -D
+		# TODO: more detail checks
+
+		cat > $tmpfile <<-EOF
+		delete 10.0.0.1 10.0.0.2 esp 10000;
+		EOF
+		$DEBUG && cat $tmpfile
+		atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+		atf_check -s exit:0 -o match:'No SAD entries.' \
+		    $HIJACKING setkey -D
+	done
+
+	rm -f $tmpfile
+}
+
+add_test_valid_keys()
+{
+	local ealgo=$1
+	local _ealgo=$(echo $ealgo | sed 's/-//g')
+	local name= desc=
+
+	name="ipsec_esp_${_ealgo}_valid_keys"
+	desc="Tests ESP ($ealgo) valid keys"
+
+	atf_test_case ${name} cleanup
+	eval "								\
+	    ${name}_head() {						\
+	        atf_set \"descr\" \"$desc\";				\
+	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
+	    };								\
+	    ${name}_body() {						\
+	        test_esp_valid_keys_common $ealgo;			\
+	    };								\
+	    ${name}_cleanup() {						\
+	        $DEBUG && dump;						\
+	        cleanup;						\
+	    }								\
+	"
+	atf_add_test_case ${name}
+}
+
+test_esp_invalid_keys_common()
+{
+	local ealgo=$1
+	local key=
+	local tmpfile=./tmp
+	local len=
+
+	rump_server_crypto_start $SOCK_LOCAL netipsec
+
+	export RUMP_SERVER=$SOCK_LOCAL
+
+	for len in $(get_invalid_keylengths $ealgo); do
+		key=$(generate_key $len)
+		cat > $tmpfile <<-EOF
+		add 10.0.0.1 10.0.0.2 esp 10000 -E $ealgo $key;
+		EOF
+		$DEBUG && cat $tmpfile
+		if [ $ealgo = null ]; then
+			# null doesn't accept any keys
+			atf_check -s exit:0 \
+			    -o match:'syntax error' -e ignore \
+			    $HIJACKING setkey -c < $tmpfile
+		else
+			atf_check -s exit:0 \
+			    -o match:'Invalid (key length|argument)' -e ignore \
+			    $HIJACKING setkey -c < $tmpfile
+		fi
+		atf_check -s exit:0 -o match:'No SAD entries.' \
+		    $HIJACKING setkey -D
+	done
+
+	rm -f $tmpfile
+}
+
+add_test_invalid_keys()
+{
+	local ealgo=$1
+	local _ealgo=$(echo $ealgo | sed 's/-//g')
+	local name= desc=
+
+	name="ipsec_esp_${_ealgo}_invalid_keys"
+	desc="Tests ESP ($ealgo) invalid keys"
+
+	atf_test_case ${name} cleanup
+	eval "								\
+	    ${name}_head() {						\
+	        atf_set \"descr\" \"$desc\";				\
+	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
+	    };								\
+	    ${name}_body() {						\
+	        test_esp_invalid_keys_common $ealgo;			\
+	    };								\
+	    ${name}_cleanup() {						\
+	        $DEBUG && dump;						\
+	        cleanup;						\
+	    }								\
+	"
+	atf_add_test_case ${name}
+}
+
+atf_init_test_cases()
+{
+
+	for ealgo in $ESP_ENCRYPTION_ALGORITHMS; do
+		add_test_valid_keys $ealgo
+		add_test_invalid_keys $ealgo
+	done
+}
Index: src/tests/net/ipsec/t_ipsec_sysctl.sh
diff -u /dev/null src/tests/net/ipsec/t_ipsec_sysctl.sh:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/t_ipsec_sysctl.sh	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,161 @@
+#	$NetBSD: t_ipsec_sysctl.sh,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+# Copyright (c) 2017 Internet Initiative Japan Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+DEBUG=${DEBUG:-false}
+
+atf_test_case ipsec_sysctl0 cleanup
+ipsec_sysctl0_head()
+{
+
+	atf_set "descr" "Tests of sysctl entries of IPsec without ipsec.so"
+	atf_set "require.progs" "rump_server"
+}
+
+ipsec_sysctl0_body()
+{
+	local sock=unix://ipsec_sysctl
+
+	rump_server_crypto_start $sock
+
+	export RUMP_SERVER=$sock
+	atf_check -s not-exit:0 -e match:'invalid' \
+	    rump.sysctl net.inet.ipsec.enabled
+	atf_check -s not-exit:0 -e match:'invalid' \
+	    rump.sysctl net.inet6.ipsec6.enabled
+}
+
+ipsec_sysctl0_cleanup()
+{
+
+	$DEBUG && dump
+	cleanup
+}
+
+atf_test_case ipsec_sysctl4 cleanup
+ipsec_sysctl4_head()
+{
+
+	atf_set "descr" "Tests of sysctl entries of IPsec without netinet6.so"
+	atf_set "require.progs" "rump_server"
+}
+
+ipsec_sysctl4_body()
+{
+	local sock=unix://ipsec_sysctl
+
+	rump_server_crypto_start $sock netipsec
+
+	export RUMP_SERVER=$sock
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet.ipsec.enabled
+	# net.inet6.ipsec6 entries exit regardless of netinet6
+	# net.inet6.ipsec6.enabled always equals net.inet.ipsec.enabled
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet6.ipsec6.enabled
+
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet.ipsec.used
+	# net.inet6.ipsec6.used always equals net.inet.ipsec.used
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ipsec6.used
+
+	# Add an SAD entry for IPv4
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c <<-EOF
+	add 10.0.0.1 10.0.0.2 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
+	EOF
+	$DEBUG && $HIJACKING setkey -D
+
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet.ipsec.used
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ipsec6.used
+
+	# Add an SPD entry for IPv4, which activates the IPsec function
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c <<-EOF
+	spdadd 10.0.0.1 10.0.0.2 any -P out ipsec esp/transport//use;
+	EOF
+	$DEBUG && $HIJACKING setkey -D
+
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet.ipsec.used
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet6.ipsec6.used
+}
+
+ipsec_sysctl4_cleanup()
+{
+
+	$DEBUG && dump
+	cleanup
+}
+
+atf_test_case ipsec_sysctl6 cleanup
+ipsec_sysctl6_head()
+{
+
+	atf_set "descr" "Tests of sysctl entries of IPsec"
+	atf_set "require.progs" "rump_server"
+}
+
+ipsec_sysctl6_body()
+{
+	local sock=unix://ipsec_sysctl
+
+	rump_server_crypto_start $sock netinet6 netipsec
+
+	export RUMP_SERVER=$sock
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet.ipsec.enabled
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet6.ipsec6.enabled
+
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet.ipsec.used
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ipsec6.used
+
+	# Add an SAD entry for IPv6
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c <<-EOF
+	add fd00::1 fd00::2 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
+	EOF
+	$DEBUG && $HIJACKING setkey -D
+
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet.ipsec.used
+	atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ipsec6.used
+
+	# Add an SPD entry for IPv6, which activates the IPsec function
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c <<-EOF
+	spdadd fd00::1 fd00::2 any -P out ipsec esp/transport//use;
+	EOF
+	$DEBUG && $HIJACKING setkey -D
+
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet.ipsec.used
+	atf_check -s exit:0 -o match:'= 1' rump.sysctl net.inet6.ipsec6.used
+}
+
+ipsec_sysctl6_cleanup()
+{
+
+	$DEBUG && dump
+	cleanup
+}
+
+atf_init_test_cases()
+{
+
+	atf_add_test_case ipsec_sysctl0
+	atf_add_test_case ipsec_sysctl4
+	atf_add_test_case ipsec_sysctl6
+}
Index: src/tests/net/ipsec/t_ipsec_transport.sh
diff -u /dev/null src/tests/net/ipsec/t_ipsec_transport.sh:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/t_ipsec_transport.sh	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,258 @@
+#	$NetBSD: t_ipsec_transport.sh,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+# Copyright (c) 2017 Internet Initiative Japan Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+SOCK_LOCAL=unix://ipsec_local
+SOCK_PEER=unix://ipsec_peer
+BUS=./bus_ipsec
+
+DEBUG=${DEBUG:-false}
+
+test_ipsec4_transport()
+{
+	local proto=$1
+	local algo=$2
+	local ip_local=10.0.0.1
+	local ip_peer=10.0.0.2
+	local keylen=$(get_one_valid_keylen $algo)
+	local key=$(generate_key $keylen)
+	local tmpfile=./tmp
+	local outfile=./out
+	local opt= proto_cap=
+
+	if [ $proto = esp ]; then
+		opt=-E
+		proto_cap=ESP
+	else
+		opt=-A
+		proto_cap=AH
+	fi
+
+	rump_server_crypto_start $SOCK_LOCAL netipsec
+	rump_server_crypto_start $SOCK_PEER netipsec
+	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+	rump_server_add_iface $SOCK_PEER shmif0 $BUS
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
+	atf_check -s exit:0 rump.ifconfig -w 10
+
+	export RUMP_SERVER=$SOCK_PEER
+	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
+	atf_check -s exit:0 rump.ifconfig -w 10
+
+	extract_new_packets $BUS > $outfile
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
+
+	extract_new_packets $BUS > $outfile
+	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: ICMP echo request" \
+	    cat $outfile
+	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: ICMP echo reply" \
+	    cat $outfile
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	# from https://www.netbsd.org/docs/network/ipsec/
+	cat > $tmpfile <<-EOF
+	add $ip_local $ip_peer $proto 10000 $opt $algo $key;
+	add $ip_peer $ip_local $proto 10001 $opt $algo $key;
+	spdadd $ip_local $ip_peer any -P out ipsec $proto/transport//require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_local $ip_peer" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_peer $ip_local" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_PEER
+	cat > $tmpfile <<-EOF
+	add $ip_local $ip_peer $proto 10000 $opt $algo $key;
+	add $ip_peer $ip_local $proto 10001 $opt $algo $key;
+	spdadd $ip_peer $ip_local any -P out ipsec $proto/transport//require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_local $ip_peer" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_peer $ip_local" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
+
+	extract_new_packets $BUS > $outfile
+	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: $proto_cap" \
+	    cat $outfile
+	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: $proto_cap" \
+	    cat $outfile
+}
+
+test_ipsec6_transport()
+{
+	local proto=$1
+	local algo=$2
+	local ip_local=fd00::1
+	local ip_peer=fd00::2
+	local keylen=$(get_one_valid_keylen $algo)
+	local key=$(generate_key $keylen)
+	local tmpfile=./tmp
+	local outfile=./out
+	local opt= proto_cap=
+
+	if [ $proto = esp ]; then
+		opt=-E
+		proto_cap=ESP
+	else
+		opt=-A
+		proto_cap=AH
+	fi
+
+	rump_server_crypto_start $SOCK_LOCAL netinet6 netipsec
+	rump_server_crypto_start $SOCK_PEER netinet6 netipsec
+	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+	rump_server_add_iface $SOCK_PEER shmif0 $BUS
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local
+	atf_check -s exit:0 rump.ifconfig -w 10
+
+	export RUMP_SERVER=$SOCK_PEER
+	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_peer
+	atf_check -s exit:0 rump.ifconfig -w 10
+
+	extract_new_packets $BUS > $outfile
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_peer
+
+	extract_new_packets $BUS > $outfile
+	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: ICMP6, echo request" \
+	    cat $outfile
+	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: ICMP6, echo reply" \
+	    cat $outfile
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	# from https://www.netbsd.org/docs/network/ipsec/
+	cat > $tmpfile <<-EOF
+	add $ip_local $ip_peer $proto 10000 $opt $algo $key;
+	add $ip_peer $ip_local $proto 10001 $opt $algo $key;
+	spdadd $ip_local $ip_peer any -P out ipsec $proto/transport//require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_local $ip_peer" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_peer $ip_local" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_PEER
+	cat > $tmpfile <<-EOF
+	add $ip_local $ip_peer $proto 10000 $opt $algo $key;
+	add $ip_peer $ip_local $proto 10001 $opt $algo $key;
+	spdadd $ip_peer $ip_local any -P out ipsec $proto/transport//require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_local $ip_peer" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 -o match:"$ip_peer $ip_local" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_peer
+
+	extract_new_packets $BUS > $outfile
+	atf_check -s exit:0 -o match:"$ip_local > $ip_peer: $proto_cap" \
+	    cat $outfile
+	atf_check -s exit:0 -o match:"$ip_peer > $ip_local: $proto_cap" \
+	    cat $outfile
+}
+
+test_transport_common()
+{
+	local ipproto=$1
+	local proto=$2
+	local algo=$3
+
+	if [ $ipproto = ipv4 ]; then
+		test_ipsec4_transport $proto $algo
+	else
+		test_ipsec6_transport $proto $algo
+	fi
+}
+
+add_test_transport_mode()
+{
+	local ipproto=$1
+	local proto=$2
+	local algo=$3
+	local _algo=$(echo $algo | sed 's/-//g')
+	local name= desc=
+
+	name="ipsec_transport_${ipproto}_${proto}_${_algo}"
+	desc="Tests of IPsec ($ipproto) transport mode with $proto ($algo)"
+
+	atf_test_case ${name} cleanup
+	eval "								\
+	    ${name}_head() {						\
+	        atf_set \"descr\" \"$desc\";				\
+	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
+	    };								\
+	    ${name}_body() {						\
+	        test_transport_common $ipproto $proto $algo;		\
+	        rump_server_destroy_ifaces;				\
+	    };								\
+	    ${name}_cleanup() {						\
+	        $DEBUG && dump;						\
+	        cleanup;						\
+	    }								\
+	"
+	atf_add_test_case ${name}
+}
+
+atf_init_test_cases()
+{
+	local algo=
+
+	for algo in $ESP_ENCRYPTION_ALGORITHMS; do
+		add_test_transport_mode ipv4 esp $algo
+		add_test_transport_mode ipv6 esp $algo
+	done
+	for algo in $AH_AUTHENTICATION_ALGORITHMS; do
+		add_test_transport_mode ipv4 ah $algo
+		add_test_transport_mode ipv6 ah $algo
+	done
+}
Index: src/tests/net/ipsec/t_ipsec_tunnel.sh
diff -u /dev/null src/tests/net/ipsec/t_ipsec_tunnel.sh:1.1
--- /dev/null	Fri Apr 14 02:56:49 2017
+++ src/tests/net/ipsec/t_ipsec_tunnel.sh	Fri Apr 14 02:56:49 2017
@@ -0,0 +1,352 @@
+#	$NetBSD: t_ipsec_tunnel.sh,v 1.1 2017/04/14 02:56:49 ozaki-r Exp $
+#
+# Copyright (c) 2017 Internet Initiative Japan Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+SOCK_LOCAL=unix://ipsec_local
+SOCK_TUNNEL_LOCAL=unix://ipsec_tunel_local
+SOCK_TUNNEL_REMOTE=unix://ipsec_tunnel_remote
+SOCK_REMOTE=unix://ipsec_remote
+BUS_LOCAL=./bus_ipsec_local
+BUS_TUNNEL=./bus_ipsec_tunnel
+BUS_REMOTE=./bus_ipsec_remote
+
+DEBUG=${DEBUG:-false}
+
+test_ipsec4_tunnel()
+{
+	local proto=$1
+	local algo=$2
+	local ip_local=10.0.1.2
+	local ip_gw_local=10.0.1.1
+	local ip_gw_local_tunnel=20.0.0.1
+	local ip_gw_remote_tunnel=20.0.0.2
+	local ip_gw_remote=10.0.2.1
+	local ip_remote=10.0.2.2
+	local subnet_local=10.0.1.0
+	local subnet_remote=10.0.2.0
+	local keylen=$(get_one_valid_keylen $algo)
+	local key=$(generate_key $keylen)
+	local tmpfile=./tmp
+	local outfile=./out
+	local opt= proto_cap=
+
+	if [ $proto = esp ]; then
+		opt=-E
+		proto_cap=ESP
+	else
+		opt=-A
+		proto_cap=AH
+	fi
+
+	# See https://www.netbsd.org/docs/network/ipsec/#sample_vpn
+	rump_server_crypto_start $SOCK_LOCAL
+	rump_server_crypto_start $SOCK_TUNNEL_LOCAL netipsec
+	rump_server_crypto_start $SOCK_TUNNEL_REMOTE netipsec
+	rump_server_crypto_start $SOCK_REMOTE
+	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL
+	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif0 $BUS_LOCAL
+	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif1 $BUS_TUNNEL
+	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif0 $BUS_REMOTE
+	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif1 $BUS_TUNNEL
+	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -net $subnet_remote $ip_gw_local
+
+	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
+	atf_check -s exit:0 rump.ifconfig shmif0 $ip_gw_local/24
+	atf_check -s exit:0 rump.ifconfig shmif1 $ip_gw_local_tunnel/24
+	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -net $subnet_remote $ip_gw_remote_tunnel
+
+	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
+	atf_check -s exit:0 rump.ifconfig shmif0 $ip_gw_remote/24
+	atf_check -s exit:0 rump.ifconfig shmif1 $ip_gw_remote_tunnel/24
+	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -net $subnet_local $ip_gw_local_tunnel
+
+	export RUMP_SERVER=$SOCK_REMOTE
+	atf_check -s exit:0 rump.ifconfig shmif0 $ip_remote/24
+	# Run ifconfig -w 10 just once for optimization
+	atf_check -s exit:0 rump.ifconfig -w 10
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -net $subnet_local $ip_gw_remote
+
+	extract_new_packets $BUS_TUNNEL > $outfile
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_remote
+
+	extract_new_packets $BUS_TUNNEL > $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_local > $ip_remote: ICMP echo request" \
+	    cat $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_remote > $ip_local: ICMP echo reply" \
+	    cat $outfile
+
+	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
+	# from https://www.netbsd.org/docs/network/ipsec/
+	cat > $tmpfile <<-EOF
+	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
+	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
+	spdadd $subnet_local/24 $subnet_remote/24 any -P out ipsec
+	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
+	spdadd $subnet_remote/24 $subnet_local/24 any -P in ipsec
+	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
+	cat > $tmpfile <<-EOF
+	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
+	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
+	spdadd $subnet_remote/24 $subnet_local/24 any -P out ipsec
+	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
+	spdadd $subnet_local/24 $subnet_remote/24 any -P in ipsec
+	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_remote
+
+	extract_new_packets $BUS_TUNNEL > $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_local_tunnel > $ip_gw_remote_tunnel: $proto_cap" \
+	    cat $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_remote_tunnel > $ip_gw_local_tunnel: $proto_cap" \
+	    cat $outfile
+}
+
+test_ipsec6_tunnel()
+{
+	local proto=$1
+	local algo=$2
+	local ip_local=fd00:1::2
+	local ip_gw_local=fd00:1::1
+	local ip_gw_local_tunnel=fc00::1
+	local ip_gw_remote_tunnel=fc00::2
+	local ip_gw_remote=fd00:2::1
+	local ip_remote=fd00:2::2
+	local subnet_local=fd00:1::
+	local subnet_remote=fd00:2::
+	local keylen=$(get_one_valid_keylen $algo)
+	local key=$(generate_key $keylen)
+	local tmpfile=./tmp
+	local outfile=./out
+	local opt= proto_cap=
+
+	if [ $proto = esp ]; then
+		opt=-E
+		proto_cap=ESP
+	else
+		opt=-A
+		proto_cap=AH
+	fi
+
+	rump_server_crypto_start $SOCK_LOCAL netinet6
+	rump_server_crypto_start $SOCK_TUNNEL_LOCAL netipsec netinet6
+	rump_server_crypto_start $SOCK_TUNNEL_REMOTE netipsec netinet6
+	rump_server_crypto_start $SOCK_REMOTE netinet6
+	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL
+	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif0 $BUS_LOCAL
+	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif1 $BUS_TUNNEL
+	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif0 $BUS_REMOTE
+	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif1 $BUS_TUNNEL
+	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local/64
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -inet6 -net $subnet_remote/64 $ip_gw_local
+
+	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
+	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_gw_local/64
+	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_gw_local_tunnel/64
+	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -inet6 -net $subnet_remote/64 $ip_gw_remote_tunnel
+
+	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
+	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_gw_remote/64
+	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_gw_remote_tunnel/64
+	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -inet6 -net $subnet_local/64 $ip_gw_local_tunnel
+
+	export RUMP_SERVER=$SOCK_REMOTE
+	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_remote
+	# Run ifconfig -w 10 just once for optimization
+	atf_check -s exit:0 rump.ifconfig -w 10
+	atf_check -s exit:0 -o ignore \
+	    rump.route -n add -inet6 -net $subnet_local/64 $ip_gw_remote
+
+	extract_new_packets $BUS_TUNNEL > $outfile
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_remote
+
+	extract_new_packets $BUS_TUNNEL > $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_local > $ip_remote: ICMP6, echo request" \
+	    cat $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_remote > $ip_local: ICMP6, echo reply" \
+	    cat $outfile
+
+	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
+	# from https://www.netbsd.org/docs/network/ipsec/
+	cat > $tmpfile <<-EOF
+	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
+	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
+	spdadd $subnet_local/64 $subnet_remote/64 any -P out ipsec
+	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
+	spdadd $subnet_remote/64 $subnet_local/64 any -P in ipsec
+	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
+	cat > $tmpfile <<-EOF
+	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
+	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
+	spdadd $subnet_remote/64 $subnet_local/64 any -P out ipsec
+	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
+	spdadd $subnet_local/64 $subnet_remote/64 any -P in ipsec
+	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
+	EOF
+	$DEBUG && cat $tmpfile
+	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
+	$DEBUG && $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
+	    $HIJACKING setkey -D
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
+	    $HIJACKING setkey -D
+	# TODO: more detail checks
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_remote
+
+	extract_new_packets $BUS_TUNNEL > $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_local_tunnel > $ip_gw_remote_tunnel: $proto_cap" \
+	    cat $outfile
+	atf_check -s exit:0 \
+	    -o match:"$ip_gw_remote_tunnel > $ip_gw_local_tunnel: $proto_cap" \
+	    cat $outfile
+}
+
+test_tunnel_common()
+{
+	local ipproto=$1
+	local proto=$2
+	local algo=$3
+
+	if [ $ipproto = ipv4 ]; then
+		test_ipsec4_tunnel $proto $algo
+	else
+		test_ipsec6_tunnel $proto $algo
+	fi
+}
+
+add_test_tunnel_mode()
+{
+	local ipproto=$1
+	local proto=$2
+	local algo=$3
+	local _algo=$(echo $algo | sed 's/-//g')
+	local name= desc=
+
+	name="ipsec_tunnel_${ipproto}_${proto}_${_algo}"
+	desc="Tests of IPsec ($ipproto) tunnel mode with $proto ($algo)"
+
+	atf_test_case ${name} cleanup
+	eval "								\
+	    ${name}_head() {						\
+	        atf_set \"descr\" \"$desc\";				\
+	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
+	    };								\
+	    ${name}_body() {						\
+	        test_tunnel_common $ipproto $proto $algo;		\
+	        rump_server_destroy_ifaces;				\
+	    };								\
+	    ${name}_cleanup() {						\
+	        $DEBUG && dump;						\
+	        cleanup;						\
+	    }								\
+	"
+	atf_add_test_case ${name}
+}
+
+atf_init_test_cases()
+{
+	local algo=
+
+	for algo in $ESP_ENCRYPTION_ALGORITHMS; do
+		add_test_tunnel_mode ipv4 esp $algo
+		add_test_tunnel_mode ipv6 esp $algo
+	done
+
+	for algo in $AH_AUTHENTICATION_ALGORITHMS; do
+		add_test_tunnel_mode ipv4 ah $algo
+		add_test_tunnel_mode ipv6 ah $algo
+	done
+}

Reply via email to