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