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