1#!/bin/sh 2# Copyright (c) 2014-2017 Oracle and/or its affiliates. All Rights Reserved. 3# 4# This program is free software; you can redistribute it and/or 5# modify it under the terms of the GNU General Public License as 6# published by the Free Software Foundation; either version 2 of 7# the License, or (at your option) any later version. 8# 9# This program is distributed in the hope that it would be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16# 17# Author: Alexey Kodanev <alexey.kodanev@oracle.com> 18# 19# VxLAN 20# ----- 21# Virtual eXtensible Local Area Network (VxLAN) provides L2 networks 22# over existed L3 networks. It is using UDP (port 8472) to encapsulate 23# data packets. More information: 24# http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-08 25# 26# Warning: Test assumes that machines don't have any existed VxLANs. 27# If machine has VxLANs, the test might fail or eventually delete 28# them in cleanup function. See "start_vni" variable which can 29# solve it. 30 31ip_local=$(tst_ipaddr) 32ip_virt_local="$(TST_IPV6= tst_ipaddr_un)" 33ip6_virt_local="$(TST_IPV6=6 tst_ipaddr_un)" 34 35ip_remote=$(tst_ipaddr rhost) 36ip_virt_remote="$(TST_IPV6= tst_ipaddr_un rhost)" 37ip6_virt_remote="$(TST_IPV6=6 tst_ipaddr_un rhost)" 38 39# Max performance loss (%) for virtual devices during network load 40VIRT_PERF_THRESHOLD=${VIRT_PERF_THRESHOLD:-80} 41vxlan_dstport=0 42 43while getopts :hi:d:6 opt; do 44 case "$opt" in 45 h) 46 echo "Usage:" 47 echo "h help" 48 echo "i n start ID to use" 49 echo "d x VxLAN destination address, 'uni' or 'multi'" 50 echo "6 run over IPv6" 51 exit 0 52 ;; 53 i) start_id=$OPTARG ;; 54 d) vxlan_dst_addr=$OPTARG ;; 55 6) # skip, test_net library already processed it 56 ;; 57 *) 58 tst_brkm TBROK "unknown option: $opt" 59 ;; 60 esac 61done 62 63cleanup_vifaces() 64{ 65 tst_resm TINFO "cleanup virtual interfaces..." 66 local viface=`ip li | sed -nE 's/^[0-9]+: (ltp_v[0-9]+)[@:].+/\1/p'` 67 for vx in $viface; do 68 ip link delete $vx 69 done 70} 71 72virt_cleanup_rmt() 73{ 74 cleanup_vifaces 75 tst_rhost_run -c "ip link delete ltp_v0 2>/dev/null" 76 if [ "$virt_tcp_syn" ]; then 77 sysctl -q net.ipv4.tcp_syn_retries=$virt_tcp_syn 78 virt_tcp_syn= 79 fi 80} 81 82virt_cleanup() 83{ 84 virt_cleanup_rmt 85 [ "$TST_NEEDS_TMPDIR" = 1 ] && tst_rmdir 86} 87 88TST_CLEANUP="cleanup_vifaces" 89trap "tst_brkm TBROK 'test interrupted'" INT 90 91virt_add() 92{ 93 local vname=$1 94 shift 95 local opt="$*" 96 97 case $virt_type in 98 vlan|vxlan) 99 [ -z "$opt" ] && opt="id 4094" 100 [ "$vxlan_dstport" -eq 1 ] && opt="dstport 0 $opt" 101 ;; 102 geneve) 103 [ -z "$opt" ] && opt="id 4094 remote $(tst_ipaddr rhost)" 104 ;; 105 gre|ip6gre) 106 [ -z "$opt" ] && \ 107 opt="remote $(tst_ipaddr rhost) dev $(tst_iface)" 108 ;; 109 esac 110 111 case $virt_type in 112 vxlan|geneve) 113 ip li add $vname type $virt_type $opt dev $(tst_iface) 114 ;; 115 gre|ip6gre) 116 ip -f inet$TST_IPV6 tu add $vname mode $virt_type $opt 117 ;; 118 *) 119 ip li add link $(tst_iface) $vname type $virt_type $opt 120 ;; 121 esac 122} 123 124virt_add_rhost() 125{ 126 local opt="" 127 case $virt_type in 128 vxlan|geneve) 129 opt="dev $(tst_iface rhost)" 130 [ "$vxlan_dstport" -eq 1 ] && opt="$opt dstport 0" 131 tst_rhost_run -s -c "ip li add ltp_v0 type $virt_type $@ $opt" 132 ;; 133 gre|ip6gre) 134 tst_rhost_run -s -c "ip -f inet$TST_IPV6 tu add ltp_v0 \ 135 mode $virt_type $@" 136 ;; 137 *) 138 tst_rhost_run -s -c "ip li add link $(tst_iface rhost) ltp_v0 \ 139 type $virt_type $@" 140 ;; 141 esac 142} 143 144virt_multiple_add_test() 145{ 146 local opt="$@" 147 local max=$(($start_id + $NS_TIMES - 1)) 148 149 tst_resm TINFO "add $NS_TIMES $virt_type, then delete" 150 151 for i in $(seq $start_id $max); do 152 virt_add ltp_v$i id $i $opt || \ 153 tst_brkm TFAIL "failed to create 'ltp_v0 $opt'" 154 ROD_SILENT "ip link set ltp_v$i up" 155 done 156 157 for i in $(seq $start_id $max); do 158 ROD_SILENT "ip link set ltp_v$i down" 159 ROD_SILENT "ip link delete ltp_v$i" 160 done 161 162 tst_resm TPASS "done" 163} 164 165virt_add_delete_test() 166{ 167 local opt="$@" 168 local max=$(($NS_TIMES - 1)) 169 170 tst_resm TINFO "add/del $virt_type $NS_TIMES times" 171 172 for i in $(seq 0 $max); do 173 virt_add ltp_v0 $opt || \ 174 tst_brkm TFAIL "failed to create 'ltp_v0 $opt'" 175 ROD_SILENT "ip link set ltp_v0 up" 176 ROD_SILENT "ip link delete ltp_v0" 177 done 178 tst_resm TPASS "done" 179} 180 181virt_setup() 182{ 183 local opt="$1" 184 local opt_r="${2:-$1}" 185 186 tst_resm TINFO "setup local ${virt_type} with '$opt'" 187 virt_add ltp_v0 $opt || \ 188 tst_brkm TBROK "failed to create 'ltp_v0 $opt'" 189 190 tst_resm TINFO "setup rhost ${virt_type} with '$opt_r'" 191 virt_add_rhost "$opt_r" 192 193 ROD_SILENT "ip addr add ${ip6_virt_local}/64 dev ltp_v0 nodad" 194 tst_rhost_run -s -c "ip ad add ${ip6_virt_remote}/64 dev ltp_v0 nodad" 195 196 ROD_SILENT "ip addr add ${ip_virt_local}/24 dev ltp_v0" 197 tst_rhost_run -s -c "ip addr add ${ip_virt_remote}/24 dev ltp_v0" 198 199 ROD_SILENT "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0" 200 tst_rhost_run -s -c "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0" 201 202 ROD_SILENT "ip li set up ltp_v0" 203 tst_rhost_run -s -c "ip li set up ltp_v0" 204} 205 206virt_tcp_syn= 207virt_minimize_timeout() 208{ 209 local mac_loc="$(cat /sys/class/net/ltp_v0/address)" 210 local mac_rmt="$(tst_rhost_run -c 'cat /sys/class/net/ltp_v0/address')" 211 212 ROD_SILENT "ip ne replace $ip_virt_remote lladdr \ 213 $mac_rmt nud permanent dev ltp_v0" 214 tst_rhost_run -s -c "ip ne replace $ip_virt_local lladdr \ 215 $mac_loc nud permanent dev ltp_v0" 216 virt_tcp_syn=$(sysctl -n net.ipv4.tcp_syn_retries) 217 ROD sysctl -q net.ipv4.tcp_syn_retries=1 218} 219 220vxlan_setup_subnet_uni() 221{ 222 if tst_kvcmp -lt "3.10"; then 223 tst_brkm TCONF "test must be run with kernel 3.10 or newer" 224 fi 225 226 [ "$(ip li add type $virt_type help 2>&1 | grep remote)" ] || \ 227 tst_brkm TCONF "iproute doesn't support remote unicast address" 228 229 local opt="$1 remote $(tst_ipaddr rhost)" 230 local opt_r="$2 remote $(tst_ipaddr)" 231 232 virt_setup "$opt" "$opt_r" 233} 234 235vxlan_setup_subnet_multi() 236{ 237 tst_check_cmds "od" 238 local b1=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 239 local b2=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 240 local b3=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 241 242 local grp= 243 if [ "$TST_IPV6" ]; then 244 grp="group ff05::$(printf '%x:%x%x' $b1 $b2 $b3)" 245 else 246 grp="group 239.$b1.$b2.$b3" 247 fi 248 249 local opt="$1 $grp" 250 local opt_r="$2 $grp" 251 252 virt_setup "$opt" "$opt_r" 253} 254 255virt_compare_netperf() 256{ 257 local ret1="pass" 258 local ret2="pass" 259 local expect_res="${1:-pass}" 260 local opts="$2" 261 262 tst_netload -H $ip_virt_remote $opts -d res_ipv4 -e $expect_res || \ 263 ret1="fail" 264 265 tst_netload -H ${ip6_virt_remote} $opts -d res_ipv6 -e $expect_res || \ 266 ret2="fail" 267 268 [ "$ret1" = "fail" -o "$ret2" = "fail" ] && return 269 270 local vt="$(cat res_ipv4)" 271 local vt6="$(cat res_ipv6)" 272 273 tst_netload -H $ip_remote $opts -d res_ipv4 274 275 local lt="$(cat res_ipv4)" 276 tst_resm TINFO "time lan($lt) $virt_type IPv4($vt) and IPv6($vt6) ms" 277 278 per=$(( $vt * 100 / $lt - 100 )) 279 per6=$(( $vt6 * 100 / $lt - 100 )) 280 281 case "$virt_type" in 282 vxlan|geneve) 283 tst_resm TINFO "IP4 $virt_type over IP$ipver slower by $per %" 284 tst_resm TINFO "IP6 $virt_type over IP$ipver slower by $per6 %" 285 ;; 286 *) 287 tst_resm TINFO "IP4 $virt_type slower by $per %" 288 tst_resm TINFO "IP6 $virt_type slower by $per6 %" 289 esac 290 291 if [ "$per" -ge "$VIRT_PERF_THRESHOLD" -o \ 292 "$per6" -ge "$VIRT_PERF_THRESHOLD" ]; then 293 tst_resm TFAIL "Test failed, threshold: $VIRT_PERF_THRESHOLD %" 294 else 295 tst_resm TPASS "Test passed, threshold: $VIRT_PERF_THRESHOLD %" 296 fi 297} 298 299virt_check_cmd() 300{ 301 $@ > /dev/null 2>&1 302 if [ $? -ne 0 ]; then 303 tst_resm TCONF "'$@' option(s) not supported, skipping it" 304 return 1 305 fi 306 ROD_SILENT "ip li delete ltp_v0" 307 return 0 308} 309 310# virt_macsec_setup [OPTIONS] 311# OPTIONS - [ cipher { default | gcm-aes-128 } ] [ encrypt { on | off } ] 312# [ protect { on | off } ] [ replay { on | off } ] [ window WINDOW ] 313# [ validate { strict | check | disabled } ] 314virt_macsec_setup() 315{ 316 local keyid0=01 317 local keyid1=02 318 local sa=0 319 local h0=$(tst_hwaddr) 320 local h1=$(tst_hwaddr rhost) 321 local cmd="ip macsec add ltp_v0" 322 local key0="01234567890123456789012345678901" 323 local key1="98765432109876543210987612343434" 324 325 virt_setup "icvlen 16 encodingsa $sa $@" 326 327 ROD $cmd tx sa $sa pn 100 on key $keyid0 $key0 328 ROD $cmd rx address $h1 port 1 329 ROD $cmd rx address $h1 port 1 sa $sa pn 100 on key $keyid1 $key1 330 331 tst_rhost_run -s -c "$cmd tx sa $sa pn 100 on key $keyid1 $key1" 332 tst_rhost_run -s -c "$cmd rx address $h0 port 1" 333 tst_rhost_run -s -c \ 334 "$cmd rx address $h0 port 1 sa $sa pn 100 on key $keyid0 $key0" 335} 336 337virt_netperf_msg_sizes() 338{ 339 local sizes="${@:-100 1000 2000 10000}" 340 client_requests=20000 341 342 for s in $sizes; do 343 virt_compare_netperf pass "-n $s -N $s" 344 done 345} 346 347# Check if we can create then delete virtual interface n times. 348# virt_test_01 [OPTIONS] 349# OPTIONS - different options separated by comma. 350virt_test_01() 351{ 352 start_id=${start_id:-"1"} 353 local opts=${1:-""} 354 local n=0 355 356 while true; do 357 n=$((n + 1)) 358 p="$(echo $opts | cut -d',' -f$n)" 359 if [ -z "$p" -a $n -gt 1 ]; then 360 break 361 fi 362 363 tst_resm TINFO "add $virt_type with '$p'" 364 365 virt_check_cmd virt_add ltp_v0 id 0 $p || continue 366 367 virt_multiple_add_test "$p" 368 369 start_id=$(($start_id + $NS_TIMES)) 370 done 371} 372 373# Check if we can create then delete virtual interface n times. 374# virt_test_02 [OPTIONS] 375# OPTIONS - different options separated by comma. 376virt_test_02() 377{ 378 start_id=${start_id:-"1"} 379 local opts=${1:-""} 380 local n=0 381 382 while true; do 383 n=$((n + 1)) 384 p="$(echo $opts | cut -d',' -f$n)" 385 if [ -z "$p" -a $n -gt 1 ]; then 386 break 387 fi 388 389 tst_resm TINFO "add and then delete $virt_type with '$p'" 390 391 virt_check_cmd virt_add ltp_v0 $p || continue 392 393 virt_add_delete_test "$p" 394 395 start_id=$(($start_id + $NS_TIMES)) 396 done 397} 398 399tst_require_root 400 401case "$virt_type" in 402vxlan|geneve) 403 if tst_kvcmp -lt "3.8"; then 404 tst_brkm TCONF "test must be run with kernel 3.8 or newer" 405 fi 406 407 if [ "$TST_IPV6" ] && tst_kvcmp -lt "3.12"; then 408 tst_brkm TCONF "test must be run with kernels >= 3.12" 409 fi 410 411 # newer versions of 'ip' complain if this option not set 412 ip li add type vxlan help 2>&1 | grep -q dstport && vxlan_dstport=1 413;; 414esac 415 416ipver=${TST_IPV6:-'4'} 417 418tst_check_cmds "ip" 419 420virt_add ltp_v0 || \ 421 tst_brkm TCONF "iproute2 or kernel doesn't support $virt_type" 422 423ROD_SILENT "ip link delete ltp_v0" 424