1d62bc4baSyz /*
2d62bc4baSyz  * CDDL HEADER START
3d62bc4baSyz  *
4d62bc4baSyz  * The contents of this file are subject to the terms of the
5d62bc4baSyz  * Common Development and Distribution License (the "License").
6d62bc4baSyz  * You may not use this file except in compliance with the License.
7d62bc4baSyz  *
8d62bc4baSyz  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d62bc4baSyz  * or http://www.opensolaris.org/os/licensing.
10d62bc4baSyz  * See the License for the specific language governing permissions
11d62bc4baSyz  * and limitations under the License.
12d62bc4baSyz  *
13d62bc4baSyz  * When distributing Covered Code, include this CDDL HEADER in each
14d62bc4baSyz  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d62bc4baSyz  * If applicable, add the following below this CDDL HEADER, with the
16d62bc4baSyz  * fields enclosed by brackets "[]" replaced with your own identifying
17d62bc4baSyz  * information: Portions Copyright [yyyy] [name of copyright owner]
18d62bc4baSyz  *
19d62bc4baSyz  * CDDL HEADER END
20d62bc4baSyz  */
21d62bc4baSyz /*
2232715170SCathy Zhou  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23*85dff7a0SAndy Fiddaman  * Copyright 2016 Joyent, Inc.
24*85dff7a0SAndy Fiddaman  * Copyright 2023 Oxide Computer Company
25d62bc4baSyz  */
26d62bc4baSyz 
27d62bc4baSyz #include <door.h>
28d62bc4baSyz #include <errno.h>
29d62bc4baSyz #include <assert.h>
30d62bc4baSyz #include <stdio.h>
31d62bc4baSyz #include <stdlib.h>
32d62bc4baSyz #include <unistd.h>
33d62bc4baSyz #include <string.h>
34d62bc4baSyz #include <strings.h>
352b24ab6bSSebastien Roy #include <zone.h>
36d62bc4baSyz #include <sys/types.h>
37d62bc4baSyz #include <sys/stat.h>
38d62bc4baSyz #include <sys/aggr.h>
3982a2fc47SJames Carlson #include <sys/mman.h>
40d62bc4baSyz #include <fcntl.h>
41d62bc4baSyz #include <libdladm.h>
42d62bc4baSyz #include <libdladm_impl.h>
43d62bc4baSyz #include <libdllink.h>
44d62bc4baSyz #include <libdlmgmt.h>
45d62bc4baSyz 
46d62bc4baSyz /*
47d62bc4baSyz  * Table of data type sizes indexed by dladm_datatype_t.
48d62bc4baSyz  */
49d62bc4baSyz static size_t dladm_datatype_size[] = {
50d62bc4baSyz 	0,				/* DLADM_TYPE_STR, use strnlen() */
51d62bc4baSyz 	sizeof (boolean_t),		/* DLADM_TYPE_BOOLEAN */
52d62bc4baSyz 	sizeof (uint64_t)		/* DLADM_TYPE_UINT64 */
53d62bc4baSyz };
54d62bc4baSyz 
55d62bc4baSyz static dladm_status_t
dladm_door_call(dladm_handle_t handle,void * arg,size_t asize,void * rbuf,size_t * rsizep)564ac67f02SAnurag S. Maskey dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf,
5732715170SCathy Zhou     size_t *rsizep)
58d62bc4baSyz {
59d62bc4baSyz 	door_arg_t	darg;
604ac67f02SAnurag S. Maskey 	int		door_fd;
61f689bed1SRishi Srivatsavai 	dladm_status_t	status;
62f689bed1SRishi Srivatsavai 	boolean_t	reopen = B_FALSE;
63d62bc4baSyz 
64d62bc4baSyz 	darg.data_ptr	= arg;
65d62bc4baSyz 	darg.data_size	= asize;
66d62bc4baSyz 	darg.desc_ptr	= NULL;
67d62bc4baSyz 	darg.desc_num	= 0;
68d62bc4baSyz 	darg.rbuf	= rbuf;
6932715170SCathy Zhou 	darg.rsize	= *rsizep;
70d62bc4baSyz 
71f689bed1SRishi Srivatsavai reopen:
724ac67f02SAnurag S. Maskey 	/* The door descriptor is opened if it isn't already */
734ac67f02SAnurag S. Maskey 	if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK)
744ac67f02SAnurag S. Maskey 		return (status);
75f689bed1SRishi Srivatsavai 	if (door_call(door_fd, &darg) == -1) {
76f689bed1SRishi Srivatsavai 		/*
77f689bed1SRishi Srivatsavai 		 * Stale door descriptor is possible if dlmgmtd was re-started
78f689bed1SRishi Srivatsavai 		 * since last door_fd open so try re-opening door file.
79f689bed1SRishi Srivatsavai 		 */
80f689bed1SRishi Srivatsavai 		if (!reopen && errno == EBADF) {
81f689bed1SRishi Srivatsavai 			(void) close(handle->door_fd);
82f689bed1SRishi Srivatsavai 			handle->door_fd = -1;
83f689bed1SRishi Srivatsavai 			reopen = B_TRUE;
84f689bed1SRishi Srivatsavai 			goto reopen;
85f689bed1SRishi Srivatsavai 		}
86d62bc4baSyz 		status = dladm_errno2status(errno);
87f689bed1SRishi Srivatsavai 	}
88d62bc4baSyz 	if (status != DLADM_STATUS_OK)
89d62bc4baSyz 		return (status);
90d62bc4baSyz 
91d62bc4baSyz 	if (darg.rbuf != rbuf) {
92d62bc4baSyz 		/*
93d62bc4baSyz 		 * The size of the input rbuf is not big enough so that
9432715170SCathy Zhou 		 * the door allocate the rbuf itself. In this case, return
9532715170SCathy Zhou 		 * the required size to the caller.
96d62bc4baSyz 		 */
97d62bc4baSyz 		(void) munmap(darg.rbuf, darg.rsize);
9832715170SCathy Zhou 		*rsizep = darg.rsize;
99d62bc4baSyz 		return (DLADM_STATUS_TOOSMALL);
10032715170SCathy Zhou 	} else if (darg.rsize != *rsizep) {
101d62bc4baSyz 		return (DLADM_STATUS_FAILED);
10232715170SCathy Zhou 	}
103d62bc4baSyz 
104024b0a25Sseb 	return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err));
105d62bc4baSyz }
106d62bc4baSyz 
107d62bc4baSyz /*
108d62bc4baSyz  * Allocate a new linkid with the given name. Return the new linkid.
109d62bc4baSyz  */
110d62bc4baSyz dladm_status_t
dladm_create_datalink_id(dladm_handle_t handle,const char * link,datalink_class_t class,uint32_t media,uint32_t flags,datalink_id_t * linkidp)1114ac67f02SAnurag S. Maskey dladm_create_datalink_id(dladm_handle_t handle, const char *link,
1124ac67f02SAnurag S. Maskey     datalink_class_t class, uint32_t media, uint32_t flags,
1134ac67f02SAnurag S. Maskey     datalink_id_t *linkidp)
114d62bc4baSyz {
115024b0a25Sseb 	dlmgmt_door_createid_t	createid;
116d62bc4baSyz 	dlmgmt_createid_retval_t retval;
117024b0a25Sseb 	uint32_t		dlmgmt_flags;
118024b0a25Sseb 	dladm_status_t		status;
11932715170SCathy Zhou 	size_t			sz = sizeof (retval);
120d62bc4baSyz 
121024b0a25Sseb 	if (link == NULL || class == DATALINK_CLASS_ALL ||
122d62bc4baSyz 	    !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) ||
123d62bc4baSyz 	    linkidp == NULL) {
124d62bc4baSyz 		return (DLADM_STATUS_BADARG);
125d62bc4baSyz 	}
126d62bc4baSyz 
127*85dff7a0SAndy Fiddaman 	if (getzoneid() != GLOBAL_ZONEID) {
128*85dff7a0SAndy Fiddaman 		/*
129*85dff7a0SAndy Fiddaman 		 * If we're creating this link in a non-global zone, then do
130*85dff7a0SAndy Fiddaman 		 * not allow it to be persistent, and flag it as transient so
131*85dff7a0SAndy Fiddaman 		 * that it will be automatically cleaned up on zone shutdown,
132*85dff7a0SAndy Fiddaman 		 * rather than being moved to the GZ.
133*85dff7a0SAndy Fiddaman 		 */
134*85dff7a0SAndy Fiddaman 		if (flags & DLADM_OPT_PERSIST)
135*85dff7a0SAndy Fiddaman 			return (DLADM_STATUS_TEMPONLY);
136*85dff7a0SAndy Fiddaman 		flags |= DLADM_OPT_TRANSIENT;
137*85dff7a0SAndy Fiddaman 	}
138*85dff7a0SAndy Fiddaman 
139d62bc4baSyz 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
140d62bc4baSyz 	dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0;
141*85dff7a0SAndy Fiddaman 	dlmgmt_flags |= (flags & DLADM_OPT_TRANSIENT) ? DLMGMT_TRANSIENT : 0;
142d62bc4baSyz 
143d62bc4baSyz 	(void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN);
144d62bc4baSyz 	createid.ld_class = class;
145d62bc4baSyz 	createid.ld_media = media;
146d62bc4baSyz 	createid.ld_flags = dlmgmt_flags;
147d62bc4baSyz 	createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID;
148d62bc4baSyz 	createid.ld_prefix = (flags & DLADM_OPT_PREFIX);
149d62bc4baSyz 
1504ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &createid, sizeof (createid),
15132715170SCathy Zhou 	    &retval, &sz)) == DLADM_STATUS_OK) {
152024b0a25Sseb 		*linkidp = retval.lr_linkid;
153024b0a25Sseb 	}
154024b0a25Sseb 	return (status);
155d62bc4baSyz }
156d62bc4baSyz 
157d62bc4baSyz /*
158d62bc4baSyz  * Destroy the given link ID.
159d62bc4baSyz  */
160d62bc4baSyz dladm_status_t
dladm_destroy_datalink_id(dladm_handle_t handle,datalink_id_t linkid,uint32_t flags)1614ac67f02SAnurag S. Maskey dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
1624ac67f02SAnurag S. Maskey     uint32_t flags)
163d62bc4baSyz {
164d62bc4baSyz 	dlmgmt_door_destroyid_t		destroyid;
165d62bc4baSyz 	dlmgmt_destroyid_retval_t	retval;
166d62bc4baSyz 	uint32_t			dlmgmt_flags;
16732715170SCathy Zhou 	size_t				sz = sizeof (retval);
168d62bc4baSyz 
169d62bc4baSyz 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
170d62bc4baSyz 	dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
171d62bc4baSyz 
172d62bc4baSyz 	destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID;
173d62bc4baSyz 	destroyid.ld_linkid = linkid;
174d62bc4baSyz 	destroyid.ld_flags = dlmgmt_flags;
175d62bc4baSyz 
17632715170SCathy Zhou 	return (dladm_door_call(handle, &destroyid, sizeof (destroyid),
17732715170SCathy Zhou 	    &retval, &sz));
178d62bc4baSyz }
179d62bc4baSyz 
180d62bc4baSyz /*
181d62bc4baSyz  * Remap a given link ID to a new name.
182d62bc4baSyz  */
183d62bc4baSyz dladm_status_t
dladm_remap_datalink_id(dladm_handle_t handle,datalink_id_t linkid,const char * link)1844ac67f02SAnurag S. Maskey dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
1854ac67f02SAnurag S. Maskey     const char *link)
186d62bc4baSyz {
187d62bc4baSyz 	dlmgmt_door_remapid_t	remapid;
188d62bc4baSyz 	dlmgmt_remapid_retval_t	retval;
18932715170SCathy Zhou 	size_t			sz = sizeof (retval);
190d62bc4baSyz 
191d62bc4baSyz 	remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID;
192d62bc4baSyz 	remapid.ld_linkid = linkid;
193d62bc4baSyz 	(void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN);
194d62bc4baSyz 
19532715170SCathy Zhou 	return (dladm_door_call(handle, &remapid, sizeof (remapid),
19632715170SCathy Zhou 	    &retval, &sz));
197d62bc4baSyz }
198d62bc4baSyz 
199d62bc4baSyz /*
200d62bc4baSyz  * Make a given link ID active.
201d62bc4baSyz  */
202d62bc4baSyz dladm_status_t
dladm_up_datalink_id(dladm_handle_t handle,datalink_id_t linkid)2034ac67f02SAnurag S. Maskey dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid)
204d62bc4baSyz {
205024b0a25Sseb 	dlmgmt_door_upid_t	upid;
206024b0a25Sseb 	dlmgmt_upid_retval_t	retval;
20732715170SCathy Zhou 	size_t			sz = sizeof (retval);
208d62bc4baSyz 
209d62bc4baSyz 	upid.ld_cmd = DLMGMT_CMD_UP_LINKID;
210d62bc4baSyz 	upid.ld_linkid = linkid;
211d62bc4baSyz 
21232715170SCathy Zhou 	return (dladm_door_call(handle, &upid, sizeof (upid), &retval, &sz));
213d62bc4baSyz }
214d62bc4baSyz 
215d62bc4baSyz /*
216d62bc4baSyz  * Create a new link with the given name.  Return the new link's handle
217d62bc4baSyz  */
218d62bc4baSyz dladm_status_t
dladm_create_conf(dladm_handle_t handle,const char * link,datalink_id_t linkid,datalink_class_t class,uint32_t media,dladm_conf_t * confp)2194ac67f02SAnurag S. Maskey dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid,
220d62bc4baSyz     datalink_class_t class, uint32_t media, dladm_conf_t *confp)
221d62bc4baSyz {
222024b0a25Sseb 	dlmgmt_door_createconf_t	createconf;
223024b0a25Sseb 	dlmgmt_createconf_retval_t	retval;
224024b0a25Sseb 	dladm_status_t			status;
22532715170SCathy Zhou 	size_t				sz = sizeof (retval);
226d62bc4baSyz 
227024b0a25Sseb 	if (link == NULL || confp == NULL)
228d62bc4baSyz 		return (DLADM_STATUS_BADARG);
229d62bc4baSyz 
230d62bc4baSyz 	(void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN);
231d62bc4baSyz 	createconf.ld_class = class;
232d62bc4baSyz 	createconf.ld_media = media;
233d62bc4baSyz 	createconf.ld_linkid = linkid;
234d62bc4baSyz 	createconf.ld_cmd = DLMGMT_CMD_CREATECONF;
23532715170SCathy Zhou 	confp->ds_confid = DLADM_INVALID_CONF;
236d62bc4baSyz 
2374ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &createconf, sizeof (createconf),
23832715170SCathy Zhou 	    &retval, &sz)) == DLADM_STATUS_OK) {
23932715170SCathy Zhou 		confp->ds_readonly = B_FALSE;
24032715170SCathy Zhou 		confp->ds_confid = retval.lr_confid;
241024b0a25Sseb 	}
242024b0a25Sseb 	return (status);
243d62bc4baSyz }
244d62bc4baSyz 
245d62bc4baSyz /*
246d62bc4baSyz  * An active physical link reported by the dlmgmtd daemon might not be active
247d62bc4baSyz  * anymore as this link might be removed during system shutdown. Check its
248d62bc4baSyz  * real status by calling dladm_phys_info().
249d62bc4baSyz  */
250d62bc4baSyz dladm_status_t
i_dladm_phys_status(dladm_handle_t handle,datalink_id_t linkid,uint32_t * flagsp)2514ac67f02SAnurag S. Maskey i_dladm_phys_status(dladm_handle_t handle, datalink_id_t linkid,
2524ac67f02SAnurag S. Maskey     uint32_t *flagsp)
253d62bc4baSyz {
254d62bc4baSyz 	dladm_phys_attr_t	dpa;
255d62bc4baSyz 	dladm_status_t		status;
256d62bc4baSyz 
257d62bc4baSyz 	assert((*flagsp) & DLMGMT_ACTIVE);
258d62bc4baSyz 
2594ac67f02SAnurag S. Maskey 	status = dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE);
260d62bc4baSyz 	if (status == DLADM_STATUS_NOTFOUND) {
261d62bc4baSyz 		/*
262d62bc4baSyz 		 * No active status, this link was removed. Update its status
263d62bc4baSyz 		 * in the daemon and delete all active linkprops.
2642d4eecfaSCathy Zhou 		 *
2652d4eecfaSCathy Zhou 		 * Note that the operation could fail. If it does, return
2662d4eecfaSCathy Zhou 		 * failure now since otherwise dladm_set_linkprop() might
2672d4eecfaSCathy Zhou 		 * call back to i_dladm_phys_status() recursively.
268d62bc4baSyz 		 */
2694ac67f02SAnurag S. Maskey 		if ((status = dladm_destroy_datalink_id(handle, linkid,
2704ac67f02SAnurag S. Maskey 		    DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK)
2712d4eecfaSCathy Zhou 			return (status);
2722d4eecfaSCathy Zhou 
2734ac67f02SAnurag S. Maskey 		(void) dladm_set_linkprop(handle, linkid, NULL, NULL, 0,
274d62bc4baSyz 		    DLADM_OPT_ACTIVE);
275d62bc4baSyz 
276d62bc4baSyz 		(*flagsp) &= ~DLMGMT_ACTIVE;
277d62bc4baSyz 		status = DLADM_STATUS_OK;
278d62bc4baSyz 	}
279d62bc4baSyz 	return (status);
280d62bc4baSyz }
281d62bc4baSyz 
282d62bc4baSyz /*
283d62bc4baSyz  * Walk each entry in the data link configuration repository and
284d62bc4baSyz  * call fn on the linkid and arg.
285d62bc4baSyz  */
286d62bc4baSyz dladm_status_t
dladm_walk_datalink_id(int (* fn)(dladm_handle_t,datalink_id_t,void *),dladm_handle_t handle,void * argp,datalink_class_t class,datalink_media_t dmedia,uint32_t flags)2874ac67f02SAnurag S. Maskey dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *),
2884ac67f02SAnurag S. Maskey     dladm_handle_t handle, void *argp, datalink_class_t class,
2894ac67f02SAnurag S. Maskey     datalink_media_t dmedia, uint32_t flags)
290d62bc4baSyz {
291d62bc4baSyz 	dlmgmt_door_getnext_t	getnext;
292d62bc4baSyz 	dlmgmt_getnext_retval_t	retval;
293c0e21d6aSToomas Soome 	uint32_t		dlmgmt_flags;
294d62bc4baSyz 	datalink_id_t		linkid = DATALINK_INVALID_LINKID;
295d62bc4baSyz 	dladm_status_t		status = DLADM_STATUS_OK;
29632715170SCathy Zhou 	size_t			sz = sizeof (retval);
297d62bc4baSyz 
298d62bc4baSyz 	if (fn == NULL)
299d62bc4baSyz 		return (DLADM_STATUS_BADARG);
300d62bc4baSyz 
301d62bc4baSyz 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
302d62bc4baSyz 	dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
303*85dff7a0SAndy Fiddaman 	dlmgmt_flags |= ((flags & DLADM_OPT_TRANSIENT) ? DLMGMT_TRANSIENT : 0);
304d62bc4baSyz 
305d62bc4baSyz 	getnext.ld_cmd = DLMGMT_CMD_GETNEXT;
306d62bc4baSyz 	getnext.ld_class = class;
307d62bc4baSyz 	getnext.ld_dmedia = dmedia;
308d62bc4baSyz 	getnext.ld_flags = dlmgmt_flags;
309d62bc4baSyz 
310d62bc4baSyz 	do {
311d62bc4baSyz 		getnext.ld_linkid = linkid;
3124ac67f02SAnurag S. Maskey 		if ((status = dladm_door_call(handle, &getnext,
31332715170SCathy Zhou 		    sizeof (getnext), &retval, &sz)) != DLADM_STATUS_OK) {
314d62bc4baSyz 			/*
3157363c184SCathy Zhou 			 * Done with walking. If no next datalink is found,
3167363c184SCathy Zhou 			 * return success.
317d62bc4baSyz 			 */
3187363c184SCathy Zhou 			if (status == DLADM_STATUS_NOTFOUND)
3197363c184SCathy Zhou 				status = DLADM_STATUS_OK;
320d62bc4baSyz 			break;
321d62bc4baSyz 		}
322d62bc4baSyz 
323d62bc4baSyz 		linkid = retval.lr_linkid;
324d62bc4baSyz 		if ((retval.lr_class == DATALINK_CLASS_PHYS) &&
325d62bc4baSyz 		    (retval.lr_flags & DLMGMT_ACTIVE)) {
326d62bc4baSyz 			/*
327d62bc4baSyz 			 * An active physical link reported by the dlmgmtd
328d62bc4baSyz 			 * daemon might not be active anymore. Check its
329d62bc4baSyz 			 * real status.
330d62bc4baSyz 			 */
3314ac67f02SAnurag S. Maskey 			if (i_dladm_phys_status(handle, linkid,
3324ac67f02SAnurag S. Maskey 			    &retval.lr_flags) != DLADM_STATUS_OK) {
333d62bc4baSyz 				continue;
334d62bc4baSyz 			}
335d62bc4baSyz 
336d62bc4baSyz 			if (!(dlmgmt_flags & retval.lr_flags))
337d62bc4baSyz 				continue;
338d62bc4baSyz 		}
339d62bc4baSyz 
3404ac67f02SAnurag S. Maskey 		if (fn(handle, linkid, argp) == DLADM_WALK_TERMINATE)
341d62bc4baSyz 			break;
342d62bc4baSyz 	} while (linkid != DATALINK_INVALID_LINKID);
343d62bc4baSyz 
344d62bc4baSyz 	return (status);
345d62bc4baSyz }
346d62bc4baSyz 
347d62bc4baSyz /*
34832715170SCathy Zhou  * Get a handle of a copy of the link configuration (kept in the daemon)
34932715170SCathy Zhou  * for the given link so it can be updated later by dladm_write_conf().
35032715170SCathy Zhou  */
35132715170SCathy Zhou dladm_status_t
dladm_open_conf(dladm_handle_t handle,datalink_id_t linkid,dladm_conf_t * confp)35232715170SCathy Zhou dladm_open_conf(dladm_handle_t handle, datalink_id_t linkid,
35332715170SCathy Zhou     dladm_conf_t *confp)
35432715170SCathy Zhou {
35532715170SCathy Zhou 	dlmgmt_door_openconf_t		openconf;
35632715170SCathy Zhou 	dlmgmt_openconf_retval_t	retval;
35732715170SCathy Zhou 	dladm_status_t			status;
35832715170SCathy Zhou 	size_t				sz;
35932715170SCathy Zhou 
36032715170SCathy Zhou 	if (linkid == DATALINK_INVALID_LINKID || confp == NULL)
36132715170SCathy Zhou 		return (DLADM_STATUS_BADARG);
36232715170SCathy Zhou 
36332715170SCathy Zhou 	sz = sizeof (retval);
36432715170SCathy Zhou 	openconf.ld_linkid = linkid;
36532715170SCathy Zhou 	openconf.ld_cmd = DLMGMT_CMD_OPENCONF;
36632715170SCathy Zhou 	confp->ds_confid = DLADM_INVALID_CONF;
36732715170SCathy Zhou 	if ((status = dladm_door_call(handle, &openconf,
36832715170SCathy Zhou 	    sizeof (openconf), &retval, &sz)) == DLADM_STATUS_OK) {
36932715170SCathy Zhou 		confp->ds_readonly = B_FALSE;
37032715170SCathy Zhou 		confp->ds_confid = retval.lr_confid;
37132715170SCathy Zhou 	}
37232715170SCathy Zhou 
37332715170SCathy Zhou 	return (status);
37432715170SCathy Zhou }
37532715170SCathy Zhou 
37632715170SCathy Zhou /*
37732715170SCathy Zhou  * Get the handle of a local snapshot of the link configuration. Note that
37832715170SCathy Zhou  * any operations with this handle are read-only, i.e., one can not update
37932715170SCathy Zhou  * the configuration with this handle.
380d62bc4baSyz  */
381d62bc4baSyz dladm_status_t
dladm_getsnap_conf(dladm_handle_t handle,datalink_id_t linkid,dladm_conf_t * confp)38232715170SCathy Zhou dladm_getsnap_conf(dladm_handle_t handle, datalink_id_t linkid,
3834ac67f02SAnurag S. Maskey     dladm_conf_t *confp)
384d62bc4baSyz {
38532715170SCathy Zhou 	dlmgmt_door_getconfsnapshot_t	snapshot;
38632715170SCathy Zhou 	dlmgmt_getconfsnapshot_retval_t	*retvalp;
38732715170SCathy Zhou 	char				*nvlbuf;
388d62bc4baSyz 	dladm_status_t			status;
38932715170SCathy Zhou 	int				err;
39032715170SCathy Zhou 	size_t				sz;
391d62bc4baSyz 
392d62bc4baSyz 	if (linkid == DATALINK_INVALID_LINKID || confp == NULL)
393d62bc4baSyz 		return (DLADM_STATUS_BADARG);
394d62bc4baSyz 
39532715170SCathy Zhou 	sz = sizeof (dlmgmt_getconfsnapshot_retval_t);
39632715170SCathy Zhou 	snapshot.ld_linkid = linkid;
39732715170SCathy Zhou 	snapshot.ld_cmd = DLMGMT_CMD_GETCONFSNAPSHOT;
39832715170SCathy Zhou again:
39932715170SCathy Zhou 	if ((retvalp = malloc(sz)) == NULL)
40032715170SCathy Zhou 		return (DLADM_STATUS_NOMEM);
40132715170SCathy Zhou 
40232715170SCathy Zhou 	if ((status = dladm_door_call(handle, &snapshot, sizeof (snapshot),
40332715170SCathy Zhou 	    retvalp, &sz)) == DLADM_STATUS_TOOSMALL) {
40432715170SCathy Zhou 		free(retvalp);
40532715170SCathy Zhou 		goto again;
40632715170SCathy Zhou 	}
40732715170SCathy Zhou 
40832715170SCathy Zhou 	if (status != DLADM_STATUS_OK) {
40932715170SCathy Zhou 		free(retvalp);
41032715170SCathy Zhou 		return (status);
41132715170SCathy Zhou 	}
412d62bc4baSyz 
41332715170SCathy Zhou 	confp->ds_readonly = B_TRUE;
41432715170SCathy Zhou 	nvlbuf = (char *)retvalp + sizeof (dlmgmt_getconfsnapshot_retval_t);
41532715170SCathy Zhou 	if ((err = nvlist_unpack(nvlbuf, retvalp->lr_nvlsz,
4160d1087e8SHans Rosenfeld 	    &(confp->ds_nvl), 0)) != 0) {
41732715170SCathy Zhou 		status = dladm_errno2status(err);
418024b0a25Sseb 	}
41932715170SCathy Zhou 	free(retvalp);
420024b0a25Sseb 	return (status);
421d62bc4baSyz }
422d62bc4baSyz 
423d62bc4baSyz /*
424d62bc4baSyz  * Commit the given link to the data link configuration repository so
425d62bc4baSyz  * that it will persist across reboots.
426d62bc4baSyz  */
427d62bc4baSyz dladm_status_t
dladm_write_conf(dladm_handle_t handle,dladm_conf_t conf)4284ac67f02SAnurag S. Maskey dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf)
429d62bc4baSyz {
430d62bc4baSyz 	dlmgmt_door_writeconf_t		writeconf;
431d62bc4baSyz 	dlmgmt_writeconf_retval_t	retval;
43232715170SCathy Zhou 	size_t				sz = sizeof (retval);
433d62bc4baSyz 
43432715170SCathy Zhou 	if (conf.ds_confid == DLADM_INVALID_CONF)
435d62bc4baSyz 		return (DLADM_STATUS_BADARG);
436d62bc4baSyz 
43732715170SCathy Zhou 	if (conf.ds_readonly)
43832715170SCathy Zhou 		return (DLADM_STATUS_DENIED);
43932715170SCathy Zhou 
440d62bc4baSyz 	writeconf.ld_cmd = DLMGMT_CMD_WRITECONF;
44132715170SCathy Zhou 	writeconf.ld_confid = conf.ds_confid;
442d62bc4baSyz 
44332715170SCathy Zhou 	return (dladm_door_call(handle, &writeconf, sizeof (writeconf),
44432715170SCathy Zhou 	    &retval, &sz));
445d62bc4baSyz }
446d62bc4baSyz 
447d62bc4baSyz /*
44832715170SCathy Zhou  * Given a dladm_conf_t, get the specific configuration field
44932715170SCathy Zhou  *
45032715170SCathy Zhou  * If the specified dladm_conf_t is a read-only snapshot of the configuration,
45132715170SCathy Zhou  * get a specific link propertie from that snapshot (nvl), otherwise, get
45232715170SCathy Zhou  * the link protperty from the dlmgmtd daemon using the given confid.
453d62bc4baSyz  */
454d62bc4baSyz dladm_status_t
dladm_get_conf_field(dladm_handle_t handle,dladm_conf_t conf,const char * attr,void * attrval,size_t attrsz)4554ac67f02SAnurag S. Maskey dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
4564ac67f02SAnurag S. Maskey     void *attrval, size_t attrsz)
457d62bc4baSyz {
45832715170SCathy Zhou 	dladm_status_t		status = DLADM_STATUS_OK;
459d62bc4baSyz 
46032715170SCathy Zhou 	if (attrval == NULL || attrsz == 0 || attr == NULL)
461d62bc4baSyz 		return (DLADM_STATUS_BADARG);
462d62bc4baSyz 
46332715170SCathy Zhou 	if (conf.ds_readonly) {
46432715170SCathy Zhou 		uchar_t		*oattrval;
46532715170SCathy Zhou 		uint32_t	oattrsz;
46632715170SCathy Zhou 		int		err;
467d62bc4baSyz 
46832715170SCathy Zhou 		if ((err = nvlist_lookup_byte_array(conf.ds_nvl, (char *)attr,
46932715170SCathy Zhou 		    &oattrval, &oattrsz)) != 0) {
47032715170SCathy Zhou 			return (dladm_errno2status(err));
47132715170SCathy Zhou 		}
47232715170SCathy Zhou 		if (oattrsz > attrsz)
47332715170SCathy Zhou 			return (DLADM_STATUS_TOOSMALL);
474d62bc4baSyz 
47532715170SCathy Zhou 		bcopy(oattrval, attrval, oattrsz);
47632715170SCathy Zhou 	} else {
47732715170SCathy Zhou 		dlmgmt_door_getattr_t	getattr;
47832715170SCathy Zhou 		dlmgmt_getattr_retval_t	retval;
47932715170SCathy Zhou 		size_t			sz = sizeof (retval);
480d62bc4baSyz 
48132715170SCathy Zhou 		if (conf.ds_confid == DLADM_INVALID_CONF)
48232715170SCathy Zhou 			return (DLADM_STATUS_BADARG);
48332715170SCathy Zhou 
48432715170SCathy Zhou 		getattr.ld_cmd = DLMGMT_CMD_GETATTR;
48532715170SCathy Zhou 		getattr.ld_confid = conf.ds_confid;
48632715170SCathy Zhou 		(void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN);
48732715170SCathy Zhou 
48832715170SCathy Zhou 		if ((status = dladm_door_call(handle, &getattr,
48932715170SCathy Zhou 		    sizeof (getattr), &retval, &sz)) != DLADM_STATUS_OK) {
49032715170SCathy Zhou 			return (status);
49132715170SCathy Zhou 		}
49232715170SCathy Zhou 
49332715170SCathy Zhou 		if (retval.lr_attrsz > attrsz)
49432715170SCathy Zhou 			return (DLADM_STATUS_TOOSMALL);
49532715170SCathy Zhou 
49632715170SCathy Zhou 		bcopy(retval.lr_attrval, attrval, retval.lr_attrsz);
49732715170SCathy Zhou 	}
49832715170SCathy Zhou 	return (status);
49962ee1d25SArtem Kachitchkine }
50062ee1d25SArtem Kachitchkine 
50162ee1d25SArtem Kachitchkine /*
50262ee1d25SArtem Kachitchkine  * Get next property attribute from data link configuration repository.
50332715170SCathy Zhou  * If last_attr is "", return the first property.
50462ee1d25SArtem Kachitchkine  */
50562ee1d25SArtem Kachitchkine dladm_status_t
dladm_getnext_conf_linkprop(dladm_handle_t handle __unused,dladm_conf_t conf,const char * last_attr,char * attr,void * attrval,size_t attrsz,size_t * attrszp)50620535e13SToomas Soome dladm_getnext_conf_linkprop(dladm_handle_t handle __unused, dladm_conf_t conf,
50762ee1d25SArtem Kachitchkine     const char *last_attr, char *attr, void *attrval, size_t attrsz,
50862ee1d25SArtem Kachitchkine     size_t *attrszp)
50962ee1d25SArtem Kachitchkine {
51032715170SCathy Zhou 	nvlist_t	*nvl = conf.ds_nvl;
51132715170SCathy Zhou 	nvpair_t	*last = NULL, *nvp;
51232715170SCathy Zhou 	uchar_t		*oattrval;
51332715170SCathy Zhou 	uint32_t	oattrsz;
51432715170SCathy Zhou 	int		err;
51532715170SCathy Zhou 
51632715170SCathy Zhou 	if (nvl == NULL || attrval == NULL || attrsz == 0 || attr == NULL ||
51732715170SCathy Zhou 	    !conf.ds_readonly)
51862ee1d25SArtem Kachitchkine 		return (DLADM_STATUS_BADARG);
51932715170SCathy Zhou 
52032715170SCathy Zhou 	while ((nvp = nvlist_next_nvpair(nvl, last)) != NULL) {
52132715170SCathy Zhou 		if (last_attr[0] == '\0')
52232715170SCathy Zhou 			break;
52332715170SCathy Zhou 		if (last != NULL && strcmp(last_attr, nvpair_name(last)) == 0)
52432715170SCathy Zhou 			break;
52532715170SCathy Zhou 		last = nvp;
52662ee1d25SArtem Kachitchkine 	}
52762ee1d25SArtem Kachitchkine 
52832715170SCathy Zhou 	if (nvp == NULL)
52932715170SCathy Zhou 		return (DLADM_STATUS_NOTFOUND);
53062ee1d25SArtem Kachitchkine 
53132715170SCathy Zhou 	if ((err = nvpair_value_byte_array(nvp, (uchar_t **)&oattrval,
532c0e21d6aSToomas Soome 	    &oattrsz)) != 0) {
53332715170SCathy Zhou 		return (dladm_errno2status(err));
53462ee1d25SArtem Kachitchkine 	}
53562ee1d25SArtem Kachitchkine 
53632715170SCathy Zhou 	*attrszp = oattrsz;
53732715170SCathy Zhou 	if (oattrsz > attrsz)
53862ee1d25SArtem Kachitchkine 		return (DLADM_STATUS_TOOSMALL);
53962ee1d25SArtem Kachitchkine 
54032715170SCathy Zhou 	(void) strlcpy(attr, nvpair_name(nvp), MAXLINKATTRLEN);
54132715170SCathy Zhou 	bcopy(oattrval, attrval, oattrsz);
542024b0a25Sseb 	return (DLADM_STATUS_OK);
543d62bc4baSyz }
544d62bc4baSyz 
545d62bc4baSyz /*
546d62bc4baSyz  * Get the link ID that is associated with the given name.
547d62bc4baSyz  */
548d62bc4baSyz dladm_status_t
dladm_name2info(dladm_handle_t handle,const char * link,datalink_id_t * linkidp,uint32_t * flagp,datalink_class_t * classp,uint32_t * mediap)5494ac67f02SAnurag S. Maskey dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp,
5504ac67f02SAnurag S. Maskey     uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap)
551d62bc4baSyz {
552d62bc4baSyz 	dlmgmt_door_getlinkid_t		getlinkid;
553d62bc4baSyz 	dlmgmt_getlinkid_retval_t	retval;
554d62bc4baSyz 	datalink_id_t			linkid;
555d62bc4baSyz 	dladm_status_t			status;
55632715170SCathy Zhou 	size_t				sz = sizeof (retval);
557d62bc4baSyz 
558d62bc4baSyz 	getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID;
559d62bc4baSyz 	(void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN);
560d62bc4baSyz 
5614ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid),
56232715170SCathy Zhou 	    &retval, &sz)) != DLADM_STATUS_OK) {
563d62bc4baSyz 		return (status);
564024b0a25Sseb 	}
565d62bc4baSyz 
566d62bc4baSyz 	linkid = retval.lr_linkid;
567d62bc4baSyz 	if (retval.lr_class == DATALINK_CLASS_PHYS &&
568d62bc4baSyz 	    retval.lr_flags & DLMGMT_ACTIVE) {
569d62bc4baSyz 		/*
570d62bc4baSyz 		 * An active physical link reported by the dlmgmtd daemon
571d62bc4baSyz 		 * might not be active anymore. Check and set its real status.
572d62bc4baSyz 		 */
5734ac67f02SAnurag S. Maskey 		status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
574d62bc4baSyz 		if (status != DLADM_STATUS_OK)
575d62bc4baSyz 			return (status);
576d62bc4baSyz 	}
577d62bc4baSyz 
578d62bc4baSyz 	if (linkidp != NULL)
579d62bc4baSyz 		*linkidp = linkid;
580d62bc4baSyz 	if (flagp != NULL) {
581*85dff7a0SAndy Fiddaman 		*flagp = (retval.lr_flags & DLMGMT_ACTIVE) ?
582*85dff7a0SAndy Fiddaman 		    DLADM_OPT_ACTIVE : 0;
583d62bc4baSyz 		*flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
584d62bc4baSyz 		    DLADM_OPT_PERSIST : 0;
585*85dff7a0SAndy Fiddaman 		*flagp |= (retval.lr_flags & DLMGMT_TRANSIENT) ?
586*85dff7a0SAndy Fiddaman 		    DLADM_OPT_TRANSIENT : 0;
587d62bc4baSyz 	}
588d62bc4baSyz 	if (classp != NULL)
589d62bc4baSyz 		*classp = retval.lr_class;
590d62bc4baSyz 	if (mediap != NULL)
591d62bc4baSyz 		*mediap = retval.lr_media;
592d62bc4baSyz 
593d62bc4baSyz 	return (DLADM_STATUS_OK);
594d62bc4baSyz }
595d62bc4baSyz 
596d62bc4baSyz /*
597d62bc4baSyz  * Get the link name that is associated with the given id.
598d62bc4baSyz  */
599d62bc4baSyz dladm_status_t
dladm_datalink_id2info(dladm_handle_t handle,datalink_id_t linkid,uint32_t * flagp,datalink_class_t * classp,uint32_t * mediap,char * link,size_t len)6004ac67f02SAnurag S. Maskey dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid,
6014ac67f02SAnurag S. Maskey     uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap, char *link,
6024ac67f02SAnurag S. Maskey     size_t len)
603d62bc4baSyz {
604024b0a25Sseb 	dlmgmt_door_getname_t	getname;
605024b0a25Sseb 	dlmgmt_getname_retval_t	retval;
606024b0a25Sseb 	dladm_status_t		status;
60732715170SCathy Zhou 	size_t			sz = sizeof (retval);
608d62bc4baSyz 
609d62bc4baSyz 	if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) ||
610d62bc4baSyz 	    (link == NULL && len != 0)) {
611d62bc4baSyz 		return (DLADM_STATUS_BADARG);
612d62bc4baSyz 	}
613d62bc4baSyz 
614d62bc4baSyz 	getname.ld_cmd = DLMGMT_CMD_GETNAME;
615d62bc4baSyz 	getname.ld_linkid = linkid;
6164ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &getname, sizeof (getname),
61732715170SCathy Zhou 	    &retval, &sz)) != DLADM_STATUS_OK) {
618d62bc4baSyz 		return (status);
619024b0a25Sseb 	}
620d62bc4baSyz 
621024b0a25Sseb 	if (len != 0 && (strlen(retval.lr_link) + 1 > len))
622d62bc4baSyz 		return (DLADM_STATUS_TOOSMALL);
623d62bc4baSyz 
624d62bc4baSyz 	if (retval.lr_class == DATALINK_CLASS_PHYS &&
625d62bc4baSyz 	    retval.lr_flags & DLMGMT_ACTIVE) {
626d62bc4baSyz 		/*
627d62bc4baSyz 		 * An active physical link reported by the dlmgmtd daemon
628d62bc4baSyz 		 * might not be active anymore. Check and set its real status.
629d62bc4baSyz 		 */
6304ac67f02SAnurag S. Maskey 		status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
631d62bc4baSyz 		if (status != DLADM_STATUS_OK)
632d62bc4baSyz 			return (status);
633d62bc4baSyz 	}
634d62bc4baSyz 
635d62bc4baSyz 	if (link != NULL)
636d62bc4baSyz 		(void) strlcpy(link, retval.lr_link, len);
637d62bc4baSyz 	if (classp != NULL)
638d62bc4baSyz 		*classp = retval.lr_class;
639d62bc4baSyz 	if (mediap != NULL)
640d62bc4baSyz 		*mediap = retval.lr_media;
641d62bc4baSyz 	if (flagp != NULL) {
642*85dff7a0SAndy Fiddaman 		*flagp = (retval.lr_flags & DLMGMT_ACTIVE) ?
643d62bc4baSyz 		    DLADM_OPT_ACTIVE : 0;
644d62bc4baSyz 		*flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
645d62bc4baSyz 		    DLADM_OPT_PERSIST : 0;
646*85dff7a0SAndy Fiddaman 		*flagp |= (retval.lr_flags & DLMGMT_TRANSIENT) ?
647*85dff7a0SAndy Fiddaman 		    DLADM_OPT_TRANSIENT : 0;
648d62bc4baSyz 	}
649d62bc4baSyz 	return (DLADM_STATUS_OK);
650d62bc4baSyz }
651d62bc4baSyz 
652d62bc4baSyz /*
653d62bc4baSyz  * Set the given attr with the given attrval for the given link.
654d62bc4baSyz  */
655d62bc4baSyz dladm_status_t
dladm_set_conf_field(dladm_handle_t handle,dladm_conf_t conf,const char * attr,dladm_datatype_t type,const void * attrval)6564ac67f02SAnurag S. Maskey dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
657d62bc4baSyz     dladm_datatype_t type, const void *attrval)
658d62bc4baSyz {
659024b0a25Sseb 	dlmgmt_door_setattr_t	setattr;
660024b0a25Sseb 	dlmgmt_setattr_retval_t	retval;
661024b0a25Sseb 	size_t			attrsz;
66232715170SCathy Zhou 	size_t			sz = sizeof (retval);
663d62bc4baSyz 
664024b0a25Sseb 	if (attr == NULL || attrval == NULL)
665d62bc4baSyz 		return (DLADM_STATUS_BADARG);
666d62bc4baSyz 
66732715170SCathy Zhou 	if (conf.ds_readonly)
66832715170SCathy Zhou 		return (DLADM_STATUS_DENIED);
66932715170SCathy Zhou 
670d62bc4baSyz 	if (type == DLADM_TYPE_STR)
671d62bc4baSyz 		attrsz = strlen(attrval) + 1;
672d62bc4baSyz 	else
673d62bc4baSyz 		attrsz = dladm_datatype_size[type];
674d62bc4baSyz 
675024b0a25Sseb 	if (attrsz > MAXLINKATTRVALLEN)
676024b0a25Sseb 		return (DLADM_STATUS_TOOSMALL);
677d62bc4baSyz 
678024b0a25Sseb 	setattr.ld_cmd = DLMGMT_CMD_SETATTR;
67932715170SCathy Zhou 	setattr.ld_confid = conf.ds_confid;
680024b0a25Sseb 	(void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN);
681640aa5d6SRyan Goodfellow 	setattr.ld_attrsz = (uint32_t)attrsz;
682024b0a25Sseb 	setattr.ld_type = type;
683024b0a25Sseb 	bcopy(attrval, &setattr.ld_attrval, attrsz);
684d62bc4baSyz 
68532715170SCathy Zhou 	return (dladm_door_call(handle, &setattr, sizeof (setattr),
68632715170SCathy Zhou 	    &retval, &sz));
687d62bc4baSyz }
688d62bc4baSyz 
689d62bc4baSyz /*
690d62bc4baSyz  * Unset the given attr the given link.
691d62bc4baSyz  */
692d62bc4baSyz dladm_status_t
dladm_unset_conf_field(dladm_handle_t handle,dladm_conf_t conf,const char * attr)6934ac67f02SAnurag S. Maskey dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf,
6944ac67f02SAnurag S. Maskey     const char *attr)
695d62bc4baSyz {
696d62bc4baSyz 	dlmgmt_door_unsetattr_t		unsetattr;
697d62bc4baSyz 	dlmgmt_unsetattr_retval_t	retval;
69832715170SCathy Zhou 	size_t				sz = sizeof (retval);
699d62bc4baSyz 
700024b0a25Sseb 	if (attr == NULL)
701d62bc4baSyz 		return (DLADM_STATUS_BADARG);
702d62bc4baSyz 
70332715170SCathy Zhou 	if (conf.ds_readonly)
70432715170SCathy Zhou 		return (DLADM_STATUS_DENIED);
70532715170SCathy Zhou 
706d62bc4baSyz 	unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR;
70732715170SCathy Zhou 	unsetattr.ld_confid = conf.ds_confid;
708d62bc4baSyz 	(void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN);
709d62bc4baSyz 
71032715170SCathy Zhou 	return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr),
71132715170SCathy Zhou 	    &retval, &sz));
712d62bc4baSyz }
713d62bc4baSyz 
714d62bc4baSyz /*
715d62bc4baSyz  * Remove the given link ID and its entry from the data link configuration
716d62bc4baSyz  * repository.
717d62bc4baSyz  */
718d62bc4baSyz dladm_status_t
dladm_remove_conf(dladm_handle_t handle,datalink_id_t linkid)7194ac67f02SAnurag S. Maskey dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid)
720d62bc4baSyz {
721d62bc4baSyz 	dlmgmt_door_removeconf_t	removeconf;
722d62bc4baSyz 	dlmgmt_removeconf_retval_t	retval;
72332715170SCathy Zhou 	size_t				sz = sizeof (retval);
724d62bc4baSyz 
725d62bc4baSyz 	removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF;
726d62bc4baSyz 	removeconf.ld_linkid = linkid;
727d62bc4baSyz 
7284ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &removeconf, sizeof (removeconf),
72932715170SCathy Zhou 	    &retval, &sz));
730d62bc4baSyz }
731d62bc4baSyz 
732d62bc4baSyz /*
733d62bc4baSyz  * Free the contents of the link structure.
734d62bc4baSyz  */
735d62bc4baSyz void
dladm_destroy_conf(dladm_handle_t handle,dladm_conf_t conf)7364ac67f02SAnurag S. Maskey dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf)
737d62bc4baSyz {
73832715170SCathy Zhou 	dlmgmt_door_destroyconf_t	dconf;
739d62bc4baSyz 	dlmgmt_destroyconf_retval_t	retval;
74032715170SCathy Zhou 	size_t				sz = sizeof (retval);
741d62bc4baSyz 
74232715170SCathy Zhou 	if (conf.ds_readonly) {
74332715170SCathy Zhou 		nvlist_free(conf.ds_nvl);
74432715170SCathy Zhou 	} else {
74532715170SCathy Zhou 		if (conf.ds_confid == DLADM_INVALID_CONF)
74632715170SCathy Zhou 			return;
747d62bc4baSyz 
74832715170SCathy Zhou 		dconf.ld_cmd = DLMGMT_CMD_DESTROYCONF;
74932715170SCathy Zhou 		dconf.ld_confid = conf.ds_confid;
750d62bc4baSyz 
75132715170SCathy Zhou 		(void) dladm_door_call(handle, &dconf, sizeof (dconf),
75232715170SCathy Zhou 		    &retval, &sz);
75332715170SCathy Zhou 	}
754d62bc4baSyz }
7552b24ab6bSSebastien Roy 
7562b24ab6bSSebastien Roy dladm_status_t
dladm_zone_boot(dladm_handle_t handle,zoneid_t zoneid)7572b24ab6bSSebastien Roy dladm_zone_boot(dladm_handle_t handle, zoneid_t zoneid)
7582b24ab6bSSebastien Roy {
7592b24ab6bSSebastien Roy 	dlmgmt_door_zoneboot_t		zoneboot;
7602b24ab6bSSebastien Roy 	dlmgmt_zoneboot_retval_t	retval;
76132715170SCathy Zhou 	size_t				sz = sizeof (retval);
7622b24ab6bSSebastien Roy 
7632b24ab6bSSebastien Roy 	zoneboot.ld_cmd = DLMGMT_CMD_ZONEBOOT;
7642b24ab6bSSebastien Roy 	zoneboot.ld_zoneid = zoneid;
76532715170SCathy Zhou 	return (dladm_door_call(handle, &zoneboot, sizeof (zoneboot),
76632715170SCathy Zhou 	    &retval, &sz));
7672b24ab6bSSebastien Roy }
7682b24ab6bSSebastien Roy 
7692b24ab6bSSebastien Roy dladm_status_t
dladm_zone_halt(dladm_handle_t handle,zoneid_t zoneid)7702b24ab6bSSebastien Roy dladm_zone_halt(dladm_handle_t handle, zoneid_t zoneid)
7712b24ab6bSSebastien Roy {
7722b24ab6bSSebastien Roy 	dlmgmt_door_zonehalt_t		zonehalt;
7732b24ab6bSSebastien Roy 	dlmgmt_zonehalt_retval_t	retval;
77432715170SCathy Zhou 	size_t				sz = sizeof (retval);
7752b24ab6bSSebastien Roy 
7762b24ab6bSSebastien Roy 	zonehalt.ld_cmd = DLMGMT_CMD_ZONEHALT;
7772b24ab6bSSebastien Roy 	zonehalt.ld_zoneid = zoneid;
77832715170SCathy Zhou 	return (dladm_door_call(handle, &zonehalt, sizeof (zonehalt),
77932715170SCathy Zhou 	    &retval, &sz));
7802b24ab6bSSebastien Roy }
781