• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2# Copyright (c) 2014-2017 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="$(TST_IPV6= tst_ipaddr_un)"
33ip6_virt_local="$(TST_IPV6=6 tst_ipaddr_un)"
34
35ip_remote=$(tst_ipaddr rhost)
36ip_virt_remote="$(TST_IPV6= tst_ipaddr_un rhost)"
37ip6_virt_remote="$(TST_IPV6=6 tst_ipaddr_un rhost)"
38
39# Max performance loss (%) for virtual devices during network load
40VIRT_PERF_THRESHOLD=${VIRT_PERF_THRESHOLD:-80}
41vxlan_dstport=0
42
43while getopts :hi:d:6 opt; do
44	case "$opt" in
45	h)
46		echo "Usage:"
47		echo "h        help"
48		echo "i n      start ID to use"
49		echo "d x      VxLAN destination address, 'uni' or 'multi'"
50		echo "6        run over IPv6"
51		exit 0
52	;;
53	i) start_id=$OPTARG ;;
54	d) vxlan_dst_addr=$OPTARG ;;
55	6) # skip, test_net library already processed it
56	;;
57	*)
58		tst_brkm TBROK "unknown option: $opt"
59	;;
60	esac
61done
62
63cleanup_vifaces()
64{
65	tst_resm TINFO "cleanup virtual interfaces..."
66	local viface=`ip li | sed -nE 's/^[0-9]+: (ltp_v[0-9]+)[@:].+/\1/p'`
67	for vx in $viface; do
68		ip link delete $vx
69	done
70}
71
72virt_cleanup_rmt()
73{
74	cleanup_vifaces
75	tst_rhost_run -c "ip link delete ltp_v0 2>/dev/null"
76	if [ "$virt_tcp_syn" ]; then
77		sysctl -q net.ipv4.tcp_syn_retries=$virt_tcp_syn
78		virt_tcp_syn=
79	fi
80}
81
82virt_cleanup()
83{
84	virt_cleanup_rmt
85	[ "$TST_NEEDS_TMPDIR" = 1 ] && tst_rmdir
86}
87
88TST_CLEANUP="cleanup_vifaces"
89trap "tst_brkm TBROK 'test interrupted'" INT
90
91virt_add()
92{
93	local vname=$1
94	shift
95	local opt="$*"
96
97	case $virt_type in
98	vlan|vxlan)
99		[ -z "$opt" ] && opt="id 4094"
100		[ "$vxlan_dstport" -eq 1 ] && opt="dstport 0 $opt"
101	;;
102	geneve)
103		[ -z "$opt" ] && opt="id 4094 remote $(tst_ipaddr rhost)"
104	;;
105	gre|ip6gre)
106		[ -z "$opt" ] && \
107			opt="remote $(tst_ipaddr rhost) dev $(tst_iface)"
108	;;
109	esac
110
111	case $virt_type in
112	vxlan|geneve)
113		ip li add $vname type $virt_type $opt dev $(tst_iface)
114	;;
115	gre|ip6gre)
116		ip -f inet$TST_IPV6 tu add $vname mode $virt_type $opt
117	;;
118	*)
119		ip li add link $(tst_iface) $vname type $virt_type $opt
120	;;
121	esac
122}
123
124virt_add_rhost()
125{
126	local opt=""
127	case $virt_type in
128	vxlan|geneve)
129		opt="dev $(tst_iface rhost)"
130		[ "$vxlan_dstport" -eq 1 ] && opt="$opt dstport 0"
131		tst_rhost_run -s -c "ip li add ltp_v0 type $virt_type $@ $opt"
132	;;
133	gre|ip6gre)
134		tst_rhost_run -s -c "ip -f inet$TST_IPV6 tu add ltp_v0 \
135				     mode $virt_type $@"
136	;;
137	*)
138		tst_rhost_run -s -c "ip li add link $(tst_iface rhost) ltp_v0 \
139				     type $virt_type $@"
140	;;
141	esac
142}
143
144virt_multiple_add_test()
145{
146	local opt="$@"
147	local max=$(($start_id + $NS_TIMES - 1))
148
149	tst_resm TINFO "add $NS_TIMES $virt_type, then delete"
150
151	for i in $(seq $start_id $max); do
152		virt_add ltp_v$i id $i $opt || \
153			tst_brkm TFAIL "failed to create 'ltp_v0 $opt'"
154		ROD_SILENT "ip link set ltp_v$i up"
155	done
156
157	for i in $(seq $start_id $max); do
158		ROD_SILENT "ip link set ltp_v$i down"
159		ROD_SILENT "ip link delete ltp_v$i"
160	done
161
162	tst_resm TPASS "done"
163}
164
165virt_add_delete_test()
166{
167	local opt="$@"
168	local max=$(($NS_TIMES - 1))
169
170	tst_resm TINFO "add/del $virt_type $NS_TIMES times"
171
172	for i in $(seq 0 $max); do
173		virt_add ltp_v0 $opt || \
174			tst_brkm TFAIL "failed to create 'ltp_v0 $opt'"
175		ROD_SILENT "ip link set ltp_v0 up"
176		ROD_SILENT "ip link delete ltp_v0"
177	done
178	tst_resm TPASS "done"
179}
180
181virt_setup()
182{
183	local opt="$1"
184	local opt_r="${2:-$1}"
185
186	tst_resm TINFO "setup local ${virt_type} with '$opt'"
187	virt_add ltp_v0 $opt || \
188		tst_brkm TBROK "failed to create 'ltp_v0 $opt'"
189
190	tst_resm TINFO "setup rhost ${virt_type} with '$opt_r'"
191	virt_add_rhost "$opt_r"
192
193	ROD_SILENT "ip addr add ${ip6_virt_local}/64 dev ltp_v0 nodad"
194	tst_rhost_run -s -c "ip ad add ${ip6_virt_remote}/64 dev ltp_v0 nodad"
195
196	ROD_SILENT "ip addr add ${ip_virt_local}/24 dev ltp_v0"
197	tst_rhost_run -s -c "ip addr add ${ip_virt_remote}/24 dev ltp_v0"
198
199	ROD_SILENT "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0"
200	tst_rhost_run -s -c "sysctl -q net.ipv6.conf.ltp_v0.accept_dad=0"
201
202	ROD_SILENT "ip li set up ltp_v0"
203	tst_rhost_run -s -c "ip li set up ltp_v0"
204}
205
206virt_tcp_syn=
207virt_minimize_timeout()
208{
209	local mac_loc="$(cat /sys/class/net/ltp_v0/address)"
210	local mac_rmt="$(tst_rhost_run -c 'cat /sys/class/net/ltp_v0/address')"
211
212	ROD_SILENT "ip ne replace $ip_virt_remote lladdr \
213		    $mac_rmt nud permanent dev ltp_v0"
214	tst_rhost_run -s -c "ip ne replace $ip_virt_local lladdr \
215			     $mac_loc nud permanent dev ltp_v0"
216	virt_tcp_syn=$(sysctl -n net.ipv4.tcp_syn_retries)
217	ROD sysctl -q net.ipv4.tcp_syn_retries=1
218}
219
220vxlan_setup_subnet_uni()
221{
222	if tst_kvcmp -lt "3.10"; then
223		tst_brkm TCONF "test must be run with kernel 3.10 or newer"
224	fi
225
226	[ "$(ip li add type $virt_type help 2>&1 | grep remote)" ] || \
227		tst_brkm TCONF "iproute doesn't support remote unicast address"
228
229	local opt="$1 remote $(tst_ipaddr rhost)"
230	local opt_r="$2 remote $(tst_ipaddr)"
231
232	virt_setup "$opt" "$opt_r"
233}
234
235vxlan_setup_subnet_multi()
236{
237	tst_check_cmds "od"
238	local b1=$(($(od -An -d -N1 /dev/urandom) % 254 + 1))
239	local b2=$(($(od -An -d -N1 /dev/urandom) % 254 + 1))
240	local b3=$(($(od -An -d -N1 /dev/urandom) % 254 + 1))
241
242	local grp=
243	if [ "$TST_IPV6" ]; then
244		grp="group ff05::$(printf '%x:%x%x' $b1 $b2 $b3)"
245	else
246		grp="group 239.$b1.$b2.$b3"
247	fi
248
249	local opt="$1 $grp"
250	local opt_r="$2 $grp"
251
252	virt_setup "$opt" "$opt_r"
253}
254
255virt_compare_netperf()
256{
257	local ret1="pass"
258	local ret2="pass"
259	local expect_res="${1:-pass}"
260	local opts="$2"
261
262	tst_netload -H $ip_virt_remote $opts -d res_ipv4 -e $expect_res || \
263		ret1="fail"
264
265	tst_netload -H ${ip6_virt_remote} $opts -d res_ipv6 -e $expect_res || \
266		ret2="fail"
267
268	[ "$ret1" = "fail" -o "$ret2" = "fail" ] && return
269
270	local vt="$(cat res_ipv4)"
271	local vt6="$(cat res_ipv6)"
272
273	tst_netload -H $ip_remote $opts -d res_ipv4
274
275	local lt="$(cat res_ipv4)"
276	tst_resm TINFO "time lan($lt) $virt_type IPv4($vt) and IPv6($vt6) ms"
277
278	per=$(( $vt * 100 / $lt - 100 ))
279	per6=$(( $vt6 * 100 / $lt - 100 ))
280
281	case "$virt_type" in
282	vxlan|geneve)
283		tst_resm TINFO "IP4 $virt_type over IP$ipver slower by $per %"
284		tst_resm TINFO "IP6 $virt_type over IP$ipver slower by $per6 %"
285	;;
286	*)
287		tst_resm TINFO "IP4 $virt_type slower by $per %"
288		tst_resm TINFO "IP6 $virt_type slower by $per6 %"
289	esac
290
291	if [ "$per" -ge "$VIRT_PERF_THRESHOLD" -o \
292	     "$per6" -ge "$VIRT_PERF_THRESHOLD" ]; then
293		tst_resm TFAIL "Test failed, threshold: $VIRT_PERF_THRESHOLD %"
294	else
295		tst_resm TPASS "Test passed, threshold: $VIRT_PERF_THRESHOLD %"
296	fi
297}
298
299virt_check_cmd()
300{
301	$@ > /dev/null 2>&1
302	if [ $? -ne 0 ]; then
303		tst_resm TCONF "'$@' option(s) not supported, skipping it"
304		return 1
305	fi
306	ROD_SILENT "ip li delete ltp_v0"
307	return 0
308}
309
310# virt_macsec_setup [OPTIONS]
311# OPTIONS - [ cipher { default | gcm-aes-128 } ] [ encrypt { on | off } ]
312#           [ protect { on | off } ] [ replay { on | off } ] [ window WINDOW ]
313#           [ validate { strict | check | disabled } ]
314virt_macsec_setup()
315{
316	local keyid0=01
317	local keyid1=02
318	local sa=0
319	local h0=$(tst_hwaddr)
320	local h1=$(tst_hwaddr rhost)
321	local cmd="ip macsec add ltp_v0"
322	local key0="01234567890123456789012345678901"
323	local key1="98765432109876543210987612343434"
324
325	virt_setup "icvlen 16 encodingsa $sa $@"
326
327	ROD $cmd tx sa $sa pn 100 on key $keyid0 $key0
328	ROD $cmd rx address $h1 port 1
329	ROD $cmd rx address $h1 port 1 sa $sa pn 100 on key $keyid1 $key1
330
331	tst_rhost_run -s -c "$cmd tx sa $sa pn 100 on key $keyid1 $key1"
332	tst_rhost_run -s -c "$cmd rx address $h0 port 1"
333	tst_rhost_run -s -c \
334		"$cmd rx address $h0 port 1 sa $sa pn 100 on key $keyid0 $key0"
335}
336
337virt_netperf_msg_sizes()
338{
339	local sizes="${@:-100 1000 2000 10000}"
340	client_requests=20000
341
342	for s in $sizes; do
343		virt_compare_netperf pass "-n $s -N $s"
344	done
345}
346
347# Check if we can create then delete virtual interface n times.
348# virt_test_01 [OPTIONS]
349# OPTIONS - different options separated by comma.
350virt_test_01()
351{
352	start_id=${start_id:-"1"}
353	local opts=${1:-""}
354	local n=0
355
356	while true; do
357		n=$((n + 1))
358		p="$(echo $opts | cut -d',' -f$n)"
359		if [ -z "$p" -a $n -gt 1 ]; then
360			break
361		fi
362
363		tst_resm TINFO "add $virt_type with '$p'"
364
365		virt_check_cmd virt_add ltp_v0 id 0 $p || continue
366
367		virt_multiple_add_test "$p"
368
369		start_id=$(($start_id + $NS_TIMES))
370	done
371}
372
373# Check if we can create then delete virtual interface n times.
374# virt_test_02 [OPTIONS]
375# OPTIONS - different options separated by comma.
376virt_test_02()
377{
378	start_id=${start_id:-"1"}
379	local opts=${1:-""}
380	local n=0
381
382	while true; do
383		n=$((n + 1))
384		p="$(echo $opts | cut -d',' -f$n)"
385		if [ -z "$p" -a $n -gt 1 ]; then
386			break
387		fi
388
389		tst_resm TINFO "add and then delete $virt_type with '$p'"
390
391		virt_check_cmd virt_add ltp_v0 $p || continue
392
393		virt_add_delete_test "$p"
394
395		start_id=$(($start_id + $NS_TIMES))
396	done
397}
398
399tst_require_root
400
401case "$virt_type" in
402vxlan|geneve)
403	if tst_kvcmp -lt "3.8"; then
404		tst_brkm TCONF "test must be run with kernel 3.8 or newer"
405	fi
406
407	if [ "$TST_IPV6" ] && tst_kvcmp -lt "3.12"; then
408		tst_brkm TCONF "test must be run with kernels >= 3.12"
409	fi
410
411	# newer versions of 'ip' complain if this option not set
412	ip li add type vxlan help 2>&1 | grep -q dstport && vxlan_dstport=1
413;;
414esac
415
416ipver=${TST_IPV6:-'4'}
417
418tst_check_cmds "ip"
419
420virt_add ltp_v0 || \
421	tst_brkm TCONF "iproute2 or kernel doesn't support $virt_type"
422
423ROD_SILENT "ip link delete ltp_v0"
424