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