• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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
31ip_local=$(tst_ipaddr)
32ip_virt_local="192.168.124.1"
33ip6_virt_local="fe80::381c:c0ff:fea8:7c01"
34mac_virt_local="3A:1C:C0:A8:7C:01"
35
36ip_remote=$(tst_ipaddr rhost)
37ip_virt_remote="192.168.124.2"
38ip6_virt_remote="fe80::381c:c0ff:fea8:7c02"
39mac_virt_remote="3A:1C:C0:A8:7C:02"
40
41# Max performance loss (%) for virtual devices during network load
42VIRT_PERF_THRESHOLD=${VIRT_PERF_THRESHOLD:-80}
43vxlan_dstport=0
44
45clients_num=2
46client_requests=500000
47max_requests=20
48
49while 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
86done
87
88cleanup_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
97TST_CLEANUP="cleanup_vifaces"
98trap "tst_brkm TBROK 'test interrupted'" INT
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	;;
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
133virt_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
152virt_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
172virt_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
187virt_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
218vxlan_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
233vxlan_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
253virt_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
301virt_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.
315virt_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.
343virt_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
368tst_require_root
369
370case "$virt_type" in
371vxlan|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;;
383esac
384
385ipver=${TST_IPV6:-'4'}
386
387tst_check_cmds "ip"
388
389virt_add ltp_v0 || \
390	tst_brkm TCONF "iproute2 or kernel doesn't support $virt_type"
391
392ROD_SILENT "ip link delete ltp_v0"
393