15895Syz147064 /*
25895Syz147064  * CDDL HEADER START
35895Syz147064  *
45895Syz147064  * The contents of this file are subject to the terms of the
55895Syz147064  * Common Development and Distribution License (the "License").
65895Syz147064  * You may not use this file except in compliance with the License.
75895Syz147064  *
85895Syz147064  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95895Syz147064  * or http://www.opensolaris.org/os/licensing.
105895Syz147064  * See the License for the specific language governing permissions
115895Syz147064  * and limitations under the License.
125895Syz147064  *
135895Syz147064  * When distributing Covered Code, include this CDDL HEADER in each
145895Syz147064  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155895Syz147064  * If applicable, add the following below this CDDL HEADER, with the
165895Syz147064  * fields enclosed by brackets "[]" replaced with your own identifying
175895Syz147064  * information: Portions Copyright [yyyy] [name of copyright owner]
185895Syz147064  *
195895Syz147064  * CDDL HEADER END
205895Syz147064  */
215895Syz147064 /*
229107Sjames.d.carlson@sun.com  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235895Syz147064  * Use is subject to license terms.
245895Syz147064  */
255895Syz147064 
265895Syz147064 #include <door.h>
275895Syz147064 #include <errno.h>
285895Syz147064 #include <assert.h>
295895Syz147064 #include <stdio.h>
305895Syz147064 #include <stdlib.h>
315895Syz147064 #include <unistd.h>
325895Syz147064 #include <string.h>
335895Syz147064 #include <strings.h>
34*10616SSebastien.Roy@Sun.COM #include <zone.h>
355895Syz147064 #include <sys/types.h>
365895Syz147064 #include <sys/stat.h>
375895Syz147064 #include <sys/aggr.h>
389107Sjames.d.carlson@sun.com #include <sys/mman.h>
395895Syz147064 #include <fcntl.h>
405895Syz147064 #include <libdladm.h>
415895Syz147064 #include <libdladm_impl.h>
425895Syz147064 #include <libdllink.h>
435895Syz147064 #include <libdlmgmt.h>
445895Syz147064 
455895Syz147064 /*
465895Syz147064  * Table of data type sizes indexed by dladm_datatype_t.
475895Syz147064  */
485895Syz147064 static size_t dladm_datatype_size[] = {
495895Syz147064 	0,				/* DLADM_TYPE_STR, use strnlen() */
505895Syz147064 	sizeof (boolean_t),		/* DLADM_TYPE_BOOLEAN */
515895Syz147064 	sizeof (uint64_t)		/* DLADM_TYPE_UINT64 */
525895Syz147064 };
535895Syz147064 
545895Syz147064 static dladm_status_t
558453SAnurag.Maskey@Sun.COM dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf,
568453SAnurag.Maskey@Sun.COM     size_t rsize)
575895Syz147064 {
585895Syz147064 	door_arg_t	darg;
598453SAnurag.Maskey@Sun.COM 	int		door_fd;
605895Syz147064 	dladm_status_t	status = DLADM_STATUS_OK;
615895Syz147064 
625895Syz147064 	darg.data_ptr	= arg;
635895Syz147064 	darg.data_size	= asize;
645895Syz147064 	darg.desc_ptr	= NULL;
655895Syz147064 	darg.desc_num	= 0;
665895Syz147064 	darg.rbuf	= rbuf;
676263Sseb 	darg.rsize	= rsize;
685895Syz147064 
698453SAnurag.Maskey@Sun.COM 	/* The door descriptor is opened if it isn't already */
708453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK)
718453SAnurag.Maskey@Sun.COM 		return (status);
728453SAnurag.Maskey@Sun.COM 	if (door_call(door_fd, &darg) == -1)
735895Syz147064 		status = dladm_errno2status(errno);
745895Syz147064 	if (status != DLADM_STATUS_OK)
755895Syz147064 		return (status);
765895Syz147064 
775895Syz147064 	if (darg.rbuf != rbuf) {
785895Syz147064 		/*
795895Syz147064 		 * The size of the input rbuf is not big enough so that
805895Syz147064 		 * the door allocate the rbuf itself. In this case, simply
815895Syz147064 		 * think something wrong with the door call.
825895Syz147064 		 */
835895Syz147064 		(void) munmap(darg.rbuf, darg.rsize);
845895Syz147064 		return (DLADM_STATUS_TOOSMALL);
855895Syz147064 	}
866263Sseb 	if (darg.rsize != rsize)
875895Syz147064 		return (DLADM_STATUS_FAILED);
885895Syz147064 
896263Sseb 	return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err));
905895Syz147064 }
915895Syz147064 
925895Syz147064 /*
935895Syz147064  * Allocate a new linkid with the given name. Return the new linkid.
945895Syz147064  */
955895Syz147064 dladm_status_t
968453SAnurag.Maskey@Sun.COM dladm_create_datalink_id(dladm_handle_t handle, const char *link,
978453SAnurag.Maskey@Sun.COM     datalink_class_t class, uint32_t media, uint32_t flags,
988453SAnurag.Maskey@Sun.COM     datalink_id_t *linkidp)
995895Syz147064 {
1006263Sseb 	dlmgmt_door_createid_t	createid;
1015895Syz147064 	dlmgmt_createid_retval_t retval;
1026263Sseb 	uint32_t		dlmgmt_flags;
1036263Sseb 	dladm_status_t		status;
1045895Syz147064 
1056263Sseb 	if (link == NULL || class == DATALINK_CLASS_ALL ||
1065895Syz147064 	    !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) ||
1075895Syz147064 	    linkidp == NULL) {
1085895Syz147064 		return (DLADM_STATUS_BADARG);
1095895Syz147064 	}
1105895Syz147064 
1115895Syz147064 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
1125895Syz147064 	dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0;
1135895Syz147064 
1145895Syz147064 	(void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN);
1155895Syz147064 	createid.ld_class = class;
1165895Syz147064 	createid.ld_media = media;
1175895Syz147064 	createid.ld_flags = dlmgmt_flags;
1185895Syz147064 	createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID;
1195895Syz147064 	createid.ld_prefix = (flags & DLADM_OPT_PREFIX);
1205895Syz147064 
1218453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_call(handle, &createid, sizeof (createid),
1228453SAnurag.Maskey@Sun.COM 	    &retval, sizeof (retval))) == DLADM_STATUS_OK) {
1236263Sseb 		*linkidp = retval.lr_linkid;
1246263Sseb 	}
1256263Sseb 	return (status);
1265895Syz147064 }
1275895Syz147064 
1285895Syz147064 /*
1295895Syz147064  * Destroy the given link ID.
1305895Syz147064  */
1315895Syz147064 dladm_status_t
1328453SAnurag.Maskey@Sun.COM dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
1338453SAnurag.Maskey@Sun.COM     uint32_t flags)
1345895Syz147064 {
1355895Syz147064 	dlmgmt_door_destroyid_t		destroyid;
1365895Syz147064 	dlmgmt_destroyid_retval_t	retval;
1375895Syz147064 	uint32_t			dlmgmt_flags;
1385895Syz147064 
1395895Syz147064 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
1405895Syz147064 	dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
1415895Syz147064 
1425895Syz147064 	destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID;
1435895Syz147064 	destroyid.ld_linkid = linkid;
1445895Syz147064 	destroyid.ld_flags = dlmgmt_flags;
1455895Syz147064 
1468453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &destroyid, sizeof (destroyid), &retval,
1478453SAnurag.Maskey@Sun.COM 	    sizeof (retval)));
1485895Syz147064 }
1495895Syz147064 
1505895Syz147064 /*
1515895Syz147064  * Remap a given link ID to a new name.
1525895Syz147064  */
1535895Syz147064 dladm_status_t
1548453SAnurag.Maskey@Sun.COM dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
1558453SAnurag.Maskey@Sun.COM     const char *link)
1565895Syz147064 {
1575895Syz147064 	dlmgmt_door_remapid_t	remapid;
1585895Syz147064 	dlmgmt_remapid_retval_t	retval;
1595895Syz147064 
1605895Syz147064 	remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID;
1615895Syz147064 	remapid.ld_linkid = linkid;
1625895Syz147064 	(void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN);
1635895Syz147064 
1648453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &remapid, sizeof (remapid), &retval,
1658453SAnurag.Maskey@Sun.COM 	    sizeof (retval)));
1665895Syz147064 }
1675895Syz147064 
1685895Syz147064 /*
1695895Syz147064  * Make a given link ID active.
1705895Syz147064  */
1715895Syz147064 dladm_status_t
1728453SAnurag.Maskey@Sun.COM dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid)
1735895Syz147064 {
1746263Sseb 	dlmgmt_door_upid_t	upid;
1756263Sseb 	dlmgmt_upid_retval_t	retval;
1765895Syz147064 
1775895Syz147064 	upid.ld_cmd = DLMGMT_CMD_UP_LINKID;
1785895Syz147064 	upid.ld_linkid = linkid;
1795895Syz147064 
1808453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &upid, sizeof (upid), &retval,
1818453SAnurag.Maskey@Sun.COM 	    sizeof (retval)));
1825895Syz147064 }
1835895Syz147064 
1845895Syz147064 /*
1855895Syz147064  * Create a new link with the given name.  Return the new link's handle
1865895Syz147064  */
1875895Syz147064 dladm_status_t
1888453SAnurag.Maskey@Sun.COM dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid,
1895895Syz147064     datalink_class_t class, uint32_t media, dladm_conf_t *confp)
1905895Syz147064 {
1916263Sseb 	dlmgmt_door_createconf_t	createconf;
1926263Sseb 	dlmgmt_createconf_retval_t	retval;
1936263Sseb 	dladm_status_t			status;
1945895Syz147064 
1956263Sseb 	if (link == NULL || confp == NULL)
1965895Syz147064 		return (DLADM_STATUS_BADARG);
1975895Syz147064 
1985895Syz147064 	(void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN);
1995895Syz147064 	createconf.ld_class = class;
2005895Syz147064 	createconf.ld_media = media;
2015895Syz147064 	createconf.ld_linkid = linkid;
2025895Syz147064 	createconf.ld_cmd = DLMGMT_CMD_CREATECONF;
2035895Syz147064 
2048453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_call(handle, &createconf, sizeof (createconf),
2056263Sseb 	    &retval, sizeof (retval))) == DLADM_STATUS_OK) {
2066263Sseb 		*confp = retval.lr_conf;
2076263Sseb 	}
2086263Sseb 	return (status);
2095895Syz147064 }
2105895Syz147064 
2115895Syz147064 /*
2125895Syz147064  * An active physical link reported by the dlmgmtd daemon might not be active
2135895Syz147064  * anymore as this link might be removed during system shutdown. Check its
2145895Syz147064  * real status by calling dladm_phys_info().
2155895Syz147064  */
2165895Syz147064 dladm_status_t
2178453SAnurag.Maskey@Sun.COM i_dladm_phys_status(dladm_handle_t handle, datalink_id_t linkid,
2188453SAnurag.Maskey@Sun.COM     uint32_t *flagsp)
2195895Syz147064 {
2205895Syz147064 	dladm_phys_attr_t	dpa;
2215895Syz147064 	dladm_status_t		status;
2225895Syz147064 
2235895Syz147064 	assert((*flagsp) & DLMGMT_ACTIVE);
2245895Syz147064 
2258453SAnurag.Maskey@Sun.COM 	status = dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE);
2265895Syz147064 	if (status == DLADM_STATUS_NOTFOUND) {
2275895Syz147064 		/*
2285895Syz147064 		 * No active status, this link was removed. Update its status
2295895Syz147064 		 * in the daemon and delete all active linkprops.
2308120SCathy.Zhou@Sun.COM 		 *
2318120SCathy.Zhou@Sun.COM 		 * Note that the operation could fail. If it does, return
2328120SCathy.Zhou@Sun.COM 		 * failure now since otherwise dladm_set_linkprop() might
2338120SCathy.Zhou@Sun.COM 		 * call back to i_dladm_phys_status() recursively.
2345895Syz147064 		 */
2358453SAnurag.Maskey@Sun.COM 		if ((status = dladm_destroy_datalink_id(handle, linkid,
2368453SAnurag.Maskey@Sun.COM 		    DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK)
2378120SCathy.Zhou@Sun.COM 			return (status);
2388120SCathy.Zhou@Sun.COM 
2398453SAnurag.Maskey@Sun.COM 		(void) dladm_set_linkprop(handle, linkid, NULL, NULL, 0,
2405895Syz147064 		    DLADM_OPT_ACTIVE);
2415895Syz147064 
2425895Syz147064 		(*flagsp) &= ~DLMGMT_ACTIVE;
2435895Syz147064 		status = DLADM_STATUS_OK;
2445895Syz147064 	}
2455895Syz147064 	return (status);
2465895Syz147064 }
2475895Syz147064 
2485895Syz147064 /*
2495895Syz147064  * Walk each entry in the data link configuration repository and
2505895Syz147064  * call fn on the linkid and arg.
2515895Syz147064  */
2525895Syz147064 dladm_status_t
2538453SAnurag.Maskey@Sun.COM dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *),
2548453SAnurag.Maskey@Sun.COM     dladm_handle_t handle, void *argp, datalink_class_t class,
2558453SAnurag.Maskey@Sun.COM     datalink_media_t dmedia, uint32_t flags)
2565895Syz147064 {
2575895Syz147064 	dlmgmt_door_getnext_t	getnext;
2585895Syz147064 	dlmgmt_getnext_retval_t	retval;
2595895Syz147064 	uint32_t 		dlmgmt_flags;
2605895Syz147064 	datalink_id_t		linkid = DATALINK_INVALID_LINKID;
2615895Syz147064 	dladm_status_t		status = DLADM_STATUS_OK;
2625895Syz147064 
2635895Syz147064 	if (fn == NULL)
2645895Syz147064 		return (DLADM_STATUS_BADARG);
2655895Syz147064 
2665895Syz147064 	dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
2675895Syz147064 	dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
2685895Syz147064 
2695895Syz147064 	getnext.ld_cmd = DLMGMT_CMD_GETNEXT;
2705895Syz147064 	getnext.ld_class = class;
2715895Syz147064 	getnext.ld_dmedia = dmedia;
2725895Syz147064 	getnext.ld_flags = dlmgmt_flags;
2735895Syz147064 
2745895Syz147064 	do {
2755895Syz147064 		getnext.ld_linkid = linkid;
2768453SAnurag.Maskey@Sun.COM 		if ((status = dladm_door_call(handle, &getnext,
2778453SAnurag.Maskey@Sun.COM 		    sizeof (getnext), &retval, sizeof (retval))) !=
2788453SAnurag.Maskey@Sun.COM 		    DLADM_STATUS_OK) {
2795895Syz147064 			/*
2805895Syz147064 			 * done with walking
2815895Syz147064 			 */
2825895Syz147064 			break;
2835895Syz147064 		}
2845895Syz147064 
2855895Syz147064 		linkid = retval.lr_linkid;
2865895Syz147064 		if ((retval.lr_class == DATALINK_CLASS_PHYS) &&
2875895Syz147064 		    (retval.lr_flags & DLMGMT_ACTIVE)) {
2885895Syz147064 			/*
2895895Syz147064 			 * An active physical link reported by the dlmgmtd
2905895Syz147064 			 * daemon might not be active anymore. Check its
2915895Syz147064 			 * real status.
2925895Syz147064 			 */
2938453SAnurag.Maskey@Sun.COM 			if (i_dladm_phys_status(handle, linkid,
2948453SAnurag.Maskey@Sun.COM 			    &retval.lr_flags) != DLADM_STATUS_OK) {
2955895Syz147064 				continue;
2965895Syz147064 			}
2975895Syz147064 
2985895Syz147064 			if (!(dlmgmt_flags & retval.lr_flags))
2995895Syz147064 				continue;
3005895Syz147064 		}
3015895Syz147064 
3028453SAnurag.Maskey@Sun.COM 		if (fn(handle, linkid, argp) == DLADM_WALK_TERMINATE)
3035895Syz147064 			break;
3045895Syz147064 	} while (linkid != DATALINK_INVALID_LINKID);
3055895Syz147064 
3065895Syz147064 	return (status);
3075895Syz147064 }
3085895Syz147064 
3095895Syz147064 /*
3105895Syz147064  * Get the link properties structure for the given link.
3115895Syz147064  */
3125895Syz147064 dladm_status_t
3138453SAnurag.Maskey@Sun.COM dladm_read_conf(dladm_handle_t handle, datalink_id_t linkid,
3148453SAnurag.Maskey@Sun.COM     dladm_conf_t *confp)
3155895Syz147064 {
3166263Sseb 	dlmgmt_door_readconf_t		readconf;
3175895Syz147064 	dlmgmt_readconf_retval_t	retval;
3185895Syz147064 	dladm_status_t			status;
3195895Syz147064 
3205895Syz147064 	if (linkid == DATALINK_INVALID_LINKID || confp == NULL)
3215895Syz147064 		return (DLADM_STATUS_BADARG);
3225895Syz147064 
3235895Syz147064 	readconf.ld_linkid = linkid;
3245895Syz147064 	readconf.ld_cmd = DLMGMT_CMD_READCONF;
3255895Syz147064 
3268453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_call(handle, &readconf, sizeof (readconf),
3276263Sseb 	    &retval, sizeof (retval))) == DLADM_STATUS_OK) {
3286263Sseb 		*confp = retval.lr_conf;
3296263Sseb 	}
3306263Sseb 	return (status);
3315895Syz147064 }
3325895Syz147064 
3335895Syz147064 /*
3345895Syz147064  * Commit the given link to the data link configuration repository so
3355895Syz147064  * that it will persist across reboots.
3365895Syz147064  */
3375895Syz147064 dladm_status_t
3388453SAnurag.Maskey@Sun.COM dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf)
3395895Syz147064 {
3405895Syz147064 	dlmgmt_door_writeconf_t		writeconf;
3415895Syz147064 	dlmgmt_writeconf_retval_t	retval;
3425895Syz147064 
3435895Syz147064 	if (conf == DLADM_INVALID_CONF)
3445895Syz147064 		return (DLADM_STATUS_BADARG);
3455895Syz147064 
3465895Syz147064 	writeconf.ld_cmd = DLMGMT_CMD_WRITECONF;
3475895Syz147064 	writeconf.ld_conf = conf;
3485895Syz147064 
3498453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &writeconf, sizeof (writeconf), &retval,
3508453SAnurag.Maskey@Sun.COM 	    sizeof (retval)));
3515895Syz147064 }
3525895Syz147064 
3535895Syz147064 /*
3545895Syz147064  * Given a link ID and a key, get the matching information from
3555895Syz147064  * data link configuration repository.
3565895Syz147064  */
3575895Syz147064 dladm_status_t
3588453SAnurag.Maskey@Sun.COM dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
3598453SAnurag.Maskey@Sun.COM     void *attrval, size_t attrsz)
3605895Syz147064 {
3616263Sseb 	dlmgmt_door_getattr_t	getattr;
3626263Sseb 	dlmgmt_getattr_retval_t	retval;
3636263Sseb 	dladm_status_t		status;
3645895Syz147064 
3655895Syz147064 	if (conf == DLADM_INVALID_CONF || attrval == NULL ||
3666263Sseb 	    attrsz == 0 || attr == NULL) {
3675895Syz147064 		return (DLADM_STATUS_BADARG);
3685895Syz147064 	}
3695895Syz147064 
3705895Syz147064 	getattr.ld_cmd = DLMGMT_CMD_GETATTR;
3715895Syz147064 	getattr.ld_conf = conf;
3725895Syz147064 	(void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN);
3735895Syz147064 
3748453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_call(handle, &getattr, sizeof (getattr),
3758453SAnurag.Maskey@Sun.COM 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
3766263Sseb 		return (status);
3776263Sseb 	}
3785895Syz147064 
3796263Sseb 	if (retval.lr_attrsz > attrsz)
3806263Sseb 		return (DLADM_STATUS_TOOSMALL);
3815895Syz147064 
3826263Sseb 	bcopy(retval.lr_attrval, attrval, retval.lr_attrsz);
3836263Sseb 	return (DLADM_STATUS_OK);
3845895Syz147064 }
3855895Syz147064 
3865895Syz147064 /*
3878460SArtem.Kachitchkin@Sun.COM  * Get next property attribute from data link configuration repository.
3888460SArtem.Kachitchkin@Sun.COM  */
3898460SArtem.Kachitchkin@Sun.COM dladm_status_t
3908460SArtem.Kachitchkin@Sun.COM dladm_getnext_conf_linkprop(dladm_handle_t handle, dladm_conf_t conf,
3918460SArtem.Kachitchkin@Sun.COM     const char *last_attr, char *attr, void *attrval, size_t attrsz,
3928460SArtem.Kachitchkin@Sun.COM     size_t *attrszp)
3938460SArtem.Kachitchkin@Sun.COM {
3948460SArtem.Kachitchkin@Sun.COM 	dlmgmt_door_linkprop_getnext_t		getnext;
3958460SArtem.Kachitchkin@Sun.COM 	dlmgmt_linkprop_getnext_retval_t	retval;
3968460SArtem.Kachitchkin@Sun.COM 	dladm_status_t				status;
3978460SArtem.Kachitchkin@Sun.COM 
3988460SArtem.Kachitchkin@Sun.COM 	if (conf == DLADM_INVALID_CONF || attrval == NULL ||
3998460SArtem.Kachitchkin@Sun.COM 	    attrsz == 0 || attr == NULL) {
4008460SArtem.Kachitchkin@Sun.COM 		return (DLADM_STATUS_BADARG);
4018460SArtem.Kachitchkin@Sun.COM 	}
4028460SArtem.Kachitchkin@Sun.COM 
4038460SArtem.Kachitchkin@Sun.COM 	getnext.ld_cmd = DLMGMT_CMD_LINKPROP_GETNEXT;
4048460SArtem.Kachitchkin@Sun.COM 	getnext.ld_conf = conf;
4058460SArtem.Kachitchkin@Sun.COM 	(void) strlcpy(getnext.ld_last_attr, last_attr, MAXLINKATTRLEN);
4068460SArtem.Kachitchkin@Sun.COM 
4078460SArtem.Kachitchkin@Sun.COM 	if ((status = dladm_door_call(handle, &getnext, sizeof (getnext),
4088460SArtem.Kachitchkin@Sun.COM 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
4098460SArtem.Kachitchkin@Sun.COM 		return (status);
4108460SArtem.Kachitchkin@Sun.COM 	}
4118460SArtem.Kachitchkin@Sun.COM 
4128460SArtem.Kachitchkin@Sun.COM 	*attrszp = retval.lr_attrsz;
4138460SArtem.Kachitchkin@Sun.COM 	if (retval.lr_attrsz > attrsz) {
4148460SArtem.Kachitchkin@Sun.COM 		return (DLADM_STATUS_TOOSMALL);
4158460SArtem.Kachitchkin@Sun.COM 	}
4168460SArtem.Kachitchkin@Sun.COM 
4178460SArtem.Kachitchkin@Sun.COM 	(void) strlcpy(attr, retval.lr_attr, MAXLINKATTRLEN);
4188460SArtem.Kachitchkin@Sun.COM 	bcopy(retval.lr_attrval, attrval, retval.lr_attrsz);
4198460SArtem.Kachitchkin@Sun.COM 	return (DLADM_STATUS_OK);
4208460SArtem.Kachitchkin@Sun.COM }
4218460SArtem.Kachitchkin@Sun.COM 
4228460SArtem.Kachitchkin@Sun.COM /*
4235895Syz147064  * Get the link ID that is associated with the given name.
4245895Syz147064  */
4255895Syz147064 dladm_status_t
4268453SAnurag.Maskey@Sun.COM dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp,
4278453SAnurag.Maskey@Sun.COM     uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap)
4285895Syz147064 {
4295895Syz147064 	dlmgmt_door_getlinkid_t		getlinkid;
4305895Syz147064 	dlmgmt_getlinkid_retval_t	retval;
4315895Syz147064 	datalink_id_t			linkid;
4325895Syz147064 	dladm_status_t			status;
4335895Syz147064 
4345895Syz147064 	getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID;
4355895Syz147064 	(void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN);
4365895Syz147064 
4378453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid),
4386263Sseb 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
4395895Syz147064 		return (status);
4406263Sseb 	}
4415895Syz147064 
4425895Syz147064 	linkid = retval.lr_linkid;
4435895Syz147064 	if (retval.lr_class == DATALINK_CLASS_PHYS &&
4445895Syz147064 	    retval.lr_flags & DLMGMT_ACTIVE) {
4455895Syz147064 		/*
4465895Syz147064 		 * An active physical link reported by the dlmgmtd daemon
4475895Syz147064 		 * might not be active anymore. Check and set its real status.
4485895Syz147064 		 */
4498453SAnurag.Maskey@Sun.COM 		status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
4505895Syz147064 		if (status != DLADM_STATUS_OK)
4515895Syz147064 			return (status);
4525895Syz147064 	}
4535895Syz147064 
4545895Syz147064 	if (linkidp != NULL)
4555895Syz147064 		*linkidp = linkid;
4565895Syz147064 	if (flagp != NULL) {
4575895Syz147064 		*flagp = retval.lr_flags & DLMGMT_ACTIVE ? DLADM_OPT_ACTIVE : 0;
4585895Syz147064 		*flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
4595895Syz147064 		    DLADM_OPT_PERSIST : 0;
4605895Syz147064 	}
4615895Syz147064 	if (classp != NULL)
4625895Syz147064 		*classp = retval.lr_class;
4635895Syz147064 	if (mediap != NULL)
4645895Syz147064 		*mediap = retval.lr_media;
4655895Syz147064 
4665895Syz147064 	return (DLADM_STATUS_OK);
4675895Syz147064 }
4685895Syz147064 
4695895Syz147064 /*
4705895Syz147064  * Get the link name that is associated with the given id.
4715895Syz147064  */
4725895Syz147064 dladm_status_t
4738453SAnurag.Maskey@Sun.COM dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid,
4748453SAnurag.Maskey@Sun.COM     uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap, char *link,
4758453SAnurag.Maskey@Sun.COM     size_t len)
4765895Syz147064 {
4776263Sseb 	dlmgmt_door_getname_t	getname;
4786263Sseb 	dlmgmt_getname_retval_t	retval;
4796263Sseb 	dladm_status_t		status;
4805895Syz147064 
4815895Syz147064 	if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) ||
4825895Syz147064 	    (link == NULL && len != 0)) {
4835895Syz147064 		return (DLADM_STATUS_BADARG);
4845895Syz147064 	}
4855895Syz147064 
4865895Syz147064 	getname.ld_cmd = DLMGMT_CMD_GETNAME;
4875895Syz147064 	getname.ld_linkid = linkid;
4888453SAnurag.Maskey@Sun.COM 	if ((status = dladm_door_call(handle, &getname, sizeof (getname),
4898453SAnurag.Maskey@Sun.COM 	    &retval, sizeof (retval))) != DLADM_STATUS_OK) {
4905895Syz147064 		return (status);
4916263Sseb 	}
4925895Syz147064 
4936263Sseb 	if (len != 0 && (strlen(retval.lr_link) + 1 > len))
4945895Syz147064 		return (DLADM_STATUS_TOOSMALL);
4955895Syz147064 
4965895Syz147064 	if (retval.lr_class == DATALINK_CLASS_PHYS &&
4975895Syz147064 	    retval.lr_flags & DLMGMT_ACTIVE) {
4985895Syz147064 		/*
4995895Syz147064 		 * An active physical link reported by the dlmgmtd daemon
5005895Syz147064 		 * might not be active anymore. Check and set its real status.
5015895Syz147064 		 */
5028453SAnurag.Maskey@Sun.COM 		status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
5035895Syz147064 		if (status != DLADM_STATUS_OK)
5045895Syz147064 			return (status);
5055895Syz147064 	}
5065895Syz147064 
5075895Syz147064 	if (link != NULL)
5085895Syz147064 		(void) strlcpy(link, retval.lr_link, len);
5095895Syz147064 	if (classp != NULL)
5105895Syz147064 		*classp = retval.lr_class;
5115895Syz147064 	if (mediap != NULL)
5125895Syz147064 		*mediap = retval.lr_media;
5135895Syz147064 	if (flagp != NULL) {
5145895Syz147064 		*flagp = retval.lr_flags & DLMGMT_ACTIVE ?
5155895Syz147064 		    DLADM_OPT_ACTIVE : 0;
5165895Syz147064 		*flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
5175895Syz147064 		    DLADM_OPT_PERSIST : 0;
5185895Syz147064 	}
5195895Syz147064 	return (DLADM_STATUS_OK);
5205895Syz147064 }
5215895Syz147064 
5225895Syz147064 /*
5235895Syz147064  * Set the given attr with the given attrval for the given link.
5245895Syz147064  */
5255895Syz147064 dladm_status_t
5268453SAnurag.Maskey@Sun.COM dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
5275895Syz147064     dladm_datatype_t type, const void *attrval)
5285895Syz147064 {
5296263Sseb 	dlmgmt_door_setattr_t	setattr;
5306263Sseb 	dlmgmt_setattr_retval_t	retval;
5316263Sseb 	size_t			attrsz;
5325895Syz147064 
5336263Sseb 	if (attr == NULL || attrval == NULL)
5345895Syz147064 		return (DLADM_STATUS_BADARG);
5355895Syz147064 
5365895Syz147064 	if (type == DLADM_TYPE_STR)
5375895Syz147064 		attrsz = strlen(attrval) + 1;
5385895Syz147064 	else
5395895Syz147064 		attrsz = dladm_datatype_size[type];
5405895Syz147064 
5416263Sseb 	if (attrsz > MAXLINKATTRVALLEN)
5426263Sseb 		return (DLADM_STATUS_TOOSMALL);
5435895Syz147064 
5446263Sseb 	setattr.ld_cmd = DLMGMT_CMD_SETATTR;
5456263Sseb 	setattr.ld_conf = conf;
5466263Sseb 	(void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN);
5476263Sseb 	setattr.ld_attrsz = attrsz;
5486263Sseb 	setattr.ld_type = type;
5496263Sseb 	bcopy(attrval, &setattr.ld_attrval, attrsz);
5505895Syz147064 
5518453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &setattr, sizeof (setattr), &retval,
5528453SAnurag.Maskey@Sun.COM 	    sizeof (retval)));
5535895Syz147064 }
5545895Syz147064 
5555895Syz147064 /*
5565895Syz147064  * Unset the given attr the given link.
5575895Syz147064  */
5585895Syz147064 dladm_status_t
5598453SAnurag.Maskey@Sun.COM dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf,
5608453SAnurag.Maskey@Sun.COM     const char *attr)
5615895Syz147064 {
5625895Syz147064 	dlmgmt_door_unsetattr_t		unsetattr;
5635895Syz147064 	dlmgmt_unsetattr_retval_t	retval;
5645895Syz147064 
5656263Sseb 	if (attr == NULL)
5665895Syz147064 		return (DLADM_STATUS_BADARG);
5675895Syz147064 
5685895Syz147064 	unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR;
5695895Syz147064 	unsetattr.ld_conf = conf;
5705895Syz147064 	(void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN);
5715895Syz147064 
5728453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr), &retval,
5738453SAnurag.Maskey@Sun.COM 	    sizeof (retval)));
5745895Syz147064 }
5755895Syz147064 
5765895Syz147064 /*
5775895Syz147064  * Remove the given link ID and its entry from the data link configuration
5785895Syz147064  * repository.
5795895Syz147064  */
5805895Syz147064 dladm_status_t
5818453SAnurag.Maskey@Sun.COM dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid)
5825895Syz147064 {
5835895Syz147064 	dlmgmt_door_removeconf_t	removeconf;
5845895Syz147064 	dlmgmt_removeconf_retval_t	retval;
5855895Syz147064 
5865895Syz147064 	removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF;
5875895Syz147064 	removeconf.ld_linkid = linkid;
5885895Syz147064 
5898453SAnurag.Maskey@Sun.COM 	return (dladm_door_call(handle, &removeconf, sizeof (removeconf),
5906263Sseb 	    &retval, sizeof (retval)));
5915895Syz147064 }
5925895Syz147064 
5935895Syz147064 /*
5945895Syz147064  * Free the contents of the link structure.
5955895Syz147064  */
5965895Syz147064 void
5978453SAnurag.Maskey@Sun.COM dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf)
5985895Syz147064 {
5995895Syz147064 	dlmgmt_door_destroyconf_t	destroyconf;
6005895Syz147064 	dlmgmt_destroyconf_retval_t	retval;
6015895Syz147064 
6025895Syz147064 	if (conf == DLADM_INVALID_CONF)
6035895Syz147064 		return;
6045895Syz147064 
6055895Syz147064 	destroyconf.ld_cmd = DLMGMT_CMD_DESTROYCONF;
6065895Syz147064 	destroyconf.ld_conf = conf;
6075895Syz147064 
6088453SAnurag.Maskey@Sun.COM 	(void) dladm_door_call(handle, &destroyconf, sizeof (destroyconf),
6096263Sseb 	    &retval, sizeof (retval));
6105895Syz147064 }
611*10616SSebastien.Roy@Sun.COM 
612*10616SSebastien.Roy@Sun.COM dladm_status_t
613*10616SSebastien.Roy@Sun.COM dladm_zone_boot(dladm_handle_t handle, zoneid_t zoneid)
614*10616SSebastien.Roy@Sun.COM {
615*10616SSebastien.Roy@Sun.COM 	dlmgmt_door_zoneboot_t		zoneboot;
616*10616SSebastien.Roy@Sun.COM 	dlmgmt_zoneboot_retval_t	retval;
617*10616SSebastien.Roy@Sun.COM 
618*10616SSebastien.Roy@Sun.COM 	zoneboot.ld_cmd = DLMGMT_CMD_ZONEBOOT;
619*10616SSebastien.Roy@Sun.COM 	zoneboot.ld_zoneid = zoneid;
620*10616SSebastien.Roy@Sun.COM 	return (dladm_door_call(handle, &zoneboot, sizeof (zoneboot), &retval,
621*10616SSebastien.Roy@Sun.COM 	    sizeof (retval)));
622*10616SSebastien.Roy@Sun.COM }
623*10616SSebastien.Roy@Sun.COM 
624*10616SSebastien.Roy@Sun.COM dladm_status_t
625*10616SSebastien.Roy@Sun.COM dladm_zone_halt(dladm_handle_t handle, zoneid_t zoneid)
626*10616SSebastien.Roy@Sun.COM {
627*10616SSebastien.Roy@Sun.COM 	dlmgmt_door_zonehalt_t		zonehalt;
628*10616SSebastien.Roy@Sun.COM 	dlmgmt_zonehalt_retval_t	retval;
629*10616SSebastien.Roy@Sun.COM 
630*10616SSebastien.Roy@Sun.COM 	zonehalt.ld_cmd = DLMGMT_CMD_ZONEHALT;
631*10616SSebastien.Roy@Sun.COM 	zonehalt.ld_zoneid = zoneid;
632*10616SSebastien.Roy@Sun.COM 	return (dladm_door_call(handle, &zonehalt, sizeof (zonehalt), &retval,
633*10616SSebastien.Roy@Sun.COM 	    sizeof (retval)));
634*10616SSebastien.Roy@Sun.COM }
635