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