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