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