Home | History | Annotate | Download | only in virt
      1 #!/bin/sh
      2 # Copyright (c) 2014-2016 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 (at] 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 
     31 ip_local=$(tst_ipaddr)
     32 ip_virt_local="192.168.124.1"
     33 ip6_virt_local="fe80::381c:c0ff:fea8:7c01"
     34 mac_virt_local="3A:1C:C0:A8:7C:01"
     35 
     36 ip_remote=$(tst_ipaddr rhost)
     37 ip_virt_remote="192.168.124.2"
     38 ip6_virt_remote="fe80::381c:c0ff:fea8:7c02"
     39 mac_virt_remote="3A:1C:C0:A8:7C:02"
     40 
     41 # Max performance loss (%) for virtual devices during network load
     42 VIRT_PERF_THRESHOLD=${VIRT_PERF_THRESHOLD:-80}
     43 vxlan_dstport=0
     44 
     45 clients_num=2
     46 client_requests=500000
     47 max_requests=20
     48 
     49 while getopts :hsx:i:r:c:R:p:n:t:d:6 opt; do
     50 	case "$opt" in
     51 	h)
     52 		echo "Usage:"
     53 		echo "h        help"
     54 		echo "s        use ssh to run remote cmds"
     55 		echo "x n      n is a number of interfaces for tc1 and tc2"
     56 		echo "i n      start ID to use"
     57 		echo "r n      client requests for TCP performance test"
     58 		echo "c n      clients run concurrently in TCP perf"
     59 		echo "R n      num of reqs, after which conn.closed in TCP perf"
     60 		echo "p x      x and x + 1 are ports in TCP perf"
     61 		echo "n x      virtual network 192.168.x"
     62 		echo "t x      performance threshold, default is 60%"
     63 		echo "d x      VxLAN destination address, 'uni' or 'multi'"
     64 		echo "6        run over IPv6"
     65 		exit 0
     66 	;;
     67 	s) TST_USE_SSH=1 ;;
     68 	x) virt_count=$OPTARG ;;
     69 	i) start_id=$OPTARG ;;
     70 	c) clients_num=$OPTARG ;;
     71 	r) client_requests=$OPTARG ;;
     72 	R) max_requests=$OPTARG ;;
     73 	p) srv_port=$OPTARG ;;
     74 	n)
     75 		ip_virt_local="192.168.${OPTARG}.1"
     76 		ip_virt_remote="192.168.${OPTARG}.2"
     77 	;;
     78 	t) VIRT_PERF_THRESHOLD=$OPTARG ;;
     79 	d) vxlan_dst_addr=$OPTARG ;;
     80 	6) # skip, test_net library already processed it
     81 	;;
     82 	*)
     83 		tst_brkm TBROK "unknown option: $opt"
     84 	;;
     85 	esac
     86 done
     87 
     88 cleanup_vifaces()
     89 {
     90 	tst_resm TINFO "cleanup virtual interfaces..."
     91 	local viface=`ip li | sed -nE 's/^[0-9]+: (ltp_v[0-9]+)[@:].+/\1/p'`
     92 	for vx in $viface; do
     93 		ip link delete $vx
     94 	done
     95 }
     96 
     97 TST_CLEANUP="cleanup_vifaces"
     98 trap "tst_brkm TBROK 'test interrupted'" INT
     99 
    100 virt_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 	;;
    111 	geneve)
    112 		[ -z "$opt" ] && opt="id 4094 remote $(tst_ipaddr rhost)"
    113 	;;
    114 	gre|ip6gre)
    115 		[ -z "$opt" ] && \
    116 			opt="remote $(tst_ipaddr rhost) dev $(tst_iface)"
    117 	;;
    118 	esac
    119 
    120 	case $virt_type in
    121 	vxlan|geneve)
    122 		ip li add $vname type $virt_type $opt
    123 	;;
    124 	gre|ip6gre)
    125 		ip -f inet$TST_IPV6 tu add $vname mode $virt_type $opt
    126 	;;
    127 	*)
    128 		ip li add link $(tst_iface) $vname type $virt_type $opt
    129 	;;
    130 	esac
    131 }
    132 
    133 virt_add_rhost()
    134 {
    135 	local opt=""
    136 	case $virt_type in
    137 	vxlan|geneve)
    138 		[ "$vxlan_dstport" -eq 1 ] && opt="dstport 0"
    139 		tst_rhost_run -s -c "ip li add ltp_v0 type $virt_type $@ $opt"
    140 	;;
    141 	gre|ip6gre)
    142 		tst_rhost_run -s -c "ip -f inet$TST_IPV6 tu add ltp_v0 \
    143 				     mode $virt_type $@"
    144 	;;
    145 	*)
    146 		tst_rhost_run -s -c "ip li add link $(tst_iface rhost) ltp_v0 \
    147 				     type $virt_type $@"
    148 	;;
    149 	esac
    150 }
    151 
    152 virt_multiple_add_test()
    153 {
    154 	local opt="$@"
    155 	local max=$(($start_id + $virt_count - 1))
    156 
    157 	tst_resm TINFO "add $virt_count $virt_type, then delete"
    158 
    159 	for i in $(seq $start_id $max); do
    160 		ROD_SILENT "virt_add ltp_v$i id $i $opt"
    161 		ROD_SILENT "ip link set ltp_v$i up"
    162 	done
    163 
    164 	for i in $(seq $start_id $max); do
    165 		ROD_SILENT "ip link set ltp_v$i down"
    166 		ROD_SILENT "ip link delete ltp_v$i"
    167 	done
    168 
    169 	tst_resm TPASS "done"
    170 }
    171 
    172 virt_add_delete_test()
    173 {
    174 	local opt="$@"
    175 	local max=$(($virt_count - 1))
    176 
    177 	tst_resm TINFO "add/del $virt_type $virt_count times"
    178 
    179 	for i in $(seq 0 $max); do
    180 		ROD_SILENT "virt_add ltp_v0 $opt"
    181 		ROD_SILENT "ip link set ltp_v0 up"
    182 		ROD_SILENT "ip link delete ltp_v0"
    183 	done
    184 	tst_resm TPASS "done"
    185 }
    186 
    187 virt_setup()
    188 {
    189 	local opt="$1"
    190 	local opt_r="$2"
    191 
    192 	tst_resm TINFO "setup local ${virt_type} with '$opt'"
    193 	ROD_SILENT "virt_add ltp_v0 $opt"
    194 
    195 	tst_resm TINFO "setup rhost ${virt_type} with '$opt_r'"
    196 	virt_add_rhost "$opt_r"
    197 
    198 	case $virt_type in
    199 	gre|ip6gre)
    200 		# We can't set hwaddr to GRE tunnel, add IPv6 link local
    201 		# addresses manually.
    202 		ROD_SILENT "ip addr add ${ip6_virt_local}/64 dev ltp_v0"
    203 		tst_rhost_run -s -c "ip ad add ${ip6_virt_remote}/64 dev ltp_v0"
    204 	;;
    205 	*)
    206 		ROD_SILENT "ip li set ltp_v0 address $mac_virt_local"
    207 		tst_rhost_run -s -c "ip li set ltp_v0 address $mac_virt_remote"
    208 	;;
    209 	esac
    210 
    211 	ROD_SILENT "ip addr add ${ip_virt_local}/24 dev ltp_v0"
    212 	tst_rhost_run -s -c "ip addr add ${ip_virt_remote}/24 dev ltp_v0"
    213 
    214 	ROD_SILENT "ip li set up ltp_v0"
    215 	tst_rhost_run -s -c "ip li set up ltp_v0"
    216 }
    217 
    218 vxlan_setup_subnet_uni()
    219 {
    220 	if tst_kvcmp -lt "3.10"; then
    221 		tst_brkm TCONF "test must be run with kernel 3.10 or newer"
    222 	fi
    223 
    224 	[ "$(ip li add type $virt_type help 2>&1 | grep remote)" ] || \
    225 		tst_brkm TCONF "iproute doesn't support remote unicast address"
    226 
    227 	local opt="$1 remote $(tst_ipaddr rhost)"
    228 	local opt_r="$2 remote $(tst_ipaddr)"
    229 
    230 	virt_setup "$opt" "$opt_r"
    231 }
    232 
    233 vxlan_setup_subnet_multi()
    234 {
    235 	tst_check_cmds "od"
    236 	local b1=$(($(od -An -d -N1 /dev/urandom) % 254 + 1))
    237 	local b2=$(($(od -An -d -N1 /dev/urandom) % 254 + 1))
    238 	local b3=$(($(od -An -d -N1 /dev/urandom) % 254 + 1))
    239 
    240 	local grp=
    241 	if [ "$TST_IPV6" ]; then
    242 		grp="group ff05::$(printf '%x:%x%x' $b1 $b2 $b3)"
    243 	else
    244 		grp="group 239.$b1.$b2.$b3"
    245 	fi
    246 
    247 	local opt="$1 $grp dev $(tst_iface)"
    248 	local opt_r="$2 $grp dev $(tst_iface rhost)"
    249 
    250 	virt_setup "$opt" "$opt_r"
    251 }
    252 
    253 virt_compare_netperf()
    254 {
    255 	local ret1="pass"
    256 	local ret2="pass"
    257 	local expect_res="${1:-pass}"
    258 
    259 	tst_netload -H $ip_virt_remote -a $clients_num -R $max_requests \
    260 		-r $client_requests -d res_ipv4 -e $expect_res || ret1="fail"
    261 
    262 	tst_netload -H ${ip6_virt_remote}%ltp_v0 -a $clients_num \
    263 		-R $max_requests -r $client_requests -d res_ipv6 \
    264 		-e $expect_res || ret2="fail"
    265 
    266 	ROD_SILENT "ip link delete ltp_v0"
    267 	tst_rhost_run -s -c "ip link delete ltp_v0"
    268 
    269 	[ "$ret1" = "fail" -o "$ret2" = "fail" ] && return
    270 
    271 	local vt="$(cat res_ipv4)"
    272 	local vt6="$(cat res_ipv6)"
    273 
    274 	tst_netload -H $ip_remote -a $clients_num -R $max_requests \
    275 		-r $client_requests -d res_ipv4
    276 
    277 	local lt="$(cat res_ipv4)"
    278 	tst_resm TINFO "time lan($lt) $virt_type IPv4($vt) and IPv6($vt6) ms"
    279 
    280 	per=$(( $vt * 100 / $lt - 100 ))
    281 	per6=$(( $vt6 * 100 / $lt - 100 ))
    282 
    283 	case "$virt_type" in
    284 	vxlan|geneve)
    285 		tst_resm TINFO "IP4 $virt_type over IP$ipver slower by $per %"
    286 		tst_resm TINFO "IP6 $virt_type over IP$ipver slower by $per6 %"
    287 	;;
    288 	*)
    289 		tst_resm TINFO "IP4 $virt_type slower by $per %"
    290 		tst_resm TINFO "IP6 $virt_type slower by $per6 %"
    291 	esac
    292 
    293 	if [ "$per" -ge "$VIRT_PERF_THRESHOLD" -o \
    294 	     "$per6" -ge "$VIRT_PERF_THRESHOLD" ]; then
    295 		tst_resm TFAIL "Test failed, threshold: $VIRT_PERF_THRESHOLD %"
    296 	else
    297 		tst_resm TPASS "Test passed, threshold: $VIRT_PERF_THRESHOLD %"
    298 	fi
    299 }
    300 
    301 virt_check_cmd()
    302 {
    303 	$@ > /dev/null 2>&1
    304 	if [ $? -ne 0 ]; then
    305 		tst_resm TCONF "'$@' option(s) not supported, skipping it"
    306 		return 1
    307 	fi
    308 	ROD_SILENT "ip li delete ltp_v0"
    309 	return 0
    310 }
    311 
    312 # Check if we can create then delete virtual interface n times.
    313 # virt_test_01 [OPTIONS]
    314 # OPTIONS - different options separated by comma.
    315 virt_test_01()
    316 {
    317 	start_id=${start_id:-"1"}
    318 	virt_count=${virt_count:-"400"}
    319 
    320 	local opts=${1:-""}
    321 	local n=0
    322 
    323 	while true; do
    324 		n=$((n + 1))
    325 		p="$(echo $opts | cut -d',' -f$n)"
    326 		if [ -z "$p" -a $n -gt 1 ]; then
    327 			break
    328 		fi
    329 
    330 		tst_resm TINFO "add $virt_type with '$p'"
    331 
    332 		virt_check_cmd virt_add ltp_v0 id 0 $p || continue
    333 
    334 		virt_multiple_add_test "$p"
    335 
    336 		start_id=$(($start_id + $virt_count))
    337 	done
    338 }
    339 
    340 # Check if we can create then delete virtual interface n times.
    341 # virt_test_02 [OPTIONS]
    342 # OPTIONS - different options separated by comma.
    343 virt_test_02()
    344 {
    345 	start_id=${start_id:-"1"}
    346 	virt_count=${virt_count:-"500"}
    347 
    348 	local opts=${1:-""}
    349 	local n=0
    350 
    351 	while true; do
    352 		n=$((n + 1))
    353 		p="$(echo $opts | cut -d',' -f$n)"
    354 		if [ -z "$p" -a $n -gt 1 ]; then
    355 			break
    356 		fi
    357 
    358 		tst_resm TINFO "add and then delete $virt_type with '$p'"
    359 
    360 		virt_check_cmd virt_add ltp_v0 $p || continue
    361 
    362 		virt_add_delete_test "$p"
    363 
    364 		start_id=$(($start_id + $virt_count))
    365 	done
    366 }
    367 
    368 tst_require_root
    369 
    370 case "$virt_type" in
    371 vxlan|geneve)
    372 	if tst_kvcmp -lt "3.8"; then
    373 		tst_brkm TCONF "test must be run with kernel 3.8 or newer"
    374 	fi
    375 
    376 	if [ "$TST_IPV6" ] && tst_kvcmp -lt "3.12"; then
    377 		tst_brkm TCONF "test must be run with kernels >= 3.12"
    378 	fi
    379 
    380 	# newer versions of 'ip' complain if this option not set
    381 	ip li add type vxlan help 2>&1 | grep -q dstport && vxlan_dstport=1
    382 ;;
    383 esac
    384 
    385 ipver=${TST_IPV6:-'4'}
    386 
    387 tst_check_cmds "ip"
    388 
    389 virt_add ltp_v0 || \
    390 	tst_brkm TCONF "iproute2 or kernel doesn't support $virt_type"
    391 
    392 ROD_SILENT "ip link delete ltp_v0"
    393