xref: /illumos-gate/usr/src/test/net-tests/tests/net_common.ksh (revision c94be9439c4f0773ef60e2cec21d548359cfea20)
1#!/usr/bin/ksh
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11
12#
13# Copyright 2019 Joyent, Inc.
14#
15
16#
17# Functions shared across the network tests.
18#
19
20DEBUG=0
21
22function dbg
23{
24	typeset msg="$*"
25	if (($DEBUG == 1)); then
26		echo "DBG [$nt_tname]: $msg"
27	fi
28}
29
30function fail
31{
32	typeset msg="$*"
33	echo "FAIL [$nt_tname]: $msg" >&2
34	exit 1
35}
36
37function maybe_fail
38{
39	typeset msg=$1
40
41	if ((BAIL == 1)); then
42		fail "$msg"
43	else
44		dbg "$msg"
45		return 1
46	fi
47}
48
49function zone_exists
50{
51	typeset name=$1
52
53	if (($# != 1)); then
54		fail "$0: incorrect number of args provided"
55	fi
56
57	dbg "checking for existence of zone: $name"
58	if zoneadm -z $name list > /dev/null 2>&1; then
59		dbg "found zone: $name"
60		return 0
61	else
62		dbg "zone not found: $name"
63		return 1
64	fi
65}
66
67function zone_running
68{
69	typeset name=$1
70	typeset state=$(zoneadm -z $name list -p | awk -F: '{ print $3 }')
71	typeset err="zone $name is not running"
72
73	if (($# != 1)); then
74		fail "$0: incorrect number of args provided"
75	fi
76
77	dbg "check if zone $name is running"
78	dbg "state of zone $name: $state"
79	if [[ "$state" == "running" ]]; then
80		dbg "zone $name is running"
81		return 0
82	fi
83
84	maybe_fail "$err"
85}
86
87function simnet_exists
88{
89	typeset name=$1
90
91	if (($# != 1)); then
92		fail "$0: incorrect number of args provided"
93	fi
94
95	if dladm show-simnet $name > /dev/null 2>&1; then
96		dbg "simnet $name found"
97		return 0
98	else
99		dbg "simnet $name not found"
100		return 1
101	fi
102}
103
104function create_simnet
105{
106	typeset name=$1
107	typeset err="failed to create simnet $name"
108
109	if (($# != 1)); then
110		fail "$0: incorrect number of args provided"
111	fi
112
113	dbg "creating simnet $name"
114	if simnet_exists $name; then
115		dbg "simnet $name already exists"
116		maybe_fail "$err"
117		return 1
118	fi
119
120	if dladm create-simnet > /dev/null $name; then
121		dbg "created simnet $name"
122		return 0
123	fi
124
125	maybe_fail "$err"
126}
127
128function delete_simnet
129{
130	typeset name=$1
131	typeset err="failed to delete simnet $name"
132
133	if (($# != 1)); then
134		fail "$0: incorrect number of args provided"
135	fi
136
137	dbg "deleting simnet $name"
138	if ! simnet_exists $name; then
139		dbg "simnet $name doesn't exist"
140		return 1
141	fi
142
143	if dladm delete-simnet $name; then
144		dbg "simnet $name deleted"
145		return 0
146	fi
147
148	maybe_fail "$err"
149}
150
151function link_simnets
152{
153	typeset sim1=$1
154	typeset sim2=$2
155	typeset err="failed to link simnet $sim1 to $sim2"
156
157	if (($# != 2)); then
158		fail "$0: incorrect number of args provided"
159	fi
160
161	dbg "linking simnet $sim1 to $sim2"
162	if dladm modify-simnet -p $sim2 $sim1 > /dev/null; then
163		dbg "linked simnet $sim1 to $sim2"
164		return 0
165	fi
166
167	maybe_fail "$err"
168}
169
170function vnic_exists
171{
172	typeset name=$1
173	typeset vid=$2
174	typeset over=$3
175	typeset zone=$4
176
177	if (($# != 4)); then
178		fail "$0: incorrect number of args provided"
179	fi
180
181	if dladm show-vnic $name > /dev/null 2>&1; then
182		typeset avid=$(dladm show-vnic -p -o vid $name)
183		typeset aover=$(dladm show-vnic -p -o over $name)
184		typeset azone=$(dladm show-linkprop -cp zone -o value $name)
185		if (($avid == $vid)) && [ $aover == $over ] && \
186			   [ $azone == $zone ]
187		then
188			return 0
189		else
190			return 1
191		fi
192	else
193		return 1
194	fi
195}
196
197function create_vnic
198{
199	typeset name=$1
200	typeset over=$2
201	typeset vid=$3
202	typeset zone=$4
203	typeset r=1
204	typeset vid_opt=""
205	typeset vnic_info="$name, vid: $vid, over: $over, zone: $zone"
206	typeset err="failed to create VNIC: $vnic_info"
207
208	if (($# != 4)); then
209		fail "$0: incorrect number of args provided"
210	fi
211
212	if ((vid != 0)); then
213		vid_opt="-v $vid"
214	fi
215
216	dbg "creating VNIC: $vnic_info"
217	if ! dladm create-vnic -t -l $over $vid_opt $name > /dev/null 2>&1
218	then
219		maybe_fail "$err"
220		return 1
221	fi
222
223	dbg "created VNIC: $vnic_info"
224	if ! zonecfg -z $zone "add net; set physical=$name; end"; then
225		maybe_fail "failed to assign $name to $zone"
226		return 1
227	fi
228
229	dbg "assigned VNIC $name to $zone"
230	if zoneadm -z $zone reboot; then
231		dbg "rebooted $zone"
232		#
233		# Make sure the vnic is visible before returning. Without this
234		# a create_addr command following immediately afterwards could
235		# fail because the zone is up but the vnic isn't visible yet.
236		#
237		sleep 1
238		return 0
239	fi
240
241	maybe_fail "failed to reboot $zone"
242}
243
244function delete_vnic
245{
246	typeset name=$1
247	typeset vid=$2
248	typeset zone=$3
249	typeset vnic_info="$name, vid: $vid, zone: $zone"
250	typeset err1="failed to assign VNIC $name from $zone to GZ"
251	typeset err2="failed to delete VNIC: $vnic_info"
252
253	if (($# != 3)); then
254		fail "$0: incorrect number of args provided"
255	fi
256
257	dbg "assigning VNIC $name from $zone to GZ"
258
259	if ! zonecfg -z $zone "remove net physical=$name"; then
260		maybe_fail "failed to remove $name from $zone"
261		return 1
262	fi
263	if ! zoneadm -z $zone reboot; then
264		maybe_fail "failed to reboot $zone"
265		return 1
266	fi
267
268	dbg "deleting VNIC: $vnic_info"
269	if dladm delete-vnic $name > /dev/null; then
270		dbg "deleted VNIC: $vnic_info"
271		return 0
272	fi
273
274	maybe_fail "$err2"
275}
276
277function create_addr
278{
279	typeset zone=$1
280	typeset vnic=$2
281	typeset ip=$3
282	typeset ipname=${vnic}/v4
283
284	if (($# != 3)); then
285		fail "$0: incorrect number of args provided"
286	fi
287
288	if zlogin $zone ipadm create-addr -t -T static -a $ip \
289		  $ipname > /dev/null
290	then
291		dbg "created addr $ipname ($ip) in zone $zone"
292		return 0
293	fi
294
295	maybe_fail "failed to create addr $ipname ($ip) in zone $zone"
296}
297
298function create_addr6
299{
300	typeset zone=$1
301	typeset vnic=$2
302	typeset ip=$3
303	typeset ll_name=${vnic}/v6
304	typeset uni_name=${vnic}/v6add
305	typeset err1="failed to create link-local addr $ll_name in zone $zone"
306	typeset err2="failed to create unicast addr $uni_name in zone $zone"
307
308	if (($# != 3)); then
309		fail "$0: incorrect number of args provided"
310	fi
311
312	if zlogin $zone ipadm create-addr -t -T addrconf $ll_name; then
313		dbg "created link-local addr $ll_name in zone $zone"
314	else
315		maybe_fail "$err1"
316		return 1
317	fi
318
319	if zlogin $zone ipadm create-addr -t -T static -a $ip/64 $uni_name; then
320		dbg "created unicast addr $uni_name in zone $zone"
321	else
322		maybe_fail "$err2"
323	fi
324}
325
326function delete_addr
327{
328	typeset zone=$1
329	typeset ifname=$2
330	typeset version=$3
331	typeset ipname=$ifname/$version
332
333	if (($# != 3)); then
334		fail "$0: incorrect number of args provided"
335	fi
336
337	if zlogin $zone ipadm show-addr $ipname > /dev/null 2>&1; then
338		if zlogin $zone ipadm delete-addr $ipname > /dev/null; then
339			dbg "deleted addr $ipname in zone $zone"
340		else
341			maybe_fail "failed to delete addr $ipname in zone $zone"
342			return 1
343		fi
344	else
345		dbg "addr $ipname doesn't exist in zone $zone"
346	fi
347
348	if [[ "v6" == "$version" ]]; then
349		typeset ipname=$ifname/v6add
350		typeset err="failed to delete addr $ipname in zone $zone"
351
352		if zlogin $zone ipadm show-addr $ipname > /dev/null 2>&1; then
353			if zlogin $zone ipadm delete-addr $ipname > /dev/null
354			then
355				dbg "deleted addr $ipname in zone $zone"
356			else
357				maybe_fail "$err"
358			fi
359		else
360			dbg "addr $ipname doesn't exist in zone $zone"
361		fi
362	fi
363}
364
365function delete_if
366{
367	typeset zone=$1
368	typeset ifname=$2
369	typeset err="failed to delete interface $ifname in zone $zone"
370
371	if (($# != 2)); then
372		fail "$0: incorrect number of args provided"
373	fi
374
375	if zlogin $zone ipadm show-if $ifname > /dev/null 2>&1; then
376		if zlogin $zone ipadm delete-if $ifname > /dev/null; then
377			dbg "deleted interface $ifname in zone $zone"
378		else
379			maybe_fail "$err"
380		fi
381	else
382		dbg "interface $ifname doesn't exist in zone $zone"
383	fi
384}
385
386function ip_fwd_enable
387{
388	typeset zone=$1
389
390	if (($# != 1)); then
391		fail "$0: incorrect number of args provided"
392	fi
393
394	if zlogin $zone routeadm -p ipv4-forwarding | \
395			egrep 'current=enabled' > /dev/null
396	then
397		dbg "IPv4 forwarding already enabled for $zone"
398	else
399		if zlogin $zone routeadm -ue ipv4-forwarding; then
400			dbg "enabled IPv4 forwarding for $zone"
401		else
402			maybe_fail "failed to enable IPv4 forwarding for $zone"
403			return 1
404		fi
405	fi
406
407	if zlogin $zone routeadm -p ipv6-forwarding | \
408			egrep 'current=enabled' > /dev/null
409	then
410		dbg "IPv6 forwarding already enabled for $zone"
411	else
412		if zlogin $zone routeadm -ue ipv6-forwarding; then
413			dbg "enabled IPv6 forwarding for $zone"
414		else
415			maybe_fail "failed to enable IPv6 forwarding for $zone"
416		fi
417	fi
418}
419
420function ip_fwd_disable
421{
422	typeset zone=$1
423
424	if (($# != 1)); then
425		fail "$0: incorrect number of args provided"
426	fi
427
428	if zlogin $zone routeadm -p ipv4-forwarding | \
429			egrep 'current=disabled' > /dev/null
430	then
431		dbg "IPv4 forwarding already disabled for $zone"
432	else
433		if zlogin $zone routeadm -ud ipv4-forwarding; then
434			dbg "disabled IPv4 forwarding in $zone"
435		else
436			maybe_fail "failed to disable IPv4 forwarding in $zone"
437			return 1
438		fi
439	fi
440
441	if zlogin $zone routeadm -p ipv6-forwarding | \
442			egrep 'current=disabled' > /dev/null
443	then
444		dbg "IPv6 forwarding already disabled for $zone"
445	else
446		if zlogin $zone routeadm -ud ipv6-forwarding; then
447			dbg "disabled IPv6 forwarding in $zone"
448		else
449			maybe_fail "failed to disable IPv6 forwarding in $zone"
450		fi
451	fi
452}
453
454function add_route
455{
456	typeset zone=$1
457	typeset dest=$2
458	typeset net=$3
459	typeset gateway=$4
460
461	if (($# != 4)); then
462		fail "$0: incorrect number of args provided"
463	fi
464
465	if zlogin $zone route -n add $net $gateway > /dev/null; then
466		dbg "added route $gateway => $net to $zone"
467		return 0
468	fi
469
470	maybe_fail "failed to add route $gateway => $net to $zone"
471}
472
473function add_route6
474{
475	typeset zone=$1
476	typeset dest=$2
477	typeset net=$3
478	typeset gateway=$4
479
480	if (($# != 4)); then
481		fail "$0: incorrect number of args provided"
482	fi
483
484	if zlogin $zone route -n add -inet6 $net $gateway > /dev/null
485	then
486		dbg "added route $gateway => $net to $zone"
487		return 0
488	fi
489
490	maybe_fail "failed to add route $gateway => $net to $zone"
491}
492
493function rm_route
494{
495	typeset zone=$1
496	typeset dest=$2
497	typeset net=$3
498	typeset gateway=$4
499	typeset gw=$(zlogin $zone route -n get $dest | \
500			     grep gateway | awk '{ print $2 }')
501	typeset err="failed to remove route $gateway => $net from $zone"
502
503	if (($# != 4)); then
504		fail "$0: incorrect number of args provided"
505	fi
506
507	if [[ "$gw" == "$gateway" ]]; then
508		if zlogin $zone route -n delete $net $gateway > /dev/null
509		then
510			dbg "removed route $gateway => $net from $zone"
511		else
512			maybe_fail "$err"
513		fi
514	else
515		dbg "$zone already lacked route $gateway => $net"
516	fi
517}
518
519function rm_route6
520{
521	typeset zone=$1
522	typeset dest=$2
523	typeset net=$3
524	typeset gateway=$4
525	typeset gw=$(zlogin $zone route -n get -inet6 $dest | \
526			     grep gateway | awk '{ print $2 }')
527	typeset err="failed to remove route $gateway => $net from $zone"
528
529	if (($# != 4)); then
530		fail "$0: incorrect number of args provided"
531	fi
532
533	if [[ "$gw" == "$gateway" ]]; then
534		if zlogin $zone route -n delete -inet6 $net $gateway > /dev/null
535		then
536			dbg "removed route $gateway => $net from $zone"
537		else
538			maybe_fail "$err"
539		fi
540	else
541		dbg "$zone already lacked route $gateway => $net"
542	fi
543}
544
545function set_linkprop
546{
547	typeset link=$1
548	typeset prop=$2
549	typeset val=$3
550	typeset err="failed to set $link prop: $prop=$val"
551
552	if (($# != 3)); then
553		fail "$0: incorrect number of args provided"
554	fi
555
556	dbg "attempt to set $link prop: $prop=$val"
557	if dladm set-linkprop -p $prop=$val $link; then
558		dbg "set $link prop: $prop=$val"
559		return 0
560	fi
561
562	maybe_fail "$err"
563}
564
565function ping
566{
567	typeset zone=$1
568	typeset src=$2
569	typeset dst=$3
570	typeset info="$src -> $dst"
571
572	if (($# != 3)); then
573		fail "$0: incorrect number of args provided"
574	fi
575
576	dbg "ping: $info"
577	if zlogin $zone ping $dst > /dev/null 2>&1; then
578		dbg "successful ping: $info"
579		return 0
580	fi
581
582	maybe_fail "could not ping: $info"
583}
584
585function ping_udp
586{
587	typeset client=$1
588	typeset client_ip=$2
589	typeset server_ip=$3
590	typeset size=$4
591	typeset num=$5
592	typeset info="$client_ip -> $server_ip (size: $size)"
593
594	if (($# != 5)); then
595		fail "$0: incorrect number of args provided"
596	fi
597
598	dbg "UDP ping: $info"
599	if zlogin $client ping -ns -U $server_ip $size $num > /dev/null; then
600		dbg "UDP ping passed: $info"
601		return 0
602	fi
603
604	maybe_fail "UDP ping failed: $info"
605}
606
607function start_server
608{
609	typeset zone=$1
610	typeset type=$2
611	typeset ip=$3
612	typeset port=$4
613	typeset ofile=$5
614
615	if (($# != 5)); then
616		fail "$0: incorrect number of args provided"
617	fi
618
619	dbg "start server $rfile"
620	zlogin $zone \
621	       /usr/bin/socat -u ${type}-LISTEN:$port,bind=[$ip],reuseaddr \
622	       CREATE:$ofile &
623	listener_ppid=$!
624	dbg "listener PPID: $listener_ppid, zone $zone"
625}
626
627function wait_for_pid
628{
629	typeset pid=$1
630	typeset seconds=$2
631	typeset s=0
632
633	if (($# != 2)); then
634		fail "$0: incorrect number of args provided"
635	fi
636
637	while true; do
638		if kill -0 $pid > /dev/null 2>&1; then
639			if ((seconds == s)); then
640				maybe_fail "timed out waiting for pid $pid"
641				return 1
642			fi
643			dbg "waiting for pid $pid"
644			sleep 1
645			((s++))
646		else
647			return 0
648		fi
649	done
650}
651