• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0-or-later
3# Copyright (c) 2018-2022 Petr Vorel <pvorel@suse.cz>
4# Copyright (c) 2016 Red Hat Inc.,  All Rights Reserved.
5# Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved.
6# Author: Hangbin Liu <haliu@redhat.com>
7
8# Authenticated encryption with associated data
9AEALGO="rfc4106_128"
10# Encryption algorithm
11EALGO="des3_ede"
12# Authentication algorithm
13AALGO="sha1"
14# Compression algorithm
15CALGO="deflate"
16
17IPSEC_REQUESTS="500"
18
19TST_OPTS="l:m:p:s:S:k:A:e:a:c:r:"
20TST_PARSE_ARGS=ipsec_lib_parse_args
21TST_SETUP=${TST_SETUP:-ipsec_lib_setup}
22TST_USAGE=ipsec_lib_usage
23
24ipsec_lib_usage()
25{
26	echo "l n     n is the number of test link when tests run"
27	echo "m x     x is ipsec mode, could be transport / tunnel"
28	echo "p x     x is ipsec protocol, could be ah / esp / comp"
29	echo "s x     x is icmp message size array"
30	echo "S n     n is IPsec SPI value"
31	echo "k x     key for vti interface"
32	echo "A x     Authenticated encryption with associated data algorithm"
33	echo "e x     Encryption algorithm"
34	echo "a x     Authentication algorithm"
35	echo "c x     Compression algorithm"
36	echo "r x     Num of requests, PING_MAX or netstress' '-r' opt"
37}
38
39ipsec_lib_parse_args()
40{
41	case "$1" in
42	l) LINK_NUM=$2;;
43	m) IPSEC_MODE=$2;;
44	p) IPSEC_PROTO=$2;;
45	s) TST_TEST_DATA="$2"; TST_TEST_DATA_IFS=":";;
46	S) SPI=$2;;
47	k) VTI_KEY=$2;;
48	A) AEALGO=$2;;
49	e) EALGO=$2;;
50	a) AALGO=$2;;
51	c) CALGO=$2;;
52	r) IPSEC_REQUESTS="$2";;
53	esac
54}
55
56ipsec_lib_setup()
57{
58	case $AEALGO in
59	rfc4106_128|rfc4543_128) AEALGO_KEY=$(get_key 160);;
60	rfc4106_192|rfc4543_192) AEALGO_KEY=$(get_key 224);;
61	rfc4106_256|rfc4543_256) AEALGO_KEY=$(get_key 288);;
62	rfc4309_128) AEALGO_KEY=$(get_key 152);;
63	rfc4309_192) AEALGO_KEY=$(get_key 216);;
64	rfc4309_256) AEALGO_KEY=$(get_key 280);;
65	esac
66
67	case $EALGO in
68	des) EALGO_KEY=$(get_key 64);;
69	des3_ede) EALGO_KEY=$(get_key 192);;
70	cast5) EALGO_KEY=$(get_key 128);;
71	blowfish) EALGO_KEY=$(get_key 448);;
72	aes|twofish|camellia|serpent) EALGO_KEY=$(get_key 256);;
73	*) tst_brk TBROK "unknown enc alg: $EALGO";;
74	esac
75
76	case $AALGO in
77	sha1|rmd160) AALGO_KEY=$(get_key 160);;
78	sha256) AALGO_KEY=$(get_key 256);;
79	sha384) AALGO_KEY=$(get_key 384);;
80	sha512) AALGO_KEY=$(get_key 512);;
81	*) tst_brk TBROK "unknown auth alg: $AALGO";;
82	esac
83
84	SPI=${SPI:-1000}
85	VTI_KEY=${VTI_KEY:-10}
86	cleanup_vti=
87	ALG=
88	ALGR=
89
90	if [ -n "$IPSEC_MODE" ]; then
91		tst_net_run -q "tst_check_drivers xfrm_user" || \
92			tst_brk TCONF "xfrm_user driver not available on lhost or rhost"
93		cleanup_xfrm=1
94	fi
95}
96
97get_key()
98{
99	local bits=$1
100	local bytes=$(( $bits / 8))
101	echo "0x$(hexdump -vn $bytes -e '1/1 "%02x"' /dev/urandom)"
102}
103
104tst_ipsec_setup()
105{
106	ipsec_lib_setup
107	# Configure SAD/SPD
108	if [ -n "$IPSEC_MODE" -a -n "$IPSEC_PROTO" ]; then
109		tst_res TINFO "IPsec[$IPSEC_PROTO/$IPSEC_MODE]"
110		tst_ipsec lhost $(tst_ipaddr) $(tst_ipaddr rhost)
111		tst_ipsec rhost $(tst_ipaddr rhost) $(tst_ipaddr)
112	fi
113}
114
115# tst_ipsec_cleanup: flush ipsec state and policy rules
116tst_ipsec_cleanup()
117{
118	[ -z "$cleanup_xfrm" ] && return
119
120	ip xfrm state flush
121	ip xfrm policy flush
122	tst_rhost_run -c "ip xfrm state flush && ip xfrm policy flush"
123
124	if [ -n "$cleanup_vti" ]; then
125		ip link del $cleanup_vti 2>/dev/null
126		tst_rhost_run -c "ip link del $cleanup_vti 2>/dev/null"
127	fi
128}
129
130ipsec_set_algoline()
131{
132	case $IPSEC_PROTO in
133	ah)
134		ALG='auth hmac('$AALGO') '$AALGO_KEY
135		ALGR='auth hmac\('$AALGO'\) '$AALGO_KEY
136		;;
137	esp)
138		ALG="enc $EALGO $EALGO_KEY auth "'hmac('$AALGO') '$AALGO_KEY
139		ALGR="enc $EALGO $EALGO_KEY auth "'hmac\('$AALGO'\) '$AALGO_KEY
140		;;
141	esp_aead)
142		case $AEALGO in
143		rfc4106_128|rfc4106_192|rfc4106_256)
144			ALG="aead "'rfc4106(gcm(aes))'" $AEALGO_KEY 128"
145			ALGR="aead "'rfc4106\(gcm\(aes\)\)'" $AEALGO_KEY 128"
146			;;
147		rfc4309_128|rfc4309_192|rfc4309_256)
148			ALG="aead "'rfc4309(ccm(aes))'" $AEALGO_KEY 128"
149			ALGR="aead "'rfc4309\(ccm\(aes\)\)'" $AEALGO_KEY 128"
150			;;
151		rfc4543_128|rfc4543_192|rfc4543_256)
152			ALG="aead "'rfc4543(gcm(aes))'" $AEALGO_KEY 128"
153			ALGR="aead "'rfc4543\(gcm\(aes\)\)'" $AEALGO_KEY 128"
154			;;
155		esac
156		;;
157	comp)
158		ALG="comp $CALGO"
159		ALGR=$ALG
160		;;
161	*)
162		tst_brk TCONF "tst_ipsec protocol mismatch"
163		;;
164	esac
165}
166
167# tst_ipsec target src_addr dst_addr: config ipsec
168#
169# target: target of the configuration host ( lhost / rhost )
170# src_addr: source IP address
171# dst_addr: destination IP address
172tst_ipsec()
173{
174	if [ $# -ne 3 ]; then
175		tst_brk TCONF "tst_ipsec parameter mismatch"
176	fi
177
178	local target=$1
179	local src=$2
180	local dst=$3
181	local mode=$IPSEC_MODE
182	local p="proto $IPSEC_PROTO"
183	[ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp"
184
185	ipsec_set_algoline
186
187	if [ $target = lhost ]; then
188		local spi_1="0x$SPI"
189		local spi_2="0x$(( $SPI + 1 ))"
190		TST_RTNL_CHK ip xfrm state add src $src dst $dst spi $spi_1 \
191			$p $ALG mode $mode sel src $src dst $dst
192		ROD ip xfrm state add src $dst dst $src spi $spi_2 \
193			$p $ALG mode $mode sel src $dst dst $src
194
195		ROD ip xfrm policy add src $src dst $dst dir out tmpl src $src \
196			dst $dst $p mode $mode
197		ROD ip xfrm policy add src $dst dst $src dir in tmpl src $dst \
198			dst $src $p mode $mode level use
199	elif [ $target = rhost ]; then
200		local spi_1="0x$(( $SPI + 1 ))"
201		local spi_2="0x$SPI"
202		tst_rhost_run -s -c "ip xfrm state add src $src dst $dst \
203			spi $spi_1 $p $ALGR mode $mode sel src $src dst $dst"
204		tst_rhost_run -s -c "ip xfrm state add src $dst dst $src \
205			spi $spi_2 $p $ALGR mode $mode sel src $dst dst $src"
206
207		tst_rhost_run -s -c "ip xfrm policy add src $src dst $dst \
208			dir out tmpl src $src dst $dst $p mode $mode"
209		tst_rhost_run -s -c "ip xfrm policy add src $dst dst $src dir \
210			in tmpl src $dst dst $src $p mode $mode level use"
211	fi
212}
213
214# tst_ipsec_vti target src_addr dst_addr vti_name
215#
216# target: target of the configuration host ( lhost / rhost )
217# src_addr: source IP address
218# dst_addr: destination IP address
219# vti_name: name of vti interface
220tst_ipsec_vti()
221{
222	if [ $# -ne 4 ]; then
223		tst_brk TCONF "tst_ipsec_vti parameter mismatch"
224	fi
225
226	local target=$1
227	local src=$2
228	local dst=$3
229	local vti=$4
230	local m="mode $IPSEC_MODE"
231	local p="proto $IPSEC_PROTO"
232	[ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp"
233
234	local key="key $VTI_KEY"
235	local mrk="mark $VTI_KEY"
236	local type="type vti$TST_IPV6"
237	local d="dev $(tst_iface)"
238	local rd="dev $(tst_iface rhost)"
239
240	ip link add type vti help 2>&1 | grep -q vti || \
241		tst_brk TCONF "iproute doesn't support 'vti'"
242
243	ipsec_set_algoline
244
245	local o_dir="src $src dst $dst"
246	local i_dir="src $dst dst $src"
247	local ipx="ip -$TST_IPVER xf"
248
249	cleanup_vti=$vti
250
251	if [ $target = lhost ]; then
252		TST_RTNL_CHK ip link add $vti $type local $src remote $dst $key $d
253		ROD ip link set $vti up
254
255		local spi_1="spi 0x$SPI"
256		local spi_2="spi 0x$(( $SPI + 1 ))"
257		TST_RTNL_CHK $ipx st add $o_dir $p $spi_1 $ALG $m
258		ROD $ipx st add $i_dir $p $spi_2 $ALG $m
259		ROD $ipx po add dir out tmpl $o_dir $p $m $mrk
260		ROD $ipx po add dir in tmpl $i_dir $p $m $mrk
261	elif [ $target = rhost ]; then
262		tst_rhost_run -s -c \
263			"ip link add $vti $type local $src remote $dst $key $rd"
264		tst_rhost_run -s -c "ip link set $vti up"
265
266		local spi_1="spi 0x$(( $SPI + 1 ))"
267		local spi_2="spi 0x$SPI"
268		tst_rhost_run -s -c "$ipx st add $o_dir $p $spi_1 $ALGR $m"
269		tst_rhost_run -s -c "$ipx st add $i_dir $p $spi_2 $ALGR $m"
270		tst_rhost_run -s -c "$ipx po add dir out tmpl $o_dir $p $m $mrk"
271		tst_rhost_run -s -c "$ipx po add dir in tmpl $i_dir $p $m $mrk"
272	fi
273}
274
275# Setup vti/vti6 interface for IPsec tunneling
276# The function sets variables:
277#  * tst_vti - vti interface name,
278#  * ip_loc_tun - local IP address on vti interface
279#  * ip_rmt_tun - remote IP address
280tst_ipsec_setup_vti()
281{
282	ipsec_lib_setup
283
284	if_loc=$(tst_iface)
285	if_rmt=$(tst_iface rhost)
286
287	ip_loc=$(tst_ipaddr)
288	ip_rmt=$(tst_ipaddr rhost)
289
290	tst_vti="ltp_vti0"
291
292	tst_res TINFO "Test vti$TST_IPV6 + IPsec[$IPSEC_PROTO/$IPSEC_MODE]"
293
294	tst_net_run -q "tst_check_drivers ip${TST_IPV6}_vti" || \
295		tst_brk TCONF "ip${TST_IPV6}_vti driver not available on lhost or rhost"
296
297	tst_ipsec_vti lhost $ip_loc $ip_rmt $tst_vti
298	tst_ipsec_vti rhost $ip_rmt $ip_loc $tst_vti
299
300	local mask address_opt
301	if [ "$TST_IPV6" ]; then
302		ip_loc_tun="${IPV6_NET32_UNUSED}::1";
303		ip_rmt_tun="${IPV6_NET32_UNUSED}::2";
304		mask=64
305		address_opt=nodad
306		ROD ip -6 route add ${IPV6_NET32_UNUSED}::/$mask dev $tst_vti
307	else
308		ip_loc_tun="${IPV4_NET16_UNUSED}.1.1";
309		ip_rmt_tun="${IPV4_NET16_UNUSED}.1.2";
310		mask=30
311		ROD ip route add ${IPV4_NET16_UNUSED}.1.0/$mask dev $tst_vti
312	fi
313
314	tst_res TINFO "Add IPs to vti tunnel, " \
315		       "loc: $ip_loc_tun/$mask, rmt: $ip_rmt_tun/$mask"
316
317	ROD ip addr add $ip_loc_tun/$mask dev $tst_vti $address_opt
318	tst_rhost_run -s -c "ip addr add $ip_rmt_tun/$mask dev $tst_vti"
319}
320
321. tst_net.sh
322