xref: /illumos-gate/usr/src/uts/common/io/mac/mac_ndd.c (revision aa71ed93)
14045d941Ssowmini /*
24045d941Ssowmini  * CDDL HEADER START
34045d941Ssowmini  *
44045d941Ssowmini  * The contents of this file are subject to the terms of the
54045d941Ssowmini  * Common Development and Distribution License (the "License").
64045d941Ssowmini  * You may not use this file except in compliance with the License.
74045d941Ssowmini  *
84045d941Ssowmini  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94045d941Ssowmini  * or http://www.opensolaris.org/os/licensing.
104045d941Ssowmini  * See the License for the specific language governing permissions
114045d941Ssowmini  * and limitations under the License.
124045d941Ssowmini  *
134045d941Ssowmini  * When distributing Covered Code, include this CDDL HEADER in each
144045d941Ssowmini  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154045d941Ssowmini  * If applicable, add the following below this CDDL HEADER, with the
164045d941Ssowmini  * fields enclosed by brackets "[]" replaced with your own identifying
174045d941Ssowmini  * information: Portions Copyright [yyyy] [name of copyright owner]
184045d941Ssowmini  *
194045d941Ssowmini  * CDDL HEADER END
204045d941Ssowmini  */
214045d941Ssowmini /*
22*aa71ed93SPrakash Jalan  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
234045d941Ssowmini  */
244045d941Ssowmini 
254045d941Ssowmini /*
264045d941Ssowmini  * functions to handle legacy ndd  ioctls
274045d941Ssowmini  */
284045d941Ssowmini #include <sys/types.h>
294045d941Ssowmini #include <sys/mac.h>
304045d941Ssowmini #include <sys/mac_impl.h>
310dc2366fSVenugopal Iyer #include <sys/mac_client_priv.h>
324045d941Ssowmini #include <inet/nd.h>
334045d941Ssowmini #include <sys/mac_ether.h>
344045d941Ssowmini #include <sys/policy.h>
354045d941Ssowmini #include <sys/strsun.h>
364045d941Ssowmini 
374045d941Ssowmini static int mac_ndd_set_ioctl(mac_impl_t *, mblk_t *, int, int *);
384045d941Ssowmini static int mac_ndd_get_ioctl(mac_impl_t *, mblk_t *, int, int *);
394045d941Ssowmini static int mac_ndd_get_names(mac_impl_t *, mblk_t *);
404045d941Ssowmini static boolean_t mac_add_name(mblk_t *, char *, int);
414045d941Ssowmini 
424045d941Ssowmini /*
434045d941Ssowmini  * add "<name> (<rwtag>) " into the mblk, allocating more memory if needed.
444045d941Ssowmini  */
454045d941Ssowmini static boolean_t
mac_add_name(mblk_t * mp,char * name,int ndd_flags)464045d941Ssowmini mac_add_name(mblk_t *mp, char *name, int ndd_flags)
474045d941Ssowmini {
484045d941Ssowmini 	char *cp, *rwtag;
494045d941Ssowmini 	int len, flags;
504045d941Ssowmini 
514045d941Ssowmini 	flags = (ndd_flags & (MAC_PROP_PERM_WRITE|MAC_PROP_PERM_READ));
524045d941Ssowmini 	switch (flags) {
534045d941Ssowmini 	case 0:
544045d941Ssowmini 		rwtag = "no read or write";
554045d941Ssowmini 		break;
564045d941Ssowmini 	case MAC_PROP_PERM_WRITE:
574045d941Ssowmini 		rwtag = "write only";
584045d941Ssowmini 		break;
594045d941Ssowmini 	case MAC_PROP_PERM_READ:
604045d941Ssowmini 		rwtag = "read only";
614045d941Ssowmini 		break;
624045d941Ssowmini 	default:
634045d941Ssowmini 		rwtag = "read and write";
644045d941Ssowmini 		break;
654045d941Ssowmini 	}
664045d941Ssowmini 
674045d941Ssowmini 	while (mp->b_cont != NULL)
684045d941Ssowmini 		mp = mp->b_cont;
694045d941Ssowmini 	/*
704045d941Ssowmini 	 * allocate space for name, <space>, '(', rwtag, ')', and
714045d941Ssowmini 	 * two terminating null chars.
724045d941Ssowmini 	 */
734045d941Ssowmini 	len = strlen(name) + strlen(rwtag) + 6;
744045d941Ssowmini 	if (mp->b_wptr + len >= mp->b_datap->db_lim) {
754045d941Ssowmini 		mp->b_cont = allocb(len, BPRI_HI);
764045d941Ssowmini 		mp = mp->b_cont;
77*aa71ed93SPrakash Jalan 		if (mp == NULL)
784045d941Ssowmini 			return (B_FALSE);
794045d941Ssowmini 	}
804045d941Ssowmini 	cp = (char *)mp->b_wptr;
814045d941Ssowmini 	(void) snprintf(cp, len, "%s (%s)", name, rwtag);
824045d941Ssowmini 	mp->b_wptr += strnlen(cp, len);
834045d941Ssowmini 	mp->b_wptr++; /* skip past the terminating \0 */
844045d941Ssowmini 	return (B_TRUE);
854045d941Ssowmini }
864045d941Ssowmini 
874045d941Ssowmini 
884045d941Ssowmini /*
894045d941Ssowmini  * handle a query for "ndd -get \?". The result is put into mp, and
904045d941Ssowmini  * more memory is allocated if needed. The resulting size of the data
914045d941Ssowmini  * is returned.
924045d941Ssowmini  */
934045d941Ssowmini static int
mac_ndd_get_names(mac_impl_t * mip,mblk_t * mp)944045d941Ssowmini mac_ndd_get_names(mac_impl_t *mip, mblk_t *mp)
954045d941Ssowmini {
964045d941Ssowmini 	int size_out, i;
974045d941Ssowmini 	mblk_t *tmp;
98afdda45fSVasumathi Sundaram - Sun Microsystems 	uint_t permflags;
99afdda45fSVasumathi Sundaram - Sun Microsystems 	int status;
100afdda45fSVasumathi Sundaram - Sun Microsystems 	uint64_t value;
1010dc2366fSVenugopal Iyer 	char *prop_name;
1024045d941Ssowmini 
1034045d941Ssowmini 	if (!mac_add_name(mp, "?", MAC_PROP_PERM_READ))
1044045d941Ssowmini 		return (-1);
1054045d941Ssowmini 
1064045d941Ssowmini 	/* first the known ndd mappings */
1074045d941Ssowmini 	for (i = 0; i < mip->mi_type->mt_mappingcount; i++) {
108afdda45fSVasumathi Sundaram - Sun Microsystems 		if ((mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_MAP_KSTAT)
109afdda45fSVasumathi Sundaram - Sun Microsystems 		    != 0)
110afdda45fSVasumathi Sundaram - Sun Microsystems 			permflags = MAC_PROP_PERM_READ;
111afdda45fSVasumathi Sundaram - Sun Microsystems 		else {
112afdda45fSVasumathi Sundaram - Sun Microsystems 			status = mip->mi_callbacks->mc_getprop(mip->mi_driver,
113afdda45fSVasumathi Sundaram - Sun Microsystems 			    mip->mi_type->mt_mapping[i].mp_name,
114afdda45fSVasumathi Sundaram - Sun Microsystems 			    mip->mi_type->mt_mapping[i].mp_prop_id,
1150dc2366fSVenugopal Iyer 			    mip->mi_type->mt_mapping[i].mp_valsize, &value);
1160dc2366fSVenugopal Iyer 			if (status != 0)
1170dc2366fSVenugopal Iyer 				continue;
1180dc2366fSVenugopal Iyer 			status = mac_prop_info((mac_handle_t)mip,
1190dc2366fSVenugopal Iyer 			    mip->mi_type->mt_mapping[i].mp_prop_id,
1200dc2366fSVenugopal Iyer 			    mip->mi_type->mt_mapping[i].mp_name, NULL, 0,
1210dc2366fSVenugopal Iyer 			    NULL, &permflags);
122afdda45fSVasumathi Sundaram - Sun Microsystems 			if (status != 0)
123646b4e2aSVasumathi Sundaram - Sun Microsystems 				continue;
124afdda45fSVasumathi Sundaram - Sun Microsystems 		}
1254045d941Ssowmini 		if (!mac_add_name(mp, mip->mi_type->mt_mapping[i].mp_name,
126afdda45fSVasumathi Sundaram - Sun Microsystems 		    permflags))
1274045d941Ssowmini 			return (-1);
1284045d941Ssowmini 	}
1294045d941Ssowmini 
1304045d941Ssowmini 	/* now the driver's ndd variables */
1314045d941Ssowmini 	for (i = 0; i < mip->mi_priv_prop_count; i++) {
1324045d941Ssowmini 
1330dc2366fSVenugopal Iyer 		prop_name = mip->mi_priv_prop[i];
1340dc2366fSVenugopal Iyer 
1350dc2366fSVenugopal Iyer 		if (mac_prop_info((mac_handle_t)mip, MAC_PROP_PRIVATE,
1360dc2366fSVenugopal Iyer 		    prop_name, NULL, 0, NULL, &permflags) != 0)
1370dc2366fSVenugopal Iyer 			return (-1);
1384045d941Ssowmini 
1394045d941Ssowmini 		/* skip over the "_" */
1400dc2366fSVenugopal Iyer 		if (!mac_add_name(mp, &prop_name[1], permflags))
1414045d941Ssowmini 			return (-1);
1424045d941Ssowmini 	}
1434045d941Ssowmini 
1444045d941Ssowmini 	tmp = mp;
1454045d941Ssowmini 	while (tmp->b_cont != NULL)
1464045d941Ssowmini 		tmp = tmp->b_cont;
1474045d941Ssowmini 	*tmp->b_wptr++ = '\0';
1484045d941Ssowmini 	size_out = msgdsize(mp);
1494045d941Ssowmini 	return (size_out);
1504045d941Ssowmini }
1514045d941Ssowmini 
1524045d941Ssowmini 
1534045d941Ssowmini /*
1544045d941Ssowmini  * Handle legacy ndd ioctls for ND_GET and ND_SET.
1554045d941Ssowmini  */
1564045d941Ssowmini void
mac_ndd_ioctl(mac_impl_t * mip,queue_t * wq,mblk_t * mp)1574045d941Ssowmini mac_ndd_ioctl(mac_impl_t *mip, queue_t *wq, mblk_t *mp)
1584045d941Ssowmini {
1594045d941Ssowmini 	IOCP    iocp;
1604045d941Ssowmini 	int	cmd, err, rval;
1614045d941Ssowmini 
1624045d941Ssowmini 	iocp = (IOCP)mp->b_rptr;
1634045d941Ssowmini 	if (iocp->ioc_count == 0 || mp->b_cont == NULL) {
1644045d941Ssowmini 		err = EINVAL;
1654045d941Ssowmini 		goto done;
1664045d941Ssowmini 	}
1674045d941Ssowmini 
1684045d941Ssowmini 	cmd = iocp->ioc_cmd;
1694045d941Ssowmini 
1704045d941Ssowmini 	if (cmd == ND_SET) {
1714045d941Ssowmini 		err = mac_ndd_set_ioctl(mip, mp, iocp->ioc_count, &rval);
1724045d941Ssowmini 	} else if (cmd == ND_GET) {
1734045d941Ssowmini 		err = mac_ndd_get_ioctl(mip, mp, iocp->ioc_count, &rval);
1744045d941Ssowmini 	}
1754045d941Ssowmini done:
1764045d941Ssowmini 	if (err == 0)
1774045d941Ssowmini 		miocack(wq, mp, msgdsize(mp->b_cont), rval);
1784045d941Ssowmini 	else
1794045d941Ssowmini 		miocnak(wq, mp, 0, err);
1804045d941Ssowmini }
1814045d941Ssowmini 
1824045d941Ssowmini static int
mac_ndd_get_ioctl(mac_impl_t * mip,mblk_t * mp,int avail,int * rval)1834045d941Ssowmini mac_ndd_get_ioctl(mac_impl_t *mip, mblk_t *mp, int avail, int *rval)
1844045d941Ssowmini {
1854045d941Ssowmini 	mblk_t		*mp1;
1864045d941Ssowmini 	char		*valp;
1874045d941Ssowmini 	uchar_t 	*value;
1884045d941Ssowmini 	uint32_t	new_value;
189*aa71ed93SPrakash Jalan 	int		size_out = 0, i;
1904045d941Ssowmini 	int		status = EINVAL;
1914045d941Ssowmini 	char		*name, priv_name[MAXLINKPROPNAME];
1924045d941Ssowmini 	uint8_t		u8;
1934045d941Ssowmini 	uint16_t	u16;
1944045d941Ssowmini 	uint32_t	u32;
1954045d941Ssowmini 	uint64_t	u64;
1964045d941Ssowmini 
1974045d941Ssowmini 	if (mp->b_cont == NULL || avail < 2)
1984045d941Ssowmini 		return (EINVAL);
1994045d941Ssowmini 	valp = (char *)mp->b_cont->b_rptr;
2004045d941Ssowmini 	mp1 = allocb(avail, BPRI_HI); /* the returned buffer */
2014045d941Ssowmini 	if (mp1 == NULL)
2024045d941Ssowmini 		return (ENOMEM);
2034045d941Ssowmini 
2044045d941Ssowmini 	if (strcmp(valp, "?") == 0) {
2054045d941Ssowmini 		/*
2064045d941Ssowmini 		 * handle "ndd -get <..> \?" queries.
2074045d941Ssowmini 		 */
2084045d941Ssowmini 		size_out = mac_ndd_get_names(mip, mp1);
2094045d941Ssowmini 		if (size_out < 0) {
2104045d941Ssowmini 			status = ENOMEM;
2114045d941Ssowmini 			goto get_done;
2124045d941Ssowmini 		}
2134045d941Ssowmini 		if (size_out > avail) {
2144045d941Ssowmini 			int excess;
2154045d941Ssowmini 			char *cp;
2164045d941Ssowmini 			/*
2174045d941Ssowmini 			 * need more user buffer space. Return as many
2184045d941Ssowmini 			 * mblks as will fit and return the needed
2194045d941Ssowmini 			 * buffer size in ioc_rval.
2204045d941Ssowmini 			 */
2214045d941Ssowmini 			excess = size_out - avail;
2224045d941Ssowmini 			*rval = size_out; /* what's needed */
2234045d941Ssowmini 			size_out -= excess;
2244045d941Ssowmini 			(void) adjmsg(mp1, -(excess + 1));
2254045d941Ssowmini 			cp = (char *)mp1->b_wptr;
2264045d941Ssowmini 			*cp = '\0';
2274045d941Ssowmini 		}
2284045d941Ssowmini 		status = 0;
2294045d941Ssowmini 		goto get_done;
2304045d941Ssowmini 	}
2314045d941Ssowmini 
2324045d941Ssowmini 	ASSERT(mip->mi_callbacks->mc_callbacks & MC_GETPROP);
2334045d941Ssowmini 	name = valp;
2344045d941Ssowmini 	valp = (char *)mp1->b_rptr;
2354045d941Ssowmini 	mp1->b_wptr = mp1->b_rptr;
2364045d941Ssowmini 
2374045d941Ssowmini 	/* first lookup ndd <-> public property mapping */
2384045d941Ssowmini 	for (i = 0; i < mip->mi_type->mt_mappingcount; i++) {
2394045d941Ssowmini 		if (strcmp(name, mip->mi_type->mt_mapping[i].mp_name) != 0)
2404045d941Ssowmini 			continue;
2414045d941Ssowmini 
2424045d941Ssowmini 		switch (mip->mi_type->mt_mapping[i].mp_valsize) {
2434045d941Ssowmini 		case 1:
2444045d941Ssowmini 			value = (uchar_t *)&u8;
2454045d941Ssowmini 			break;
2464045d941Ssowmini 		case 2:
2474045d941Ssowmini 			value = (uchar_t *)&u16;
2484045d941Ssowmini 			break;
2494045d941Ssowmini 		case 4:
2504045d941Ssowmini 			value = (uchar_t *)&u32;
2514045d941Ssowmini 			break;
2524045d941Ssowmini 		default:
2534045d941Ssowmini 			value = (uchar_t *)&u64;
2544045d941Ssowmini 			break;
2554045d941Ssowmini 		}
2564045d941Ssowmini 
2574045d941Ssowmini 		if ((mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_MAP_KSTAT)
2584045d941Ssowmini 		    != 0) {
2594045d941Ssowmini 			u64 = mac_stat_get((mac_handle_t)mip,
2604045d941Ssowmini 			    mip->mi_type->mt_mapping[i].mp_kstat);
2614045d941Ssowmini 			status = 0;
2624045d941Ssowmini 			/*
2634045d941Ssowmini 			 * ether_stats are all always KSTAT_DATA_UINT32
2644045d941Ssowmini 			 */
2654045d941Ssowmini 			new_value = u32 = (long)u64;
2664045d941Ssowmini 		} else {
2674045d941Ssowmini 			status = mip->mi_callbacks->mc_getprop(mip->mi_driver,
2680dc2366fSVenugopal Iyer 			    name, mip->mi_type->mt_mapping[i].mp_prop_id,
2690dc2366fSVenugopal Iyer 			    mip->mi_type->mt_mapping[i].mp_valsize, value);
2704045d941Ssowmini 			switch (mip->mi_type->mt_mapping[i].mp_valsize) {
2714045d941Ssowmini 			case 1:
2724045d941Ssowmini 				new_value = u8;
2734045d941Ssowmini 				break;
2744045d941Ssowmini 			case 2:
2754045d941Ssowmini 				new_value = u16;
2764045d941Ssowmini 				break;
2774045d941Ssowmini 			case 4:
2784045d941Ssowmini 				new_value = u32;
2794045d941Ssowmini 				break;
2804045d941Ssowmini 			case 8:
2814045d941Ssowmini 				/*
2824045d941Ssowmini 				 * The only uint64_t is for speed, which is
2834045d941Ssowmini 				 * converted to Mbps in ndd reports.
2844045d941Ssowmini 				 */
2854045d941Ssowmini 				new_value = (u64/1000000);
2864045d941Ssowmini 				break;
2874045d941Ssowmini 			}
2884045d941Ssowmini 		}
2894045d941Ssowmini 
2904045d941Ssowmini 		if (status != 0)
2914045d941Ssowmini 			goto get_done;
2924045d941Ssowmini 
2934045d941Ssowmini 		(void) snprintf(valp, avail, "%d", new_value);
2944045d941Ssowmini 		goto update_reply;
2954045d941Ssowmini 	}
2964045d941Ssowmini 
2974045d941Ssowmini 	/*
2984045d941Ssowmini 	 * could not find a public property. try the private prop route
2994045d941Ssowmini 	 * where all string processing will be done by the driver.
3004045d941Ssowmini 	 */
3014045d941Ssowmini 	(void) snprintf(priv_name, sizeof (priv_name), "_%s", name);
3024045d941Ssowmini 	status = mip->mi_callbacks->mc_getprop(mip->mi_driver, priv_name,
3030dc2366fSVenugopal Iyer 	    MAC_PROP_PRIVATE, avail - 2, mp1->b_rptr);
3044045d941Ssowmini 	if (status != 0)
3054045d941Ssowmini 		goto get_done;
3064045d941Ssowmini 
3074045d941Ssowmini update_reply:
3084045d941Ssowmini 	size_out += strnlen((const char *)mp1->b_rptr, avail);
3094045d941Ssowmini 	valp += size_out;
3104045d941Ssowmini 	*valp++ = '\0'; /* need \0\0 */
3114045d941Ssowmini 	*valp++ = '\0';
3124045d941Ssowmini 	mp1->b_wptr = (uchar_t *)valp;
3134045d941Ssowmini 	*rval = 0;
3144045d941Ssowmini 
3154045d941Ssowmini get_done:
3164045d941Ssowmini 	freemsg(mp->b_cont);
3174045d941Ssowmini 	if (status == 0)
3184045d941Ssowmini 		mp->b_cont = mp1;
3194045d941Ssowmini 	else {
3204045d941Ssowmini 		freemsg(mp1);
3214045d941Ssowmini 		mp->b_cont = NULL;
3224045d941Ssowmini 	}
3234045d941Ssowmini 	return (status);
3244045d941Ssowmini }
3254045d941Ssowmini 
3264045d941Ssowmini static int
mac_ndd_set_ioctl(mac_impl_t * mip,mblk_t * mp,int avail,int * rval)3274045d941Ssowmini mac_ndd_set_ioctl(mac_impl_t *mip, mblk_t *mp, int avail, int *rval)
3284045d941Ssowmini {
3294045d941Ssowmini 	mblk_t  	*mp1;
3304045d941Ssowmini 	char		*valp, *name, *new_valuep;
3314045d941Ssowmini 	uchar_t 	*vp;
3324045d941Ssowmini 	long		new_value;
3334045d941Ssowmini 	int		status, i;
3344045d941Ssowmini 	uint8_t		u8;
3354045d941Ssowmini 	uint16_t	u16;
3364045d941Ssowmini 	uint32_t	u32;
3374045d941Ssowmini 	IOCP		iocp;
3384045d941Ssowmini 	char		priv_name[MAXLINKPROPNAME];
3394045d941Ssowmini 
3404045d941Ssowmini 	if (avail == 0 || !(mp1 = mp->b_cont))
3414045d941Ssowmini 		return (EINVAL);
3424045d941Ssowmini 
3434045d941Ssowmini 	if (mp1->b_cont) {
3444045d941Ssowmini 		freemsg(mp1->b_cont);
3454045d941Ssowmini 		mp1->b_cont = NULL;
3464045d941Ssowmini 	}
3474045d941Ssowmini 	mp1->b_datap->db_lim[-1] = '\0';
3484045d941Ssowmini 	valp = (char *)mp1->b_rptr;
3494045d941Ssowmini 	name = valp;
3504045d941Ssowmini 	*rval = 0;
3514045d941Ssowmini 	while (*valp++)
3524045d941Ssowmini 		;
3534045d941Ssowmini 	if (valp >= (char *)mp1->b_wptr)
3544045d941Ssowmini 		valp = NULL;
3554045d941Ssowmini 
3564045d941Ssowmini 	new_valuep = valp;
3574045d941Ssowmini 	if (ddi_strtol(valp, NULL, 0, &new_value) != 0)
3584045d941Ssowmini 		goto priv_prop;
3594045d941Ssowmini 
3604045d941Ssowmini 	iocp = (IOCP)mp->b_rptr;
3614045d941Ssowmini 	if (valp != NULL &&
3624045d941Ssowmini 	    ((iocp->ioc_cr == NULL) ||
3634045d941Ssowmini 	    ((status = secpolicy_net_config(iocp->ioc_cr, B_FALSE)) != 0)))
3644045d941Ssowmini 		return (status);
3654045d941Ssowmini 
3664045d941Ssowmini 	status = EINVAL;
3674045d941Ssowmini 
3684045d941Ssowmini 	/* first lookup ndd <-> public property mapping */
3694045d941Ssowmini 	for (i = 0; i < mip->mi_type->mt_mappingcount; i++) {
3704045d941Ssowmini 		if (strcmp(name, mip->mi_type->mt_mapping[i].mp_name) != 0)
3714045d941Ssowmini 			continue;
3724045d941Ssowmini 
3734045d941Ssowmini 		if (mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_MAP_KSTAT)
3744045d941Ssowmini 			return (EINVAL);
3754045d941Ssowmini 
3764045d941Ssowmini 		if (new_value > mip->mi_type->mt_mapping[i].mp_maxval ||
3774045d941Ssowmini 		    new_value < mip->mi_type->mt_mapping[i].mp_minval ||
3784045d941Ssowmini 		    (mip->mi_type->mt_mapping[i].mp_flags & MAC_PROP_PERM_WRITE)
3794045d941Ssowmini 		    == 0)
3804045d941Ssowmini 			return (EINVAL);
3814045d941Ssowmini 		switch (mip->mi_type->mt_mapping[i].mp_valsize) {
3824045d941Ssowmini 		case 1:
3834045d941Ssowmini 			u8 = (uint8_t)new_value;
3844045d941Ssowmini 			vp = (uchar_t *)&u8;
3854045d941Ssowmini 			break;
3864045d941Ssowmini 		case 2:
3874045d941Ssowmini 			u16 = (uint16_t)new_value;
3884045d941Ssowmini 			vp = (uchar_t *)&u16;
3894045d941Ssowmini 			break;
3904045d941Ssowmini 		case 4:
3914045d941Ssowmini 			u32 = (uint32_t)new_value;
3924045d941Ssowmini 			vp = (uchar_t *)&u32;
3934045d941Ssowmini 			break;
3944045d941Ssowmini 		case 8:
3954045d941Ssowmini 			vp = (uchar_t *)&new_value;
3964045d941Ssowmini 			break;
3974045d941Ssowmini 		default:
3984045d941Ssowmini 			return (ENOTSUP);
3994045d941Ssowmini 		}
4004045d941Ssowmini 
4014045d941Ssowmini 		status = mip->mi_callbacks->mc_setprop(mip->mi_driver,
4024045d941Ssowmini 		    name, mip->mi_type->mt_mapping[i].mp_prop_id,
4034045d941Ssowmini 		    mip->mi_type->mt_mapping[i].mp_valsize, (const void *)vp);
4044045d941Ssowmini 		goto done;
4054045d941Ssowmini 	}
4064045d941Ssowmini 
4074045d941Ssowmini priv_prop:
4084045d941Ssowmini 	(void) snprintf(priv_name, sizeof (priv_name), "_%s", name);
4094045d941Ssowmini 	status = mip->mi_callbacks->mc_setprop(mip->mi_driver, priv_name,
4103fd94f8cSam 	    MAC_PROP_PRIVATE, strlen(new_valuep), new_valuep);
4114045d941Ssowmini done:
4124045d941Ssowmini 	freemsg(mp1);
4134045d941Ssowmini 	mp->b_cont = NULL;
4144045d941Ssowmini 	return (status);
4154045d941Ssowmini }
416