1#!/bin/sh 2# Copyright (c) 2016 Red Hat Inc., All Rights Reserved. 3# Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved. 4# 5# This program is free software; you can redistribute it and/or 6# modify it under the terms of the GNU General Public License as 7# published by the Free Software Foundation; either version 2 of 8# the License, or (at your option) any later version. 9# 10# This program is distributed in the hope that it would be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, see <http://www.gnu.org/licenses/>. 17# 18# Author: Hangbin Liu <haliu@redhat.com> 19# 20####################################################################### 21 22. test_net.sh 23 24# Authenticated encryption with associated data 25AEALGO="rfc4106_128" 26# Encryption algorithm 27EALGO="des3_ede" 28# Authentication algorithm 29AALGO="sha1" 30# Compression algorithm 31CALGO="deflate" 32 33IPSEC_REQUESTS="500" 34IPSEC_SIZE_ARRAY="${IPSEC_SIZE_ARRAY:-10 100 1000 2000 10000 65000}" 35 36while getopts "hl:m:p:s:S:k:A:e:a:c:r:6" opt; do 37 case "$opt" in 38 h) 39 echo "Usage:" 40 echo "h help" 41 echo "l n n is the number of test link when tests run" 42 echo "m x x is ipsec mode, could be transport / tunnel" 43 echo "p x x is ipsec protocol, could be ah / esp / comp" 44 echo "s x x is icmp messge size array" 45 echo "S n n is IPsec SPI value" 46 echo "k x key for vti interface" 47 echo "A x Authenticated encryption with associated data algorithm" 48 echo "e x Encryption algorithm" 49 echo "a x Authentication algorithm" 50 echo "c x Compression algorithm" 51 echo "r x Num of requests, PING_MAX or netstress' '-r' opt" 52 echo "6 run over IPv6" 53 exit 0 54 ;; 55 l) LINK_NUM=$OPTARG ;; 56 m) IPSEC_MODE=$OPTARG ;; 57 p) IPSEC_PROTO=$OPTARG ;; 58 s) IPSEC_SIZE_ARRAY="$OPTARG" ;; 59 S) SPI=$OPTARG ;; 60 k) VTI_KEY=$OPTARG ;; 61 A) AEALGO=$OPTARG ;; 62 e) EALGO=$OPTARG ;; 63 a) AALGO=$OPTARG ;; 64 c) CALGO=$OPTARG ;; 65 r) IPSEC_REQUESTS="$OPTARG" ;; 66 6) # skip, test_net library already processed it 67 ;; 68 *) tst_brkm TBROK "unknown option: $opt" ;; 69 esac 70done 71 72get_key() 73{ 74 local bits=$1 75 local xdg_num=$(( $bits / 4 )) 76 echo "0x$(tr -dc "[:xdigit:]" < /dev/urandom | head -c$xdg_num)" 77} 78 79case $AEALGO in 80rfc4106_128|rfc4543_128) AEALGO_KEY=$(get_key 160) ;; 81rfc4106_192|rfc4543_192) AEALGO_KEY=$(get_key 224) ;; 82rfc4106_256|rfc4543_256) AEALGO_KEY=$(get_key 288) ;; 83rfc4309_128) AEALGO_KEY=$(get_key 152) ;; 84rfc4309_192) AEALGO_KEY=$(get_key 216) ;; 85rfc4309_256) AEALGO_KEY=$(get_key 280) ;; 86esac 87 88case $EALGO in 89des) EALGO_KEY=$(get_key 64) ;; 90des3_ede) EALGO_KEY=$(get_key 192) ;; 91cast5) EALGO_KEY=$(get_key 128) ;; 92blowfish) EALGO_KEY=$(get_key 448) ;; 93aes|twofish|camellia|serpent) EALGO_KEY=$(get_key 256) ;; 94*) tst_brkm TBROK "unknown enc alg: $EALGO" ;; 95esac 96 97case $AALGO in 98sha1|rmd160) AALGO_KEY=$(get_key 160) ;; 99sha256) AALGO_KEY=$(get_key 256) ;; 100sha384) AALGO_KEY=$(get_key 384) ;; 101sha512) AALGO_KEY=$(get_key 512) ;; 102*) tst_brkm TBROK "unknown auth alg: $AALGO" ;; 103esac 104 105SPI=${SPI:-1000} 106VTI_KEY=${VTI_KEY:-10} 107cleanup_vti= 108ALG= 109ALGR= 110 111# tst_ipsec_cleanup: flush ipsec state and policy rules 112tst_ipsec_cleanup() 113{ 114 ip xfrm state flush 115 ip xfrm policy flush 116 tst_rhost_run -c "ip xfrm state flush && ip xfrm policy flush" 117 118 if [ -n "$cleanup_vti" ]; then 119 ip li del $cleanup_vti 2>/dev/null 120 tst_rhost_run -c "ip li del $cleanup_vti 2>/dev/null" 121 fi 122 123 [ "$TST_NEEDS_TMPDIR" = 1 ] && tst_rmdir 124} 125 126ipsec_set_algoline() 127{ 128 case $IPSEC_PROTO in 129 ah) 130 ALG='auth hmac('$AALGO') '$AALGO_KEY 131 ALGR='auth hmac\('$AALGO'\) '$AALGO_KEY 132 ;; 133 esp) 134 ALG="enc $EALGO $EALGO_KEY auth "'hmac('$AALGO') '$AALGO_KEY 135 ALGR="enc $EALGO $EALGO_KEY auth "'hmac\('$AALGO'\) '$AALGO_KEY 136 ;; 137 esp_aead) 138 case $AEALGO in 139 rfc4106_128|rfc4106_192|rfc4106_256) 140 ALG="aead "'rfc4106(gcm(aes))'" $AEALGO_KEY 128" 141 ALGR="aead "'rfc4106\(gcm\(aes\)\)'" $AEALGO_KEY 128" 142 ;; 143 rfc4309_128|rfc4309_192|rfc4309_256) 144 ALG="aead "'rfc4309(ccm(aes))'" $AEALGO_KEY 128" 145 ALGR="aead "'rfc4309\(ccm\(aes\)\)'" $AEALGO_KEY 128" 146 ;; 147 rfc4543_128|rfc4543_192|rfc4543_256) 148 ALG="aead "'rfc4543(gcm(aes))'" $AEALGO_KEY 128" 149 ALGR="aead "'rfc4543\(gcm\(aes\)\)'" $AEALGO_KEY 128" 150 ;; 151 esac 152 ;; 153 comp) 154 ALG="comp $CALGO" 155 ALGR=$ALG 156 ;; 157 *) 158 tst_brkm TCONF "tst_ipsec protocol mismatch" 159 ;; 160 esac 161} 162 163ipsec_try() 164{ 165 local output="$($@ 2>&1 || echo 'TERR')" 166 167 if echo "$output" | grep -q "TERR"; then 168 echo "$output" | grep -q \ 169 'RTNETLINK answers: Function not implemented' && \ 170 tst_brkm TCONF "'$@': not implemented" 171 echo "$output" | grep -q \ 172 'RTNETLINK answers: Operation not supported' && \ 173 tst_brkm TCONF "'$@': not supported (maybe missing 'ip${TST_IPV6}_vti' kernel module)" 174 tst_brkm TBROK "$@ failed: $output" 175 fi 176} 177 178# tst_ipsec target src_addr dst_addr: config ipsec 179# 180# target: target of the configuration host ( lhost / rhost ) 181# src_addr: source IP address 182# dst_addr: destination IP address 183tst_ipsec() 184{ 185 if [ $# -ne 3 ]; then 186 tst_brkm TCONF "tst_ipsec parameter mismatch" 187 fi 188 189 local target=$1 190 local src=$2 191 local dst=$3 192 local mode=$IPSEC_MODE 193 local p="proto $IPSEC_PROTO" 194 [ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp" 195 196 ipsec_set_algoline 197 198 if [ $target = lhost ]; then 199 local spi_1="0x$SPI" 200 local spi_2="0x$(( $SPI + 1 ))" 201 ipsec_try ip xfrm state add src $src dst $dst spi $spi_1 \ 202 $p $ALG mode $mode sel src $src dst $dst 203 ROD ip xfrm state add src $dst dst $src spi $spi_2 \ 204 $p $ALG mode $mode sel src $dst dst $src 205 206 ROD ip xfrm policy add src $src dst $dst dir out tmpl src $src \ 207 dst $dst $p mode $mode 208 ROD ip xfrm policy add src $dst dst $src dir in tmpl src $dst \ 209 dst $src $p mode $mode level use 210 elif [ $target = rhost ]; then 211 local spi_1="0x$(( $SPI + 1 ))" 212 local spi_2="0x$SPI" 213 tst_rhost_run -s -c "ip xfrm state add src $src dst $dst \ 214 spi $spi_1 $p $ALGR mode $mode sel src $src dst $dst" 215 tst_rhost_run -s -c "ip xfrm state add src $dst dst $src \ 216 spi $spi_2 $p $ALGR mode $mode sel src $dst dst $src" 217 218 tst_rhost_run -s -c "ip xfrm policy add src $src dst $dst \ 219 dir out tmpl src $src dst $dst $p mode $mode" 220 tst_rhost_run -s -c "ip xfrm policy add src $dst dst $src dir \ 221 in tmpl src $dst dst $src $p mode $mode level use" 222 fi 223} 224 225# tst_ipsec_vti target src_addr dst_addr vti_name 226# 227# target: target of the configuration host ( lhost / rhost ) 228# src_addr: source IP address 229# dst_addr: destination IP address 230# vti_name: name of vti interface 231tst_ipsec_vti() 232{ 233 if [ $# -ne 4 ]; then 234 tst_brkm TCONF "tst_ipsec_vti parameter mismatch" 235 fi 236 237 local target=$1 238 local src=$2 239 local dst=$3 240 local vti=$4 241 local m="mode $IPSEC_MODE" 242 local p="proto $IPSEC_PROTO" 243 [ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp" 244 245 local key="key $VTI_KEY" 246 local mrk="mark $VTI_KEY" 247 local type="type vti$TST_IPV6" 248 local d="dev $(tst_iface)" 249 local rd="dev $(tst_iface rhost)" 250 251 ip li add type vti help 2>&1 | grep -q vti || \ 252 tst_brkm TCONF "iproute doesn't support 'vti'" 253 254 ipsec_set_algoline 255 256 local o_dir="src $src dst $dst" 257 local i_dir="src $dst dst $src" 258 local ipx="ip -${TST_IPV6:-4} xf" 259 260 cleanup_vti=$vti 261 262 if [ $target = lhost ]; then 263 ipsec_try ip li add $vti $type local $src remote $dst $key $d 264 ROD ip li set $vti up 265 266 local spi_1="spi 0x$SPI" 267 local spi_2="spi 0x$(( $SPI + 1 ))" 268 ipsec_try $ipx st add $o_dir $p $spi_1 $ALG $m 269 ROD $ipx st add $i_dir $p $spi_2 $ALG $m 270 ROD $ipx po add dir out tmpl $o_dir $p $m $mrk 271 ROD $ipx po add dir in tmpl $i_dir $p $m $mrk 272 elif [ $target = rhost ]; then 273 tst_rhost_run -s -c \ 274 "ip li add $vti $type local $src remote $dst $key $rd" 275 tst_rhost_run -s -c "ip li set $vti up" 276 277 local spi_1="spi 0x$(( $SPI + 1 ))" 278 local spi_2="spi 0x$SPI" 279 tst_rhost_run -s -c "$ipx st add $o_dir $p $spi_1 $ALGR $m" 280 tst_rhost_run -s -c "$ipx st add $i_dir $p $spi_2 $ALGR $m" 281 tst_rhost_run -s -c "$ipx po add dir out tmpl $o_dir $p $m $mrk" 282 tst_rhost_run -s -c "$ipx po add dir in tmpl $i_dir $p $m $mrk" 283 fi 284} 285 286# Setup vti/vti6 interface for IPsec tunneling 287# The function sets variables: 288# * tst_vti - vti interface name, 289# * ip_loc_tun - local IP address on vti interface 290# * ip_rmt_tun - remote IP address 291tst_ipsec_setup_vti() 292{ 293 if_loc=$(tst_iface) 294 if_rmt=$(tst_iface rhost) 295 296 ip_loc=$(tst_ipaddr) 297 ip_rmt=$(tst_ipaddr rhost) 298 299 tst_vti="ltp_vti0" 300 301 tst_resm TINFO "Test vti$TST_IPV6 + IPsec[$IPSEC_PROTO/$IPSEC_MODE]" 302 303 tst_ipsec_vti lhost $ip_loc $ip_rmt $tst_vti 304 tst_ipsec_vti rhost $ip_rmt $ip_loc $tst_vti 305 306 local mask= 307 if [ "$TST_IPV6" ]; then 308 ip_loc_tun="${IPV6_NET32_UNUSED}::1"; 309 ip_rmt_tun="${IPV6_NET32_UNUSED}::2"; 310 mask=64 311 ROD ip -6 route add ${IPV6_NET32_UNUSED}::/$mask dev $tst_vti 312 else 313 ip_loc_tun="${IPV4_NET16_UNUSED}.1.1"; 314 ip_rmt_tun="${IPV4_NET16_UNUSED}.1.2"; 315 mask=30 316 ROD ip route add ${IPV4_NET16_UNUSED}.1.0/$mask dev $tst_vti 317 fi 318 319 tst_resm TINFO "Add IPs to vti tunnel, " \ 320 "loc: $ip_loc_tun/$mask, rmt: $ip_rmt_tun/$mask" 321 322 ROD ip a add $ip_loc_tun/$mask dev $tst_vti nodad 323 tst_rhost_run -s -c "ip a add $ip_rmt_tun/$mask dev $tst_vti" 324} 325