xref: /onnv-gate/usr/src/lib/libnwam/common/libnwam_ncp.c (revision 11767:8f30d0e611c6)
1*11767SAnurag.Maskey@Sun.COM /*
2*11767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
3*11767SAnurag.Maskey@Sun.COM  *
4*11767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
5*11767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
6*11767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
7*11767SAnurag.Maskey@Sun.COM  *
8*11767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
11*11767SAnurag.Maskey@Sun.COM  * and limitations under the License.
12*11767SAnurag.Maskey@Sun.COM  *
13*11767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11767SAnurag.Maskey@Sun.COM  *
19*11767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
20*11767SAnurag.Maskey@Sun.COM  */
21*11767SAnurag.Maskey@Sun.COM 
22*11767SAnurag.Maskey@Sun.COM /*
23*11767SAnurag.Maskey@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*11767SAnurag.Maskey@Sun.COM  * Use is subject to license terms.
25*11767SAnurag.Maskey@Sun.COM  */
26*11767SAnurag.Maskey@Sun.COM 
27*11767SAnurag.Maskey@Sun.COM #include <assert.h>
28*11767SAnurag.Maskey@Sun.COM #include <ctype.h>
29*11767SAnurag.Maskey@Sun.COM #include <libgen.h>
30*11767SAnurag.Maskey@Sun.COM #include <netdb.h>
31*11767SAnurag.Maskey@Sun.COM #include <sys/param.h>
32*11767SAnurag.Maskey@Sun.COM #include <sys/types.h>
33*11767SAnurag.Maskey@Sun.COM #include <sys/stat.h>
34*11767SAnurag.Maskey@Sun.COM #include <sys/socket.h>
35*11767SAnurag.Maskey@Sun.COM #include <netinet/in.h>
36*11767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
37*11767SAnurag.Maskey@Sun.COM #include <stdio.h>
38*11767SAnurag.Maskey@Sun.COM #include <stdlib.h>
39*11767SAnurag.Maskey@Sun.COM #include <strings.h>
40*11767SAnurag.Maskey@Sun.COM #include <unistd.h>
41*11767SAnurag.Maskey@Sun.COM #include <libdladm.h>
42*11767SAnurag.Maskey@Sun.COM 
43*11767SAnurag.Maskey@Sun.COM #include "libnwam_impl.h"
44*11767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h>
45*11767SAnurag.Maskey@Sun.COM #include <libnwam.h>
46*11767SAnurag.Maskey@Sun.COM 
47*11767SAnurag.Maskey@Sun.COM /*
48*11767SAnurag.Maskey@Sun.COM  * Functions to support creating, modifying, destroying, querying the
49*11767SAnurag.Maskey@Sun.COM  * state of and changing the state of NCP (Network Configuration Profiles)
50*11767SAnurag.Maskey@Sun.COM  * and the NCUs (Network Configuration Units) that are contained in those
51*11767SAnurag.Maskey@Sun.COM  * NCP objects.  An NCP is simply a container for a set of NCUs which represent
52*11767SAnurag.Maskey@Sun.COM  * the datalink and interface configuration preferences for the system.
53*11767SAnurag.Maskey@Sun.COM  * An NCP can consist a set of prioritized link NCUs, e.g. wired links preferred
54*11767SAnurag.Maskey@Sun.COM  * over wireless, a set of manually enabled/diasbled NCUs, or a combination
55*11767SAnurag.Maskey@Sun.COM  * of both. Interface NCUs inherit activation from their underlying links,
56*11767SAnurag.Maskey@Sun.COM  * so if wired is preferred over wireless and a cable is plugged in,
57*11767SAnurag.Maskey@Sun.COM  * the wired link NCU will be active, as will the IP interface NCU above it.
58*11767SAnurag.Maskey@Sun.COM  */
59*11767SAnurag.Maskey@Sun.COM 
60*11767SAnurag.Maskey@Sun.COM /*
61*11767SAnurag.Maskey@Sun.COM  * The NCU property table is used to mapping property types to property name
62*11767SAnurag.Maskey@Sun.COM  * strings, their associated value types etc. The table is used for validation
63*11767SAnurag.Maskey@Sun.COM  * purposes, and for commit()ing and read()ing NCUs.
64*11767SAnurag.Maskey@Sun.COM  */
65*11767SAnurag.Maskey@Sun.COM 
66*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_type(nwam_value_t);
67*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_class(nwam_value_t);
68*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_ncp(nwam_value_t);
69*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_priority_mode(nwam_value_t);
70*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_ncu_activation_mode(nwam_value_t);
71*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_link_autopush(nwam_value_t);
72*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_link_mtu(nwam_value_t);
73*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_ip_version(nwam_value_t);
74*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_addrsrc_v4(nwam_value_t);
75*11767SAnurag.Maskey@Sun.COM static nwam_error_t valid_addrsrc_v6(nwam_value_t);
76*11767SAnurag.Maskey@Sun.COM 
77*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table_entry ncu_prop_table_entries[] = {
78*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_TYPE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1, valid_type,
79*11767SAnurag.Maskey@Sun.COM 	    "specifies the NCU type - valid values are \'datalink\' and \'ip\'",
80*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
81*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_CLASS, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
82*11767SAnurag.Maskey@Sun.COM 	    valid_class,
83*11767SAnurag.Maskey@Sun.COM 	    "specifies the NCU class - valid values are "
84*11767SAnurag.Maskey@Sun.COM 	    "\'phys\' and \'ip\'",
85*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
86*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_PARENT_NCP, NWAM_VALUE_TYPE_STRING, B_FALSE, 1, 1,
87*11767SAnurag.Maskey@Sun.COM 	    valid_ncp,
88*11767SAnurag.Maskey@Sun.COM 	    "specifies the parent NCP name",
89*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
90*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_ACTIVATION_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
91*11767SAnurag.Maskey@Sun.COM 	    valid_ncu_activation_mode,
92*11767SAnurag.Maskey@Sun.COM 	    "specifies the NCU activation mode - valid values are:\n"
93*11767SAnurag.Maskey@Sun.COM 	    "\'prioritized\' and \'manual\'",
94*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
95*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_ENABLED, NWAM_VALUE_TYPE_BOOLEAN, B_TRUE, 0, 1,
96*11767SAnurag.Maskey@Sun.COM 	    nwam_valid_boolean,
97*11767SAnurag.Maskey@Sun.COM 	    "specifies if manual NCU is to be enabled",
98*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
99*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_PRIORITY_GROUP, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
100*11767SAnurag.Maskey@Sun.COM 	    nwam_valid_uint64,
101*11767SAnurag.Maskey@Sun.COM 	    "specifies the priority grouping of NCUs - lower values are "
102*11767SAnurag.Maskey@Sun.COM 	    "prioritized, negative values are invalid",
103*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
104*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_PRIORITY_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
105*11767SAnurag.Maskey@Sun.COM 	    valid_priority_mode,
106*11767SAnurag.Maskey@Sun.COM 	    "specifies the mode of prioritization - valid values are:\n"
107*11767SAnurag.Maskey@Sun.COM 	    "\'exclusive\', \'shared\' and \'all\'",
108*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
109*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_LINK_MAC_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
110*11767SAnurag.Maskey@Sun.COM 	    nwam_valid_mac_addr,
111*11767SAnurag.Maskey@Sun.COM 	    "specifies MAC address of form aa:bb:cc:dd:ee:ff for the link",
112*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
113*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_LINK_AUTOPUSH, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
114*11767SAnurag.Maskey@Sun.COM 	    NWAM_MAX_NUM_VALUES, valid_link_autopush,
115*11767SAnurag.Maskey@Sun.COM 	    "specifies modules to autopush on link",
116*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
117*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_LINK_MTU, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
118*11767SAnurag.Maskey@Sun.COM 	    valid_link_mtu,
119*11767SAnurag.Maskey@Sun.COM 	    "specifies MTU for link",
120*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
121*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IP_VERSION, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
122*11767SAnurag.Maskey@Sun.COM 	    NWAM_MAX_NUM_VALUES, valid_ip_version,
123*11767SAnurag.Maskey@Sun.COM 	    "specifies IP versions for IP NCU - valid values are:\n"
124*11767SAnurag.Maskey@Sun.COM 	    "\'ipv4\' and \'ipv6\'",
125*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
126*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IPV4_ADDRSRC, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
127*11767SAnurag.Maskey@Sun.COM 	    NWAM_MAX_NUM_VALUES, valid_addrsrc_v4,
128*11767SAnurag.Maskey@Sun.COM 	    "specifies IPv4 address source(s) - valid values are:\n"
129*11767SAnurag.Maskey@Sun.COM 	    "\'dhcp\' and \'static\'",
130*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
131*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IPV4_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
132*11767SAnurag.Maskey@Sun.COM 	    NWAM_MAX_NUM_VALUES, nwam_valid_host_v4,
133*11767SAnurag.Maskey@Sun.COM 	    "specifies static IPv4 host address(es)",
134*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
135*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
136*11767SAnurag.Maskey@Sun.COM 	    1, nwam_valid_route_v4,
137*11767SAnurag.Maskey@Sun.COM 	    "specifies per-interface default IPv4 route",
138*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
139*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IPV6_ADDRSRC, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
140*11767SAnurag.Maskey@Sun.COM 	    NWAM_MAX_NUM_VALUES, valid_addrsrc_v6,
141*11767SAnurag.Maskey@Sun.COM 	    "specifies IPv6 address source(s) - valid values are:\n"
142*11767SAnurag.Maskey@Sun.COM 	    "\'dhcp\', \'autoconf\' and \'static\'.\n"
143*11767SAnurag.Maskey@Sun.COM 	    "\'dhcp\' and \'autoconf\' are mandatory values.",
144*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
145*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IPV6_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
146*11767SAnurag.Maskey@Sun.COM 	    NWAM_MAX_NUM_VALUES, nwam_valid_host_v6,
147*11767SAnurag.Maskey@Sun.COM 	    "specifies static IPv6 host address(es)",
148*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
149*11767SAnurag.Maskey@Sun.COM 	{NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
150*11767SAnurag.Maskey@Sun.COM 	    1, nwam_valid_route_v6,
151*11767SAnurag.Maskey@Sun.COM 	    "specifies per-interface default IPv6 route",
152*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE}
153*11767SAnurag.Maskey@Sun.COM };
154*11767SAnurag.Maskey@Sun.COM 
155*11767SAnurag.Maskey@Sun.COM #define	NWAM_NUM_NCU_PROPS	(sizeof (ncu_prop_table_entries) / \
156*11767SAnurag.Maskey@Sun.COM 				sizeof (*ncu_prop_table_entries))
157*11767SAnurag.Maskey@Sun.COM 
158*11767SAnurag.Maskey@Sun.COM struct nwam_prop_table ncu_prop_table =
159*11767SAnurag.Maskey@Sun.COM 	{ NWAM_NUM_NCU_PROPS, ncu_prop_table_entries };
160*11767SAnurag.Maskey@Sun.COM 
161*11767SAnurag.Maskey@Sun.COM nwam_error_t
162*11767SAnurag.Maskey@Sun.COM nwam_ncp_get_name(nwam_ncp_handle_t ncph, char **namep)
163*11767SAnurag.Maskey@Sun.COM {
164*11767SAnurag.Maskey@Sun.COM 	return (nwam_get_name(ncph, namep));
165*11767SAnurag.Maskey@Sun.COM }
166*11767SAnurag.Maskey@Sun.COM 
167*11767SAnurag.Maskey@Sun.COM static nwam_error_t
168*11767SAnurag.Maskey@Sun.COM nwam_ncp_name_to_file(const char *name, char **filename)
169*11767SAnurag.Maskey@Sun.COM {
170*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL && filename != NULL);
171*11767SAnurag.Maskey@Sun.COM 
172*11767SAnurag.Maskey@Sun.COM 	if ((*filename = malloc(MAXPATHLEN)) == NULL)
173*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
174*11767SAnurag.Maskey@Sun.COM 
175*11767SAnurag.Maskey@Sun.COM 	(void) snprintf(*filename, MAXPATHLEN, "%s%s%s%s", NWAM_CONF_DIR,
176*11767SAnurag.Maskey@Sun.COM 	    NWAM_NCP_CONF_FILE_PRE, name, NWAM_NCP_CONF_FILE_SUF);
177*11767SAnurag.Maskey@Sun.COM 
178*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
179*11767SAnurag.Maskey@Sun.COM }
180*11767SAnurag.Maskey@Sun.COM 
181*11767SAnurag.Maskey@Sun.COM /* ARGSUSED1 */
182*11767SAnurag.Maskey@Sun.COM nwam_error_t
183*11767SAnurag.Maskey@Sun.COM nwam_ncp_create(const char *name, uint64_t flags, nwam_ncp_handle_t *ncphp)
184*11767SAnurag.Maskey@Sun.COM {
185*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
186*11767SAnurag.Maskey@Sun.COM 	char *ncpfile;
187*11767SAnurag.Maskey@Sun.COM 
188*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, name, ncphp))
189*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
190*11767SAnurag.Maskey@Sun.COM 		return (err);
191*11767SAnurag.Maskey@Sun.COM 
192*11767SAnurag.Maskey@Sun.COM 	/* Create empty container for NCUs */
193*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(name, &ncpfile))
194*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
195*11767SAnurag.Maskey@Sun.COM 		nwam_free(*ncphp);
196*11767SAnurag.Maskey@Sun.COM 		*ncphp = NULL;
197*11767SAnurag.Maskey@Sun.COM 		return (err);
198*11767SAnurag.Maskey@Sun.COM 	}
199*11767SAnurag.Maskey@Sun.COM 
200*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_commit(ncpfile, *ncphp, flags)) != NWAM_SUCCESS) {
201*11767SAnurag.Maskey@Sun.COM 		nwam_free(*ncphp);
202*11767SAnurag.Maskey@Sun.COM 		*ncphp = NULL;
203*11767SAnurag.Maskey@Sun.COM 	}
204*11767SAnurag.Maskey@Sun.COM 
205*11767SAnurag.Maskey@Sun.COM 	free(ncpfile);
206*11767SAnurag.Maskey@Sun.COM 
207*11767SAnurag.Maskey@Sun.COM 	return (err);
208*11767SAnurag.Maskey@Sun.COM }
209*11767SAnurag.Maskey@Sun.COM 
210*11767SAnurag.Maskey@Sun.COM /* Used by libnwam_files.c */
211*11767SAnurag.Maskey@Sun.COM nwam_error_t
212*11767SAnurag.Maskey@Sun.COM nwam_ncp_file_to_name(const char *path, char **name)
213*11767SAnurag.Maskey@Sun.COM {
214*11767SAnurag.Maskey@Sun.COM 	char path_copy[MAXPATHLEN];
215*11767SAnurag.Maskey@Sun.COM 	char *filename, *suffix;
216*11767SAnurag.Maskey@Sun.COM 
217*11767SAnurag.Maskey@Sun.COM 	assert(path != NULL && name != NULL);
218*11767SAnurag.Maskey@Sun.COM 
219*11767SAnurag.Maskey@Sun.COM 	/* Make a copy as basename(3c) may modify string */
220*11767SAnurag.Maskey@Sun.COM 	(void) strlcpy(path_copy, path, MAXPATHLEN);
221*11767SAnurag.Maskey@Sun.COM 
222*11767SAnurag.Maskey@Sun.COM 	if ((*name = malloc(NWAM_MAX_NAME_LEN)) == NULL)
223*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
224*11767SAnurag.Maskey@Sun.COM 
225*11767SAnurag.Maskey@Sun.COM 	if ((filename = basename(path_copy)) == NULL) {
226*11767SAnurag.Maskey@Sun.COM 		free(*name);
227*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
228*11767SAnurag.Maskey@Sun.COM 	}
229*11767SAnurag.Maskey@Sun.COM 
230*11767SAnurag.Maskey@Sun.COM 	/* Ensure filename begins/ends with right prefix/suffix */
231*11767SAnurag.Maskey@Sun.COM 	if (sscanf(filename, NWAM_NCP_CONF_FILE_PRE "%256[^\n]s", *name) < 1) {
232*11767SAnurag.Maskey@Sun.COM 		free(*name);
233*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
234*11767SAnurag.Maskey@Sun.COM 	}
235*11767SAnurag.Maskey@Sun.COM 	suffix = *name + strlen(*name) - strlen(NWAM_NCP_CONF_FILE_SUF);
236*11767SAnurag.Maskey@Sun.COM 	if (strstr(*name, NWAM_NCP_CONF_FILE_SUF) != suffix) {
237*11767SAnurag.Maskey@Sun.COM 		free(*name);
238*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
239*11767SAnurag.Maskey@Sun.COM 	}
240*11767SAnurag.Maskey@Sun.COM 	suffix[0] = '\0';
241*11767SAnurag.Maskey@Sun.COM 
242*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
243*11767SAnurag.Maskey@Sun.COM }
244*11767SAnurag.Maskey@Sun.COM 
245*11767SAnurag.Maskey@Sun.COM /* ARGSUSED1 */
246*11767SAnurag.Maskey@Sun.COM nwam_error_t
247*11767SAnurag.Maskey@Sun.COM nwam_ncp_read(const char *name, uint64_t flags, nwam_ncp_handle_t *ncphp)
248*11767SAnurag.Maskey@Sun.COM {
249*11767SAnurag.Maskey@Sun.COM 	char *filename;
250*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
251*11767SAnurag.Maskey@Sun.COM 
252*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL && ncphp != NULL);
253*11767SAnurag.Maskey@Sun.COM 
254*11767SAnurag.Maskey@Sun.COM 	/* try to read the associated ncp configuration */
255*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(name, &filename)) != NWAM_SUCCESS) {
256*11767SAnurag.Maskey@Sun.COM 		*ncphp = NULL;
257*11767SAnurag.Maskey@Sun.COM 		return (err);
258*11767SAnurag.Maskey@Sun.COM 	}
259*11767SAnurag.Maskey@Sun.COM 
260*11767SAnurag.Maskey@Sun.COM 	err = nwam_read(NWAM_OBJECT_TYPE_NCP, filename, name, flags, ncphp);
261*11767SAnurag.Maskey@Sun.COM 	free(filename);
262*11767SAnurag.Maskey@Sun.COM 	return (err);
263*11767SAnurag.Maskey@Sun.COM }
264*11767SAnurag.Maskey@Sun.COM 
265*11767SAnurag.Maskey@Sun.COM static nwam_error_t
266*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_parent_ncp_name(nwam_ncu_handle_t ncuh, char **parentnamep)
267*11767SAnurag.Maskey@Sun.COM {
268*11767SAnurag.Maskey@Sun.COM 	nwam_value_t parentval = NULL;
269*11767SAnurag.Maskey@Sun.COM 	char *parentname;
270*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
271*11767SAnurag.Maskey@Sun.COM 
272*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_PARENT_NCP,
273*11767SAnurag.Maskey@Sun.COM 	    &parentval)) != NWAM_SUCCESS ||
274*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_value_get_string(parentval, &parentname))
275*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
276*11767SAnurag.Maskey@Sun.COM 	    (*parentnamep = strdup(parentname)) == NULL) {
277*11767SAnurag.Maskey@Sun.COM 		if (parentval != NULL)
278*11767SAnurag.Maskey@Sun.COM 			nwam_value_free(parentval);
279*11767SAnurag.Maskey@Sun.COM 		*parentnamep = NULL;
280*11767SAnurag.Maskey@Sun.COM 		return (err);
281*11767SAnurag.Maskey@Sun.COM 	}
282*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(parentval);
283*11767SAnurag.Maskey@Sun.COM 
284*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
285*11767SAnurag.Maskey@Sun.COM }
286*11767SAnurag.Maskey@Sun.COM 
287*11767SAnurag.Maskey@Sun.COM static int
288*11767SAnurag.Maskey@Sun.COM nwam_ncp_copy_callback(nwam_ncu_handle_t oldncuh, void *arg)
289*11767SAnurag.Maskey@Sun.COM {
290*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
291*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t newncuh = NULL;
292*11767SAnurag.Maskey@Sun.COM 	char *oldparent;
293*11767SAnurag.Maskey@Sun.COM 	char *oldfilename = NULL, *newfilename = NULL;
294*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t newncph = (nwam_ncp_handle_t)arg;
295*11767SAnurag.Maskey@Sun.COM 	nwam_value_t newparentval;
296*11767SAnurag.Maskey@Sun.COM 
297*11767SAnurag.Maskey@Sun.COM 	/* Get filenames for the new and old NCU's */
298*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_parent_ncp_name(oldncuh, &oldparent))
299*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
300*11767SAnurag.Maskey@Sun.COM 		return (err);
301*11767SAnurag.Maskey@Sun.COM 	err = nwam_ncp_name_to_file(oldparent, &oldfilename);
302*11767SAnurag.Maskey@Sun.COM 	free(oldparent);
303*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
304*11767SAnurag.Maskey@Sun.COM 		return (err);
305*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(newncph->nwh_name, &newfilename))
306*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
307*11767SAnurag.Maskey@Sun.COM 		goto fail;
308*11767SAnurag.Maskey@Sun.COM 
309*11767SAnurag.Maskey@Sun.COM 	/* new NCU name (and typedname) is the same as the old name */
310*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, oldncuh->nwh_name,
311*11767SAnurag.Maskey@Sun.COM 	    &newncuh)) != NWAM_SUCCESS)
312*11767SAnurag.Maskey@Sun.COM 		goto fail;
313*11767SAnurag.Maskey@Sun.COM 	/* Duplicate the old NCU's data */
314*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_dup_object_list(oldncuh->nwh_data,
315*11767SAnurag.Maskey@Sun.COM 	    &(newncuh->nwh_data))) != NWAM_SUCCESS)
316*11767SAnurag.Maskey@Sun.COM 		goto fail;
317*11767SAnurag.Maskey@Sun.COM 
318*11767SAnurag.Maskey@Sun.COM 	/* Update the parent property for the new NCU */
319*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_create_string(newncph->nwh_name, &newparentval))
320*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
321*11767SAnurag.Maskey@Sun.COM 		goto fail;
322*11767SAnurag.Maskey@Sun.COM 	err = nwam_set_prop_value(newncuh->nwh_data, NWAM_NCU_PROP_PARENT_NCP,
323*11767SAnurag.Maskey@Sun.COM 	    newparentval);
324*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(newparentval);
325*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
326*11767SAnurag.Maskey@Sun.COM 		goto fail;
327*11767SAnurag.Maskey@Sun.COM 
328*11767SAnurag.Maskey@Sun.COM 	/* Save the new NCU */
329*11767SAnurag.Maskey@Sun.COM 	err = nwam_commit(newfilename, newncuh, 0);
330*11767SAnurag.Maskey@Sun.COM 
331*11767SAnurag.Maskey@Sun.COM fail:
332*11767SAnurag.Maskey@Sun.COM 	free(oldfilename);
333*11767SAnurag.Maskey@Sun.COM 	free(newfilename);
334*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_free(newncuh);
335*11767SAnurag.Maskey@Sun.COM 	return (err);
336*11767SAnurag.Maskey@Sun.COM }
337*11767SAnurag.Maskey@Sun.COM 
338*11767SAnurag.Maskey@Sun.COM nwam_error_t
339*11767SAnurag.Maskey@Sun.COM nwam_ncp_copy(nwam_ncp_handle_t oldncph, const char *newname,
340*11767SAnurag.Maskey@Sun.COM     nwam_ncp_handle_t *newncphp)
341*11767SAnurag.Maskey@Sun.COM {
342*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
343*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
344*11767SAnurag.Maskey@Sun.COM 	int cb_ret;
345*11767SAnurag.Maskey@Sun.COM 
346*11767SAnurag.Maskey@Sun.COM 	assert(oldncph != NULL && newname != NULL && newncphp != NULL);
347*11767SAnurag.Maskey@Sun.COM 
348*11767SAnurag.Maskey@Sun.COM 	/* check if newname NCP already exists */
349*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncp_read(newname, 0,  &ncph) == NWAM_SUCCESS) {
350*11767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
351*11767SAnurag.Maskey@Sun.COM 		*newncphp = NULL;
352*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
353*11767SAnurag.Maskey@Sun.COM 	}
354*11767SAnurag.Maskey@Sun.COM 
355*11767SAnurag.Maskey@Sun.COM 	/* create new handle */
356*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_create(newname, 0, newncphp)) != NWAM_SUCCESS)
357*11767SAnurag.Maskey@Sun.COM 		return (err);
358*11767SAnurag.Maskey@Sun.COM 
359*11767SAnurag.Maskey@Sun.COM 	err = nwam_ncp_walk_ncus(oldncph, nwam_ncp_copy_callback, *newncphp,
360*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_CLASS_ALL, &cb_ret);
361*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
362*11767SAnurag.Maskey@Sun.COM 		/* remove the NCP even if any NCU's had already been copied */
363*11767SAnurag.Maskey@Sun.COM 		(void) nwam_ncp_destroy(*newncphp, 0);
364*11767SAnurag.Maskey@Sun.COM 		*newncphp = NULL;
365*11767SAnurag.Maskey@Sun.COM 		if (err == NWAM_WALK_HALTED)
366*11767SAnurag.Maskey@Sun.COM 			return (cb_ret);
367*11767SAnurag.Maskey@Sun.COM 		else
368*11767SAnurag.Maskey@Sun.COM 			return (err);
369*11767SAnurag.Maskey@Sun.COM 	}
370*11767SAnurag.Maskey@Sun.COM 
371*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
372*11767SAnurag.Maskey@Sun.COM }
373*11767SAnurag.Maskey@Sun.COM 
374*11767SAnurag.Maskey@Sun.COM /*
375*11767SAnurag.Maskey@Sun.COM  * Convert type to flag
376*11767SAnurag.Maskey@Sun.COM  */
377*11767SAnurag.Maskey@Sun.COM static uint64_t
378*11767SAnurag.Maskey@Sun.COM nwam_ncu_type_to_flag(nwam_ncu_type_t type)
379*11767SAnurag.Maskey@Sun.COM {
380*11767SAnurag.Maskey@Sun.COM 	switch (type) {
381*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_LINK:
382*11767SAnurag.Maskey@Sun.COM 		return (NWAM_FLAG_NCU_TYPE_LINK);
383*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_INTERFACE:
384*11767SAnurag.Maskey@Sun.COM 		return (NWAM_FLAG_NCU_TYPE_INTERFACE);
385*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_ANY:
386*11767SAnurag.Maskey@Sun.COM 		return (NWAM_FLAG_NCU_TYPE_ALL);
387*11767SAnurag.Maskey@Sun.COM 	default:
388*11767SAnurag.Maskey@Sun.COM 		return (0);
389*11767SAnurag.Maskey@Sun.COM 	}
390*11767SAnurag.Maskey@Sun.COM }
391*11767SAnurag.Maskey@Sun.COM 
392*11767SAnurag.Maskey@Sun.COM /*
393*11767SAnurag.Maskey@Sun.COM  * Convert class to flag
394*11767SAnurag.Maskey@Sun.COM  */
395*11767SAnurag.Maskey@Sun.COM uint64_t
396*11767SAnurag.Maskey@Sun.COM nwam_ncu_class_to_flag(nwam_ncu_class_t class)
397*11767SAnurag.Maskey@Sun.COM {
398*11767SAnurag.Maskey@Sun.COM 	switch (class) {
399*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_CLASS_PHYS:
400*11767SAnurag.Maskey@Sun.COM 		return (NWAM_FLAG_NCU_CLASS_PHYS);
401*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_CLASS_IP:
402*11767SAnurag.Maskey@Sun.COM 		return (NWAM_FLAG_NCU_CLASS_IP);
403*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_CLASS_ANY:
404*11767SAnurag.Maskey@Sun.COM 		return (NWAM_FLAG_NCU_CLASS_ALL);
405*11767SAnurag.Maskey@Sun.COM 	default:
406*11767SAnurag.Maskey@Sun.COM 		return (0);
407*11767SAnurag.Maskey@Sun.COM 	}
408*11767SAnurag.Maskey@Sun.COM }
409*11767SAnurag.Maskey@Sun.COM 
410*11767SAnurag.Maskey@Sun.COM /*
411*11767SAnurag.Maskey@Sun.COM  * Infer NCU type from NCU class
412*11767SAnurag.Maskey@Sun.COM  */
413*11767SAnurag.Maskey@Sun.COM nwam_ncu_type_t
414*11767SAnurag.Maskey@Sun.COM nwam_ncu_class_to_type(nwam_ncu_class_t class)
415*11767SAnurag.Maskey@Sun.COM {
416*11767SAnurag.Maskey@Sun.COM 	switch (class) {
417*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_CLASS_PHYS:
418*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NCU_TYPE_LINK);
419*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_CLASS_IP:
420*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NCU_TYPE_INTERFACE);
421*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_CLASS_ANY:
422*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NCU_TYPE_ANY);
423*11767SAnurag.Maskey@Sun.COM 	default:
424*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NCU_TYPE_UNKNOWN);
425*11767SAnurag.Maskey@Sun.COM 	}
426*11767SAnurag.Maskey@Sun.COM }
427*11767SAnurag.Maskey@Sun.COM 
428*11767SAnurag.Maskey@Sun.COM /*
429*11767SAnurag.Maskey@Sun.COM  * Make ncp active, deactivating any other active ncp.
430*11767SAnurag.Maskey@Sun.COM  */
431*11767SAnurag.Maskey@Sun.COM nwam_error_t
432*11767SAnurag.Maskey@Sun.COM nwam_ncp_enable(nwam_ncp_handle_t ncph)
433*11767SAnurag.Maskey@Sun.COM {
434*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
435*11767SAnurag.Maskey@Sun.COM 	char *name;
436*11767SAnurag.Maskey@Sun.COM 
437*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL);
438*11767SAnurag.Maskey@Sun.COM 
439*11767SAnurag.Maskey@Sun.COM 	err = nwam_enable(NULL, ncph);
440*11767SAnurag.Maskey@Sun.COM 
441*11767SAnurag.Maskey@Sun.COM 	if (err == NWAM_ERROR_BIND) {
442*11767SAnurag.Maskey@Sun.COM 		/*
443*11767SAnurag.Maskey@Sun.COM 		 * nwamd is not running, set active_ncp property so when
444*11767SAnurag.Maskey@Sun.COM 		 * nwamd is next started, this NCP will be used.
445*11767SAnurag.Maskey@Sun.COM 		 */
446*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_ncp_get_name(ncph, &name)) != NWAM_SUCCESS)
447*11767SAnurag.Maskey@Sun.COM 			return (err);
448*11767SAnurag.Maskey@Sun.COM 
449*11767SAnurag.Maskey@Sun.COM 		err = nwam_set_smf_string_property(NWAM_FMRI, NWAM_PG,
450*11767SAnurag.Maskey@Sun.COM 		    NWAM_PROP_ACTIVE_NCP, name);
451*11767SAnurag.Maskey@Sun.COM 		free(name);
452*11767SAnurag.Maskey@Sun.COM 	}
453*11767SAnurag.Maskey@Sun.COM 
454*11767SAnurag.Maskey@Sun.COM 	return (err);
455*11767SAnurag.Maskey@Sun.COM }
456*11767SAnurag.Maskey@Sun.COM 
457*11767SAnurag.Maskey@Sun.COM /* Compare NCP names c1 and c2 using strcasecmp() */
458*11767SAnurag.Maskey@Sun.COM static int
459*11767SAnurag.Maskey@Sun.COM ncpname_cmp(const void *c1, const void *c2)
460*11767SAnurag.Maskey@Sun.COM {
461*11767SAnurag.Maskey@Sun.COM 	return (strcasecmp(*(const char **)c1, *(const char **)c2));
462*11767SAnurag.Maskey@Sun.COM }
463*11767SAnurag.Maskey@Sun.COM 
464*11767SAnurag.Maskey@Sun.COM /* ARGSUSED1 */
465*11767SAnurag.Maskey@Sun.COM nwam_error_t
466*11767SAnurag.Maskey@Sun.COM nwam_walk_ncps(int (*cb)(nwam_ncp_handle_t, void *), void *data,
467*11767SAnurag.Maskey@Sun.COM     uint64_t flags, int *retp)
468*11767SAnurag.Maskey@Sun.COM {
469*11767SAnurag.Maskey@Sun.COM 	char *ncpname, **ncpfiles;
470*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
471*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
472*11767SAnurag.Maskey@Sun.COM 	nwam_value_t value;
473*11767SAnurag.Maskey@Sun.COM 	void *objlist;
474*11767SAnurag.Maskey@Sun.COM 	uint_t i, num_ncpfiles;
475*11767SAnurag.Maskey@Sun.COM 	int ret = 0;
476*11767SAnurag.Maskey@Sun.COM 
477*11767SAnurag.Maskey@Sun.COM 	assert(cb != NULL);
478*11767SAnurag.Maskey@Sun.COM 
479*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
480*11767SAnurag.Maskey@Sun.COM 		return (err);
481*11767SAnurag.Maskey@Sun.COM 	/*
482*11767SAnurag.Maskey@Sun.COM 	 * To get list of NCP files, call nwam_read_object_from_backend()
483*11767SAnurag.Maskey@Sun.COM 	 * with "parent" argument set to NULL. We get back an object list
484*11767SAnurag.Maskey@Sun.COM 	 * consisting of string arrays for each object type - NCP, ENM
485*11767SAnurag.Maskey@Sun.COM 	 * and location. We retrieve the NCP list, which corresponds to
486*11767SAnurag.Maskey@Sun.COM 	 * the set of NCP backend parent objects (these are files at present).
487*11767SAnurag.Maskey@Sun.COM 	 */
488*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_read_object_from_backend(NULL, NULL, flags,
489*11767SAnurag.Maskey@Sun.COM 	    &objlist)) != NWAM_SUCCESS)
490*11767SAnurag.Maskey@Sun.COM 		return (err);
491*11767SAnurag.Maskey@Sun.COM 
492*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_get_prop_value(objlist, NWAM_NCP_OBJECT_STRING, &value))
493*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
494*11767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(objlist);
495*11767SAnurag.Maskey@Sun.COM 		return (err);
496*11767SAnurag.Maskey@Sun.COM 	}
497*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_get_string_array(value, &ncpfiles,
498*11767SAnurag.Maskey@Sun.COM 	    &num_ncpfiles)) != NWAM_SUCCESS) {
499*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(value);
500*11767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(objlist);
501*11767SAnurag.Maskey@Sun.COM 		return (err);
502*11767SAnurag.Maskey@Sun.COM 	}
503*11767SAnurag.Maskey@Sun.COM 
504*11767SAnurag.Maskey@Sun.COM 	/* sort the NCP names alphabetically */
505*11767SAnurag.Maskey@Sun.COM 	qsort(ncpfiles, num_ncpfiles, sizeof (char *), ncpname_cmp);
506*11767SAnurag.Maskey@Sun.COM 
507*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < num_ncpfiles; i++) {
508*11767SAnurag.Maskey@Sun.COM 		if (nwam_ncp_file_to_name(ncpfiles[i], &ncpname)
509*11767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS)
510*11767SAnurag.Maskey@Sun.COM 			continue;
511*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, ncpname,
512*11767SAnurag.Maskey@Sun.COM 		    &ncph)) != NWAM_SUCCESS) {
513*11767SAnurag.Maskey@Sun.COM 			free(ncpname);
514*11767SAnurag.Maskey@Sun.COM 			break;
515*11767SAnurag.Maskey@Sun.COM 		}
516*11767SAnurag.Maskey@Sun.COM 		ret = cb(ncph, data);
517*11767SAnurag.Maskey@Sun.COM 		free(ncph);
518*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
519*11767SAnurag.Maskey@Sun.COM 		if (ret != 0) {
520*11767SAnurag.Maskey@Sun.COM 			err = NWAM_WALK_HALTED;
521*11767SAnurag.Maskey@Sun.COM 			break;
522*11767SAnurag.Maskey@Sun.COM 		}
523*11767SAnurag.Maskey@Sun.COM 	}
524*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(value);
525*11767SAnurag.Maskey@Sun.COM 	nwam_free_object_list(objlist);
526*11767SAnurag.Maskey@Sun.COM 
527*11767SAnurag.Maskey@Sun.COM 	if (retp != NULL)
528*11767SAnurag.Maskey@Sun.COM 		*retp = ret;
529*11767SAnurag.Maskey@Sun.COM 	return (err);
530*11767SAnurag.Maskey@Sun.COM }
531*11767SAnurag.Maskey@Sun.COM 
532*11767SAnurag.Maskey@Sun.COM /*
533*11767SAnurag.Maskey@Sun.COM  * Checks if NCP is read-only.  Only NWAM_NCP_NAME_AUTOMATIC is read-only
534*11767SAnurag.Maskey@Sun.COM  * for all but the netadm user (which nwamd runs as).
535*11767SAnurag.Maskey@Sun.COM  */
536*11767SAnurag.Maskey@Sun.COM nwam_error_t
537*11767SAnurag.Maskey@Sun.COM nwam_ncp_get_read_only(nwam_ncp_handle_t ncph, boolean_t *readp)
538*11767SAnurag.Maskey@Sun.COM {
539*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
540*11767SAnurag.Maskey@Sun.COM 	char *name;
541*11767SAnurag.Maskey@Sun.COM 
542*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL && readp != NULL);
543*11767SAnurag.Maskey@Sun.COM 
544*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_get_name(ncph, &name)) != NWAM_SUCCESS)
545*11767SAnurag.Maskey@Sun.COM 		return (err);
546*11767SAnurag.Maskey@Sun.COM 
547*11767SAnurag.Maskey@Sun.COM 	if (NWAM_NCP_AUTOMATIC(name))
548*11767SAnurag.Maskey@Sun.COM 		*readp = !nwam_uid_is_netadm();
549*11767SAnurag.Maskey@Sun.COM 	else
550*11767SAnurag.Maskey@Sun.COM 		*readp = B_FALSE;
551*11767SAnurag.Maskey@Sun.COM 
552*11767SAnurag.Maskey@Sun.COM 	free(name);
553*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
554*11767SAnurag.Maskey@Sun.COM }
555*11767SAnurag.Maskey@Sun.COM 
556*11767SAnurag.Maskey@Sun.COM /* Checks if NCU is writable depending on its parent */
557*11767SAnurag.Maskey@Sun.COM nwam_error_t
558*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_read_only(nwam_ncu_handle_t ncuh, boolean_t *readp)
559*11767SAnurag.Maskey@Sun.COM {
560*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
561*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
562*11767SAnurag.Maskey@Sun.COM 
563*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && readp != NULL);
564*11767SAnurag.Maskey@Sun.COM 
565*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_ncp(ncuh, &ncph)) != NWAM_SUCCESS)
566*11767SAnurag.Maskey@Sun.COM 		return (err);
567*11767SAnurag.Maskey@Sun.COM 
568*11767SAnurag.Maskey@Sun.COM 	err = nwam_ncp_get_read_only(ncph, readp);
569*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
570*11767SAnurag.Maskey@Sun.COM 	return (err);
571*11767SAnurag.Maskey@Sun.COM }
572*11767SAnurag.Maskey@Sun.COM 
573*11767SAnurag.Maskey@Sun.COM /* Returns true if the NCP is active */
574*11767SAnurag.Maskey@Sun.COM static boolean_t
575*11767SAnurag.Maskey@Sun.COM nwam_ncp_is_active(nwam_ncp_handle_t ncph)
576*11767SAnurag.Maskey@Sun.COM {
577*11767SAnurag.Maskey@Sun.COM 	char *active_ncp, *name;
578*11767SAnurag.Maskey@Sun.COM 	boolean_t ret;
579*11767SAnurag.Maskey@Sun.COM 
580*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL);
581*11767SAnurag.Maskey@Sun.COM 
582*11767SAnurag.Maskey@Sun.COM 	/*
583*11767SAnurag.Maskey@Sun.COM 	 * Determine which NCP is active via the nwamd/active_ncp property
584*11767SAnurag.Maskey@Sun.COM 	 * value.  This allows us to determine which NCP is active even
585*11767SAnurag.Maskey@Sun.COM 	 * if nwamd is not running.
586*11767SAnurag.Maskey@Sun.COM 	 */
587*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncp_get_name(ncph, &name) != NWAM_SUCCESS ||
588*11767SAnurag.Maskey@Sun.COM 	    nwam_get_smf_string_property(NWAM_FMRI, NWAM_PG,
589*11767SAnurag.Maskey@Sun.COM 	    NWAM_PROP_ACTIVE_NCP, &active_ncp) != NWAM_SUCCESS)
590*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
591*11767SAnurag.Maskey@Sun.COM 
592*11767SAnurag.Maskey@Sun.COM 	ret = (strcmp(name, active_ncp) == 0);
593*11767SAnurag.Maskey@Sun.COM 
594*11767SAnurag.Maskey@Sun.COM 	free(active_ncp);
595*11767SAnurag.Maskey@Sun.COM 	free(name);
596*11767SAnurag.Maskey@Sun.COM 
597*11767SAnurag.Maskey@Sun.COM 	return (ret);
598*11767SAnurag.Maskey@Sun.COM }
599*11767SAnurag.Maskey@Sun.COM 
600*11767SAnurag.Maskey@Sun.COM nwam_error_t
601*11767SAnurag.Maskey@Sun.COM nwam_ncp_destroy(nwam_ncp_handle_t ncph, uint64_t flags)
602*11767SAnurag.Maskey@Sun.COM {
603*11767SAnurag.Maskey@Sun.COM 	char *filename;
604*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
605*11767SAnurag.Maskey@Sun.COM 	boolean_t read_only;
606*11767SAnurag.Maskey@Sun.COM 
607*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL);
608*11767SAnurag.Maskey@Sun.COM 
609*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_get_read_only(ncph, &read_only)) != NWAM_SUCCESS)
610*11767SAnurag.Maskey@Sun.COM 		return (err);
611*11767SAnurag.Maskey@Sun.COM 	if (read_only)
612*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_DESTROYABLE);
613*11767SAnurag.Maskey@Sun.COM 
614*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncp_is_active(ncph))
615*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_IN_USE);
616*11767SAnurag.Maskey@Sun.COM 
617*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &filename))
618*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
619*11767SAnurag.Maskey@Sun.COM 		return (err);
620*11767SAnurag.Maskey@Sun.COM 
621*11767SAnurag.Maskey@Sun.COM 	err = nwam_destroy(filename, ncph, flags);
622*11767SAnurag.Maskey@Sun.COM 	free(filename);
623*11767SAnurag.Maskey@Sun.COM 
624*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
625*11767SAnurag.Maskey@Sun.COM }
626*11767SAnurag.Maskey@Sun.COM 
627*11767SAnurag.Maskey@Sun.COM static nwam_error_t
628*11767SAnurag.Maskey@Sun.COM nwam_ncu_internal_name_to_name(const char *internalname,
629*11767SAnurag.Maskey@Sun.COM     nwam_ncu_type_t *typep, char **namep)
630*11767SAnurag.Maskey@Sun.COM {
631*11767SAnurag.Maskey@Sun.COM 	char *prefixstr;
632*11767SAnurag.Maskey@Sun.COM 
633*11767SAnurag.Maskey@Sun.COM 	assert(internalname != NULL && namep != NULL);
634*11767SAnurag.Maskey@Sun.COM 
635*11767SAnurag.Maskey@Sun.COM 	if (strncasecmp(internalname, NWAM_NCU_LINK_NAME_PRE,
636*11767SAnurag.Maskey@Sun.COM 	    strlen(NWAM_NCU_LINK_NAME_PRE)) == 0) {
637*11767SAnurag.Maskey@Sun.COM 		prefixstr = NWAM_NCU_LINK_NAME_PRE;
638*11767SAnurag.Maskey@Sun.COM 		*typep = NWAM_NCU_TYPE_LINK;
639*11767SAnurag.Maskey@Sun.COM 	} else if (strncasecmp(internalname, NWAM_NCU_INTERFACE_NAME_PRE,
640*11767SAnurag.Maskey@Sun.COM 	    strlen(NWAM_NCU_INTERFACE_NAME_PRE)) == 0) {
641*11767SAnurag.Maskey@Sun.COM 		prefixstr = NWAM_NCU_INTERFACE_NAME_PRE;
642*11767SAnurag.Maskey@Sun.COM 		*typep = NWAM_NCU_TYPE_INTERFACE;
643*11767SAnurag.Maskey@Sun.COM 	} else {
644*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
645*11767SAnurag.Maskey@Sun.COM 	}
646*11767SAnurag.Maskey@Sun.COM 
647*11767SAnurag.Maskey@Sun.COM 	*namep = strdup(internalname + strlen(prefixstr));
648*11767SAnurag.Maskey@Sun.COM 	if (*namep == NULL)
649*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
650*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
651*11767SAnurag.Maskey@Sun.COM }
652*11767SAnurag.Maskey@Sun.COM 
653*11767SAnurag.Maskey@Sun.COM /* ARGSUSED2 */
654*11767SAnurag.Maskey@Sun.COM static int
655*11767SAnurag.Maskey@Sun.COM ncu_selectcb(struct nwam_handle *hp, uint64_t flags, void *data)
656*11767SAnurag.Maskey@Sun.COM {
657*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh = hp;
658*11767SAnurag.Maskey@Sun.COM 	nwam_value_t typeval = NULL, classval = NULL;
659*11767SAnurag.Maskey@Sun.COM 	uint64_t type, class, matchflags, walkfilter;
660*11767SAnurag.Maskey@Sun.COM 
661*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval)
662*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
663*11767SAnurag.Maskey@Sun.COM 	    nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS, &classval)
664*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
665*11767SAnurag.Maskey@Sun.COM 		if (typeval != NULL)
666*11767SAnurag.Maskey@Sun.COM 			nwam_value_free(typeval);
667*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
668*11767SAnurag.Maskey@Sun.COM 	}
669*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS ||
670*11767SAnurag.Maskey@Sun.COM 	    nwam_value_get_uint64(classval, &class) != NWAM_SUCCESS) {
671*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(typeval);
672*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(classval);
673*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
674*11767SAnurag.Maskey@Sun.COM 	}
675*11767SAnurag.Maskey@Sun.COM 
676*11767SAnurag.Maskey@Sun.COM 	matchflags = nwam_ncu_type_to_flag(type) |
677*11767SAnurag.Maskey@Sun.COM 	    nwam_ncu_class_to_flag(class);
678*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(typeval);
679*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(classval);
680*11767SAnurag.Maskey@Sun.COM 
681*11767SAnurag.Maskey@Sun.COM 	if ((walkfilter = (flags & NWAM_WALK_FILTER_MASK)) == 0)
682*11767SAnurag.Maskey@Sun.COM 		walkfilter = NWAM_FLAG_NCU_TYPE_CLASS_ALL;
683*11767SAnurag.Maskey@Sun.COM 
684*11767SAnurag.Maskey@Sun.COM 	if (matchflags & walkfilter)
685*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
686*11767SAnurag.Maskey@Sun.COM 	return (NWAM_INVALID_ARG);
687*11767SAnurag.Maskey@Sun.COM }
688*11767SAnurag.Maskey@Sun.COM 
689*11767SAnurag.Maskey@Sun.COM nwam_error_t
690*11767SAnurag.Maskey@Sun.COM nwam_ncp_walk_ncus(nwam_ncp_handle_t ncph,
691*11767SAnurag.Maskey@Sun.COM     int(*cb)(nwam_ncu_handle_t, void *), void *data, uint64_t flags, int *retp)
692*11767SAnurag.Maskey@Sun.COM {
693*11767SAnurag.Maskey@Sun.COM 	char *ncpfile;
694*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
695*11767SAnurag.Maskey@Sun.COM 
696*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL && cb != NULL);
697*11767SAnurag.Maskey@Sun.COM 
698*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_valid_flags(flags,
699*11767SAnurag.Maskey@Sun.COM 	    NWAM_FLAG_NCU_TYPE_CLASS_ALL | NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
700*11767SAnurag.Maskey@Sun.COM 		return (err);
701*11767SAnurag.Maskey@Sun.COM 
702*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &ncpfile))
703*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
704*11767SAnurag.Maskey@Sun.COM 		return (err);
705*11767SAnurag.Maskey@Sun.COM 
706*11767SAnurag.Maskey@Sun.COM 	err = nwam_walk(NWAM_OBJECT_TYPE_NCU, ncpfile, cb, data, flags,
707*11767SAnurag.Maskey@Sun.COM 	    retp, ncu_selectcb);
708*11767SAnurag.Maskey@Sun.COM 	free(ncpfile);
709*11767SAnurag.Maskey@Sun.COM 
710*11767SAnurag.Maskey@Sun.COM 	return (err);
711*11767SAnurag.Maskey@Sun.COM }
712*11767SAnurag.Maskey@Sun.COM 
713*11767SAnurag.Maskey@Sun.COM void
714*11767SAnurag.Maskey@Sun.COM nwam_ncp_free(nwam_ncp_handle_t ncph)
715*11767SAnurag.Maskey@Sun.COM {
716*11767SAnurag.Maskey@Sun.COM 	nwam_free(ncph);
717*11767SAnurag.Maskey@Sun.COM }
718*11767SAnurag.Maskey@Sun.COM 
719*11767SAnurag.Maskey@Sun.COM /*
720*11767SAnurag.Maskey@Sun.COM  * Are ncu type and class compatible?
721*11767SAnurag.Maskey@Sun.COM  */
722*11767SAnurag.Maskey@Sun.COM static boolean_t
723*11767SAnurag.Maskey@Sun.COM nwam_ncu_type_class_compatible(nwam_ncu_type_t type, nwam_ncu_class_t class)
724*11767SAnurag.Maskey@Sun.COM {
725*11767SAnurag.Maskey@Sun.COM 	switch (type) {
726*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_LINK:
727*11767SAnurag.Maskey@Sun.COM 		return (class == NWAM_NCU_CLASS_PHYS);
728*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_INTERFACE:
729*11767SAnurag.Maskey@Sun.COM 		return (class == NWAM_NCU_CLASS_IP);
730*11767SAnurag.Maskey@Sun.COM 	default:
731*11767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
732*11767SAnurag.Maskey@Sun.COM 	}
733*11767SAnurag.Maskey@Sun.COM }
734*11767SAnurag.Maskey@Sun.COM 
735*11767SAnurag.Maskey@Sun.COM /* Name to validate may be internal name. If so, convert it before validating */
736*11767SAnurag.Maskey@Sun.COM static boolean_t
737*11767SAnurag.Maskey@Sun.COM valid_ncu_name(const char *name)
738*11767SAnurag.Maskey@Sun.COM {
739*11767SAnurag.Maskey@Sun.COM 	char *n;
740*11767SAnurag.Maskey@Sun.COM 	boolean_t ret;
741*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t type;
742*11767SAnurag.Maskey@Sun.COM 
743*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_internal_name_to_name(name, &type, &n) == NWAM_SUCCESS) {
744*11767SAnurag.Maskey@Sun.COM 
745*11767SAnurag.Maskey@Sun.COM 		ret = dladm_valid_linkname(n);
746*11767SAnurag.Maskey@Sun.COM 		free(n);
747*11767SAnurag.Maskey@Sun.COM 	} else {
748*11767SAnurag.Maskey@Sun.COM 		ret = dladm_valid_linkname(name);
749*11767SAnurag.Maskey@Sun.COM 	}
750*11767SAnurag.Maskey@Sun.COM 
751*11767SAnurag.Maskey@Sun.COM 	return (ret);
752*11767SAnurag.Maskey@Sun.COM }
753*11767SAnurag.Maskey@Sun.COM 
754*11767SAnurag.Maskey@Sun.COM nwam_error_t
755*11767SAnurag.Maskey@Sun.COM nwam_ncu_create(nwam_ncp_handle_t ncph, const char *name,
756*11767SAnurag.Maskey@Sun.COM     nwam_ncu_type_t type, nwam_ncu_class_t class, nwam_ncu_handle_t *ncuhp)
757*11767SAnurag.Maskey@Sun.COM {
758*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh;
759*11767SAnurag.Maskey@Sun.COM 	nwam_value_t typeval = NULL, classval = NULL, parentval = NULL;
760*11767SAnurag.Maskey@Sun.COM 	nwam_value_t enabledval = NULL;
761*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
762*11767SAnurag.Maskey@Sun.COM 	boolean_t read_only;
763*11767SAnurag.Maskey@Sun.COM 	char *typedname;
764*11767SAnurag.Maskey@Sun.COM 
765*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL && name != NULL && ncuhp != NULL);
766*11767SAnurag.Maskey@Sun.COM 
767*11767SAnurag.Maskey@Sun.COM 	if (!valid_ncu_name(name))
768*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
769*11767SAnurag.Maskey@Sun.COM 
770*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_get_read_only(ncph, &read_only)) != NWAM_SUCCESS)
771*11767SAnurag.Maskey@Sun.COM 		return (err);
772*11767SAnurag.Maskey@Sun.COM 	if (read_only)
773*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_READ_ONLY);
774*11767SAnurag.Maskey@Sun.COM 
775*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_read(ncph, name, type, 0, &ncuh) == NWAM_SUCCESS) {
776*11767SAnurag.Maskey@Sun.COM 		nwam_ncu_free(ncuh);
777*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
778*11767SAnurag.Maskey@Sun.COM 	}
779*11767SAnurag.Maskey@Sun.COM 
780*11767SAnurag.Maskey@Sun.COM 	if (!valid_ncu_name(name) ||
781*11767SAnurag.Maskey@Sun.COM 	    !nwam_ncu_type_class_compatible(type, class))
782*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
783*11767SAnurag.Maskey@Sun.COM 
784*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_name_to_typed_name(name, type, &typedname))
785*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
786*11767SAnurag.Maskey@Sun.COM 		return (err);
787*11767SAnurag.Maskey@Sun.COM 
788*11767SAnurag.Maskey@Sun.COM 	/* Create handle */
789*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, typedname, ncuhp))
790*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
791*11767SAnurag.Maskey@Sun.COM 		return (err);
792*11767SAnurag.Maskey@Sun.COM 	free(typedname);
793*11767SAnurag.Maskey@Sun.COM 
794*11767SAnurag.Maskey@Sun.COM 	/*
795*11767SAnurag.Maskey@Sun.COM 	 * Create new object list for NCU.  The new NCU is initialized with
796*11767SAnurag.Maskey@Sun.COM 	 * the appropriate type and class.
797*11767SAnurag.Maskey@Sun.COM 	 */
798*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_alloc_object_list(&(*ncuhp)->nwh_data)) != NWAM_SUCCESS)
799*11767SAnurag.Maskey@Sun.COM 		goto finish;
800*11767SAnurag.Maskey@Sun.COM 
801*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_create_uint64(type, &typeval))
802*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
803*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_value_create_uint64(class, &classval))
804*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
805*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_value_create_string(ncph->nwh_name, &parentval))
806*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
807*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_value_create_boolean(B_TRUE, &enabledval))
808*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
809*11767SAnurag.Maskey@Sun.COM 		goto finish;
810*11767SAnurag.Maskey@Sun.COM 	}
811*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_set_prop_value((*ncuhp)->nwh_data, NWAM_NCU_PROP_TYPE,
812*11767SAnurag.Maskey@Sun.COM 	    typeval)) != NWAM_SUCCESS ||
813*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_set_prop_value((*ncuhp)->nwh_data, NWAM_NCU_PROP_CLASS,
814*11767SAnurag.Maskey@Sun.COM 	    classval)) != NWAM_SUCCESS ||
815*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_set_prop_value((*ncuhp)->nwh_data,
816*11767SAnurag.Maskey@Sun.COM 	    NWAM_NCU_PROP_PARENT_NCP, parentval)) != NWAM_SUCCESS ||
817*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_set_prop_value((*ncuhp)->nwh_data,
818*11767SAnurag.Maskey@Sun.COM 	    NWAM_NCU_PROP_ENABLED, enabledval)) != NWAM_SUCCESS) {
819*11767SAnurag.Maskey@Sun.COM 		goto finish;
820*11767SAnurag.Maskey@Sun.COM 	}
821*11767SAnurag.Maskey@Sun.COM 
822*11767SAnurag.Maskey@Sun.COM 	/* Set default IP, datalink properties */
823*11767SAnurag.Maskey@Sun.COM 	if (type == NWAM_NCU_TYPE_INTERFACE && class == NWAM_NCU_CLASS_IP) {
824*11767SAnurag.Maskey@Sun.COM 
825*11767SAnurag.Maskey@Sun.COM 		uint64_t ver[] = { IPV4_VERSION, IPV6_VERSION };
826*11767SAnurag.Maskey@Sun.COM 		uint64_t v6src[] = { NWAM_ADDRSRC_DHCP, NWAM_ADDRSRC_AUTOCONF };
827*11767SAnurag.Maskey@Sun.COM 		uint_t vercnt = 2, v6srccnt = 2;
828*11767SAnurag.Maskey@Sun.COM 		nwam_value_t ipver = NULL, v4addrsrc = NULL, v6addrsrc = NULL;
829*11767SAnurag.Maskey@Sun.COM 
830*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_value_create_uint64_array(ver, vercnt, &ipver))
831*11767SAnurag.Maskey@Sun.COM 		    != NWAM_SUCCESS ||
832*11767SAnurag.Maskey@Sun.COM 		    (err = nwam_value_create_uint64(NWAM_ADDRSRC_DHCP,
833*11767SAnurag.Maskey@Sun.COM 		    &v4addrsrc)) != NWAM_SUCCESS ||
834*11767SAnurag.Maskey@Sun.COM 		    (err = nwam_value_create_uint64_array(v6src, v6srccnt,
835*11767SAnurag.Maskey@Sun.COM 		    &v6addrsrc)) != NWAM_SUCCESS) {
836*11767SAnurag.Maskey@Sun.COM 			nwam_value_free(ipver);
837*11767SAnurag.Maskey@Sun.COM 			nwam_value_free(v4addrsrc);
838*11767SAnurag.Maskey@Sun.COM 			goto finish;
839*11767SAnurag.Maskey@Sun.COM 		}
840*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_set_prop_value((*ncuhp)->nwh_data,
841*11767SAnurag.Maskey@Sun.COM 		    NWAM_NCU_PROP_IP_VERSION, ipver)) == NWAM_SUCCESS &&
842*11767SAnurag.Maskey@Sun.COM 		    (err = nwam_set_prop_value((*ncuhp)->nwh_data,
843*11767SAnurag.Maskey@Sun.COM 		    NWAM_NCU_PROP_IPV4_ADDRSRC, v4addrsrc)) == NWAM_SUCCESS) {
844*11767SAnurag.Maskey@Sun.COM 			err = nwam_set_prop_value((*ncuhp)->nwh_data,
845*11767SAnurag.Maskey@Sun.COM 			    NWAM_NCU_PROP_IPV6_ADDRSRC, v6addrsrc);
846*11767SAnurag.Maskey@Sun.COM 		}
847*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(ipver);
848*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(v4addrsrc);
849*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(v6addrsrc);
850*11767SAnurag.Maskey@Sun.COM 	} else {
851*11767SAnurag.Maskey@Sun.COM 		nwam_value_t actval = NULL;
852*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL,
853*11767SAnurag.Maskey@Sun.COM 		    &actval)) != NWAM_SUCCESS)
854*11767SAnurag.Maskey@Sun.COM 			goto finish;
855*11767SAnurag.Maskey@Sun.COM 		err = nwam_set_prop_value((*ncuhp)->nwh_data,
856*11767SAnurag.Maskey@Sun.COM 		    NWAM_NCU_PROP_ACTIVATION_MODE, actval);
857*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(actval);
858*11767SAnurag.Maskey@Sun.COM 	}
859*11767SAnurag.Maskey@Sun.COM 
860*11767SAnurag.Maskey@Sun.COM finish:
861*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(typeval);
862*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(classval);
863*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(parentval);
864*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(enabledval);
865*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
866*11767SAnurag.Maskey@Sun.COM 		nwam_ncu_free(*ncuhp);
867*11767SAnurag.Maskey@Sun.COM 		*ncuhp = NULL;
868*11767SAnurag.Maskey@Sun.COM 	}
869*11767SAnurag.Maskey@Sun.COM 	return (err);
870*11767SAnurag.Maskey@Sun.COM }
871*11767SAnurag.Maskey@Sun.COM 
872*11767SAnurag.Maskey@Sun.COM nwam_error_t
873*11767SAnurag.Maskey@Sun.COM nwam_ncu_read(nwam_ncp_handle_t ncph, const char *name,
874*11767SAnurag.Maskey@Sun.COM     nwam_ncu_type_t type, uint64_t flags, nwam_ncu_handle_t *ncuhp)
875*11767SAnurag.Maskey@Sun.COM {
876*11767SAnurag.Maskey@Sun.COM 	char *ncpfile, *typedname;
877*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err, err_ip, err_link;
878*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh_ip, ncuh_link;
879*11767SAnurag.Maskey@Sun.COM 
880*11767SAnurag.Maskey@Sun.COM 	assert(ncph != NULL && name != NULL && ncuhp != NULL);
881*11767SAnurag.Maskey@Sun.COM 
882*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &ncpfile))
883*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
884*11767SAnurag.Maskey@Sun.COM 		return (err);
885*11767SAnurag.Maskey@Sun.COM 
886*11767SAnurag.Maskey@Sun.COM 	if (type == NWAM_NCU_TYPE_ANY) {
887*11767SAnurag.Maskey@Sun.COM 
888*11767SAnurag.Maskey@Sun.COM 		free(ncpfile);
889*11767SAnurag.Maskey@Sun.COM 
890*11767SAnurag.Maskey@Sun.COM 		/*
891*11767SAnurag.Maskey@Sun.COM 		 * If we get to this point, we have discovered that no
892*11767SAnurag.Maskey@Sun.COM 		 * NCU type is discernable from name or type arguments.
893*11767SAnurag.Maskey@Sun.COM 		 * Either exactly one NCU called name must exist of either
894*11767SAnurag.Maskey@Sun.COM 		 * type, or the operation should fail.
895*11767SAnurag.Maskey@Sun.COM 		 */
896*11767SAnurag.Maskey@Sun.COM 		err_ip = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_INTERFACE,
897*11767SAnurag.Maskey@Sun.COM 		    flags, &ncuh_ip);
898*11767SAnurag.Maskey@Sun.COM 		err_link = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK,
899*11767SAnurag.Maskey@Sun.COM 		    flags, &ncuh_link);
900*11767SAnurag.Maskey@Sun.COM 
901*11767SAnurag.Maskey@Sun.COM 		*ncuhp = NULL;
902*11767SAnurag.Maskey@Sun.COM 
903*11767SAnurag.Maskey@Sun.COM 		if (err_ip == NWAM_SUCCESS && err_link == NWAM_SUCCESS) {
904*11767SAnurag.Maskey@Sun.COM 			nwam_ncu_free(ncuh_ip);
905*11767SAnurag.Maskey@Sun.COM 			nwam_ncu_free(ncuh_link);
906*11767SAnurag.Maskey@Sun.COM 			err = NWAM_ENTITY_MULTIPLE_VALUES;
907*11767SAnurag.Maskey@Sun.COM 		} else if (err_ip != NWAM_SUCCESS && err_link != NWAM_SUCCESS) {
908*11767SAnurag.Maskey@Sun.COM 			err = NWAM_ENTITY_NOT_FOUND;
909*11767SAnurag.Maskey@Sun.COM 		} else {
910*11767SAnurag.Maskey@Sun.COM 			if (err_ip == NWAM_SUCCESS) {
911*11767SAnurag.Maskey@Sun.COM 				*ncuhp = ncuh_ip;
912*11767SAnurag.Maskey@Sun.COM 			} else {
913*11767SAnurag.Maskey@Sun.COM 				*ncuhp = ncuh_link;
914*11767SAnurag.Maskey@Sun.COM 			}
915*11767SAnurag.Maskey@Sun.COM 			err = NWAM_SUCCESS;
916*11767SAnurag.Maskey@Sun.COM 		}
917*11767SAnurag.Maskey@Sun.COM 
918*11767SAnurag.Maskey@Sun.COM 		return (err);
919*11767SAnurag.Maskey@Sun.COM 	}
920*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_name_to_typed_name(name, type, &typedname)) !=
921*11767SAnurag.Maskey@Sun.COM 	    NWAM_SUCCESS) {
922*11767SAnurag.Maskey@Sun.COM 		free(ncpfile);
923*11767SAnurag.Maskey@Sun.COM 		return (err);
924*11767SAnurag.Maskey@Sun.COM 	}
925*11767SAnurag.Maskey@Sun.COM 	err = nwam_read(NWAM_OBJECT_TYPE_NCU, ncpfile, typedname, flags, ncuhp);
926*11767SAnurag.Maskey@Sun.COM 
927*11767SAnurag.Maskey@Sun.COM 	free(typedname);
928*11767SAnurag.Maskey@Sun.COM 	free(ncpfile);
929*11767SAnurag.Maskey@Sun.COM 
930*11767SAnurag.Maskey@Sun.COM 	return (err);
931*11767SAnurag.Maskey@Sun.COM }
932*11767SAnurag.Maskey@Sun.COM 
933*11767SAnurag.Maskey@Sun.COM nwam_error_t
934*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_name(nwam_ncu_handle_t ncuh, char **namep)
935*11767SAnurag.Maskey@Sun.COM {
936*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t type;
937*11767SAnurag.Maskey@Sun.COM 
938*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && namep != NULL);
939*11767SAnurag.Maskey@Sun.COM 
940*11767SAnurag.Maskey@Sun.COM 	return (nwam_ncu_internal_name_to_name(ncuh->nwh_name, &type, namep));
941*11767SAnurag.Maskey@Sun.COM }
942*11767SAnurag.Maskey@Sun.COM 
943*11767SAnurag.Maskey@Sun.COM nwam_error_t
944*11767SAnurag.Maskey@Sun.COM nwam_ncu_name_to_typed_name(const char *name, nwam_ncu_type_t type,
945*11767SAnurag.Maskey@Sun.COM     char **typednamep)
946*11767SAnurag.Maskey@Sun.COM {
947*11767SAnurag.Maskey@Sun.COM 	char *prefixstr;
948*11767SAnurag.Maskey@Sun.COM 	size_t typednamesz;
949*11767SAnurag.Maskey@Sun.COM 
950*11767SAnurag.Maskey@Sun.COM 	assert(name != NULL && typednamep != NULL);
951*11767SAnurag.Maskey@Sun.COM 
952*11767SAnurag.Maskey@Sun.COM 	switch (type) {
953*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_INTERFACE:
954*11767SAnurag.Maskey@Sun.COM 		prefixstr = NWAM_NCU_INTERFACE_NAME_PRE;
955*11767SAnurag.Maskey@Sun.COM 		break;
956*11767SAnurag.Maskey@Sun.COM 	case NWAM_NCU_TYPE_LINK:
957*11767SAnurag.Maskey@Sun.COM 		prefixstr = NWAM_NCU_LINK_NAME_PRE;
958*11767SAnurag.Maskey@Sun.COM 		break;
959*11767SAnurag.Maskey@Sun.COM 	default:
960*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
961*11767SAnurag.Maskey@Sun.COM 	}
962*11767SAnurag.Maskey@Sun.COM 	typednamesz = strlen(name) + strlen(prefixstr) + 1;
963*11767SAnurag.Maskey@Sun.COM 	if ((*typednamep = malloc(typednamesz)) == NULL)
964*11767SAnurag.Maskey@Sun.COM 		return (NWAM_NO_MEMORY);
965*11767SAnurag.Maskey@Sun.COM 
966*11767SAnurag.Maskey@Sun.COM 	/* Name may be already qualified by type */
967*11767SAnurag.Maskey@Sun.COM 	if (strncasecmp(prefixstr, name, strlen(prefixstr)) == 0) {
968*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(*typednamep, typednamesz, "%s", name);
969*11767SAnurag.Maskey@Sun.COM 	} else {
970*11767SAnurag.Maskey@Sun.COM 		(void) snprintf(*typednamep, typednamesz, "%s%s",
971*11767SAnurag.Maskey@Sun.COM 		    prefixstr, name);
972*11767SAnurag.Maskey@Sun.COM 	}
973*11767SAnurag.Maskey@Sun.COM 
974*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
975*11767SAnurag.Maskey@Sun.COM }
976*11767SAnurag.Maskey@Sun.COM 
977*11767SAnurag.Maskey@Sun.COM nwam_error_t
978*11767SAnurag.Maskey@Sun.COM nwam_ncu_typed_name_to_name(const char *typed_name, nwam_ncu_type_t *typep,
979*11767SAnurag.Maskey@Sun.COM     char **name)
980*11767SAnurag.Maskey@Sun.COM {
981*11767SAnurag.Maskey@Sun.COM 	return (nwam_ncu_internal_name_to_name(typed_name, typep, name));
982*11767SAnurag.Maskey@Sun.COM }
983*11767SAnurag.Maskey@Sun.COM 
984*11767SAnurag.Maskey@Sun.COM void
985*11767SAnurag.Maskey@Sun.COM nwam_ncu_free(nwam_ncu_handle_t ncuh)
986*11767SAnurag.Maskey@Sun.COM {
987*11767SAnurag.Maskey@Sun.COM 	nwam_free(ncuh);
988*11767SAnurag.Maskey@Sun.COM }
989*11767SAnurag.Maskey@Sun.COM 
990*11767SAnurag.Maskey@Sun.COM nwam_error_t
991*11767SAnurag.Maskey@Sun.COM nwam_ncu_copy(nwam_ncu_handle_t oldncuh, const char *newname,
992*11767SAnurag.Maskey@Sun.COM     nwam_ncu_handle_t *newncuhp)
993*11767SAnurag.Maskey@Sun.COM {
994*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
995*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_handle_t ncuh;
996*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
997*11767SAnurag.Maskey@Sun.COM 	nwam_value_t typeval;
998*11767SAnurag.Maskey@Sun.COM 	uint64_t type;
999*11767SAnurag.Maskey@Sun.COM 	char *typednewname;
1000*11767SAnurag.Maskey@Sun.COM 
1001*11767SAnurag.Maskey@Sun.COM 	assert(oldncuh != NULL && newname != NULL && newncuhp != NULL);
1002*11767SAnurag.Maskey@Sun.COM 
1003*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_get_prop_value(oldncuh, NWAM_NCU_PROP_TYPE,
1004*11767SAnurag.Maskey@Sun.COM 	    &typeval) != NWAM_SUCCESS) {
1005*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
1006*11767SAnurag.Maskey@Sun.COM 	}
1007*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS) {
1008*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(typeval);
1009*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
1010*11767SAnurag.Maskey@Sun.COM 	}
1011*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(typeval);
1012*11767SAnurag.Maskey@Sun.COM 
1013*11767SAnurag.Maskey@Sun.COM 	/* check if newname NCU already exists */
1014*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_ncp(oldncuh, &ncph)) != NWAM_SUCCESS)
1015*11767SAnurag.Maskey@Sun.COM 		return (err);
1016*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_read(ncph, newname, type, 0, &ncuh) == NWAM_SUCCESS) {
1017*11767SAnurag.Maskey@Sun.COM 		nwam_ncu_free(ncuh);
1018*11767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
1019*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_EXISTS);
1020*11767SAnurag.Maskey@Sun.COM 	}
1021*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
1022*11767SAnurag.Maskey@Sun.COM 
1023*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_name_to_typed_name(newname, type, &typednewname))
1024*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1025*11767SAnurag.Maskey@Sun.COM 		return (err);
1026*11767SAnurag.Maskey@Sun.COM 
1027*11767SAnurag.Maskey@Sun.COM 	err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, typednewname, newncuhp);
1028*11767SAnurag.Maskey@Sun.COM 	free(typednewname);
1029*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1030*11767SAnurag.Maskey@Sun.COM 		return (err);
1031*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_dup_object_list(oldncuh->nwh_data,
1032*11767SAnurag.Maskey@Sun.COM 	    &((*newncuhp)->nwh_data))) != NWAM_SUCCESS) {
1033*11767SAnurag.Maskey@Sun.COM 		free(*newncuhp);
1034*11767SAnurag.Maskey@Sun.COM 		*newncuhp = NULL;
1035*11767SAnurag.Maskey@Sun.COM 		return (err);
1036*11767SAnurag.Maskey@Sun.COM 	}
1037*11767SAnurag.Maskey@Sun.COM 
1038*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1039*11767SAnurag.Maskey@Sun.COM }
1040*11767SAnurag.Maskey@Sun.COM 
1041*11767SAnurag.Maskey@Sun.COM nwam_error_t
1042*11767SAnurag.Maskey@Sun.COM nwam_ncu_delete_prop(nwam_ncu_handle_t ncuh, const char *propname)
1043*11767SAnurag.Maskey@Sun.COM {
1044*11767SAnurag.Maskey@Sun.COM 	boolean_t ro_ncu, ro_prop;
1045*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1046*11767SAnurag.Maskey@Sun.COM 	void *olddata;
1047*11767SAnurag.Maskey@Sun.COM 
1048*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && propname != NULL);
1049*11767SAnurag.Maskey@Sun.COM 
1050*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_read_only(ncuh, &ro_ncu)) != NWAM_SUCCESS ||
1051*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_ncu_prop_read_only(propname, &ro_prop)) != NWAM_SUCCESS)
1052*11767SAnurag.Maskey@Sun.COM 		return (err);
1053*11767SAnurag.Maskey@Sun.COM 	if (ro_ncu || ro_prop)
1054*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_READ_ONLY);
1055*11767SAnurag.Maskey@Sun.COM 
1056*11767SAnurag.Maskey@Sun.COM 	/*
1057*11767SAnurag.Maskey@Sun.COM 	 * Duplicate data, remove property and validate. If validation
1058*11767SAnurag.Maskey@Sun.COM 	 * fails, revert to data duplicated prior to remove.
1059*11767SAnurag.Maskey@Sun.COM 	 */
1060*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_dup_object_list(ncuh->nwh_data, &olddata))
1061*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1062*11767SAnurag.Maskey@Sun.COM 		return (err);
1063*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_delete_prop(ncuh->nwh_data, propname))
1064*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
1065*11767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(ncuh->nwh_data);
1066*11767SAnurag.Maskey@Sun.COM 		ncuh->nwh_data = olddata;
1067*11767SAnurag.Maskey@Sun.COM 		return (err);
1068*11767SAnurag.Maskey@Sun.COM 	}
1069*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_validate(ncuh, NULL)) != NWAM_SUCCESS) {
1070*11767SAnurag.Maskey@Sun.COM 		nwam_free_object_list(ncuh->nwh_data);
1071*11767SAnurag.Maskey@Sun.COM 		ncuh->nwh_data = olddata;
1072*11767SAnurag.Maskey@Sun.COM 		return (err);
1073*11767SAnurag.Maskey@Sun.COM 	}
1074*11767SAnurag.Maskey@Sun.COM 	nwam_free_object_list(olddata);
1075*11767SAnurag.Maskey@Sun.COM 
1076*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1077*11767SAnurag.Maskey@Sun.COM }
1078*11767SAnurag.Maskey@Sun.COM 
1079*11767SAnurag.Maskey@Sun.COM nwam_error_t
1080*11767SAnurag.Maskey@Sun.COM nwam_ncu_set_prop_value(nwam_ncu_handle_t ncuh, const char *propname,
1081*11767SAnurag.Maskey@Sun.COM     nwam_value_t value)
1082*11767SAnurag.Maskey@Sun.COM {
1083*11767SAnurag.Maskey@Sun.COM 	boolean_t ro_ncu, ro_prop;
1084*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1085*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
1086*11767SAnurag.Maskey@Sun.COM 
1087*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && propname != NULL && value != NULL);
1088*11767SAnurag.Maskey@Sun.COM 
1089*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_read_only(ncuh, &ro_ncu)) != NWAM_SUCCESS ||
1090*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_ncu_prop_read_only(propname, &ro_prop)) != NWAM_SUCCESS)
1091*11767SAnurag.Maskey@Sun.COM 		return (err);
1092*11767SAnurag.Maskey@Sun.COM 	if (ro_ncu || ro_prop)
1093*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_READ_ONLY);
1094*11767SAnurag.Maskey@Sun.COM 
1095*11767SAnurag.Maskey@Sun.COM 	err = nwam_ncu_get_ncp(ncuh, &ncph);
1096*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS && err != NWAM_INVALID_ARG) {
1097*11767SAnurag.Maskey@Sun.COM 		/*
1098*11767SAnurag.Maskey@Sun.COM 		 * If "parent" property doesn't exist, NWAM_INVALID_ARG
1099*11767SAnurag.Maskey@Sun.COM 		 * is returned.  Allow the setting to continue.
1100*11767SAnurag.Maskey@Sun.COM 		 */
1101*11767SAnurag.Maskey@Sun.COM 		return (err);
1102*11767SAnurag.Maskey@Sun.COM 	}
1103*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
1104*11767SAnurag.Maskey@Sun.COM 
1105*11767SAnurag.Maskey@Sun.COM 	/* Need to ensure property, type and value are valid */
1106*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_validate_prop(ncuh, propname, value))
1107*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1108*11767SAnurag.Maskey@Sun.COM 		return (err);
1109*11767SAnurag.Maskey@Sun.COM 
1110*11767SAnurag.Maskey@Sun.COM 	return (nwam_set_prop_value(ncuh->nwh_data, propname, value));
1111*11767SAnurag.Maskey@Sun.COM }
1112*11767SAnurag.Maskey@Sun.COM 
1113*11767SAnurag.Maskey@Sun.COM nwam_error_t
1114*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_prop_value(nwam_ncu_handle_t ncuh, const char *propname,
1115*11767SAnurag.Maskey@Sun.COM     nwam_value_t *valuep)
1116*11767SAnurag.Maskey@Sun.COM {
1117*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && propname != NULL && valuep != NULL);
1118*11767SAnurag.Maskey@Sun.COM 
1119*11767SAnurag.Maskey@Sun.COM 	return (nwam_get_prop_value(ncuh->nwh_data, propname, valuep));
1120*11767SAnurag.Maskey@Sun.COM }
1121*11767SAnurag.Maskey@Sun.COM 
1122*11767SAnurag.Maskey@Sun.COM nwam_error_t
1123*11767SAnurag.Maskey@Sun.COM nwam_ncu_walk_props(nwam_ncu_handle_t ncuh,
1124*11767SAnurag.Maskey@Sun.COM     int (*cb)(const char *, nwam_value_t, void *),
1125*11767SAnurag.Maskey@Sun.COM     void *data, uint64_t flags, int *retp)
1126*11767SAnurag.Maskey@Sun.COM {
1127*11767SAnurag.Maskey@Sun.COM 	return (nwam_walk_props(ncuh, cb, data, flags, retp));
1128*11767SAnurag.Maskey@Sun.COM }
1129*11767SAnurag.Maskey@Sun.COM 
1130*11767SAnurag.Maskey@Sun.COM nwam_error_t
1131*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_ncp(nwam_ncu_handle_t ncuh, nwam_ncp_handle_t *ncphp)
1132*11767SAnurag.Maskey@Sun.COM {
1133*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1134*11767SAnurag.Maskey@Sun.COM 	char *parentname = NULL;
1135*11767SAnurag.Maskey@Sun.COM 
1136*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &parentname))
1137*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS ||
1138*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, parentname, ncphp))
1139*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
1140*11767SAnurag.Maskey@Sun.COM 		if (parentname != NULL)
1141*11767SAnurag.Maskey@Sun.COM 			free(parentname);
1142*11767SAnurag.Maskey@Sun.COM 		return (err);
1143*11767SAnurag.Maskey@Sun.COM 	}
1144*11767SAnurag.Maskey@Sun.COM 	free(parentname);
1145*11767SAnurag.Maskey@Sun.COM 
1146*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1147*11767SAnurag.Maskey@Sun.COM }
1148*11767SAnurag.Maskey@Sun.COM 
1149*11767SAnurag.Maskey@Sun.COM nwam_error_t
1150*11767SAnurag.Maskey@Sun.COM nwam_ncu_commit(nwam_ncu_handle_t ncuh, uint64_t flags)
1151*11767SAnurag.Maskey@Sun.COM {
1152*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1153*11767SAnurag.Maskey@Sun.COM 	boolean_t read_only;
1154*11767SAnurag.Maskey@Sun.COM 	char *ncpfile, *ncpname;
1155*11767SAnurag.Maskey@Sun.COM 
1156*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && ncuh->nwh_data != NULL);
1157*11767SAnurag.Maskey@Sun.COM 
1158*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1159*11767SAnurag.Maskey@Sun.COM 		return (err);
1160*11767SAnurag.Maskey@Sun.COM 	if (read_only)
1161*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_READ_ONLY);
1162*11767SAnurag.Maskey@Sun.COM 
1163*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_validate(ncuh, NULL)) != NWAM_SUCCESS ||
1164*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1165*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1166*11767SAnurag.Maskey@Sun.COM 		return (err);
1167*11767SAnurag.Maskey@Sun.COM 
1168*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(ncpname, &ncpfile)) != NWAM_SUCCESS) {
1169*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
1170*11767SAnurag.Maskey@Sun.COM 		return (err);
1171*11767SAnurag.Maskey@Sun.COM 	}
1172*11767SAnurag.Maskey@Sun.COM 
1173*11767SAnurag.Maskey@Sun.COM 	err = nwam_commit(ncpfile, ncuh, flags);
1174*11767SAnurag.Maskey@Sun.COM 
1175*11767SAnurag.Maskey@Sun.COM 	free(ncpname);
1176*11767SAnurag.Maskey@Sun.COM 	free(ncpfile);
1177*11767SAnurag.Maskey@Sun.COM 
1178*11767SAnurag.Maskey@Sun.COM 	return (err);
1179*11767SAnurag.Maskey@Sun.COM }
1180*11767SAnurag.Maskey@Sun.COM /* Get the NCU type */
1181*11767SAnurag.Maskey@Sun.COM nwam_error_t
1182*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_ncu_type(nwam_ncu_handle_t ncuh, nwam_ncu_type_t *typep)
1183*11767SAnurag.Maskey@Sun.COM {
1184*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1185*11767SAnurag.Maskey@Sun.COM 	nwam_value_t typeval;
1186*11767SAnurag.Maskey@Sun.COM 	uint64_t type;
1187*11767SAnurag.Maskey@Sun.COM 
1188*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval))
1189*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1190*11767SAnurag.Maskey@Sun.COM 		return (err);
1191*11767SAnurag.Maskey@Sun.COM 	err = nwam_value_get_uint64(typeval, &type);
1192*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(typeval);
1193*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1194*11767SAnurag.Maskey@Sun.COM 		return (err);
1195*11767SAnurag.Maskey@Sun.COM 
1196*11767SAnurag.Maskey@Sun.COM 	*typep = type;
1197*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1198*11767SAnurag.Maskey@Sun.COM }
1199*11767SAnurag.Maskey@Sun.COM 
1200*11767SAnurag.Maskey@Sun.COM /* Get the NCU class */
1201*11767SAnurag.Maskey@Sun.COM nwam_error_t
1202*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_ncu_class(nwam_ncu_handle_t ncuh, nwam_ncu_class_t *classp)
1203*11767SAnurag.Maskey@Sun.COM {
1204*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1205*11767SAnurag.Maskey@Sun.COM 	nwam_value_t classval;
1206*11767SAnurag.Maskey@Sun.COM 	uint64_t class;
1207*11767SAnurag.Maskey@Sun.COM 
1208*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS,
1209*11767SAnurag.Maskey@Sun.COM 	    &classval)) != NWAM_SUCCESS)
1210*11767SAnurag.Maskey@Sun.COM 		return (err);
1211*11767SAnurag.Maskey@Sun.COM 	err = nwam_value_get_uint64(classval, &class);
1212*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(classval);
1213*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1214*11767SAnurag.Maskey@Sun.COM 		return (err);
1215*11767SAnurag.Maskey@Sun.COM 
1216*11767SAnurag.Maskey@Sun.COM 	*classp = class;
1217*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1218*11767SAnurag.Maskey@Sun.COM }
1219*11767SAnurag.Maskey@Sun.COM 
1220*11767SAnurag.Maskey@Sun.COM /*
1221*11767SAnurag.Maskey@Sun.COM  * Determine if the NCU has manual activation-mode or not.
1222*11767SAnurag.Maskey@Sun.COM  */
1223*11767SAnurag.Maskey@Sun.COM nwam_error_t
1224*11767SAnurag.Maskey@Sun.COM nwam_ncu_is_manual(nwam_ncu_handle_t ncuh, boolean_t *manualp)
1225*11767SAnurag.Maskey@Sun.COM {
1226*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1227*11767SAnurag.Maskey@Sun.COM 	nwam_value_t actval;
1228*11767SAnurag.Maskey@Sun.COM 	uint64_t activation;
1229*11767SAnurag.Maskey@Sun.COM 
1230*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL);
1231*11767SAnurag.Maskey@Sun.COM 
1232*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ACTIVATION_MODE,
1233*11767SAnurag.Maskey@Sun.COM 	    &actval)) != NWAM_SUCCESS)
1234*11767SAnurag.Maskey@Sun.COM 		return (err);
1235*11767SAnurag.Maskey@Sun.COM 	err = nwam_value_get_uint64(actval, &activation);
1236*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(actval);
1237*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1238*11767SAnurag.Maskey@Sun.COM 		return (err);
1239*11767SAnurag.Maskey@Sun.COM 
1240*11767SAnurag.Maskey@Sun.COM 	if (activation == NWAM_ACTIVATION_MODE_MANUAL)
1241*11767SAnurag.Maskey@Sun.COM 		*manualp = B_TRUE;
1242*11767SAnurag.Maskey@Sun.COM 	else
1243*11767SAnurag.Maskey@Sun.COM 		*manualp = B_FALSE;
1244*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1245*11767SAnurag.Maskey@Sun.COM }
1246*11767SAnurag.Maskey@Sun.COM 
1247*11767SAnurag.Maskey@Sun.COM /* Determine if NCU is enabled or not */
1248*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1249*11767SAnurag.Maskey@Sun.COM nwam_ncu_is_enabled(nwam_ncu_handle_t ncuh, boolean_t *enabledp)
1250*11767SAnurag.Maskey@Sun.COM {
1251*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1252*11767SAnurag.Maskey@Sun.COM 	nwam_value_t enabledval;
1253*11767SAnurag.Maskey@Sun.COM 
1254*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL);
1255*11767SAnurag.Maskey@Sun.COM 
1256*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ENABLED,
1257*11767SAnurag.Maskey@Sun.COM 	    &enabledval)) != NWAM_SUCCESS)
1258*11767SAnurag.Maskey@Sun.COM 		return (err);
1259*11767SAnurag.Maskey@Sun.COM 	err = nwam_value_get_boolean(enabledval, enabledp);
1260*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(enabledval);
1261*11767SAnurag.Maskey@Sun.COM 	return (err);
1262*11767SAnurag.Maskey@Sun.COM }
1263*11767SAnurag.Maskey@Sun.COM 
1264*11767SAnurag.Maskey@Sun.COM /* Update the enabled property */
1265*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1266*11767SAnurag.Maskey@Sun.COM nwam_ncu_update_enabled(nwam_ncu_handle_t ncuh, boolean_t enabled)
1267*11767SAnurag.Maskey@Sun.COM {
1268*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1269*11767SAnurag.Maskey@Sun.COM 	nwam_value_t enabledval;
1270*11767SAnurag.Maskey@Sun.COM 
1271*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_value_create_boolean(enabled, &enabledval))
1272*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1273*11767SAnurag.Maskey@Sun.COM 		return (err);
1274*11767SAnurag.Maskey@Sun.COM 	err = nwam_set_prop_value(ncuh->nwh_data, NWAM_NCU_PROP_ENABLED,
1275*11767SAnurag.Maskey@Sun.COM 	    enabledval);
1276*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(enabledval);
1277*11767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS)
1278*11767SAnurag.Maskey@Sun.COM 		return (err);
1279*11767SAnurag.Maskey@Sun.COM 	return (nwam_ncu_commit(ncuh, NWAM_FLAG_ENTITY_ENABLE));
1280*11767SAnurag.Maskey@Sun.COM }
1281*11767SAnurag.Maskey@Sun.COM 
1282*11767SAnurag.Maskey@Sun.COM /*
1283*11767SAnurag.Maskey@Sun.COM  * Make ncu active; fails if the NCU's parent NCP is not active.
1284*11767SAnurag.Maskey@Sun.COM  */
1285*11767SAnurag.Maskey@Sun.COM nwam_error_t
1286*11767SAnurag.Maskey@Sun.COM nwam_ncu_enable(nwam_ncu_handle_t ncuh)
1287*11767SAnurag.Maskey@Sun.COM {
1288*11767SAnurag.Maskey@Sun.COM 	char *ncpname = NULL;
1289*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1290*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t type;
1291*11767SAnurag.Maskey@Sun.COM 	boolean_t read_only, enabled, manual;
1292*11767SAnurag.Maskey@Sun.COM 
1293*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL);
1294*11767SAnurag.Maskey@Sun.COM 
1295*11767SAnurag.Maskey@Sun.COM 	/* Don't allow NCUs of Automatic NCP to be enabled */
1296*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1297*11767SAnurag.Maskey@Sun.COM 		return (err);
1298*11767SAnurag.Maskey@Sun.COM 	if (read_only)
1299*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_MANUAL);
1300*11767SAnurag.Maskey@Sun.COM 
1301*11767SAnurag.Maskey@Sun.COM 	/* Link NCUs with manual activation-mode or IP NCUs can be enabled */
1302*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_ncu_type(ncuh, &type)) != NWAM_SUCCESS)
1303*11767SAnurag.Maskey@Sun.COM 		return (err);
1304*11767SAnurag.Maskey@Sun.COM 
1305*11767SAnurag.Maskey@Sun.COM 	if (type == NWAM_NCU_TYPE_LINK) {
1306*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_ncu_is_manual(ncuh, &manual)) != NWAM_SUCCESS)
1307*11767SAnurag.Maskey@Sun.COM 			return (err);
1308*11767SAnurag.Maskey@Sun.COM 		if (!manual)
1309*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_MANUAL);
1310*11767SAnurag.Maskey@Sun.COM 	}
1311*11767SAnurag.Maskey@Sun.COM 
1312*11767SAnurag.Maskey@Sun.COM 	/* Make sure NCU is not enabled */
1313*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_is_enabled(ncuh, &enabled)) != NWAM_SUCCESS ||
1314*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1315*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1316*11767SAnurag.Maskey@Sun.COM 		return (err);
1317*11767SAnurag.Maskey@Sun.COM 
1318*11767SAnurag.Maskey@Sun.COM 	if (enabled) {
1319*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
1320*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1321*11767SAnurag.Maskey@Sun.COM 	}
1322*11767SAnurag.Maskey@Sun.COM 
1323*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_update_enabled(ncuh, B_TRUE)) != NWAM_SUCCESS) {
1324*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
1325*11767SAnurag.Maskey@Sun.COM 		return (err);
1326*11767SAnurag.Maskey@Sun.COM 	}
1327*11767SAnurag.Maskey@Sun.COM 
1328*11767SAnurag.Maskey@Sun.COM 	err = nwam_enable(ncpname, ncuh);
1329*11767SAnurag.Maskey@Sun.COM 	free(ncpname);
1330*11767SAnurag.Maskey@Sun.COM 
1331*11767SAnurag.Maskey@Sun.COM 	/* nwamd may not be running, that's okay. */
1332*11767SAnurag.Maskey@Sun.COM 	if (err == NWAM_ERROR_BIND)
1333*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1334*11767SAnurag.Maskey@Sun.COM 	else
1335*11767SAnurag.Maskey@Sun.COM 		return (err);
1336*11767SAnurag.Maskey@Sun.COM }
1337*11767SAnurag.Maskey@Sun.COM 
1338*11767SAnurag.Maskey@Sun.COM /*
1339*11767SAnurag.Maskey@Sun.COM  * Disable ncu; fails if the NCU's parent NCP is not active, or if the
1340*11767SAnurag.Maskey@Sun.COM  * NCU is not currently active.
1341*11767SAnurag.Maskey@Sun.COM  */
1342*11767SAnurag.Maskey@Sun.COM nwam_error_t
1343*11767SAnurag.Maskey@Sun.COM nwam_ncu_disable(nwam_ncu_handle_t ncuh)
1344*11767SAnurag.Maskey@Sun.COM {
1345*11767SAnurag.Maskey@Sun.COM 	char *ncpname = NULL;
1346*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1347*11767SAnurag.Maskey@Sun.COM 	nwam_ncu_type_t type;
1348*11767SAnurag.Maskey@Sun.COM 	boolean_t read_only, enabled, manual;
1349*11767SAnurag.Maskey@Sun.COM 
1350*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL);
1351*11767SAnurag.Maskey@Sun.COM 
1352*11767SAnurag.Maskey@Sun.COM 	/* Don't allow NCUs of Automatic NCP to be disabled */
1353*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1354*11767SAnurag.Maskey@Sun.COM 		return (err);
1355*11767SAnurag.Maskey@Sun.COM 	if (read_only)
1356*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_MANUAL);
1357*11767SAnurag.Maskey@Sun.COM 
1358*11767SAnurag.Maskey@Sun.COM 	/* Link NCUs with manual activation-mode or IP NCUs can be disabled */
1359*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_ncu_type(ncuh, &type)) != NWAM_SUCCESS)
1360*11767SAnurag.Maskey@Sun.COM 		return (err);
1361*11767SAnurag.Maskey@Sun.COM 
1362*11767SAnurag.Maskey@Sun.COM 	if (type == NWAM_NCU_TYPE_LINK) {
1363*11767SAnurag.Maskey@Sun.COM 		if ((err = nwam_ncu_is_manual(ncuh, &manual)) != NWAM_SUCCESS)
1364*11767SAnurag.Maskey@Sun.COM 			return (err);
1365*11767SAnurag.Maskey@Sun.COM 		if (!manual)
1366*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_MANUAL);
1367*11767SAnurag.Maskey@Sun.COM 	}
1368*11767SAnurag.Maskey@Sun.COM 
1369*11767SAnurag.Maskey@Sun.COM 	/* Make sure NCU is enabled */
1370*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_is_enabled(ncuh, &enabled)) != NWAM_SUCCESS ||
1371*11767SAnurag.Maskey@Sun.COM 	    (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1372*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1373*11767SAnurag.Maskey@Sun.COM 		return (err);
1374*11767SAnurag.Maskey@Sun.COM 
1375*11767SAnurag.Maskey@Sun.COM 	if (!enabled) {
1376*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
1377*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1378*11767SAnurag.Maskey@Sun.COM 	}
1379*11767SAnurag.Maskey@Sun.COM 
1380*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_update_enabled(ncuh, B_FALSE)) != NWAM_SUCCESS) {
1381*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
1382*11767SAnurag.Maskey@Sun.COM 		return (err);
1383*11767SAnurag.Maskey@Sun.COM 	}
1384*11767SAnurag.Maskey@Sun.COM 
1385*11767SAnurag.Maskey@Sun.COM 	err = nwam_disable(ncpname, ncuh);
1386*11767SAnurag.Maskey@Sun.COM 	free(ncpname);
1387*11767SAnurag.Maskey@Sun.COM 
1388*11767SAnurag.Maskey@Sun.COM 	/* nwamd may not be running, that's okay. */
1389*11767SAnurag.Maskey@Sun.COM 	if (err == NWAM_ERROR_BIND)
1390*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1391*11767SAnurag.Maskey@Sun.COM 	else
1392*11767SAnurag.Maskey@Sun.COM 		return (err);
1393*11767SAnurag.Maskey@Sun.COM }
1394*11767SAnurag.Maskey@Sun.COM 
1395*11767SAnurag.Maskey@Sun.COM nwam_error_t
1396*11767SAnurag.Maskey@Sun.COM nwam_ncu_destroy(nwam_ncu_handle_t ncuh, uint64_t flags)
1397*11767SAnurag.Maskey@Sun.COM {
1398*11767SAnurag.Maskey@Sun.COM 	char *ncpname, *ncpfile;
1399*11767SAnurag.Maskey@Sun.COM 	boolean_t read_only;
1400*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1401*11767SAnurag.Maskey@Sun.COM 
1402*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL);
1403*11767SAnurag.Maskey@Sun.COM 
1404*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1405*11767SAnurag.Maskey@Sun.COM 		return (err);
1406*11767SAnurag.Maskey@Sun.COM 	if (read_only)
1407*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_DESTROYABLE);
1408*11767SAnurag.Maskey@Sun.COM 
1409*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1410*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1411*11767SAnurag.Maskey@Sun.COM 		return (err);
1412*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncp_name_to_file(ncpname, &ncpfile))
1413*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
1414*11767SAnurag.Maskey@Sun.COM 		free(ncpname);
1415*11767SAnurag.Maskey@Sun.COM 		return (err);
1416*11767SAnurag.Maskey@Sun.COM 	}
1417*11767SAnurag.Maskey@Sun.COM 
1418*11767SAnurag.Maskey@Sun.COM 	err = nwam_destroy(ncpfile, ncuh, flags);
1419*11767SAnurag.Maskey@Sun.COM 
1420*11767SAnurag.Maskey@Sun.COM 	free(ncpname);
1421*11767SAnurag.Maskey@Sun.COM 	free(ncpfile);
1422*11767SAnurag.Maskey@Sun.COM 
1423*11767SAnurag.Maskey@Sun.COM 	return (err);
1424*11767SAnurag.Maskey@Sun.COM }
1425*11767SAnurag.Maskey@Sun.COM 
1426*11767SAnurag.Maskey@Sun.COM nwam_error_t
1427*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_prop_description(const char *propname, const char **descriptionp)
1428*11767SAnurag.Maskey@Sun.COM {
1429*11767SAnurag.Maskey@Sun.COM 	return (nwam_get_prop_description(ncu_prop_table, propname,
1430*11767SAnurag.Maskey@Sun.COM 	    descriptionp));
1431*11767SAnurag.Maskey@Sun.COM }
1432*11767SAnurag.Maskey@Sun.COM 
1433*11767SAnurag.Maskey@Sun.COM /* Get expected property data type */
1434*11767SAnurag.Maskey@Sun.COM nwam_error_t
1435*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_prop_type(const char *propname, nwam_value_type_t *typep)
1436*11767SAnurag.Maskey@Sun.COM {
1437*11767SAnurag.Maskey@Sun.COM 	return (nwam_get_prop_type(ncu_prop_table, propname, typep));
1438*11767SAnurag.Maskey@Sun.COM }
1439*11767SAnurag.Maskey@Sun.COM 
1440*11767SAnurag.Maskey@Sun.COM nwam_error_t
1441*11767SAnurag.Maskey@Sun.COM nwam_ncu_prop_read_only(const char *propname, boolean_t *readp)
1442*11767SAnurag.Maskey@Sun.COM {
1443*11767SAnurag.Maskey@Sun.COM 	if ((*readp = NWAM_NCU_PROP_SETONCE(propname)) == B_TRUE)
1444*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1445*11767SAnurag.Maskey@Sun.COM 
1446*11767SAnurag.Maskey@Sun.COM 	return (nwam_prop_read_only(ncu_prop_table, propname, readp));
1447*11767SAnurag.Maskey@Sun.COM }
1448*11767SAnurag.Maskey@Sun.COM 
1449*11767SAnurag.Maskey@Sun.COM nwam_error_t
1450*11767SAnurag.Maskey@Sun.COM nwam_ncu_prop_multivalued(const char *propname, boolean_t *multip)
1451*11767SAnurag.Maskey@Sun.COM {
1452*11767SAnurag.Maskey@Sun.COM 	return (nwam_prop_multivalued(ncu_prop_table, propname, multip));
1453*11767SAnurag.Maskey@Sun.COM }
1454*11767SAnurag.Maskey@Sun.COM 
1455*11767SAnurag.Maskey@Sun.COM /*
1456*11767SAnurag.Maskey@Sun.COM  * Ensure that the properties in the ncu, determined by that ncu's
1457*11767SAnurag.Maskey@Sun.COM  * type and class, belong there.
1458*11767SAnurag.Maskey@Sun.COM  */
1459*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1460*11767SAnurag.Maskey@Sun.COM nwam_ncu_validate_prop_membership(nwam_ncu_handle_t ncuh, const char *propname)
1461*11767SAnurag.Maskey@Sun.COM {
1462*11767SAnurag.Maskey@Sun.COM 	struct nwam_prop_table_entry *pte;
1463*11767SAnurag.Maskey@Sun.COM 	nwam_value_t typeval, classval;
1464*11767SAnurag.Maskey@Sun.COM 	uint64_t type, class;
1465*11767SAnurag.Maskey@Sun.COM 	uint64_t typeflags = 0, classflags = 0;
1466*11767SAnurag.Maskey@Sun.COM 
1467*11767SAnurag.Maskey@Sun.COM 	/* Get type/class from ncu */
1468*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval)
1469*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1470*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
1471*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS) {
1472*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(typeval);
1473*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
1474*11767SAnurag.Maskey@Sun.COM 	}
1475*11767SAnurag.Maskey@Sun.COM 	typeflags = nwam_ncu_type_to_flag((nwam_ncu_type_t)type);
1476*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(typeval);
1477*11767SAnurag.Maskey@Sun.COM 
1478*11767SAnurag.Maskey@Sun.COM 	if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS, &classval)
1479*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1480*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
1481*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(classval, &class) != NWAM_SUCCESS) {
1482*11767SAnurag.Maskey@Sun.COM 		nwam_value_free(classval);
1483*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
1484*11767SAnurag.Maskey@Sun.COM 	}
1485*11767SAnurag.Maskey@Sun.COM 	classflags = nwam_ncu_class_to_flag((nwam_ncu_class_t)class);
1486*11767SAnurag.Maskey@Sun.COM 	nwam_value_free(classval);
1487*11767SAnurag.Maskey@Sun.COM 
1488*11767SAnurag.Maskey@Sun.COM 	if ((pte = nwam_get_prop_table_entry(ncu_prop_table, propname)) == NULL)
1489*11767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
1490*11767SAnurag.Maskey@Sun.COM 
1491*11767SAnurag.Maskey@Sun.COM 	if (typeflags & pte->prop_type_membership &&
1492*11767SAnurag.Maskey@Sun.COM 	    classflags & pte->prop_class_membership) {
1493*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1494*11767SAnurag.Maskey@Sun.COM 	} else {
1495*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_MEMBER);
1496*11767SAnurag.Maskey@Sun.COM 	}
1497*11767SAnurag.Maskey@Sun.COM }
1498*11767SAnurag.Maskey@Sun.COM 
1499*11767SAnurag.Maskey@Sun.COM /* Validate property's ncu membership and type, number and range of values */
1500*11767SAnurag.Maskey@Sun.COM nwam_error_t
1501*11767SAnurag.Maskey@Sun.COM nwam_ncu_validate_prop(nwam_ncu_handle_t ncuh, const char *propname,
1502*11767SAnurag.Maskey@Sun.COM     nwam_value_t value)
1503*11767SAnurag.Maskey@Sun.COM {
1504*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1505*11767SAnurag.Maskey@Sun.COM 
1506*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL && propname != NULL);
1507*11767SAnurag.Maskey@Sun.COM 
1508*11767SAnurag.Maskey@Sun.COM 	/* First, determine if this property is valid for this ncu */
1509*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_validate_prop_membership(ncuh, propname))
1510*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1511*11767SAnurag.Maskey@Sun.COM 		return (err);
1512*11767SAnurag.Maskey@Sun.COM 
1513*11767SAnurag.Maskey@Sun.COM 	return (nwam_validate_prop(ncu_prop_table, ncuh, propname, value));
1514*11767SAnurag.Maskey@Sun.COM }
1515*11767SAnurag.Maskey@Sun.COM 
1516*11767SAnurag.Maskey@Sun.COM /* Property-specific value validation functions follow */
1517*11767SAnurag.Maskey@Sun.COM 
1518*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1519*11767SAnurag.Maskey@Sun.COM valid_type(nwam_value_t value)
1520*11767SAnurag.Maskey@Sun.COM {
1521*11767SAnurag.Maskey@Sun.COM 	uint64_t type;
1522*11767SAnurag.Maskey@Sun.COM 
1523*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(value, &type) != NWAM_SUCCESS ||
1524*11767SAnurag.Maskey@Sun.COM 	    type > NWAM_NCU_TYPE_INTERFACE)
1525*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1526*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1527*11767SAnurag.Maskey@Sun.COM }
1528*11767SAnurag.Maskey@Sun.COM 
1529*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1530*11767SAnurag.Maskey@Sun.COM valid_class(nwam_value_t value)
1531*11767SAnurag.Maskey@Sun.COM {
1532*11767SAnurag.Maskey@Sun.COM 	uint64_t class;
1533*11767SAnurag.Maskey@Sun.COM 
1534*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(value, &class) != NWAM_SUCCESS ||
1535*11767SAnurag.Maskey@Sun.COM 	    class > NWAM_NCU_CLASS_IP)
1536*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1537*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1538*11767SAnurag.Maskey@Sun.COM }
1539*11767SAnurag.Maskey@Sun.COM 
1540*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1541*11767SAnurag.Maskey@Sun.COM valid_ncp(nwam_value_t value)
1542*11767SAnurag.Maskey@Sun.COM {
1543*11767SAnurag.Maskey@Sun.COM 	char *ncp;
1544*11767SAnurag.Maskey@Sun.COM 
1545*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_string(value, &ncp) != NWAM_SUCCESS)
1546*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1547*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1548*11767SAnurag.Maskey@Sun.COM }
1549*11767SAnurag.Maskey@Sun.COM 
1550*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1551*11767SAnurag.Maskey@Sun.COM valid_priority_mode(nwam_value_t value)
1552*11767SAnurag.Maskey@Sun.COM {
1553*11767SAnurag.Maskey@Sun.COM 	uint64_t priority_mode;
1554*11767SAnurag.Maskey@Sun.COM 
1555*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(value, &priority_mode) != NWAM_SUCCESS ||
1556*11767SAnurag.Maskey@Sun.COM 	    priority_mode > NWAM_PRIORITY_MODE_ALL)
1557*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1558*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1559*11767SAnurag.Maskey@Sun.COM }
1560*11767SAnurag.Maskey@Sun.COM 
1561*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1562*11767SAnurag.Maskey@Sun.COM valid_ncu_activation_mode(nwam_value_t value)
1563*11767SAnurag.Maskey@Sun.COM {
1564*11767SAnurag.Maskey@Sun.COM 	uint64_t activation_mode;
1565*11767SAnurag.Maskey@Sun.COM 
1566*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64(value, &activation_mode) != NWAM_SUCCESS)
1567*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1568*11767SAnurag.Maskey@Sun.COM 
1569*11767SAnurag.Maskey@Sun.COM 	switch (activation_mode) {
1570*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTIVATION_MODE_MANUAL:
1571*11767SAnurag.Maskey@Sun.COM 	case NWAM_ACTIVATION_MODE_PRIORITIZED:
1572*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1573*11767SAnurag.Maskey@Sun.COM 	}
1574*11767SAnurag.Maskey@Sun.COM 	return (NWAM_ENTITY_INVALID_VALUE);
1575*11767SAnurag.Maskey@Sun.COM }
1576*11767SAnurag.Maskey@Sun.COM 
1577*11767SAnurag.Maskey@Sun.COM /* ARGSUSED0 */
1578*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1579*11767SAnurag.Maskey@Sun.COM valid_link_autopush(nwam_value_t value)
1580*11767SAnurag.Maskey@Sun.COM {
1581*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1582*11767SAnurag.Maskey@Sun.COM }
1583*11767SAnurag.Maskey@Sun.COM 
1584*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1585*11767SAnurag.Maskey@Sun.COM valid_ip_version(nwam_value_t value)
1586*11767SAnurag.Maskey@Sun.COM {
1587*11767SAnurag.Maskey@Sun.COM 	uint64_t *versions;
1588*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
1589*11767SAnurag.Maskey@Sun.COM 
1590*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64_array(value, &versions, &numvalues)
1591*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1592*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1593*11767SAnurag.Maskey@Sun.COM 
1594*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
1595*11767SAnurag.Maskey@Sun.COM 		if (versions[i] != IPV4_VERSION &&
1596*11767SAnurag.Maskey@Sun.COM 		    versions[i] != IPV6_VERSION)
1597*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1598*11767SAnurag.Maskey@Sun.COM 	}
1599*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1600*11767SAnurag.Maskey@Sun.COM }
1601*11767SAnurag.Maskey@Sun.COM 
1602*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1603*11767SAnurag.Maskey@Sun.COM valid_addrsrc_v4(nwam_value_t value)
1604*11767SAnurag.Maskey@Sun.COM {
1605*11767SAnurag.Maskey@Sun.COM 	uint64_t *addrsrc;
1606*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
1607*11767SAnurag.Maskey@Sun.COM 
1608*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64_array(value, &addrsrc, &numvalues)
1609*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1610*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1611*11767SAnurag.Maskey@Sun.COM 
1612*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
1613*11767SAnurag.Maskey@Sun.COM 		if (addrsrc[i] != NWAM_ADDRSRC_DHCP &&
1614*11767SAnurag.Maskey@Sun.COM 		    addrsrc[i] != NWAM_ADDRSRC_STATIC)
1615*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
1616*11767SAnurag.Maskey@Sun.COM 	}
1617*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1618*11767SAnurag.Maskey@Sun.COM }
1619*11767SAnurag.Maskey@Sun.COM 
1620*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1621*11767SAnurag.Maskey@Sun.COM valid_addrsrc_v6(nwam_value_t value)
1622*11767SAnurag.Maskey@Sun.COM {
1623*11767SAnurag.Maskey@Sun.COM 	uint64_t *addrsrc;
1624*11767SAnurag.Maskey@Sun.COM 	uint_t i, numvalues;
1625*11767SAnurag.Maskey@Sun.COM 	boolean_t dhcp_found = B_FALSE, autoconf_found = B_FALSE;
1626*11767SAnurag.Maskey@Sun.COM 
1627*11767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_uint64_array(value, &addrsrc, &numvalues)
1628*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1629*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1630*11767SAnurag.Maskey@Sun.COM 
1631*11767SAnurag.Maskey@Sun.COM 	for (i = 0; i < numvalues; i++) {
1632*11767SAnurag.Maskey@Sun.COM 		if (addrsrc[i] != NWAM_ADDRSRC_DHCP &&
1633*11767SAnurag.Maskey@Sun.COM 		    addrsrc[i] != NWAM_ADDRSRC_STATIC &&
1634*11767SAnurag.Maskey@Sun.COM 		    addrsrc[i] != NWAM_ADDRSRC_AUTOCONF)
1635*11767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_INVALID_VALUE);
1636*11767SAnurag.Maskey@Sun.COM 		if (addrsrc[i] == NWAM_ADDRSRC_DHCP)
1637*11767SAnurag.Maskey@Sun.COM 			dhcp_found = B_TRUE;
1638*11767SAnurag.Maskey@Sun.COM 		if (addrsrc[i] == NWAM_ADDRSRC_AUTOCONF)
1639*11767SAnurag.Maskey@Sun.COM 			autoconf_found = B_TRUE;
1640*11767SAnurag.Maskey@Sun.COM 	}
1641*11767SAnurag.Maskey@Sun.COM 	/*
1642*11767SAnurag.Maskey@Sun.COM 	 * DHCP and AUTOCONF need to be specified as v6 address sources
1643*11767SAnurag.Maskey@Sun.COM 	 * since there is no way to switch them off in NWAM at present.
1644*11767SAnurag.Maskey@Sun.COM 	 */
1645*11767SAnurag.Maskey@Sun.COM 	if (dhcp_found && autoconf_found)
1646*11767SAnurag.Maskey@Sun.COM 		return (NWAM_SUCCESS);
1647*11767SAnurag.Maskey@Sun.COM 	else
1648*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID_VALUE);
1649*11767SAnurag.Maskey@Sun.COM }
1650*11767SAnurag.Maskey@Sun.COM 
1651*11767SAnurag.Maskey@Sun.COM /* ARGSUSED0 */
1652*11767SAnurag.Maskey@Sun.COM static nwam_error_t
1653*11767SAnurag.Maskey@Sun.COM valid_link_mtu(nwam_value_t value)
1654*11767SAnurag.Maskey@Sun.COM {
1655*11767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
1656*11767SAnurag.Maskey@Sun.COM }
1657*11767SAnurag.Maskey@Sun.COM 
1658*11767SAnurag.Maskey@Sun.COM nwam_error_t
1659*11767SAnurag.Maskey@Sun.COM nwam_ncu_validate(nwam_ncu_handle_t ncuh, const char **errpropp)
1660*11767SAnurag.Maskey@Sun.COM {
1661*11767SAnurag.Maskey@Sun.COM 	return (nwam_validate(ncu_prop_table, ncuh, errpropp));
1662*11767SAnurag.Maskey@Sun.COM }
1663*11767SAnurag.Maskey@Sun.COM 
1664*11767SAnurag.Maskey@Sun.COM /*
1665*11767SAnurag.Maskey@Sun.COM  * Given the ncu type and ncu class, return the list of properties that needs
1666*11767SAnurag.Maskey@Sun.COM  * to be set. Note this list is a complete property list that includes both
1667*11767SAnurag.Maskey@Sun.COM  * the required ones and the optional ones. Caller needs to free prop_list.
1668*11767SAnurag.Maskey@Sun.COM  */
1669*11767SAnurag.Maskey@Sun.COM nwam_error_t
1670*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_default_proplist(nwam_ncu_type_t type, nwam_ncu_class_t class,
1671*11767SAnurag.Maskey@Sun.COM     const char ***prop_list, uint_t *numvalues)
1672*11767SAnurag.Maskey@Sun.COM {
1673*11767SAnurag.Maskey@Sun.COM 	uint64_t typeflags = nwam_ncu_type_to_flag(type);
1674*11767SAnurag.Maskey@Sun.COM 	uint64_t classflags = nwam_ncu_class_to_flag(class);
1675*11767SAnurag.Maskey@Sun.COM 
1676*11767SAnurag.Maskey@Sun.COM 	return (nwam_get_default_proplist(ncu_prop_table, typeflags,
1677*11767SAnurag.Maskey@Sun.COM 	    classflags, prop_list, numvalues));
1678*11767SAnurag.Maskey@Sun.COM }
1679*11767SAnurag.Maskey@Sun.COM 
1680*11767SAnurag.Maskey@Sun.COM nwam_error_t
1681*11767SAnurag.Maskey@Sun.COM nwam_ncp_get_state(nwam_ncp_handle_t ncph, nwam_state_t *statep,
1682*11767SAnurag.Maskey@Sun.COM     nwam_aux_state_t *auxp)
1683*11767SAnurag.Maskey@Sun.COM {
1684*11767SAnurag.Maskey@Sun.COM 	return (nwam_get_state(ncph->nwh_name, ncph, statep, auxp));
1685*11767SAnurag.Maskey@Sun.COM }
1686*11767SAnurag.Maskey@Sun.COM 
1687*11767SAnurag.Maskey@Sun.COM nwam_error_t
1688*11767SAnurag.Maskey@Sun.COM nwam_ncu_get_state(nwam_ncu_handle_t ncuh, nwam_state_t *statep,
1689*11767SAnurag.Maskey@Sun.COM     nwam_aux_state_t *auxp)
1690*11767SAnurag.Maskey@Sun.COM {
1691*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_handle_t ncph;
1692*11767SAnurag.Maskey@Sun.COM 	char *ncpname;
1693*11767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
1694*11767SAnurag.Maskey@Sun.COM 
1695*11767SAnurag.Maskey@Sun.COM 	assert(ncuh != NULL);
1696*11767SAnurag.Maskey@Sun.COM 
1697*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_ncp(ncuh, &ncph)) != NWAM_SUCCESS)
1698*11767SAnurag.Maskey@Sun.COM 		return (err);
1699*11767SAnurag.Maskey@Sun.COM 	if (!nwam_ncp_is_active(ncph)) {
1700*11767SAnurag.Maskey@Sun.COM 		nwam_ncp_free(ncph);
1701*11767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_INVALID);
1702*11767SAnurag.Maskey@Sun.COM 	}
1703*11767SAnurag.Maskey@Sun.COM 	nwam_ncp_free(ncph);
1704*11767SAnurag.Maskey@Sun.COM 
1705*11767SAnurag.Maskey@Sun.COM 	if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1706*11767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS)
1707*11767SAnurag.Maskey@Sun.COM 		return (err);
1708*11767SAnurag.Maskey@Sun.COM 
1709*11767SAnurag.Maskey@Sun.COM 	err = nwam_request_state(NWAM_OBJECT_TYPE_NCU, ncuh->nwh_name, ncpname,
1710*11767SAnurag.Maskey@Sun.COM 	    statep, auxp);
1711*11767SAnurag.Maskey@Sun.COM 	free(ncpname);
1712*11767SAnurag.Maskey@Sun.COM 	return (err);
1713*11767SAnurag.Maskey@Sun.COM }
1714*11767SAnurag.Maskey@Sun.COM 
1715*11767SAnurag.Maskey@Sun.COM nwam_error_t
1716*11767SAnurag.Maskey@Sun.COM nwam_ncp_get_active_priority_group(int64_t *priorityp)
1717*11767SAnurag.Maskey@Sun.COM {
1718*11767SAnurag.Maskey@Sun.COM 	return (nwam_request_active_priority_group(priorityp));
1719*11767SAnurag.Maskey@Sun.COM }
1720