• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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