17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5ba2e4443Sseb  * Common Development and Distribution License (the "License").
6ba2e4443Sseb  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
221cfa752fSRamaswamy Tummala  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23399dcf08Scarlos antonio neira bustos  */
24399dcf08Scarlos antonio neira bustos 
253d349c31SPeter Tribble /*
26bf410489SAndy Fiddaman  * Copyright (c) 2015, Joyent, Inc.
273d349c31SPeter Tribble  * Copyright 2020 Peter Tribble.
28bf410489SAndy Fiddaman  * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
293d349c31SPeter Tribble  */
303d349c31SPeter Tribble 
317c478bd9Sstevel@tonic-gate #include <unistd.h>
327c478bd9Sstevel@tonic-gate #include <errno.h>
33d62bc4baSyz #include <ctype.h>
340ba2cbe9Sxc #include <fcntl.h>
350ba2cbe9Sxc #include <strings.h>
360ba2cbe9Sxc #include <dirent.h>
37da14cebeSEric Cheng #include <stdlib.h>
3836589d6bSRobert Mustacchi #include <assert.h>
3936589d6bSRobert Mustacchi #include <stdio.h>
4036589d6bSRobert Mustacchi #include <stdarg.h>
4125ec3e3dSEric Cheng #include <netinet/in.h>
4225ec3e3dSEric Cheng #include <arpa/inet.h>
43b9e076dcSyz #include <sys/param.h>
440ba2cbe9Sxc #include <sys/stat.h>
454ac67f02SAnurag S. Maskey #include <sys/dld.h>
4682a2fc47SJames Carlson #include <sys/dld_ioc.h>
470ba2cbe9Sxc #include <libdladm_impl.h>
4833343a97Smeem #include <libintl.h>
49d62bc4baSyz #include <libdlpi.h>
50c569ef53SMichael Lim #include <libdllink.h>
51aae21359Skrgopi 
524ac67f02SAnurag S. Maskey static char	dladm_rootdir[MAXPATHLEN] = "/";
534ac67f02SAnurag S. Maskey 
54b509e89bSRishi Srivatsavai typedef struct media_type_desc {
55b509e89bSRishi Srivatsavai 	uint32_t	media_type;
56b509e89bSRishi Srivatsavai #define	MAX_MEDIA_TYPE_STRING	32
57b509e89bSRishi Srivatsavai 	const char	media_type_str[MAX_MEDIA_TYPE_STRING];
58b509e89bSRishi Srivatsavai } media_type_t;
59b509e89bSRishi Srivatsavai 
60b509e89bSRishi Srivatsavai static media_type_t media_type_table[] =  {
61b509e89bSRishi Srivatsavai 	{ DL_ETHER,	"Ethernet" },
62b509e89bSRishi Srivatsavai 	{ DL_WIFI,	"WiFi" },
63b509e89bSRishi Srivatsavai 	{ DL_IB,	"Infiniband" },
64b509e89bSRishi Srivatsavai 	{ DL_IPV4,	"IPv4Tunnel" },
65b509e89bSRishi Srivatsavai 	{ DL_IPV6,	"IPv6Tunnel" },
662b24ab6bSSebastien Roy 	{ DL_6TO4,	"6to4Tunnel" },
67b509e89bSRishi Srivatsavai 	{ DL_CSMACD,	"CSMA/CD" },
68b509e89bSRishi Srivatsavai 	{ DL_TPB,	"TokenBus" },
69b509e89bSRishi Srivatsavai 	{ DL_TPR,	"TokenRing" },
70b509e89bSRishi Srivatsavai 	{ DL_METRO,	"MetroNet" },
71b509e89bSRishi Srivatsavai 	{ DL_HDLC,	"HDLC" },
72b509e89bSRishi Srivatsavai 	{ DL_CHAR,	"SyncCharacter" },
73b509e89bSRishi Srivatsavai 	{ DL_CTCA,	"CTCA" },
743d349c31SPeter Tribble 	{ DL_FDDI,	"FDDI" },
753d349c31SPeter Tribble 	{ DL_FC,	"FiberChannel" },
763d349c31SPeter Tribble 	{ DL_ATM,	"ATM" },
773d349c31SPeter Tribble 	{ DL_IPATM,	"ATM(ClassicIP)" },
783d349c31SPeter Tribble 	{ DL_X25,	"X.25" },
793d349c31SPeter Tribble 	{ DL_IPX25,	"X.25(ClassicIP)" },
803d349c31SPeter Tribble 	{ DL_ISDN,	"ISDN" },
813d349c31SPeter Tribble 	{ DL_HIPPI,	"HIPPI" },
823d349c31SPeter Tribble 	{ DL_100VG,	"100BaseVGEthernet" },
833d349c31SPeter Tribble 	{ DL_100VGTPR,	"100BaseVGTokenRing" },
843d349c31SPeter Tribble 	{ DL_ETH_CSMA,	"IEEE802.3" },
853d349c31SPeter Tribble 	{ DL_100BT,	"100BaseT" },
863d349c31SPeter Tribble 	{ DL_FRAME,	"FrameRelay" },
873d349c31SPeter Tribble 	{ DL_MPFRAME,	"MPFrameRelay" },
883d349c31SPeter Tribble 	{ DL_ASYNC,	"AsyncCharacter" },
893d349c31SPeter Tribble 	{ DL_IPNET,	"IPNET" },
903d349c31SPeter Tribble 	{ DL_OTHER,	"Other" }
91b509e89bSRishi Srivatsavai };
92b509e89bSRishi Srivatsavai #define	MEDIATYPECOUNT	(sizeof (media_type_table) / sizeof (media_type_t))
93b509e89bSRishi Srivatsavai 
9425ec3e3dSEric Cheng typedef struct {
9525ec3e3dSEric Cheng 	uint32_t	lp_type;
9625ec3e3dSEric Cheng 	char		*lp_name;
9725ec3e3dSEric Cheng } link_protect_t;
9825ec3e3dSEric Cheng 
9925ec3e3dSEric Cheng static link_protect_t link_protect_types[] = {
10025ec3e3dSEric Cheng 	{ MPT_MACNOSPOOF, "mac-nospoof" },
1010dc2366fSVenugopal Iyer 	{ MPT_RESTRICTED, "restricted" },
10225ec3e3dSEric Cheng 	{ MPT_IPNOSPOOF, "ip-nospoof" },
1030dc2366fSVenugopal Iyer 	{ MPT_DHCPNOSPOOF, "dhcp-nospoof" }
10425ec3e3dSEric Cheng };
10525ec3e3dSEric Cheng #define	LPTYPES	(sizeof (link_protect_types) / sizeof (link_protect_t))
10625ec3e3dSEric Cheng 
1074ac67f02SAnurag S. Maskey dladm_status_t
dladm_open(dladm_handle_t * handle)1084ac67f02SAnurag S. Maskey dladm_open(dladm_handle_t *handle)
1094ac67f02SAnurag S. Maskey {
1104ac67f02SAnurag S. Maskey 	int dld_fd;
1114ac67f02SAnurag S. Maskey 
1124ac67f02SAnurag S. Maskey 	if (handle == NULL)
1134ac67f02SAnurag S. Maskey 		return (DLADM_STATUS_BADARG);
1144ac67f02SAnurag S. Maskey 
1154ac67f02SAnurag S. Maskey 	if ((dld_fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
1164ac67f02SAnurag S. Maskey 		return (dladm_errno2status(errno));
1174ac67f02SAnurag S. Maskey 
1184ac67f02SAnurag S. Maskey 	/*
119bbf21555SRichard Lowe 	 * Don't open DLMGMT_DOOR now.  dlmgmtd(8) is not able to
1204ac67f02SAnurag S. Maskey 	 * open the door when the dladm handle is opened because the
1214ac67f02SAnurag S. Maskey 	 * door hasn't been created yet at that time.  Thus, we must
1224ac67f02SAnurag S. Maskey 	 * open it on-demand in dladm_door_fd().  Move the open()
1234ac67f02SAnurag S. Maskey 	 * to dladm_door_fd() for all cases.
1244ac67f02SAnurag S. Maskey 	 */
1254ac67f02SAnurag S. Maskey 
1264ac67f02SAnurag S. Maskey 	if ((*handle = malloc(sizeof (struct dladm_handle))) == NULL) {
1274ac67f02SAnurag S. Maskey 		(void) close(dld_fd);
1284ac67f02SAnurag S. Maskey 		return (DLADM_STATUS_NOMEM);
1294ac67f02SAnurag S. Maskey 	}
1304ac67f02SAnurag S. Maskey 
1314ac67f02SAnurag S. Maskey 	(*handle)->dld_fd = dld_fd;
1324ac67f02SAnurag S. Maskey 	(*handle)->door_fd = -1;
133399dcf08Scarlos antonio neira bustos 	(*handle)->dld_kcp = NULL;
1344ac67f02SAnurag S. Maskey 
1354ac67f02SAnurag S. Maskey 	return (DLADM_STATUS_OK);
1364ac67f02SAnurag S. Maskey }
1374ac67f02SAnurag S. Maskey 
1384ac67f02SAnurag S. Maskey void
dladm_close(dladm_handle_t handle)1394ac67f02SAnurag S. Maskey dladm_close(dladm_handle_t handle)
1404ac67f02SAnurag S. Maskey {
1414ac67f02SAnurag S. Maskey 	if (handle != NULL) {
1424ac67f02SAnurag S. Maskey 		(void) close(handle->dld_fd);
1434ac67f02SAnurag S. Maskey 		if (handle->door_fd != -1)
1444ac67f02SAnurag S. Maskey 			(void) close(handle->door_fd);
145399dcf08Scarlos antonio neira bustos 		if (handle->dld_kcp != NULL)
146399dcf08Scarlos antonio neira bustos 			(void) kstat_close(handle->dld_kcp);
1474ac67f02SAnurag S. Maskey 		free(handle);
1484ac67f02SAnurag S. Maskey 	}
1494ac67f02SAnurag S. Maskey }
1504ac67f02SAnurag S. Maskey 
1514ac67f02SAnurag S. Maskey int
dladm_dld_fd(dladm_handle_t handle)1524ac67f02SAnurag S. Maskey dladm_dld_fd(dladm_handle_t handle)
1534ac67f02SAnurag S. Maskey {
1544ac67f02SAnurag S. Maskey 	return (handle->dld_fd);
1554ac67f02SAnurag S. Maskey }
1564ac67f02SAnurag S. Maskey 
157399dcf08Scarlos antonio neira bustos kstat_ctl_t *
dladm_dld_kcp(dladm_handle_t handle)158399dcf08Scarlos antonio neira bustos dladm_dld_kcp(dladm_handle_t handle)
159399dcf08Scarlos antonio neira bustos {
160399dcf08Scarlos antonio neira bustos 	if (handle->dld_kcp == NULL)
161399dcf08Scarlos antonio neira bustos 		handle->dld_kcp = kstat_open();
162399dcf08Scarlos antonio neira bustos 	return (handle->dld_kcp);
163399dcf08Scarlos antonio neira bustos }
164399dcf08Scarlos antonio neira bustos 
1654ac67f02SAnurag S. Maskey /*
1664ac67f02SAnurag S. Maskey  * If DLMGMT_DOOR hasn't been opened in the handle yet, open it.
1674ac67f02SAnurag S. Maskey  */
1684ac67f02SAnurag S. Maskey dladm_status_t
dladm_door_fd(dladm_handle_t handle,int * door_fd)1694ac67f02SAnurag S. Maskey dladm_door_fd(dladm_handle_t handle, int *door_fd)
1704ac67f02SAnurag S. Maskey {
1714ac67f02SAnurag S. Maskey 	int fd;
1724ac67f02SAnurag S. Maskey 
1734ac67f02SAnurag S. Maskey 	if (handle->door_fd == -1) {
1744ac67f02SAnurag S. Maskey 		if ((fd = open(DLMGMT_DOOR, O_RDONLY)) < 0)
1754ac67f02SAnurag S. Maskey 			return (dladm_errno2status(errno));
1764ac67f02SAnurag S. Maskey 		handle->door_fd = fd;
1774ac67f02SAnurag S. Maskey 	}
1784ac67f02SAnurag S. Maskey 	*door_fd = handle->door_fd;
1794ac67f02SAnurag S. Maskey 
1804ac67f02SAnurag S. Maskey 	return (DLADM_STATUS_OK);
1814ac67f02SAnurag S. Maskey }
1820ba2cbe9Sxc 
1830ba2cbe9Sxc const char *
dladm_status2str(dladm_status_t status,char * buf)1840ba2cbe9Sxc dladm_status2str(dladm_status_t status, char *buf)
1850ba2cbe9Sxc {
1860ba2cbe9Sxc 	const char	*s;
1870ba2cbe9Sxc 
1880ba2cbe9Sxc 	switch (status) {
1890ba2cbe9Sxc 	case DLADM_STATUS_OK:
1900ba2cbe9Sxc 		s = "ok";
1910ba2cbe9Sxc 		break;
1920ba2cbe9Sxc 	case DLADM_STATUS_BADARG:
1930ba2cbe9Sxc 		s = "invalid argument";
1940ba2cbe9Sxc 		break;
1950ba2cbe9Sxc 	case DLADM_STATUS_FAILED:
1960ba2cbe9Sxc 		s = "operation failed";
1970ba2cbe9Sxc 		break;
1980ba2cbe9Sxc 	case DLADM_STATUS_TOOSMALL:
1990ba2cbe9Sxc 		s = "buffer size too small";
2000ba2cbe9Sxc 		break;
2010ba2cbe9Sxc 	case DLADM_STATUS_NOTSUP:
2020ba2cbe9Sxc 		s = "operation not supported";
2030ba2cbe9Sxc 		break;
2040ba2cbe9Sxc 	case DLADM_STATUS_NOTFOUND:
2050ba2cbe9Sxc 		s = "object not found";
2060ba2cbe9Sxc 		break;
2070ba2cbe9Sxc 	case DLADM_STATUS_BADVAL:
2080ba2cbe9Sxc 		s = "invalid value";
2090ba2cbe9Sxc 		break;
2100ba2cbe9Sxc 	case DLADM_STATUS_NOMEM:
2110ba2cbe9Sxc 		s = "insufficient memory";
2120ba2cbe9Sxc 		break;
2130ba2cbe9Sxc 	case DLADM_STATUS_EXIST:
2140ba2cbe9Sxc 		s = "object already exists";
2150ba2cbe9Sxc 		break;
2160ba2cbe9Sxc 	case DLADM_STATUS_LINKINVAL:
2170ba2cbe9Sxc 		s = "invalid link";
2180ba2cbe9Sxc 		break;
2190ba2cbe9Sxc 	case DLADM_STATUS_PROPRDONLY:
2200ba2cbe9Sxc 		s = "read-only property";
2210ba2cbe9Sxc 		break;
2220ba2cbe9Sxc 	case DLADM_STATUS_BADVALCNT:
2230ba2cbe9Sxc 		s = "invalid number of values";
2240ba2cbe9Sxc 		break;
2250ba2cbe9Sxc 	case DLADM_STATUS_DBNOTFOUND:
2260ba2cbe9Sxc 		s = "database not found";
2270ba2cbe9Sxc 		break;
2280ba2cbe9Sxc 	case DLADM_STATUS_DENIED:
2290ba2cbe9Sxc 		s = "permission denied";
2300ba2cbe9Sxc 		break;
2310ba2cbe9Sxc 	case DLADM_STATUS_IOERR:
2320ba2cbe9Sxc 		s = "I/O error";
2330ba2cbe9Sxc 		break;
234f4b3ec61Sdh 	case DLADM_STATUS_TEMPONLY:
235da14cebeSEric Cheng 		s = "change cannot be persistent";
236f4b3ec61Sdh 		break;
237f595a68aSyz 	case DLADM_STATUS_TIMEDOUT:
238f595a68aSyz 		s = "operation timed out";
239f595a68aSyz 		break;
240f595a68aSyz 	case DLADM_STATUS_ISCONN:
241f595a68aSyz 		s = "already connected";
242f595a68aSyz 		break;
243f595a68aSyz 	case DLADM_STATUS_NOTCONN:
244f595a68aSyz 		s = "not connected";
245f595a68aSyz 		break;
246f595a68aSyz 	case DLADM_STATUS_REPOSITORYINVAL:
247f595a68aSyz 		s = "invalid configuration repository";
248f595a68aSyz 		break;
249f595a68aSyz 	case DLADM_STATUS_MACADDRINVAL:
250f595a68aSyz 		s = "invalid MAC address";
251f595a68aSyz 		break;
252f595a68aSyz 	case DLADM_STATUS_KEYINVAL:
253f595a68aSyz 		s = "invalid key";
254f595a68aSyz 		break;
255843e1988Sjohnlev 	case DLADM_STATUS_INVALIDMACADDRLEN:
256843e1988Sjohnlev 		s = "invalid MAC address length";
257843e1988Sjohnlev 		break;
258843e1988Sjohnlev 	case DLADM_STATUS_INVALIDMACADDRTYPE:
259843e1988Sjohnlev 		s = "invalid MAC address type";
260843e1988Sjohnlev 		break;
261d62bc4baSyz 	case DLADM_STATUS_LINKBUSY:
262d62bc4baSyz 		s = "link busy";
263d62bc4baSyz 		break;
264d62bc4baSyz 	case DLADM_STATUS_VIDINVAL:
265d62bc4baSyz 		s = "invalid VLAN identifier";
266843e1988Sjohnlev 		break;
267d62bc4baSyz 	case DLADM_STATUS_TRYAGAIN:
268d62bc4baSyz 		s = "try again later";
269843e1988Sjohnlev 		break;
270d62bc4baSyz 	case DLADM_STATUS_NONOTIF:
271d62bc4baSyz 		s = "link notification is not supported";
272843e1988Sjohnlev 		break;
273da14cebeSEric Cheng 	case DLADM_STATUS_BADTIMEVAL:
274da14cebeSEric Cheng 		s = "invalid time range";
275da14cebeSEric Cheng 		break;
276da14cebeSEric Cheng 	case DLADM_STATUS_INVALIDMACADDR:
277da14cebeSEric Cheng 		s = "invalid MAC address value";
278da14cebeSEric Cheng 		break;
279da14cebeSEric Cheng 	case DLADM_STATUS_INVALIDMACADDRNIC:
280da14cebeSEric Cheng 		s = "MAC address reserved for use by underlying data-link";
281da14cebeSEric Cheng 		break;
282da14cebeSEric Cheng 	case DLADM_STATUS_INVALIDMACADDRINUSE:
283da14cebeSEric Cheng 		s = "MAC address is already in use";
284da14cebeSEric Cheng 		break;
285da14cebeSEric Cheng 	case DLADM_STATUS_MACFACTORYSLOTINVALID:
286da14cebeSEric Cheng 		s = "invalid factory MAC address slot";
287da14cebeSEric Cheng 		break;
288da14cebeSEric Cheng 	case DLADM_STATUS_MACFACTORYSLOTUSED:
289da14cebeSEric Cheng 		s = "factory MAC address slot already used";
290da14cebeSEric Cheng 		break;
291da14cebeSEric Cheng 	case DLADM_STATUS_MACFACTORYSLOTALLUSED:
292da14cebeSEric Cheng 		s = "all factory MAC address slots are in use";
293da14cebeSEric Cheng 		break;
294da14cebeSEric Cheng 	case DLADM_STATUS_MACFACTORYNOTSUP:
295da14cebeSEric Cheng 		s = "factory MAC address slots not supported";
296da14cebeSEric Cheng 		break;
297da14cebeSEric Cheng 	case DLADM_STATUS_INVALIDMACPREFIX:
298da14cebeSEric Cheng 		s = "Invalid MAC address prefix value";
299da14cebeSEric Cheng 		break;
300da14cebeSEric Cheng 	case DLADM_STATUS_INVALIDMACPREFIXLEN:
301da14cebeSEric Cheng 		s = "Invalid MAC address prefix length";
302da14cebeSEric Cheng 		break;
303c569ef53SMichael Lim 	case DLADM_STATUS_BADCPUID:
304da14cebeSEric Cheng 		s = "non-existent processor ID";
305da14cebeSEric Cheng 		break;
306da14cebeSEric Cheng 	case DLADM_STATUS_CPUERR:
307da14cebeSEric Cheng 		s = "could not determine processor status";
308da14cebeSEric Cheng 		break;
309da14cebeSEric Cheng 	case DLADM_STATUS_CPUNOTONLINE:
310da14cebeSEric Cheng 		s = "processor not online";
311da14cebeSEric Cheng 		break;
312c569ef53SMichael Lim 	case DLADM_STATUS_TOOMANYELEMENTS:
313c569ef53SMichael Lim 		s = "too many elements specified";
314c569ef53SMichael Lim 		break;
315c569ef53SMichael Lim 	case DLADM_STATUS_BADRANGE:
316c569ef53SMichael Lim 		s = "invalid range";
317c569ef53SMichael Lim 		break;
318da14cebeSEric Cheng 	case DLADM_STATUS_DB_NOTFOUND:
319da14cebeSEric Cheng 		s = "database not found";
320da14cebeSEric Cheng 		break;
321da14cebeSEric Cheng 	case DLADM_STATUS_DB_PARSE_ERR:
322da14cebeSEric Cheng 		s = "database parse error";
323da14cebeSEric Cheng 		break;
324da14cebeSEric Cheng 	case DLADM_STATUS_PROP_PARSE_ERR:
325da14cebeSEric Cheng 		s = "property parse error";
326da14cebeSEric Cheng 		break;
327da14cebeSEric Cheng 	case DLADM_STATUS_ATTR_PARSE_ERR:
328da14cebeSEric Cheng 		s = "attribute parse error";
329da14cebeSEric Cheng 		break;
330da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_DB_ERR:
331da14cebeSEric Cheng 		s = "flow database error";
332da14cebeSEric Cheng 		break;
333da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_DB_OPEN_ERR:
334da14cebeSEric Cheng 		s = "flow database open error";
335da14cebeSEric Cheng 		break;
336da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_DB_PARSE_ERR:
337da14cebeSEric Cheng 		s = "flow database parse error";
338da14cebeSEric Cheng 		break;
339da14cebeSEric Cheng 	case DLADM_STATUS_FLOWPROP_DB_PARSE_ERR:
340da14cebeSEric Cheng 		s = "flow property database parse error";
341da14cebeSEric Cheng 		break;
342da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_ADD_ERR:
343da14cebeSEric Cheng 		s = "flow add error";
344da14cebeSEric Cheng 		break;
345da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_WALK_ERR:
346da14cebeSEric Cheng 		s = "flow walk error";
347da14cebeSEric Cheng 		break;
348da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_IDENTICAL:
349da14cebeSEric Cheng 		s = "a flow with identical attributes exists";
350da14cebeSEric Cheng 		break;
351da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_INCOMPATIBLE:
352da14cebeSEric Cheng 		s = "flow(s) with incompatible attributes exists";
353da14cebeSEric Cheng 		break;
354da14cebeSEric Cheng 	case DLADM_STATUS_FLOW_EXISTS:
355da14cebeSEric Cheng 		s = "link still has flows";
356da14cebeSEric Cheng 		break;
357da14cebeSEric Cheng 	case DLADM_STATUS_PERSIST_FLOW_EXISTS:
358da14cebeSEric Cheng 		s = "persistent flow with the same name exists";
359da14cebeSEric Cheng 		break;
360da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_IP:
361da14cebeSEric Cheng 		s = "invalid IP address";
362da14cebeSEric Cheng 		break;
363da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_PREFIXLEN:
364da14cebeSEric Cheng 		s = "invalid IP prefix length";
365da14cebeSEric Cheng 		break;
366da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_PROTOCOL:
367da14cebeSEric Cheng 		s = "invalid IP protocol";
368da14cebeSEric Cheng 		break;
369da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_PORT:
370da14cebeSEric Cheng 		s = "invalid port number";
371da14cebeSEric Cheng 		break;
372da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_DSF:
373da14cebeSEric Cheng 		s = "invalid dsfield";
374da14cebeSEric Cheng 		break;
375da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_DSFMASK:
376da14cebeSEric Cheng 		s = "invalid dsfield mask";
377da14cebeSEric Cheng 		break;
378da14cebeSEric Cheng 	case DLADM_STATUS_INVALID_MACMARGIN:
379da14cebeSEric Cheng 		s = "MTU check failed, use lower MTU or -f option";
380da14cebeSEric Cheng 		break;
381da14cebeSEric Cheng 	case DLADM_STATUS_BADPROP:
382da14cebeSEric Cheng 		s = "invalid property";
383da14cebeSEric Cheng 		break;
384da14cebeSEric Cheng 	case DLADM_STATUS_MINMAXBW:
38580109390SMichael Lim 		s = "minimum value for maxbw is 1200K";
386da14cebeSEric Cheng 		break;
387da14cebeSEric Cheng 	case DLADM_STATUS_NO_HWRINGS:
388da14cebeSEric Cheng 		s = "request hw rings failed";
389da14cebeSEric Cheng 		break;
3904eaa4710SRishi Srivatsavai 	case DLADM_STATUS_PERMONLY:
3914eaa4710SRishi Srivatsavai 		s = "change must be persistent";
3924eaa4710SRishi Srivatsavai 		break;
3934eaa4710SRishi Srivatsavai 	case DLADM_STATUS_OPTMISSING:
3944eaa4710SRishi Srivatsavai 		s = "optional software not installed";
3954eaa4710SRishi Srivatsavai 		break;
3962b24ab6bSSebastien Roy 	case DLADM_STATUS_IPTUNTYPE:
3972b24ab6bSSebastien Roy 		s = "invalid IP tunnel type";
3982b24ab6bSSebastien Roy 		break;
3992b24ab6bSSebastien Roy 	case DLADM_STATUS_IPTUNTYPEREQD:
4002b24ab6bSSebastien Roy 		s = "IP tunnel type required";
4012b24ab6bSSebastien Roy 		break;
4022b24ab6bSSebastien Roy 	case DLADM_STATUS_BADIPTUNLADDR:
4032b24ab6bSSebastien Roy 		s = "invalid local IP tunnel address";
4042b24ab6bSSebastien Roy 		break;
4052b24ab6bSSebastien Roy 	case DLADM_STATUS_BADIPTUNRADDR:
4062b24ab6bSSebastien Roy 		s = "invalid remote IP tunnel address";
4072b24ab6bSSebastien Roy 		break;
4082b24ab6bSSebastien Roy 	case DLADM_STATUS_ADDRINUSE:
4092b24ab6bSSebastien Roy 		s = "address already in use";
4102b24ab6bSSebastien Roy 		break;
4110dc2366fSVenugopal Iyer 	case DLADM_STATUS_POOLCPU:
4120dc2366fSVenugopal Iyer 		s = "pool and cpus property are mutually exclusive";
4130dc2366fSVenugopal Iyer 		break;
4141cfa752fSRamaswamy Tummala 	case DLADM_STATUS_INVALID_PORT_INSTANCE:
4151cfa752fSRamaswamy Tummala 		s = "invalid IB phys link";
4161cfa752fSRamaswamy Tummala 		break;
417