1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2018-2019 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_require_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 72vxlan_dstport=0 73 74# Max performance loss (%) for virtual devices during network load 75VIRT_PERF_THRESHOLD=${VIRT_PERF_THRESHOLD:-80} 76if [ -n "$VIRT_PERF_THRESHOLD_MIN" ] && [ "$VIRT_PERF_THRESHOLD" -lt $VIRT_PERF_THRESHOLD_MIN ]; then 77 VIRT_PERF_THRESHOLD="$VIRT_PERF_THRESHOLD_MIN" 78fi 79 80cleanup_vifaces() 81{ 82 tst_res TINFO "cleanup virtual interfaces..." 83 local viface=`ip li | sed -nE 's/^[0-9]+: (ltp_v[0-9]+)[@:].+/\1/p'` 84 for vx in $viface; do 85 ip link delete $vx 86 done 87} 88 89virt_cleanup_rmt() 90{ 91 cleanup_vifaces 92 tst_rhost_run -c "ip link delete ltp_v0 2>/dev/null" 93 if [ "$virt_tcp_syn" ]; then 94 sysctl -q net.ipv4.tcp_syn_retries=$virt_tcp_syn 95 virt_tcp_syn= 96 fi 97} 98 99virt_cleanup() 100{ 101 virt_cleanup_rmt 102} 103 104virt_add() 105{ 106 local vname=$1 107 shift 108 local opt="$*" 109 110 case $virt_type in 111 vlan|vxlan) 112 [ -z "$opt" ] && opt="id 4094" 113 [ "$vxlan_dstport" -eq 1 ] && opt="dstport 0 $opt" 114 [ "$virt_type" = "vxlan" ] && opt="$opt dev $(tst_iface)" 115 ;; 116 geneve) 117 [ -z "$opt" ] && opt="id 4094 remote $(tst_ipaddr rhost)" 118 ;; 119 gre|ip6gre) 120 [ -z "$opt" ] && \ 121 opt="remote $(tst_ipaddr rhost) dev $(tst_iface)" 122 ;; 123 sit) 124 [ -z "$opt" ] && opt="remote $(tst_ipaddr rhost) local $(tst_ipaddr)" 125 ;; 126 esac 127 128 case $virt_type in 129 vxlan|geneve|sit) 130 ip li add $vname type $virt_type $opt 131 ;; 132 gre|ip6gre) 133 ip -f inet$TST_IPV6 tu add $vname mode $virt_type $opt 134 ;; 135 *) 136 ip li add link $(tst_iface) $vname type $virt_type $opt 137 ;; 138 esac 139} 140 141virt_add_rhost() 142{ 143 local opt="" 144 case $virt_type in 145 vxlan|geneve) 146 [ "$virt_type" = "vxlan" ] && opt="dev $(tst_iface rhost)" 147 [ "$vxlan_dstport" -eq 1 ] && opt="$opt dstport 0" 148 tst_rhost_run -s -c "ip li add ltp_v0 type $virt_type $@ $opt" 149 ;; 150 sit) 151 tst_rhost_run -s -c "ip link add ltp_v0 type $virt_type $@" 152 ;; 153 gre|ip6gre) 154 tst_rhost_run -s -c "ip -f inet$TST_IPV6 tu add ltp_v0 \ 155 mode $virt_type $@" 156 ;; 157 *) 158 tst_rhost_run -s -c "ip li add link $(tst_iface rhost) ltp_v0 \ 159 type $virt_type $@" 160 ;; 161 esac 162} 163 164virt_multiple_add_test() 165{ 166 local opt="$@" 167 local max=$(($start_id + $NS_TIMES - 1)) 168 local i 169 170 tst_res TINFO "add $NS_TIMES $virt_type, then delete" 171 172 for i in $(seq $start_id $max); do 173 virt_add ltp_v$i id $i $opt || \ 174 tst_brk TFAIL "failed to create 'ltp_v0 $opt'" 175 ROD_SILENT "ip link set ltp_v$i up" 176 done 177 178 for i in $(seq $start_id $max); do 179 ROD_SILENT "ip link set ltp_v$i down" 180 ROD_SILENT "ip link delete ltp_v$i" 181 done 182 183 tst_res TPASS "done" 184} 185 186virt_add_delete_test() 187{ 188 local opt="$@" 189 local max=$(($NS_TIMES - 1)) 190 local i 191 192 tst_res TINFO "add/del $virt_type $NS_TIMES times" 193 194 for i in $(seq 0 $max); do 195 virt_add ltp_v0 $opt || \ 196 tst_brk TFAIL "failed to create 'ltp_v0 $opt'" 197 ROD_SILENT "ip link set ltp_v0 up" 198 ROD_SILENT "ip link delete ltp_v0" 199 done 200 tst_res TPASS "done" 201} 202 203virt_setup() 204{ 205 local opt="$1" 206 local opt_r="${2:-$1}" 207 208 tst_res TINFO "setup local ${virt_type} with '$opt'" 209 virt_add ltp_v0 $opt || \ 210 tst_brk TBROK "failed to create 'ltp_v0 $opt'" 211 212 tst_res TINFO "setup rhost ${virt_type} with '$opt_r'" 213 virt_add_rhost "$opt_r" 214 215 ROD_SILENT "ip addr add ${ip6_virt_local}/64 dev ltp_v0 nodad" 216 tst_rhost_run -s -c "ip ad add ${ip6_virt_remote}/64 dev ltp_v0 nodad" 217 218 ROD_SILENT "ip addr add ${ip_virt_local}/24 dev ltp_v0" 219 tst_rhost_run -s -c "ip addr add ${ip_virt_remote}/24 dev ltp_v0" 220 221 ROD_SILENT "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0" 222 tst_rhost_run -s -c "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0" 223 224 ROD_SILENT "ip li set up ltp_v0" 225 tst_rhost_run -s -c "ip li set up ltp_v0" 226} 227 228virt_tcp_syn= 229virt_minimize_timeout() 230{ 231 local mac_loc="$(cat /sys/class/net/ltp_v0/address)" 232 local mac_rmt="$(tst_rhost_run -c 'cat /sys/class/net/ltp_v0/address')" 233 234 ROD_SILENT "ip ne replace $ip_virt_remote lladdr \ 235 $mac_rmt nud permanent dev ltp_v0" 236 tst_rhost_run -s -c "ip ne replace $ip_virt_local lladdr \ 237 $mac_loc nud permanent dev ltp_v0" 238 virt_tcp_syn=$(sysctl -n net.ipv4.tcp_syn_retries) 239 ROD sysctl -q net.ipv4.tcp_syn_retries=1 240} 241 242vxlan_setup_subnet_uni() 243{ 244 if tst_kvcmp -lt "3.10"; then 245 tst_brk TCONF "test must be run with kernel 3.10 or newer" 246 fi 247 248 [ "$(ip li add type $virt_type help 2>&1 | grep remote)" ] || \ 249 tst_brk TCONF "iproute doesn't support remote unicast address" 250 251 local opt="$1 remote $(tst_ipaddr rhost)" 252 local opt_r="$2 remote $(tst_ipaddr)" 253 254 virt_setup "$opt" "$opt_r" 255} 256 257vxlan_setup_subnet_multi() 258{ 259 tst_require_cmds "od" 260 local b1=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 261 local b2=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 262 local b3=$(($(od -An -d -N1 /dev/urandom) % 254 + 1)) 263 264 local grp= 265 if [ "$TST_IPV6" ]; then 266 grp="group ff05::$(printf '%x:%x%x' $b1 $b2 $b3)" 267 else 268 grp="group 239.$b1.$b2.$b3" 269 fi 270 271 local opt="$1 $grp" 272 local opt_r="$2 $grp" 273 274 virt_setup "$opt" "$opt_r" 275} 276 277virt_compare_netperf() 278{ 279 local ret1="pass" 280 local ret2="pass" 281 local expect_res="${1:-pass}" 282 local opts="$2" 283 284 tst_netload -H $ip_virt_remote $opts -d res_ipv4 -e $expect_res \ 285 -D ltp_v0 || ret1="fail" 286 287 tst_netload -H ${ip6_virt_remote} $opts -d res_ipv6 -e $expect_res \ 288 -D ltp_v0 || ret2="fail" 289 290 [ "$ret1" = "fail" -o "$ret2" = "fail" ] && return 291 292 local vt="$(cat res_ipv4)" 293 local vt6="$(cat res_ipv6)" 294 295 tst_netload -H $ip_remote $opts -d res_ipv4 296 297 local lt="$(cat res_ipv4)" 298 tst_res TINFO "time lan($lt) $virt_type IPv4($vt) and IPv6($vt6) ms" 299 300 per=$(( $vt * 100 / $lt - 100 )) 301 per6=$(( $vt6 * 100 / $lt - 100 )) 302 303 case "$virt_type" in 304 vxlan|geneve) 305 tst_res TINFO "IP4 $virt_type over IP$TST_IPVER slower by $per %" 306 tst_res TINFO "IP6 $virt_type over IP$TST_IPVER slower by $per6 %" 307 ;; 308 *) 309 tst_res TINFO "IP4 $virt_type slower by $per %" 310 tst_res TINFO "IP6 $virt_type slower by $per6 %" 311 esac 312 313 if [ "$per" -ge "$VIRT_PERF_THRESHOLD" -o \ 314 "$per6" -ge "$VIRT_PERF_THRESHOLD" ]; then 315 tst_res TFAIL "Test failed, threshold: $VIRT_PERF_THRESHOLD %" 316 else 317 tst_res TPASS "Test passed, threshold: $VIRT_PERF_THRESHOLD %" 318 fi 319} 320 321virt_check_cmd() 322{ 323 $@ > /dev/null 2>&1 324 if [ $? -ne 0 ]; then 325 tst_res TCONF "'$@' option(s) not supported, skipping it" 326 return 1 327 fi 328 ROD_SILENT "ip li delete ltp_v0" 329 return 0 330} 331 332virt_netperf_msg_sizes() 333{ 334 local sizes="100 1000 2000 $TST_NET_MAX_PKT" 335 local s 336 337 for s in $sizes; do 338 virt_compare_netperf pass "-n $s -N $s" 339 done 340} 341 342virt_netperf_rand_sizes() 343{ 344 local max_pkt_size="$TST_NET_MAX_PKT" 345 local types="tcp udp udp_lite" 346 347 for t in $types; do 348 virt_compare_netperf pass "-A $max_pkt_size -T $t" 349 done 350} 351 352# Check if we can create then delete virtual interface. 353virt_test_01() 354{ 355 start_id="${start_id:-1}" 356 357 tst_res TINFO "add $virt_type with '$2'" 358 virt_check_cmd virt_add ltp_v0 id 0 $2 || return 359 virt_multiple_add_test "$2" 360} 361 362# Check if we can create then delete virtual interface. 363virt_test_02() 364{ 365 start_id="${start_id:-1}" 366 367 tst_res TINFO "add and then delete $virt_type with '$2'" 368 virt_check_cmd virt_add ltp_v0 $2 || return 369 virt_add_delete_test "$2" 370 start_id=$(($start_id + $NS_TIMES)) 371} 372 373virt_gre_setup() 374{ 375 virt_type="gre" 376 [ "$TST_IPV6" ] && virt_type="ip6gre" 377 virt_lib_setup 378 379 if [ -z $ip_local -o -z $ip_remote ]; then 380 tst_brk TBROK "you must specify IP address" 381 fi 382 383 tst_res TINFO "test $virt_type" 384 virt_setup "local $(tst_ipaddr) remote $(tst_ipaddr rhost) dev $(tst_iface)" \ 385 "local $(tst_ipaddr rhost) remote $(tst_ipaddr) dev $(tst_iface rhost)" 386} 387