xref: /illumos-gate/usr/src/test/util-tests/tests/dladm/create-vnic.ksh (revision 140b22a28f90404bf6c622c65289ea57e765a045)
1*140b22a2SHans Rosenfeld#!/usr/bin/ksh
2*140b22a2SHans Rosenfeld#
3*140b22a2SHans Rosenfeld# This file and its contents are supplied under the terms of the
4*140b22a2SHans Rosenfeld# Common Development and Distribution License ("CDDL"), version 1.0.
5*140b22a2SHans Rosenfeld# You may only use this file in accordance with the terms of version
6*140b22a2SHans Rosenfeld# 1.0 of the CDDL.
7*140b22a2SHans Rosenfeld#
8*140b22a2SHans Rosenfeld# A full copy of the text of the CDDL should have accompanied this
9*140b22a2SHans Rosenfeld# source.  A copy of the CDDL is also available via the Internet at
10*140b22a2SHans Rosenfeld# http://www.illumos.org/license/CDDL.
11*140b22a2SHans Rosenfeld#
12*140b22a2SHans Rosenfeld
13*140b22a2SHans Rosenfeld#
14*140b22a2SHans Rosenfeld# Copyright 2026 Hans Rosenfeld
15*140b22a2SHans Rosenfeld#
16*140b22a2SHans Rosenfeld
17*140b22a2SHans Rosenfeld# This test exercises the 'dladm {create,show,delete}-vnic' commands and the
18*140b22a2SHans Rosenfeld# underlying operations of libdladm and the vnic driver.
19*140b22a2SHans Rosenfeld#
20*140b22a2SHans Rosenfeld# The test repeatedly creates a vnic with various differing configurations,
21*140b22a2SHans Rosenfeld# some of which are illegal and expected to fail. For those cases that are
22*140b22a2SHans Rosenfeld# expected to succeed, the test verifies that the persistent and active
23*140b22a2SHans Rosenfeld# configurations match what was created. Afterwards, the test  deletes the
24*140b22a2SHans Rosenfeld# created vnic device and verifies it is no longer present in the active and
25*140b22a2SHans Rosenfeld# the persistent configuration.
26*140b22a2SHans Rosenfeld
27*140b22a2SHans Rosenfeld
28*140b22a2SHans Rosenfeldunalias -a
29*140b22a2SHans Rosenfeldset -o pipefail
30*140b22a2SHans Rosenfeldexport LANG=C.UTF-8
31*140b22a2SHans Rosenfeld
32*140b22a2SHans Rosenfelddl_exit=0
33*140b22a2SHans Rosenfelddl_stub="UTILtest_stub$$"
34*140b22a2SHans Rosenfelddl_vnic="UTILtest_vnic$$"
35*140b22a2SHans Rosenfelddl_vrid="12"
36*140b22a2SHans Rosenfeld
37*140b22a2SHans Rosenfelddl_create="dladm create-vnic"
38*140b22a2SHans Rosenfelddl_delete="dladm delete-vnic"
39*140b22a2SHans Rosenfelddl_show="dladm show-vnic"
40*140b22a2SHans Rosenfeld
41*140b22a2SHans Rosenfeldtypeset -A dl_macs
42*140b22a2SHans Rosenfelddl_macs["random0"]="2:8:20"
43*140b22a2SHans Rosenfelddl_macs["random"]="2:8:20"
44*140b22a2SHans Rosenfelddl_macs["prefix"]="8:0:2b"
45*140b22a2SHans Rosenfelddl_macs["fixed"]="${dl_macs[prefix]}:12:34:56"
46*140b22a2SHans Rosenfelddl_macs["vrrp_inet"]=$(printf "0:0:5e:0:1:%x" ${dl_vrid})
47*140b22a2SHans Rosenfelddl_macs["vrrp_inet6"]=$(printf "0:0:5e:0:2:%x" ${dl_vrid})
48*140b22a2SHans Rosenfeld
49*140b22a2SHans Rosenfeldtypeset -A dl_vlan
50*140b22a2SHans Rosenfelddl_vlan["novlan"]="0"
51*140b22a2SHans Rosenfelddl_vlan["vlan"]="123"
52*140b22a2SHans Rosenfeld
53*140b22a2SHans Rosenfeldtypeset -A dl_configs
54*140b22a2SHans Rosenfeld# "factory MACs" apparently exist only in nxge(4d), so we expect them to fail
55*140b22a2SHans Rosenfelddl_configs["fail_factory"]="-m factory -n 12"
56*140b22a2SHans Rosenfelddl_configs["fail_fixed"]="-m fixed"
57*140b22a2SHans Rosenfeld
58*140b22a2SHans Rosenfelddl_configs["fail_dup_m"]="-m random -m random"
59*140b22a2SHans Rosenfelddl_configs["fail_dup_n"]="-m factory -n 12 -n 12"
60*140b22a2SHans Rosenfelddl_configs["fail_dup_v"]="-v ${dl_vlan[vlan]} -v ${dl_vlan[vlan]}"
61*140b22a2SHans Rosenfeld
62*140b22a2SHans Rosenfelddl_configs["fail_no_m_r"]="-r ${dl_macs[prefix]}"
63*140b22a2SHans Rosenfelddl_configs["fail_no_m_r"]="-n 12"
64*140b22a2SHans Rosenfelddl_configs["fail_no_v_f"]="-f"
65*140b22a2SHans Rosenfelddl_configs["fail_no_VA"]="-m vrrp"
66*140b22a2SHans Rosenfelddl_configs["fail_no_V"]="-m vrrp -A inet"
67*140b22a2SHans Rosenfelddl_configs["fail_no_A"]="-m vrrp -V ${dl_vrid}"
68*140b22a2SHans Rosenfeld
69*140b22a2SHans Rosenfelddl_configs["fail_invalid_v_4095"]="-v 4095"
70*140b22a2SHans Rosenfelddl_configs["fail_invalid_v_12345"]="-v 12345"
71*140b22a2SHans Rosenfelddl_configs["fail_invalid_A"]="-m vrrp -V ${dl_vrid} -A unix"
72*140b22a2SHans Rosenfelddl_configs["fail_invalid_prefix"]="-m radnom -r ${dl_macs[fixed]}"
73*140b22a2SHans Rosenfeld
74*140b22a2SHans Rosenfeld
75*140b22a2SHans Rosenfelddl_configs["random0"]=
76*140b22a2SHans Rosenfelddl_configs["random"]="-m random"
77*140b22a2SHans Rosenfelddl_configs["prefix"]="-m random -r ${dl_macs[prefix]}"
78*140b22a2SHans Rosenfelddl_configs["fixed"]="-m ${dl_macs[fixed]}"
79*140b22a2SHans Rosenfelddl_configs["vrrp_inet"]="-m vrrp -V ${dl_vrid} -A inet"
80*140b22a2SHans Rosenfelddl_configs["vrrp_inet6"]="-m vrrp -V ${dl_vrid} -A inet6"
81*140b22a2SHans Rosenfeld
82*140b22a2SHans Rosenfeldtypeset -A dl_types
83*140b22a2SHans Rosenfelddl_types["random0"]="random"
84*140b22a2SHans Rosenfelddl_types["random"]="random"
85*140b22a2SHans Rosenfelddl_types["prefix"]="random"
86*140b22a2SHans Rosenfelddl_types["fixed"]="fixed"
87*140b22a2SHans Rosenfelddl_types["vrrp_inet"]="vrrp, ${dl_vrid}/inet"
88*140b22a2SHans Rosenfelddl_types["vrrp_inet6"]="vrrp, ${dl_vrid}/inet6"
89*140b22a2SHans Rosenfeld
90*140b22a2SHans Rosenfeldtypeset -A dl_extra_configs
91*140b22a2SHans Rosenfelddl_extra_configs["novlan"]=""
92*140b22a2SHans Rosenfelddl_extra_configs["vlan"]="-v ${dl_vlan[vlan]}"
93*140b22a2SHans Rosenfeld
94*140b22a2SHans Rosenfeldfatal()
95*140b22a2SHans Rosenfeld{
96*140b22a2SHans Rosenfeld    typeset msg="$*"
97*140b22a2SHans Rosenfeld    echo "TEST FAILED: $msg" >&2
98*140b22a2SHans Rosenfeld    exit 1
99*140b22a2SHans Rosenfeld}
100*140b22a2SHans Rosenfeld
101*140b22a2SHans Rosenfeldwarn()
102*140b22a2SHans Rosenfeld{
103*140b22a2SHans Rosenfeld    typeset msg="$*"
104*140b22a2SHans Rosenfeld    echo "TEST FAILED: $msg" >&2
105*140b22a2SHans Rosenfeld    dl_exit=1
106*140b22a2SHans Rosenfeld}
107*140b22a2SHans Rosenfeld
108*140b22a2SHans Rosenfeldcleanup()
109*140b22a2SHans Rosenfeld{
110*140b22a2SHans Rosenfeld    dladm delete-etherstub ${dl_stub} 2>/dev/null
111*140b22a2SHans Rosenfeld}
112*140b22a2SHans Rosenfeld
113*140b22a2SHans Rosenfeldsetup()
114*140b22a2SHans Rosenfeld{
115*140b22a2SHans Rosenfeld    dladm create-etherstub ${dl_stub} || fatal "failed to create ${dl_stub}"
116*140b22a2SHans Rosenfeld}
117*140b22a2SHans Rosenfeld
118*140b22a2SHans Rosenfeldtest_create()
119*140b22a2SHans Rosenfeld{
120*140b22a2SHans Rosenfeld    typeset conf="$1"
121*140b22a2SHans Rosenfeld    typeset extra="$2"
122*140b22a2SHans Rosenfeld    typeset args="$3"
123*140b22a2SHans Rosenfeld
124*140b22a2SHans Rosenfeld    typeset config="${dl_configs[${conf}]} ${dl_extra_configs[${extra}]}"
125*140b22a2SHans Rosenfeld    typeset create="${dl_create}"
126*140b22a2SHans Rosenfeld    typeset out
127*140b22a2SHans Rosenfeld    typeset ret
128*140b22a2SHans Rosenfeld
129*140b22a2SHans Rosenfeld    [[ ! -z "${args}" ]] && create="${dl_create} ${args}"
130*140b22a2SHans Rosenfeld
131*140b22a2SHans Rosenfeld    out=$(${create} -l ${dl_stub} ${config} ${dl_vnic} 2>&1)
132*140b22a2SHans Rosenfeld    ret=$?
133*140b22a2SHans Rosenfeld
134*140b22a2SHans Rosenfeld    if [[ "${conf:0:4}" == "fail" ]]; then
135*140b22a2SHans Rosenfeld        if (( ret == 0 )); then
136*140b22a2SHans Rosenfeld            warn "'${create}' [$conf, $extra] returned ${ret}"
137*140b22a2SHans Rosenfeld        fi
138*140b22a2SHans Rosenfeld        return ${ret}
139*140b22a2SHans Rosenfeld    else
140*140b22a2SHans Rosenfeld        if (( ret != 0 )); then
141*140b22a2SHans Rosenfeld	    warn "'${create}' [$conf, $extra] returned ${ret}, " \
142*140b22a2SHans Rosenfeld                 "error message:\n${out}"
143*140b22a2SHans Rosenfeld        fi
144*140b22a2SHans Rosenfeld        return ${ret}
145*140b22a2SHans Rosenfeld    fi
146*140b22a2SHans Rosenfeld}
147*140b22a2SHans Rosenfeld
148*140b22a2SHans Rosenfeldcompare()
149*140b22a2SHans Rosenfeld{
150*140b22a2SHans Rosenfeld    typeset cmd=$1
151*140b22a2SHans Rosenfeld    typeset name=$2
152*140b22a2SHans Rosenfeld    typeset val=$3
153*140b22a2SHans Rosenfeld    typeset exp=$4
154*140b22a2SHans Rosenfeld
155*140b22a2SHans Rosenfeld    if [[ "${val}" != "${exp}" ]]; then
156*140b22a2SHans Rosenfeld        warn "'${cmd}' [$c, $e] returned wrong value for ${name}: '${val}'" \
157*140b22a2SHans Rosenfeld            "(expected '${exp}')"
158*140b22a2SHans Rosenfeld    fi
159*140b22a2SHans Rosenfeld}
160*140b22a2SHans Rosenfeld
161*140b22a2SHans Rosenfeldtest_show()
162*140b22a2SHans Rosenfeld{
163*140b22a2SHans Rosenfeld    typeset conf="$1"
164*140b22a2SHans Rosenfeld    typeset extra="$2"
165*140b22a2SHans Rosenfeld    typeset args="$3"
166*140b22a2SHans Rosenfeld
167*140b22a2SHans Rosenfeld    typeset show=${dl_show}
168*140b22a2SHans Rosenfeld    typeset fields="link,over,macaddress,macaddrtype,vid"
169*140b22a2SHans Rosenfeld    typeset out
170*140b22a2SHans Rosenfeld    typeset ret
171*140b22a2SHans Rosenfeld
172*140b22a2SHans Rosenfeld    [[ ! -z "${args}" ]] && show="${dl_show} ${args}"
173*140b22a2SHans Rosenfeld
174*140b22a2SHans Rosenfeld    out=$(${show} -p -o ${fields} ${dl_vnic} 2>&1)
175*140b22a2SHans Rosenfeld    ret=$?
176*140b22a2SHans Rosenfeld
177*140b22a2SHans Rosenfeld    if (( ret != 0 )); then
178*140b22a2SHans Rosenfeld	warn "'${show}' [${conf}, ${extra}] returned ${ret}, error message:\n" \
179*140b22a2SHans Rosenfeld             "${out}"
180*140b22a2SHans Rosenfeld        return
181*140b22a2SHans Rosenfeld    fi
182*140b22a2SHans Rosenfeld
183*140b22a2SHans Rosenfeld    if [[ -z "${out}" ]]; then
184*140b22a2SHans Rosenfeld        warn "'${show}' [${conf}, ${extra}] output was empty"
185*140b22a2SHans Rosenfeld        return
186*140b22a2SHans Rosenfeld    fi
187*140b22a2SHans Rosenfeld
188*140b22a2SHans Rosenfeld    typeset link
189*140b22a2SHans Rosenfeld    typeset over
190*140b22a2SHans Rosenfeld    typeset addr
191*140b22a2SHans Rosenfeld    typeset type
192*140b22a2SHans Rosenfeld    typeset vid
193*140b22a2SHans Rosenfeld
194*140b22a2SHans Rosenfeld    echo "${out}" | IFS=":" read link over addr type vid
195*140b22a2SHans Rosenfeld
196*140b22a2SHans Rosenfeld    compare "${show}" "link" "${link}" "${dl_vnic}"
197*140b22a2SHans Rosenfeld    ret=$?
198*140b22a2SHans Rosenfeld    [[ ${ret} != 0 ]] && return ${ret};
199*140b22a2SHans Rosenfeld
200*140b22a2SHans Rosenfeld    compare "${show}" "over" "${over}" "${dl_stub}"
201*140b22a2SHans Rosenfeld    ret=$?
202*140b22a2SHans Rosenfeld    [[ ${ret} != 0 ]] && return ${ret};
203*140b22a2SHans Rosenfeld
204*140b22a2SHans Rosenfeld    if [[ "${conf}" == "prefix" || "${dl_types[${conf}]}" == "random" ]]; then
205*140b22a2SHans Rosenfeld        compare "${show}" "addr" "${addr:0:6}" "${dl_macs[${conf}]}"
206*140b22a2SHans Rosenfeld        ret=$?
207*140b22a2SHans Rosenfeld    else
208*140b22a2SHans Rosenfeld        compare "${show}" "addr" "${addr}" "${dl_macs[${conf}]}"
209*140b22a2SHans Rosenfeld        ret=$?
210*140b22a2SHans Rosenfeld    fi
211*140b22a2SHans Rosenfeld    [[ ${ret} != 0 ]] && return ${ret};
212*140b22a2SHans Rosenfeld
213*140b22a2SHans Rosenfeld    compare "${show}" "type" "${type}" "${dl_types[${conf}]}"
214*140b22a2SHans Rosenfeld    ret=$?
215*140b22a2SHans Rosenfeld    [[ ${ret} != 0 ]] && return ${ret};
216*140b22a2SHans Rosenfeld
217*140b22a2SHans Rosenfeld    compare "${show}" "vid" "${vid}" "${dl_vlan[${extra}]}"
218*140b22a2SHans Rosenfeld    ret=$?
219*140b22a2SHans Rosenfeld
220*140b22a2SHans Rosenfeld    return ${ret};
221*140b22a2SHans Rosenfeld}
222*140b22a2SHans Rosenfeld
223*140b22a2SHans Rosenfeldtest_delete()
224*140b22a2SHans Rosenfeld{
225*140b22a2SHans Rosenfeld    typeset conf="$1"
226*140b22a2SHans Rosenfeld    typeset extra="$2"
227*140b22a2SHans Rosenfeld    typeset out
228*140b22a2SHans Rosenfeld    typeset ret
229*140b22a2SHans Rosenfeld
230*140b22a2SHans Rosenfeld    out=$(${dl_delete} ${dl_vnic} 2>&1)
231*140b22a2SHans Rosenfeld    ret=$?
232*140b22a2SHans Rosenfeld
233*140b22a2SHans Rosenfeld    if (( ret != 0 )); then
234*140b22a2SHans Rosenfeld	warn "'${dl_delete}' [$conf, $extra] returned ${ret}, error message:\n" \
235*140b22a2SHans Rosenfeld             "${out}"
236*140b22a2SHans Rosenfeld        return
237*140b22a2SHans Rosenfeld    fi
238*140b22a2SHans Rosenfeld
239*140b22a2SHans Rosenfeld    out=$(${dl_show} -p -o link ${dl_vnic} 2>&1)
240*140b22a2SHans Rosenfeld    ret=$?
241*140b22a2SHans Rosenfeld
242*140b22a2SHans Rosenfeld    if (( ret == 0 )); then
243*140b22a2SHans Rosenfeld	warn "'${dl_show}' after '${dl_delete}' [$conf, $extra] returned " \
244*140b22a2SHans Rosenfeld             "${ret}, output:\n${out}"
245*140b22a2SHans Rosenfeld        return
246*140b22a2SHans Rosenfeld    fi
247*140b22a2SHans Rosenfeld
248*140b22a2SHans Rosenfeld    out=$(${dl_show} -P -p -o link ${dl_vnic} 2>&1)
249*140b22a2SHans Rosenfeld    ret=$?
250*140b22a2SHans Rosenfeld
251*140b22a2SHans Rosenfeld    if (( ret == 0 )); then
252*140b22a2SHans Rosenfeld	warn "'${dl_show} -P' after '${dl_delete}' [$conf, $extra] returned " \
253*140b22a2SHans Rosenfeld             "${ret}, output:\n${out}"
254*140b22a2SHans Rosenfeld        return
255*140b22a2SHans Rosenfeld    fi
256*140b22a2SHans Rosenfeld}
257*140b22a2SHans Rosenfeld
258*140b22a2SHans Rosenfeldtrap cleanup EXIT
259*140b22a2SHans Rosenfeld
260*140b22a2SHans Rosenfeldsetup
261*140b22a2SHans Rosenfeldfor c in "${!dl_configs[@]}"; do
262*140b22a2SHans Rosenfeld    for e in "${!dl_extra_configs[@]}"; do
263*140b22a2SHans Rosenfeld        test_create "$c" "$e"
264*140b22a2SHans Rosenfeld        ret=$?
265*140b22a2SHans Rosenfeld        [[ ${ret} != 0 ]] && break;
266*140b22a2SHans Rosenfeld
267*140b22a2SHans Rosenfeld        test_show "$c" "$e"
268*140b22a2SHans Rosenfeld        test_show "$c" "$e" "-P"
269*140b22a2SHans Rosenfeld        test_delete "$c" "$e"
270*140b22a2SHans Rosenfeld    done
271*140b22a2SHans Rosenfelddone
272*140b22a2SHans Rosenfeldcleanup
273*140b22a2SHans Rosenfeld
274*140b22a2SHans Rosenfeldif (( dl_exit == 0 )); then
275*140b22a2SHans Rosenfeld	printf "All tests passed successfully\n"
276*140b22a2SHans Rosenfeldfi
277*140b22a2SHans Rosenfeldexit $dl_exit
278