1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2018 Petr Vorel <pvorel@suse.cz> 4# Copyright (c) 2014-2017 Oracle and/or its affiliates. All Rights Reserved. 5# Author: Alexey Kodanev <alexey.kodanev@oracle.com> 6# 7# VxLAN 8# ----- 9# Virtual eXtensible Local Area Network (VxLAN) provides L2 networks 10# over existed L3 networks. It is using UDP (port 8472) to encapsulate 11# data packets. More information: 12# http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-08 13# 14# Warning: Test assumes that machines don't have any existed VxLANs. 15# If machine has VxLANs, the test might fail or eventually delete 16# them in cleanup function. See "start_vni" variable which can 17# solve it. 18 19TST_SETUP="${TST_SETUP:-virt_lib_setup}" 20TST_CLEANUP="${TST_CLEANUP:-cleanup_vifaces}" 21 22virt_lib_usage() 23{ 24 echo "i n start ID to use" 25 echo "d x VxLAN destination address, 'uni' or 'multi'" 26} 27 28virt_lib_parse_args() 29{ 30 case "$1" in 31 i) start_id=$2 ;; 32 d) vxlan_dst_addr=$2 ;; 33 esac 34} 35 36virt_lib_setup() 37{ 38 case "$virt_type" in 39 vxlan|geneve) 40 if tst_kvcmp -lt "3.8"; then 41 tst_brk TCONF "test must be run with kernel 3.8 or newer" 42 fi 43 44 if [ "$TST_IPV6" ] && tst_kvcmp -lt "3.12"; then 45 tst_brk TCONF "test must be run with kernels >= 3.12" 46 fi 47 48 # newer versions of 'ip' complain if this option not set 49 ip li add type vxlan help 2>&1 | grep -q dstport && vxlan_dstport=1 50 ;; 51 esac 52 53 tst_test_cmds "ip" 54 55 virt_add ltp_v0 || \ 56 tst_brk TCONF "iproute2 or kernel doesn't support $virt_type" 57 58 ROD_SILENT "ip link delete ltp_v0" 59} 60 61TST_NEEDS_ROOT=1 62. tst_net.sh 63 64ip_local=$(tst_ipaddr) 65ip_virt_local="$(TST_IPV6= tst_ipaddr_un)" 66ip6_virt_local="$(TST_IPV6=6 tst_ipaddr_un)" 67 68ip_remote=$(tst_ipaddr rhost) 69ip_virt_remote="$(TST_IPV6= tst_ipaddr_un rhost)" 70ip6_virt_remote="$(TST_IPV6=6 tst_ipaddr_un rhost)" 71 72# Max performance loss (%) for virtual devices during network load 73VIRT_PERF_THRESHOLD=${VIRT_PERF_THRESHOLD:-80} 74vxlan_dstport=0 75 76cleanup_vifaces() 77{ 78 tst_res TINFO "cleanup virtual interfaces..." 79 local viface=`ip li | sed -nE 's/^[0-9]+: (ltp_v[0-9]+)[@:].+/\1/p'` 80 for vx in $viface; do 81 ip link delete $vx 82 done 83} 84 85virt_cleanup_rmt() 86{ 87 cleanup_vifaces 88 tst_rhost_run -c "ip link delete ltp_v0 2>/dev/null" 89 if [ "$virt_tcp_syn" ]; then 90 sysctl -q net.ipv4.tcp_syn_retries=$virt_tcp_syn 91 virt_tcp_syn= 92 fi 93} 94 95virt_cleanup() 96{ 97 virt_cleanup_rmt 98} 99 100virt_add() 101{ 102 local vname=$1 103 shift 104 local opt="$*" 105 106 case $virt_type in 107 vlan|vxlan) 108 [ -z "$opt" ] && opt="id 4094" 109 [ "$vxlan_dstport" -eq 1 ] && opt="dstport 0 $opt" 110 [ "$virt_type" = "vxlan" ] && opt="$opt dev $(tst_iface)" 111 ;; 112 geneve) 113 [ -z "$opt" ] && opt="id 4094 remote $(tst_ipaddr rhost)" 114 ;; 115 gre|ip6gre) 116 [ -z "$opt" ] && \ 117 opt="remote $(tst_ipaddr rhost) dev $(tst_iface)" 118 ;; 119 sit) 120 [ -z "$opt" ] && opt="remote $(tst_ipaddr rhost) local $(tst_ipaddr)" 121 ;; 122 esac 123 124 case $virt_type in 125 vxlan|geneve|sit) 126 ip li add $vname type $virt_type $opt 127 ;; 128 gre|ip6gre) 129 ip -f inet$TST_IPV6 tu add $vname mode $virt_type $opt 130 ;; 131 *) 132 ip li add link $(tst_iface) $vname type $virt_type $opt 133 ;; 134 esac 135} 136 137virt_add_rhost() 138{ 139 local opt="" 140 case $virt_type in 141 vxlan|geneve) 142 [ "$virt_type" = "vxlan" ] && opt="dev $(tst_iface rhost)" 143 [ "$vxlan_dstport" -eq 1 ] && opt="$opt dstport 0" 144 tst_rhost_run -s -c "ip li add ltp_v0 type $virt_type $@ $opt" 145 ;; 146 sit) 147 tst_rhost_run -s -c "ip link add ltp_v0 type $virt_type $@" 148 ;; 149 gre|ip6gre) 150 tst_rhost_run -s -c "ip -f inet$TST_IPV6 tu add ltp_v0 \ 151 mode $virt_type $@" 152 ;; 153 *) 154 tst_rhost_run -s -c "ip li add link $(tst_iface rhost) ltp_v0 \ 155 type $virt_type $@" 156 ;; 157 esac 158} 159 160virt_multiple_add_test() 161{ 162 local opt="$@" 163 local max=$(($start_id + $NS_TIMES - 1)) 164 local i 165 166 tst_res TINFO "add $NS_TIMES $virt_type, then delete" 167 168 for i in $(seq $start_id $max); do 169 virt_add ltp_v$i id $i $opt || \ 170 tst_brk TFAIL "failed to create 'ltp_v0 $opt'" 171 ROD_SILENT "ip link set ltp_v$i up" 172 done 173 174 for i in $(seq $start_id $max); do 175 ROD_SILENT "ip link set ltp_v$i down" 176 ROD_SILENT "ip link delete ltp_v$i" 177 done 178 179 tst_res TPASS "done" 180} 181 182virt_add_delete_test() 183{ 184 local opt="$@" 185 local max=$(($NS_TIMES - 1)) 186 local i 187 188 tst_res TINFO "add/del $virt_type $NS_TIMES times" 189 190 for i in $(seq 0 $max); do 191 virt_add ltp_v0 $opt || \ 192 tst_brk TFAIL "failed to create 'ltp_v0 $opt'" 193 ROD_SILENT "ip link set ltp_v0 up" 194 ROD_SILENT "ip link delete ltp_v0" 195 done 196 tst_res TPASS "done" 197} 198 199virt_setup() 200{ 201 local opt="$1" 202 local opt_r="${2:-$1}" 203 204 tst_res TINFO "setup local ${virt_type} with '$opt'" 205 virt_add ltp_v0 $opt || \ 206 tst_brk TBROK "failed to create 'ltp_v0 $opt'" 207 208 tst_res TINFO "setup rhost ${virt_type} with '$opt_r'" 209 virt_add_rhost "$opt_r" 210 211 ROD_SILENT "ip addr add ${ip6_virt_local}/64 dev ltp_v0 nodad" 212 tst_rhost_run -s -c "ip ad add ${ip6_virt_remote}/64 dev ltp_v0 nodad" 213 214 ROD_SILENT "ip addr add ${ip_virt_local}/24 dev ltp_v0" 215 tst_rhost_run -s -c "ip addr add ${ip_virt_remote}/24 dev ltp_v0" 216 217 ROD_SILENT "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0" 218 tst_rhost_run -s -c "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0" 219 220 ROD_SILENT "ip li set up ltp_v0" 221 tst_rhost_run -s -c "ip li set up ltp_v0" 222} 223 224virt_tcp_syn= 225virt_minimize_timeout() 226{ 227 local mac_loc="$(cat /sys/class/net/ltp_v0/address)" 228 local mac_rmt="$(tst_rhost_run -c 'cat /sys/class/net/ltp_v0/address')" 229 230 ROD_SILENT "ip ne replace $ip_virt_remote lladdr \ 231 $mac_rmt nud permanent dev ltp_v0" 232 tst_rhost_run -s -c "ip ne replace $ip_virt_local lladdr \ 233 $mac_loc nud permanent dev ltp_v0" 234 virt_tcp_syn=$(sysctl -n net.ipv4.tcp_syn_retries) 235 ROD sysctl -q net.ipv4.tcp_syn_retries=1 236} 237 238vxlan_setup_subnet_uni() 239{ 240 if tst_kvcmp -lt "3.10"; then 241 tst_brk TCONF "test must be run with kernel 3.10 or newer" 242 fi 243 244 [ "$(ip li add type $virt_type help 2>&1 | grep remote)" ] || \ 245 tst_brk TCONF "iproute doesn't support remote unicast address" 246 247 local opt="$1 remote $(tst_ipaddr rhost)" 248 local opt_r="$2 remote $(tst_ipaddr)" 249 250 virt_setup "$opt" "$opt_r" 251} 252 253vxlan_setup_subnet_multi() 254{ 255 tst_test_cmds "od" 256 local b1=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 257 local b2=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 258 local b3=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 259 260 local grp= 261 if [ "$TST_IPV6" ]; then 262 grp="group ff05::$(printf '%x:%x%x' $b1 $b2 $b3)" 263 else 264 grp="group 239.$b1.$b2.$b3" 265 fi 266 267 local opt="$1 $grp" 268 local opt_r="$2 $grp" 269 270 virt_setup "$opt" "$opt_r" 271} 272 273virt_compare_netperf() 274{ 275 local ret1="pass" 276 local ret2="pass" 277 local expect_res="${1:-pass}" 278 local opts="$2" 279 280 tst_netload -H $ip_virt_remote $opts -d res_ipv4 -e $expect_res \ 281 -D ltp_v0 || ret1="fail" 282 283 tst_netload -H ${ip6_virt_remote} $opts -d res_ipv6 -e $expect_res \ 284 -D ltp_v0 || ret2="fail" 285 286 [ "$ret1" = "fail" -o "$ret2" = "fail" ] && return 287 288 local vt="$(cat res_ipv4)" 289 local vt6="$(cat res_ipv6)" 290 291 tst_netload -H $ip_remote $opts -d res_ipv4 292 293 local lt="$(cat res_ipv4)" 294 tst_res TINFO "time lan($lt) $virt_type IPv4($vt) and IPv6($vt6) ms" 295 296 per=$(( $vt * 100 / $lt - 100 )) 297 per6=$(( $vt6 * 100 / $lt - 100 )) 298 299 case "$virt_type" in 300 vxlan|geneve) 301 tst_res TINFO "IP4 $virt_type over IP$TST_IPVER slower by $per %" 302 tst_res TINFO "IP6 $virt_type over IP$TST_IPVER slower by $per6 %" 303 ;; 304 *) 305 tst_res TINFO "IP4 $virt_type slower by $per %" 306 tst_res TINFO "IP6 $virt_type slower by $per6 %" 307 esac 308 309 if [ "$per" -ge "$VIRT_PERF_THRESHOLD" -o \ 310 "$per6" -ge "$VIRT_PERF_THRESHOLD" ]; then 311 tst_res TFAIL "Test failed, threshold: $VIRT_PERF_THRESHOLD %" 312 else 313 tst_res TPASS "Test passed, threshold: $VIRT_PERF_THRESHOLD %" 314 fi 315} 316 317virt_check_cmd() 318{ 319 $@ > /dev/null 2>&1 320 if [ $? -ne 0 ]; then 321 tst_res TCONF "'$@' option(s) not supported, skipping it" 322 return 1 323 fi 324 ROD_SILENT "ip li delete ltp_v0" 325 return 0 326} 327 328virt_netperf_msg_sizes() 329{ 330 local sizes="100 1000 2000 10000" 331 local s 332 333 for s in $sizes; do 334 virt_compare_netperf pass "-n $s -N $s" 335 done 336} 337 338# Check if we can create then delete virtual interface. 339virt_test_01() 340{ 341 start_id="${start_id:-1}" 342 343 tst_res TINFO "add $virt_type with '$2'" 344 virt_check_cmd virt_add ltp_v0 id 0 $2 || return 345 virt_multiple_add_test "$2" 346} 347 348# Check if we can create then delete virtual interface. 349virt_test_02() 350{ 351 start_id="${start_id:-1}" 352 353 tst_res TINFO "add and then delete $virt_type with '$2'" 354 virt_check_cmd virt_add ltp_v0 $2 || return 355 virt_add_delete_test "$2" 356 start_id=$(($start_id + $NS_TIMES)) 357} 358