xref: /titanic_50/usr/src/lib/libdladm/common/libdlmgmt.c (revision 4ac67f0276a8313b5cefec38af347b94b7bfb526)
1d62bc4baSyz147064 /*
2d62bc4baSyz147064  * CDDL HEADER START
3d62bc4baSyz147064  *
4d62bc4baSyz147064  * The contents of this file are subject to the terms of the
5d62bc4baSyz147064  * Common Development and Distribution License (the "License").
6d62bc4baSyz147064  * You may not use this file except in compliance with the License.
7d62bc4baSyz147064  *
8d62bc4baSyz147064  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d62bc4baSyz147064  * or http://www.opensolaris.org/os/licensing.
10d62bc4baSyz147064  * See the License for the specific language governing permissions
11d62bc4baSyz147064  * and limitations under the License.
12d62bc4baSyz147064  *
13d62bc4baSyz147064  * When distributing Covered Code, include this CDDL HEADER in each
14d62bc4baSyz147064  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d62bc4baSyz147064  * If applicable, add the following below this CDDL HEADER, with the
16d62bc4baSyz147064  * fields enclosed by brackets "[]" replaced with your own identifying
17d62bc4baSyz147064  * information: Portions Copyright [yyyy] [name of copyright owner]
18d62bc4baSyz147064  *
19d62bc4baSyz147064  * CDDL HEADER END
20d62bc4baSyz147064  */
21d62bc4baSyz147064 /*
22d62bc4baSyz147064  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23d62bc4baSyz147064  * Use is subject to license terms.
24d62bc4baSyz147064  */
25d62bc4baSyz147064 
26d62bc4baSyz147064 #include <door.h>
27d62bc4baSyz147064 #include <errno.h>
28d62bc4baSyz147064 #include <assert.h>
29d62bc4baSyz147064 #include <stdio.h>
30d62bc4baSyz147064 #include <stdlib.h>
31d62bc4baSyz147064 #include <unistd.h>
32d62bc4baSyz147064 #include <string.h>
33d62bc4baSyz147064 #include <strings.h>
34d62bc4baSyz147064 #include <sys/types.h>
35d62bc4baSyz147064 #include <sys/stat.h>
36d62bc4baSyz147064 #include <sys/aggr.h>
37d62bc4baSyz147064 #include <fcntl.h>
38d62bc4baSyz147064 #include <libdladm.h>
39d62bc4baSyz147064 #include <libdladm_impl.h>
40d62bc4baSyz147064 #include <libdllink.h>
41d62bc4baSyz147064 #include <libdlmgmt.h>
42d62bc4baSyz147064 
43d62bc4baSyz147064 /*
44d62bc4baSyz147064  * Table of data type sizes indexed by dladm_datatype_t.
45d62bc4baSyz147064  */
46d62bc4baSyz147064 static size_t dladm_datatype_size[] = {
47d62bc4baSyz147064 	0,				/* DLADM_TYPE_STR, use strnlen() */
48d62bc4baSyz147064 	sizeof (boolean_t),		/* DLADM_TYPE_BOOLEAN */
49d62bc4baSyz147064 	sizeof (uint64_t)		/* DLADM_TYPE_UINT64 */
50d62bc4baSyz147064 };
51d62bc4baSyz147064 
52d62bc4baSyz147064 static dladm_status_t
53*4ac67f02SAnurag S. Maskey dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf,
54*4ac67f02SAnurag S. Maskey     size_t rsize)
55d62bc4baSyz147064 {
56d62bc4baSyz147064 	door_arg_t	darg;
57*4ac67f02SAnurag S. Maskey 	int		door_fd;
58d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
59d62bc4baSyz147064 
60d62bc4baSyz147064 	darg.data_ptr	= arg;
61d62bc4baSyz147064 	darg.data_size	= asize;
62d62bc4baSyz147064 	darg.desc_ptr	= NULL;
63d62bc4baSyz147064 	darg.desc_num	= 0;
64d62bc4baSyz147064 	darg.rbuf	= rbuf;
65024b0a25Sseb 	darg.rsize	= rsize;
66d62bc4baSyz147064 
67*4ac67f02SAnurag S. Maskey 	/* The door descriptor is opened if it isn't already */
68*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK)
69*4ac67f02SAnurag S. Maskey 		return (status);
70*4ac67f02SAnurag S. Maskey 	if (door_call(door_fd, &darg) == -1)
71d62bc4baSyz147064 		status = dladm_errno2status(errno);
72d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
73d62bc4baSyz147064 		return (status);
74d62bc4baSyz147064 
75d62bc4baSyz147064 	if (darg.rbuf != rbuf) {
76d62bc4baSyz147064 		/*
77d62bc4baSyz147064 		 * The size of the input rbuf is not big enough so that
78d62bc4baSyz147064 		 * the door allocate the rbuf itself. In this case, simply
79d62bc4baSyz147064 		 * think something wrong with the door call.
80d62bc4baSyz147064 		 */
81d62bc4baSyz147064 		(void) munmap(darg.rbuf, darg.rsize);
82d62bc4baSyz147064 		return (DLADM_STATUS_TOOSMALL);
83d62bc4baSyz147064 	}
84024b0a25Sseb 	if (darg.rsize != rsize)
85d62bc4baSyz147064 		return (DLADM_STATUS_FAILED);
86d62bc4baSyz147064 
87024b0a25Sseb 	return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err));
88d62bc4baSyz147064 }
89d62bc4baSyz147064 
90d62bc4baSyz147064 /*
91d62bc4baSyz147064  * Allocate a new linkid with the given name. Return the new linkid.
92d62bc4baSyz147064  */
93d62bc4baSyz147064 dladm_status_t
94*4ac67f02SAnurag S. Maskey dladm_create_datalink_id(dladm_handle_t handle, const char *link,
95*4ac67f02SAnurag S. Maskey     datalink_class_t class, uint32_t media, uint32_t flags,
96*4ac67f02SAnurag S. Maskey     datalink_id_t *linkidp)
97d62bc4baSyz147064 {
98d62bc4baSyz147064 	dlmgmt_door_createid_t	createid;
99d62bc4baSyz147064 	dlmgmt_createid_retval_t retval;
100d62bc4baSyz147064 	uint32_t		dlmgmt_flags;
101d62bc4baSyz147064 	dladm_status_t		status;
102d62bc4baSyz147064 
103024b0a25Sseb 	if (link == NULL || class == DATALINK_CLASS_ALL ||
104d62bc4baSyz147064 	    !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) ||
105d62bc4baSyz147064 	    linkidp == NULL) {
106d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
107d62bc4baSyz147064 	}
108d62bc4baSyz147064 
109d62bc4baSyz147064 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
110d62bc4baSyz147064 	dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0;
111d62bc4baSyz147064 
112d62bc4baSyz147064 	(void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN);
113d62bc4baSyz147064 	createid.ld_class = class;
114d62bc4baSyz147064 	createid.ld_media = media;
115d62bc4baSyz147064 	createid.ld_flags = dlmgmt_flags;
116d62bc4baSyz147064 	createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID;
117d62bc4baSyz147064 	createid.ld_prefix = (flags & DLADM_OPT_PREFIX);
118d62bc4baSyz147064 
119*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &createid, sizeof (createid),
120*4ac67f02SAnurag S. Maskey 	    &retval, sizeof (retval))) == DLADM_STATUS_OK) {
121d62bc4baSyz147064 		*linkidp = retval.lr_linkid;
122024b0a25Sseb 	}
123024b0a25Sseb 	return (status);
124d62bc4baSyz147064 }
125d62bc4baSyz147064 
126d62bc4baSyz147064 /*
127d62bc4baSyz147064  * Destroy the given link ID.
128d62bc4baSyz147064  */
129d62bc4baSyz147064 dladm_status_t
130*4ac67f02SAnurag S. Maskey dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
131*4ac67f02SAnurag S. Maskey     uint32_t flags)
132d62bc4baSyz147064 {
133d62bc4baSyz147064 	dlmgmt_door_destroyid_t		destroyid;
134d62bc4baSyz147064 	dlmgmt_destroyid_retval_t	retval;
135d62bc4baSyz147064 	uint32_t			dlmgmt_flags;
136d62bc4baSyz147064 
137d62bc4baSyz147064 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
138d62bc4baSyz147064 	dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
139d62bc4baSyz147064 
140d62bc4baSyz147064 	destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID;
141d62bc4baSyz147064 	destroyid.ld_linkid = linkid;
142d62bc4baSyz147064 	destroyid.ld_flags = dlmgmt_flags;
143d62bc4baSyz147064 
144*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &destroyid, sizeof (destroyid), &retval,
145*4ac67f02SAnurag S. Maskey 	    sizeof (retval)));
146d62bc4baSyz147064 }
147d62bc4baSyz147064 
148d62bc4baSyz147064 /*
149d62bc4baSyz147064  * Remap a given link ID to a new name.
150d62bc4baSyz147064  */
151d62bc4baSyz147064 dladm_status_t
152*4ac67f02SAnurag S. Maskey dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
153*4ac67f02SAnurag S. Maskey     const char *link)
154d62bc4baSyz147064 {
155d62bc4baSyz147064 	dlmgmt_door_remapid_t	remapid;
156d62bc4baSyz147064 	dlmgmt_remapid_retval_t	retval;
157d62bc4baSyz147064 
158d62bc4baSyz147064 	remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID;
159d62bc4baSyz147064 	remapid.ld_linkid = linkid;
160d62bc4baSyz147064 	(void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN);
161d62bc4baSyz147064 
162*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &remapid, sizeof (remapid), &retval,
163*4ac67f02SAnurag S. Maskey 	    sizeof (retval)));
164d62bc4baSyz147064 }
165d62bc4baSyz147064 
166d62bc4baSyz147064 /*
167d62bc4baSyz147064  * Make a given link ID active.
168d62bc4baSyz147064  */
169d62bc4baSyz147064 dladm_status_t
170*4ac67f02SAnurag S. Maskey dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid)
171d62bc4baSyz147064 {
172d62bc4baSyz147064 	dlmgmt_door_upid_t	upid;
173d62bc4baSyz147064 	dlmgmt_upid_retval_t	retval;
174d62bc4baSyz147064 
175d62bc4baSyz147064 	upid.ld_cmd = DLMGMT_CMD_UP_LINKID;
176d62bc4baSyz147064 	upid.ld_linkid = linkid;
177d62bc4baSyz147064 
178*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &upid, sizeof (upid), &retval,
179*4ac67f02SAnurag S. Maskey 	    sizeof (retval)));
180d62bc4baSyz147064 }
181d62bc4baSyz147064 
182d62bc4baSyz147064 /*
183d62bc4baSyz147064  * Create a new link with the given name.  Return the new link's handle
184d62bc4baSyz147064  */
185d62bc4baSyz147064 dladm_status_t
186*4ac67f02SAnurag S. Maskey dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid,
187d62bc4baSyz147064     datalink_class_t class, uint32_t media, dladm_conf_t *confp)
188d62bc4baSyz147064 {
189d62bc4baSyz147064 	dlmgmt_door_createconf_t	createconf;
190d62bc4baSyz147064 	dlmgmt_createconf_retval_t	retval;
191d62bc4baSyz147064 	dladm_status_t			status;
192d62bc4baSyz147064 
193024b0a25Sseb 	if (link == NULL || confp == NULL)
194d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
195d62bc4baSyz147064 
196d62bc4baSyz147064 	(void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN);
197d62bc4baSyz147064 	createconf.ld_class = class;
198d62bc4baSyz147064 	createconf.ld_media = media;
199d62bc4baSyz147064 	createconf.ld_linkid = linkid;
200d62bc4baSyz147064 	createconf.ld_cmd = DLMGMT_CMD_CREATECONF;
201d62bc4baSyz147064 
202*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &createconf, sizeof (createconf),
203024b0a25Sseb 	    &retval, sizeof (retval))) == DLADM_STATUS_OK) {
204d62bc4baSyz147064 		*confp = retval.lr_conf;
205024b0a25Sseb 	}
206024b0a25Sseb 	return (status);
207d62bc4baSyz147064 }
208d62bc4baSyz147064 
209d62bc4baSyz147064 /*
210d62bc4baSyz147064  * An active physical link reported by the dlmgmtd daemon might not be active
211d62bc4baSyz147064  * anymore as this link might be removed during system shutdown. Check its
212d62bc4baSyz147064  * real status by calling dladm_phys_info().
213d62bc4baSyz147064  */
214d62bc4baSyz147064 dladm_status_t
215*4ac67f02SAnurag S. Maskey i_dladm_phys_status(dladm_handle_t handle, datalink_id_t linkid,
216*4ac67f02SAnurag S. Maskey     uint32_t *flagsp)
217d62bc4baSyz147064 {
218d62bc4baSyz147064 	dladm_phys_attr_t	dpa;
219d62bc4baSyz147064 	dladm_status_t		status;
220d62bc4baSyz147064 
221d62bc4baSyz147064 	assert((*flagsp) & DLMGMT_ACTIVE);
222d62bc4baSyz147064 
223*4ac67f02SAnurag S. Maskey 	status = dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE);
224d62bc4baSyz147064 	if (status == DLADM_STATUS_NOTFOUND) {
225d62bc4baSyz147064 		/*
226d62bc4baSyz147064 		 * No active status, this link was removed. Update its status
227d62bc4baSyz147064 		 * in the daemon and delete all active linkprops.
2282d4eecfaSCathy Zhou 		 *
2292d4eecfaSCathy Zhou 		 * Note that the operation could fail. If it does, return
2302d4eecfaSCathy Zhou 		 * failure now since otherwise dladm_set_linkprop() might
2312d4eecfaSCathy Zhou 		 * call back to i_dladm_phys_status() recursively.
232d62bc4baSyz147064 		 */
233*4ac67f02SAnurag S. Maskey 		if ((status = dladm_destroy_datalink_id(handle, linkid,
234*4ac67f02SAnurag S. Maskey 		    DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK)
2352d4eecfaSCathy Zhou 			return (status);
2362d4eecfaSCathy Zhou 
237*4ac67f02SAnurag S. Maskey 		(void) dladm_set_linkprop(handle, linkid, NULL, NULL, 0,
238d62bc4baSyz147064 		    DLADM_OPT_ACTIVE);
239d62bc4baSyz147064 
240d62bc4baSyz147064 		(*flagsp) &= ~DLMGMT_ACTIVE;
241d62bc4baSyz147064 		status = DLADM_STATUS_OK;
242d62bc4baSyz147064 	}
243d62bc4baSyz147064 	return (status);
244d62bc4baSyz147064 }
245d62bc4baSyz147064 
246d62bc4baSyz147064 /*
247d62bc4baSyz147064  * Walk each entry in the data link configuration repository and
248d62bc4baSyz147064  * call fn on the linkid and arg.
249d62bc4baSyz147064  */
250d62bc4baSyz147064 dladm_status_t
251*4ac67f02SAnurag S. Maskey dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *),
252*4ac67f02SAnurag S. Maskey     dladm_handle_t handle, void *argp, datalink_class_t class,
253*4ac67f02SAnurag S. Maskey     datalink_media_t dmedia, uint32_t flags)
254d62bc4baSyz147064 {
255d62bc4baSyz147064 	dlmgmt_door_getnext_t	getnext;
256d62bc4baSyz147064 	dlmgmt_getnext_retval_t	retval;
257d62bc4baSyz147064 	uint32_t 		dlmgmt_flags;
258d62bc4baSyz147064 	datalink_id_t		linkid = DATALINK_INVALID_LINKID;
259d62bc4baSyz147064 	dladm_status_t		status = DLADM_STATUS_OK;
260d62bc4baSyz147064 
261d62bc4baSyz147064 	if (fn == NULL)
262d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
263d62bc4baSyz147064 
264d62bc4baSyz147064 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
265d62bc4baSyz147064 	dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
266d62bc4baSyz147064 
267d62bc4baSyz147064 	getnext.ld_cmd = DLMGMT_CMD_GETNEXT;
268d62bc4baSyz147064 	getnext.ld_class = class;
269d62bc4baSyz147064 	getnext.ld_dmedia = dmedia;
270d62bc4baSyz147064 	getnext.ld_flags = dlmgmt_flags;
271d62bc4baSyz147064 
272d62bc4baSyz147064 	do {
273d62bc4baSyz147064 		getnext.ld_linkid = linkid;
274*4ac67f02SAnurag S. Maskey 		if ((status = dladm_door_call(handle, &getnext,
275*4ac67f02SAnurag S. Maskey 		    sizeof (getnext), &retval, sizeof (retval))) !=
276*4ac67f02SAnurag S. Maskey 		    DLADM_STATUS_OK) {
277d62bc4baSyz147064 			/*
278d62bc4baSyz147064 			 * done with walking
279d62bc4baSyz147064 			 */
280d62bc4baSyz147064 			break;
281d62bc4baSyz147064 		}
282d62bc4baSyz147064 
283d62bc4baSyz147064 		linkid = retval.lr_linkid;
284d62bc4baSyz147064 		if ((retval.lr_class == DATALINK_CLASS_PHYS) &&
285d62bc4baSyz147064 		    (retval.lr_flags & DLMGMT_ACTIVE)) {
286d62bc4baSyz147064 			/*
287d62bc4baSyz147064 			 * An active physical link reported by the dlmgmtd
288d62bc4baSyz147064 			 * daemon might not be active anymore. Check its
289d62bc4baSyz147064 			 * real status.
290d62bc4baSyz147064 			 */
291*4ac67f02SAnurag S. Maskey 			if (i_dladm_phys_status(handle, linkid,
292*4ac67f02SAnurag S. Maskey 			    &retval.lr_flags) != DLADM_STATUS_OK) {
293d62bc4baSyz147064 				continue;
294d62bc4baSyz147064 			}
295d62bc4baSyz147064 
296d62bc4baSyz147064 			if (!(dlmgmt_flags & retval.lr_flags))
297d62bc4baSyz147064 				continue;
298d62bc4baSyz147064 		}
299d62bc4baSyz147064 
300*4ac67f02SAnurag S. Maskey 		if (fn(handle, linkid, argp) == DLADM_WALK_TERMINATE)
301d62bc4baSyz147064 			break;
302d62bc4baSyz147064 	} while (linkid != DATALINK_INVALID_LINKID);
303d62bc4baSyz147064 
304d62bc4baSyz147064 	return (status);
305d62bc4baSyz147064 }
306d62bc4baSyz147064 
307d62bc4baSyz147064 /*
308d62bc4baSyz147064  * Get the link properties structure for the given link.
309d62bc4baSyz147064  */
310d62bc4baSyz147064 dladm_status_t
311*4ac67f02SAnurag S. Maskey dladm_read_conf(dladm_handle_t handle, datalink_id_t linkid,
312*4ac67f02SAnurag S. Maskey     dladm_conf_t *confp)
313d62bc4baSyz147064 {
314d62bc4baSyz147064 	dlmgmt_door_readconf_t		readconf;
315d62bc4baSyz147064 	dlmgmt_readconf_retval_t	retval;
316d62bc4baSyz147064 	dladm_status_t			status;
317d62bc4baSyz147064 
318d62bc4baSyz147064 	if (linkid == DATALINK_INVALID_LINKID || confp == NULL)
319d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
320d62bc4baSyz147064 
321d62bc4baSyz147064 	readconf.ld_linkid = linkid;
322d62bc4baSyz147064 	readconf.ld_cmd = DLMGMT_CMD_READCONF;
323d62bc4baSyz147064 
324*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &readconf, sizeof (readconf),
325024b0a25Sseb 	    &retval, sizeof (retval))) == DLADM_STATUS_OK) {
326d62bc4baSyz147064 		*confp = retval.lr_conf;
327024b0a25Sseb 	}
328024b0a25Sseb 	return (status);
329d62bc4baSyz147064 }
330d62bc4baSyz147064 
331d62bc4baSyz147064 /*
332d62bc4baSyz147064  * Commit the given link to the data link configuration repository so
333d62bc4baSyz147064  * that it will persist across reboots.
334d62bc4baSyz147064  */
335d62bc4baSyz147064 dladm_status_t
336*4ac67f02SAnurag S. Maskey dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf)
337d62bc4baSyz147064 {
338d62bc4baSyz147064 	dlmgmt_door_writeconf_t		writeconf;
339d62bc4baSyz147064 	dlmgmt_writeconf_retval_t	retval;
340d62bc4baSyz147064 
341d62bc4baSyz147064 	if (conf == DLADM_INVALID_CONF)
342d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
343d62bc4baSyz147064 
344d62bc4baSyz147064 	writeconf.ld_cmd = DLMGMT_CMD_WRITECONF;
345d62bc4baSyz147064 	writeconf.ld_conf = conf;
346d62bc4baSyz147064 
347*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &writeconf, sizeof (writeconf), &retval,
348*4ac67f02SAnurag S. Maskey 	    sizeof (retval)));
349d62bc4baSyz147064 }
350d62bc4baSyz147064 
351d62bc4baSyz147064 /*
352d62bc4baSyz147064  * Given a link ID and a key, get the matching information from
353d62bc4baSyz147064  * data link configuration repository.
354d62bc4baSyz147064  */
355d62bc4baSyz147064 dladm_status_t
356*4ac67f02SAnurag S. Maskey dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
357*4ac67f02SAnurag S. Maskey     void *attrval, size_t attrsz)
358d62bc4baSyz147064 {
359d62bc4baSyz147064 	dlmgmt_door_getattr_t	getattr;
360024b0a25Sseb 	dlmgmt_getattr_retval_t	retval;
361024b0a25Sseb 	dladm_status_t		status;
362d62bc4baSyz147064 
363d62bc4baSyz147064 	if (conf == DLADM_INVALID_CONF || attrval == NULL ||
364024b0a25Sseb 	    attrsz == 0 || attr == NULL) {
365d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
366d62bc4baSyz147064 	}
367d62bc4baSyz147064 
368d62bc4baSyz147064 	getattr.ld_cmd = DLMGMT_CMD_GETATTR;
369d62bc4baSyz147064 	getattr.ld_conf = conf;
370d62bc4baSyz147064 	(void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN);
371d62bc4baSyz147064 
372*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &getattr, sizeof (getattr),
373*4ac67f02SAnurag S. Maskey 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
374d62bc4baSyz147064 		return (status);
375d62bc4baSyz147064 	}
376d62bc4baSyz147064 
377024b0a25Sseb 	if (retval.lr_attrsz > attrsz)
378024b0a25Sseb 		return (DLADM_STATUS_TOOSMALL);
379024b0a25Sseb 
380024b0a25Sseb 	bcopy(retval.lr_attrval, attrval, retval.lr_attrsz);
381024b0a25Sseb 	return (DLADM_STATUS_OK);
382024b0a25Sseb }
383024b0a25Sseb 
384d62bc4baSyz147064 /*
385d62bc4baSyz147064  * Get the link ID that is associated with the given name.
386d62bc4baSyz147064  */
387d62bc4baSyz147064 dladm_status_t
388*4ac67f02SAnurag S. Maskey dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp,
389*4ac67f02SAnurag S. Maskey     uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap)
390d62bc4baSyz147064 {
391d62bc4baSyz147064 	dlmgmt_door_getlinkid_t		getlinkid;
392d62bc4baSyz147064 	dlmgmt_getlinkid_retval_t	retval;
393d62bc4baSyz147064 	datalink_id_t			linkid;
394d62bc4baSyz147064 	dladm_status_t			status;
395d62bc4baSyz147064 
396d62bc4baSyz147064 	getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID;
397d62bc4baSyz147064 	(void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN);
398d62bc4baSyz147064 
399*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid),
400024b0a25Sseb 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
401d62bc4baSyz147064 		return (status);
402024b0a25Sseb 	}
403d62bc4baSyz147064 
404d62bc4baSyz147064 	linkid = retval.lr_linkid;
405d62bc4baSyz147064 	if (retval.lr_class == DATALINK_CLASS_PHYS &&
406d62bc4baSyz147064 	    retval.lr_flags & DLMGMT_ACTIVE) {
407d62bc4baSyz147064 		/*
408d62bc4baSyz147064 		 * An active physical link reported by the dlmgmtd daemon
409d62bc4baSyz147064 		 * might not be active anymore. Check and set its real status.
410d62bc4baSyz147064 		 */
411*4ac67f02SAnurag S. Maskey 		status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
412d62bc4baSyz147064 		if (status != DLADM_STATUS_OK)
413d62bc4baSyz147064 			return (status);
414d62bc4baSyz147064 	}
415d62bc4baSyz147064 
416d62bc4baSyz147064 	if (linkidp != NULL)
417d62bc4baSyz147064 		*linkidp = linkid;
418d62bc4baSyz147064 	if (flagp != NULL) {
419d62bc4baSyz147064 		*flagp = retval.lr_flags & DLMGMT_ACTIVE ? DLADM_OPT_ACTIVE : 0;
420d62bc4baSyz147064 		*flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
421d62bc4baSyz147064 		    DLADM_OPT_PERSIST : 0;
422d62bc4baSyz147064 	}
423d62bc4baSyz147064 	if (classp != NULL)
424d62bc4baSyz147064 		*classp = retval.lr_class;
425d62bc4baSyz147064 	if (mediap != NULL)
426d62bc4baSyz147064 		*mediap = retval.lr_media;
427d62bc4baSyz147064 
428d62bc4baSyz147064 	return (DLADM_STATUS_OK);
429d62bc4baSyz147064 }
430d62bc4baSyz147064 
431d62bc4baSyz147064 /*
432d62bc4baSyz147064  * Get the link name that is associated with the given id.
433d62bc4baSyz147064  */
434d62bc4baSyz147064 dladm_status_t
435*4ac67f02SAnurag S. Maskey dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid,
436*4ac67f02SAnurag S. Maskey     uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap, char *link,
437*4ac67f02SAnurag S. Maskey     size_t len)
438d62bc4baSyz147064 {
439d62bc4baSyz147064 	dlmgmt_door_getname_t	getname;
440d62bc4baSyz147064 	dlmgmt_getname_retval_t	retval;
441d62bc4baSyz147064 	dladm_status_t		status;
442d62bc4baSyz147064 
443d62bc4baSyz147064 	if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) ||
444d62bc4baSyz147064 	    (link == NULL && len != 0)) {
445d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
446d62bc4baSyz147064 	}
447d62bc4baSyz147064 
448d62bc4baSyz147064 	getname.ld_cmd = DLMGMT_CMD_GETNAME;
449d62bc4baSyz147064 	getname.ld_linkid = linkid;
450*4ac67f02SAnurag S. Maskey 	if ((status = dladm_door_call(handle, &getname, sizeof (getname),
451*4ac67f02SAnurag S. Maskey 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
452d62bc4baSyz147064 		return (status);
453d62bc4baSyz147064 	}
454d62bc4baSyz147064 
455024b0a25Sseb 	if (len != 0 && (strlen(retval.lr_link) + 1 > len))
456024b0a25Sseb 		return (DLADM_STATUS_TOOSMALL);
457024b0a25Sseb 
458d62bc4baSyz147064 	if (retval.lr_class == DATALINK_CLASS_PHYS &&
459d62bc4baSyz147064 	    retval.lr_flags & DLMGMT_ACTIVE) {
460d62bc4baSyz147064 		/*
461d62bc4baSyz147064 		 * An active physical link reported by the dlmgmtd daemon
462d62bc4baSyz147064 		 * might not be active anymore. Check and set its real status.
463d62bc4baSyz147064 		 */
464*4ac67f02SAnurag S. Maskey 		status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
465d62bc4baSyz147064 		if (status != DLADM_STATUS_OK)
466d62bc4baSyz147064 			return (status);
467d62bc4baSyz147064 	}
468d62bc4baSyz147064 
469d62bc4baSyz147064 	if (link != NULL)
470d62bc4baSyz147064 		(void) strlcpy(link, retval.lr_link, len);
471d62bc4baSyz147064 	if (classp != NULL)
472d62bc4baSyz147064 		*classp = retval.lr_class;
473d62bc4baSyz147064 	if (mediap != NULL)
474d62bc4baSyz147064 		*mediap = retval.lr_media;
475d62bc4baSyz147064 	if (flagp != NULL) {
476d62bc4baSyz147064 		*flagp = retval.lr_flags & DLMGMT_ACTIVE ?
477d62bc4baSyz147064 		    DLADM_OPT_ACTIVE : 0;
478d62bc4baSyz147064 		*flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
479d62bc4baSyz147064 		    DLADM_OPT_PERSIST : 0;
480d62bc4baSyz147064 	}
481d62bc4baSyz147064 	return (DLADM_STATUS_OK);
482d62bc4baSyz147064 }
483d62bc4baSyz147064 
484d62bc4baSyz147064 /*
485d62bc4baSyz147064  * Set the given attr with the given attrval for the given link.
486d62bc4baSyz147064  */
487d62bc4baSyz147064 dladm_status_t
488*4ac67f02SAnurag S. Maskey dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
489d62bc4baSyz147064     dladm_datatype_t type, const void *attrval)
490d62bc4baSyz147064 {
491024b0a25Sseb 	dlmgmt_door_setattr_t	setattr;
492d62bc4baSyz147064 	dlmgmt_setattr_retval_t	retval;
493024b0a25Sseb 	size_t			attrsz;
494d62bc4baSyz147064 
495024b0a25Sseb 	if (attr == NULL || attrval == NULL)
496d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
497d62bc4baSyz147064 
498d62bc4baSyz147064 	if (type == DLADM_TYPE_STR)
499d62bc4baSyz147064 		attrsz = strlen(attrval) + 1;
500d62bc4baSyz147064 	else
501d62bc4baSyz147064 		attrsz = dladm_datatype_size[type];
502d62bc4baSyz147064 
503024b0a25Sseb 	if (attrsz > MAXLINKATTRVALLEN)
504024b0a25Sseb 		return (DLADM_STATUS_TOOSMALL);
505d62bc4baSyz147064 
506024b0a25Sseb 	setattr.ld_cmd = DLMGMT_CMD_SETATTR;
507024b0a25Sseb 	setattr.ld_conf = conf;
508024b0a25Sseb 	(void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN);
509024b0a25Sseb 	setattr.ld_attrsz = attrsz;
510024b0a25Sseb 	setattr.ld_type = type;
511024b0a25Sseb 	bcopy(attrval, &setattr.ld_attrval, attrsz);
512d62bc4baSyz147064 
513*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &setattr, sizeof (setattr), &retval,
514*4ac67f02SAnurag S. Maskey 	    sizeof (retval)));
515d62bc4baSyz147064 }
516d62bc4baSyz147064 
517d62bc4baSyz147064 /*
518d62bc4baSyz147064  * Unset the given attr the given link.
519d62bc4baSyz147064  */
520d62bc4baSyz147064 dladm_status_t
521*4ac67f02SAnurag S. Maskey dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf,
522*4ac67f02SAnurag S. Maskey     const char *attr)
523d62bc4baSyz147064 {
524d62bc4baSyz147064 	dlmgmt_door_unsetattr_t		unsetattr;
525d62bc4baSyz147064 	dlmgmt_unsetattr_retval_t	retval;
526d62bc4baSyz147064 
527024b0a25Sseb 	if (attr == NULL)
528d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
529d62bc4baSyz147064 
530d62bc4baSyz147064 	unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR;
531d62bc4baSyz147064 	unsetattr.ld_conf = conf;
532d62bc4baSyz147064 	(void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN);
533d62bc4baSyz147064 
534*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr), &retval,
535*4ac67f02SAnurag S. Maskey 	    sizeof (retval)));
536d62bc4baSyz147064 }
537d62bc4baSyz147064 
538d62bc4baSyz147064 /*
539d62bc4baSyz147064  * Remove the given link ID and its entry from the data link configuration
540d62bc4baSyz147064  * repository.
541d62bc4baSyz147064  */
542d62bc4baSyz147064 dladm_status_t
543*4ac67f02SAnurag S. Maskey dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid)
544d62bc4baSyz147064 {
545d62bc4baSyz147064 	dlmgmt_door_removeconf_t	removeconf;
546d62bc4baSyz147064 	dlmgmt_removeconf_retval_t	retval;
547d62bc4baSyz147064 
548d62bc4baSyz147064 	removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF;
549d62bc4baSyz147064 	removeconf.ld_linkid = linkid;
550d62bc4baSyz147064 
551*4ac67f02SAnurag S. Maskey 	return (dladm_door_call(handle, &removeconf, sizeof (removeconf),
552024b0a25Sseb 	    &retval, sizeof (retval)));
553d62bc4baSyz147064 }
554d62bc4baSyz147064 
555d62bc4baSyz147064 /*
556d62bc4baSyz147064  * Free the contents of the link structure.
557d62bc4baSyz147064  */
558d62bc4baSyz147064 void
559*4ac67f02SAnurag S. Maskey dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf)
560d62bc4baSyz147064 {
561d62bc4baSyz147064 	dlmgmt_door_destroyconf_t	destroyconf;
562d62bc4baSyz147064 	dlmgmt_destroyconf_retval_t	retval;
563d62bc4baSyz147064 
564d62bc4baSyz147064 	if (conf == DLADM_INVALID_CONF)
565d62bc4baSyz147064 		return;
566d62bc4baSyz147064 
567d62bc4baSyz147064 	destroyconf.ld_cmd = DLMGMT_CMD_DESTROYCONF;
568d62bc4baSyz147064 	destroyconf.ld_conf = conf;
569d62bc4baSyz147064 
570*4ac67f02SAnurag S. Maskey 	(void) dladm_door_call(handle, &destroyconf, sizeof (destroyconf),
571024b0a25Sseb 	    &retval, sizeof (retval));
572d62bc4baSyz147064 }
573