xref: /titanic_51/usr/src/lib/libnwam/common/libnwam_ncp.c (revision 69b43529e65fb6eb0c88e6b7b42025e9bf025b8a)
16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
236ba597c5SAnurag S. Maskey  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
246ba597c5SAnurag S. Maskey  * Use is subject to license terms.
256ba597c5SAnurag S. Maskey  */
266ba597c5SAnurag S. Maskey 
276ba597c5SAnurag S. Maskey #include <assert.h>
286ba597c5SAnurag S. Maskey #include <ctype.h>
296ba597c5SAnurag S. Maskey #include <libgen.h>
306ba597c5SAnurag S. Maskey #include <netdb.h>
316ba597c5SAnurag S. Maskey #include <sys/param.h>
326ba597c5SAnurag S. Maskey #include <sys/types.h>
336ba597c5SAnurag S. Maskey #include <sys/stat.h>
346ba597c5SAnurag S. Maskey #include <sys/socket.h>
356ba597c5SAnurag S. Maskey #include <netinet/in.h>
366ba597c5SAnurag S. Maskey #include <arpa/inet.h>
376ba597c5SAnurag S. Maskey #include <stdio.h>
386ba597c5SAnurag S. Maskey #include <stdlib.h>
396ba597c5SAnurag S. Maskey #include <strings.h>
406ba597c5SAnurag S. Maskey #include <unistd.h>
416ba597c5SAnurag S. Maskey #include <libdladm.h>
426ba597c5SAnurag S. Maskey 
436ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
446ba597c5SAnurag S. Maskey #include <libnwam_priv.h>
456ba597c5SAnurag S. Maskey #include <libnwam.h>
466ba597c5SAnurag S. Maskey 
476ba597c5SAnurag S. Maskey /*
486ba597c5SAnurag S. Maskey  * Functions to support creating, modifying, destroying, querying the
496ba597c5SAnurag S. Maskey  * state of and changing the state of NCP (Network Configuration Profiles)
506ba597c5SAnurag S. Maskey  * and the NCUs (Network Configuration Units) that are contained in those
516ba597c5SAnurag S. Maskey  * NCP objects.  An NCP is simply a container for a set of NCUs which represent
526ba597c5SAnurag S. Maskey  * the datalink and interface configuration preferences for the system.
536ba597c5SAnurag S. Maskey  * An NCP can consist a set of prioritized link NCUs, e.g. wired links preferred
546ba597c5SAnurag S. Maskey  * over wireless, a set of manually enabled/diasbled NCUs, or a combination
556ba597c5SAnurag S. Maskey  * of both. Interface NCUs inherit activation from their underlying links,
566ba597c5SAnurag S. Maskey  * so if wired is preferred over wireless and a cable is plugged in,
576ba597c5SAnurag S. Maskey  * the wired link NCU will be active, as will the IP interface NCU above it.
586ba597c5SAnurag S. Maskey  */
596ba597c5SAnurag S. Maskey 
606ba597c5SAnurag S. Maskey /*
616ba597c5SAnurag S. Maskey  * The NCU property table is used to mapping property types to property name
626ba597c5SAnurag S. Maskey  * strings, their associated value types etc. The table is used for validation
636ba597c5SAnurag S. Maskey  * purposes, and for commit()ing and read()ing NCUs.
646ba597c5SAnurag S. Maskey  */
656ba597c5SAnurag S. Maskey 
666ba597c5SAnurag S. Maskey static nwam_error_t valid_type(nwam_value_t);
676ba597c5SAnurag S. Maskey static nwam_error_t valid_class(nwam_value_t);
686ba597c5SAnurag S. Maskey static nwam_error_t valid_ncp(nwam_value_t);
696ba597c5SAnurag S. Maskey static nwam_error_t valid_priority_mode(nwam_value_t);
706ba597c5SAnurag S. Maskey static nwam_error_t valid_ncu_activation_mode(nwam_value_t);
716ba597c5SAnurag S. Maskey static nwam_error_t valid_link_autopush(nwam_value_t);
726ba597c5SAnurag S. Maskey static nwam_error_t valid_link_mtu(nwam_value_t);
736ba597c5SAnurag S. Maskey static nwam_error_t valid_ip_version(nwam_value_t);
746ba597c5SAnurag S. Maskey static nwam_error_t valid_addrsrc_v4(nwam_value_t);
756ba597c5SAnurag S. Maskey static nwam_error_t valid_addrsrc_v6(nwam_value_t);
766ba597c5SAnurag S. Maskey 
776ba597c5SAnurag S. Maskey struct nwam_prop_table_entry ncu_prop_table_entries[] = {
786ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_TYPE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1, valid_type,
796ba597c5SAnurag S. Maskey 	    "specifies the NCU type - valid values are \'datalink\' and \'ip\'",
806ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
816ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_CLASS, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
826ba597c5SAnurag S. Maskey 	    valid_class,
836ba597c5SAnurag S. Maskey 	    "specifies the NCU class - valid values are "
846ba597c5SAnurag S. Maskey 	    "\'phys\' and \'ip\'",
856ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
866ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_PARENT_NCP, NWAM_VALUE_TYPE_STRING, B_FALSE, 1, 1,
876ba597c5SAnurag S. Maskey 	    valid_ncp,
886ba597c5SAnurag S. Maskey 	    "specifies the parent NCP name",
896ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
906ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_ACTIVATION_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
916ba597c5SAnurag S. Maskey 	    valid_ncu_activation_mode,
926ba597c5SAnurag S. Maskey 	    "specifies the NCU activation mode - valid values are:\n"
936ba597c5SAnurag S. Maskey 	    "\'prioritized\' and \'manual\'",
946ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
956ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_ENABLED, NWAM_VALUE_TYPE_BOOLEAN, B_TRUE, 0, 1,
966ba597c5SAnurag S. Maskey 	    nwam_valid_boolean,
976ba597c5SAnurag S. Maskey 	    "specifies if manual NCU is to be enabled",
986ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
996ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_PRIORITY_GROUP, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
1006ba597c5SAnurag S. Maskey 	    nwam_valid_uint64,
1016ba597c5SAnurag S. Maskey 	    "specifies the priority grouping of NCUs - lower values are "
1026ba597c5SAnurag S. Maskey 	    "prioritized, negative values are invalid",
1036ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
1046ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_PRIORITY_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
1056ba597c5SAnurag S. Maskey 	    valid_priority_mode,
1066ba597c5SAnurag S. Maskey 	    "specifies the mode of prioritization - valid values are:\n"
1076ba597c5SAnurag S. Maskey 	    "\'exclusive\', \'shared\' and \'all\'",
1086ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
1096ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_LINK_MAC_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
1106ba597c5SAnurag S. Maskey 	    nwam_valid_mac_addr,
1116ba597c5SAnurag S. Maskey 	    "specifies MAC address of form aa:bb:cc:dd:ee:ff for the link",
1126ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
1136ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_LINK_AUTOPUSH, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
1146ba597c5SAnurag S. Maskey 	    NWAM_MAX_NUM_VALUES, valid_link_autopush,
1156ba597c5SAnurag S. Maskey 	    "specifies modules to autopush on link",
1166ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
1176ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_LINK_MTU, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
1186ba597c5SAnurag S. Maskey 	    valid_link_mtu,
1196ba597c5SAnurag S. Maskey 	    "specifies MTU for link",
1206ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
1216ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IP_VERSION, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
1226ba597c5SAnurag S. Maskey 	    NWAM_MAX_NUM_VALUES, valid_ip_version,
1236ba597c5SAnurag S. Maskey 	    "specifies IP versions for IP NCU - valid values are:\n"
1246ba597c5SAnurag S. Maskey 	    "\'ipv4\' and \'ipv6\'",
1256ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
1266ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IPV4_ADDRSRC, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
1276ba597c5SAnurag S. Maskey 	    NWAM_MAX_NUM_VALUES, valid_addrsrc_v4,
1286ba597c5SAnurag S. Maskey 	    "specifies IPv4 address source(s) - valid values are:\n"
1296ba597c5SAnurag S. Maskey 	    "\'dhcp\' and \'static\'",
1306ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
1316ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IPV4_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
1326ba597c5SAnurag S. Maskey 	    NWAM_MAX_NUM_VALUES, nwam_valid_host_v4,
1336ba597c5SAnurag S. Maskey 	    "specifies static IPv4 host address(es)",
1346ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
1356ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
1366ba597c5SAnurag S. Maskey 	    1, nwam_valid_route_v4,
1376ba597c5SAnurag S. Maskey 	    "specifies per-interface default IPv4 route",
1386ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
1396ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IPV6_ADDRSRC, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
1406ba597c5SAnurag S. Maskey 	    NWAM_MAX_NUM_VALUES, valid_addrsrc_v6,
1416ba597c5SAnurag S. Maskey 	    "specifies IPv6 address source(s) - valid values are:\n"
1426ba597c5SAnurag S. Maskey 	    "\'dhcp\', \'autoconf\' and \'static\'.\n"
1436ba597c5SAnurag S. Maskey 	    "\'dhcp\' and \'autoconf\' are mandatory values.",
1446ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
1456ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IPV6_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
1466ba597c5SAnurag S. Maskey 	    NWAM_MAX_NUM_VALUES, nwam_valid_host_v6,
1476ba597c5SAnurag S. Maskey 	    "specifies static IPv6 host address(es)",
1486ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
1496ba597c5SAnurag S. Maskey 	{NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
1506ba597c5SAnurag S. Maskey 	    1, nwam_valid_route_v6,
1516ba597c5SAnurag S. Maskey 	    "specifies per-interface default IPv6 route",
1526ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE}
1536ba597c5SAnurag S. Maskey };
1546ba597c5SAnurag S. Maskey 
1556ba597c5SAnurag S. Maskey #define	NWAM_NUM_NCU_PROPS	(sizeof (ncu_prop_table_entries) / \
1566ba597c5SAnurag S. Maskey 				sizeof (*ncu_prop_table_entries))
1576ba597c5SAnurag S. Maskey 
1586ba597c5SAnurag S. Maskey struct nwam_prop_table ncu_prop_table =
1596ba597c5SAnurag S. Maskey 	{ NWAM_NUM_NCU_PROPS, ncu_prop_table_entries };
1606ba597c5SAnurag S. Maskey 
1616ba597c5SAnurag S. Maskey nwam_error_t
1626ba597c5SAnurag S. Maskey nwam_ncp_get_name(nwam_ncp_handle_t ncph, char **namep)
1636ba597c5SAnurag S. Maskey {
1646ba597c5SAnurag S. Maskey 	return (nwam_get_name(ncph, namep));
1656ba597c5SAnurag S. Maskey }
1666ba597c5SAnurag S. Maskey 
1676ba597c5SAnurag S. Maskey static nwam_error_t
1686ba597c5SAnurag S. Maskey nwam_ncp_name_to_file(const char *name, char **filename)
1696ba597c5SAnurag S. Maskey {
1706ba597c5SAnurag S. Maskey 	assert(name != NULL && filename != NULL);
1716ba597c5SAnurag S. Maskey 
1726ba597c5SAnurag S. Maskey 	if ((*filename = malloc(MAXPATHLEN)) == NULL)
1736ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
1746ba597c5SAnurag S. Maskey 
1756ba597c5SAnurag S. Maskey 	(void) snprintf(*filename, MAXPATHLEN, "%s%s%s%s", NWAM_CONF_DIR,
1766ba597c5SAnurag S. Maskey 	    NWAM_NCP_CONF_FILE_PRE, name, NWAM_NCP_CONF_FILE_SUF);
1776ba597c5SAnurag S. Maskey 
1786ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1796ba597c5SAnurag S. Maskey }
1806ba597c5SAnurag S. Maskey 
1816ba597c5SAnurag S. Maskey /* ARGSUSED1 */
1826ba597c5SAnurag S. Maskey nwam_error_t
1836ba597c5SAnurag S. Maskey nwam_ncp_create(const char *name, uint64_t flags, nwam_ncp_handle_t *ncphp)
1846ba597c5SAnurag S. Maskey {
1856ba597c5SAnurag S. Maskey 	nwam_error_t err;
1866ba597c5SAnurag S. Maskey 	char *ncpfile;
1876ba597c5SAnurag S. Maskey 
1886ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, name, ncphp))
1896ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
1906ba597c5SAnurag S. Maskey 		return (err);
1916ba597c5SAnurag S. Maskey 
1926ba597c5SAnurag S. Maskey 	/* Create empty container for NCUs */
1936ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(name, &ncpfile))
1946ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
1956ba597c5SAnurag S. Maskey 		nwam_free(*ncphp);
1966ba597c5SAnurag S. Maskey 		*ncphp = NULL;
1976ba597c5SAnurag S. Maskey 		return (err);
1986ba597c5SAnurag S. Maskey 	}
1996ba597c5SAnurag S. Maskey 
2006ba597c5SAnurag S. Maskey 	if ((err = nwam_commit(ncpfile, *ncphp, flags)) != NWAM_SUCCESS) {
2016ba597c5SAnurag S. Maskey 		nwam_free(*ncphp);
2026ba597c5SAnurag S. Maskey 		*ncphp = NULL;
2036ba597c5SAnurag S. Maskey 	}
2046ba597c5SAnurag S. Maskey 
2056ba597c5SAnurag S. Maskey 	free(ncpfile);
2066ba597c5SAnurag S. Maskey 
2076ba597c5SAnurag S. Maskey 	return (err);
2086ba597c5SAnurag S. Maskey }
2096ba597c5SAnurag S. Maskey 
2106ba597c5SAnurag S. Maskey /* Used by libnwam_files.c */
2116ba597c5SAnurag S. Maskey nwam_error_t
2126ba597c5SAnurag S. Maskey nwam_ncp_file_to_name(const char *path, char **name)
2136ba597c5SAnurag S. Maskey {
2146ba597c5SAnurag S. Maskey 	char path_copy[MAXPATHLEN];
2156ba597c5SAnurag S. Maskey 	char *filename, *suffix;
2166ba597c5SAnurag S. Maskey 
2176ba597c5SAnurag S. Maskey 	assert(path != NULL && name != NULL);
2186ba597c5SAnurag S. Maskey 
2196ba597c5SAnurag S. Maskey 	/* Make a copy as basename(3c) may modify string */
2206ba597c5SAnurag S. Maskey 	(void) strlcpy(path_copy, path, MAXPATHLEN);
2216ba597c5SAnurag S. Maskey 
2226ba597c5SAnurag S. Maskey 	if ((*name = malloc(NWAM_MAX_NAME_LEN)) == NULL)
2236ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
2246ba597c5SAnurag S. Maskey 
2256ba597c5SAnurag S. Maskey 	if ((filename = basename(path_copy)) == NULL) {
2266ba597c5SAnurag S. Maskey 		free(*name);
2276ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
2286ba597c5SAnurag S. Maskey 	}
2296ba597c5SAnurag S. Maskey 
2306ba597c5SAnurag S. Maskey 	/* Ensure filename begins/ends with right prefix/suffix */
2316ba597c5SAnurag S. Maskey 	if (sscanf(filename, NWAM_NCP_CONF_FILE_PRE "%256[^\n]s", *name) < 1) {
2326ba597c5SAnurag S. Maskey 		free(*name);
2336ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
2346ba597c5SAnurag S. Maskey 	}
2356ba597c5SAnurag S. Maskey 	suffix = *name + strlen(*name) - strlen(NWAM_NCP_CONF_FILE_SUF);
2366ba597c5SAnurag S. Maskey 	if (strstr(*name, NWAM_NCP_CONF_FILE_SUF) != suffix) {
2376ba597c5SAnurag S. Maskey 		free(*name);
2386ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
2396ba597c5SAnurag S. Maskey 	}
2406ba597c5SAnurag S. Maskey 	suffix[0] = '\0';
2416ba597c5SAnurag S. Maskey 
2426ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
2436ba597c5SAnurag S. Maskey }
2446ba597c5SAnurag S. Maskey 
2456ba597c5SAnurag S. Maskey /* ARGSUSED1 */
2466ba597c5SAnurag S. Maskey nwam_error_t
2476ba597c5SAnurag S. Maskey nwam_ncp_read(const char *name, uint64_t flags, nwam_ncp_handle_t *ncphp)
2486ba597c5SAnurag S. Maskey {
2496ba597c5SAnurag S. Maskey 	char *filename;
2506ba597c5SAnurag S. Maskey 	nwam_error_t err;
2516ba597c5SAnurag S. Maskey 
2526ba597c5SAnurag S. Maskey 	assert(name != NULL && ncphp != NULL);
2536ba597c5SAnurag S. Maskey 
2546ba597c5SAnurag S. Maskey 	/* try to read the associated ncp configuration */
2556ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(name, &filename)) != NWAM_SUCCESS) {
2566ba597c5SAnurag S. Maskey 		*ncphp = NULL;
2576ba597c5SAnurag S. Maskey 		return (err);
2586ba597c5SAnurag S. Maskey 	}
2596ba597c5SAnurag S. Maskey 
2606ba597c5SAnurag S. Maskey 	err = nwam_read(NWAM_OBJECT_TYPE_NCP, filename, name, flags, ncphp);
2616ba597c5SAnurag S. Maskey 	free(filename);
2626ba597c5SAnurag S. Maskey 	return (err);
2636ba597c5SAnurag S. Maskey }
2646ba597c5SAnurag S. Maskey 
2656ba597c5SAnurag S. Maskey static nwam_error_t
2666ba597c5SAnurag S. Maskey nwam_ncu_get_parent_ncp_name(nwam_ncu_handle_t ncuh, char **parentnamep)
2676ba597c5SAnurag S. Maskey {
2686ba597c5SAnurag S. Maskey 	nwam_value_t parentval = NULL;
2696ba597c5SAnurag S. Maskey 	char *parentname;
2706ba597c5SAnurag S. Maskey 	nwam_error_t err;
2716ba597c5SAnurag S. Maskey 
2726ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_PARENT_NCP,
2736ba597c5SAnurag S. Maskey 	    &parentval)) != NWAM_SUCCESS ||
2746ba597c5SAnurag S. Maskey 	    (err = nwam_value_get_string(parentval, &parentname))
2756ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
2766ba597c5SAnurag S. Maskey 	    (*parentnamep = strdup(parentname)) == NULL) {
2776ba597c5SAnurag S. Maskey 		if (parentval != NULL)
2786ba597c5SAnurag S. Maskey 			nwam_value_free(parentval);
2796ba597c5SAnurag S. Maskey 		*parentnamep = NULL;
2806ba597c5SAnurag S. Maskey 		return (err);
2816ba597c5SAnurag S. Maskey 	}
2826ba597c5SAnurag S. Maskey 	nwam_value_free(parentval);
2836ba597c5SAnurag S. Maskey 
2846ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
2856ba597c5SAnurag S. Maskey }
2866ba597c5SAnurag S. Maskey 
2876ba597c5SAnurag S. Maskey static int
2886ba597c5SAnurag S. Maskey nwam_ncp_copy_callback(nwam_ncu_handle_t oldncuh, void *arg)
2896ba597c5SAnurag S. Maskey {
2906ba597c5SAnurag S. Maskey 	nwam_error_t err;
2916ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t newncuh = NULL;
2926ba597c5SAnurag S. Maskey 	char *oldparent;
2936ba597c5SAnurag S. Maskey 	char *oldfilename = NULL, *newfilename = NULL;
2946ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t newncph = (nwam_ncp_handle_t)arg;
2956ba597c5SAnurag S. Maskey 	nwam_value_t newparentval;
2966ba597c5SAnurag S. Maskey 
2976ba597c5SAnurag S. Maskey 	/* Get filenames for the new and old NCU's */
2986ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_parent_ncp_name(oldncuh, &oldparent))
2996ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
3006ba597c5SAnurag S. Maskey 		return (err);
3016ba597c5SAnurag S. Maskey 	err = nwam_ncp_name_to_file(oldparent, &oldfilename);
3026ba597c5SAnurag S. Maskey 	free(oldparent);
3036ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
3046ba597c5SAnurag S. Maskey 		return (err);
3056ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(newncph->nwh_name, &newfilename))
3066ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
3076ba597c5SAnurag S. Maskey 		goto fail;
3086ba597c5SAnurag S. Maskey 
3096ba597c5SAnurag S. Maskey 	/* new NCU name (and typedname) is the same as the old name */
3106ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, oldncuh->nwh_name,
3116ba597c5SAnurag S. Maskey 	    &newncuh)) != NWAM_SUCCESS)
3126ba597c5SAnurag S. Maskey 		goto fail;
3136ba597c5SAnurag S. Maskey 	/* Duplicate the old NCU's data */
3146ba597c5SAnurag S. Maskey 	if ((err = nwam_dup_object_list(oldncuh->nwh_data,
3156ba597c5SAnurag S. Maskey 	    &(newncuh->nwh_data))) != NWAM_SUCCESS)
3166ba597c5SAnurag S. Maskey 		goto fail;
3176ba597c5SAnurag S. Maskey 
3186ba597c5SAnurag S. Maskey 	/* Update the parent property for the new NCU */
3196ba597c5SAnurag S. Maskey 	if ((err = nwam_value_create_string(newncph->nwh_name, &newparentval))
3206ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
3216ba597c5SAnurag S. Maskey 		goto fail;
3226ba597c5SAnurag S. Maskey 	err = nwam_set_prop_value(newncuh->nwh_data, NWAM_NCU_PROP_PARENT_NCP,
3236ba597c5SAnurag S. Maskey 	    newparentval);
3246ba597c5SAnurag S. Maskey 	nwam_value_free(newparentval);
3256ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
3266ba597c5SAnurag S. Maskey 		goto fail;
3276ba597c5SAnurag S. Maskey 
3286ba597c5SAnurag S. Maskey 	/* Save the new NCU */
3296ba597c5SAnurag S. Maskey 	err = nwam_commit(newfilename, newncuh, 0);
3306ba597c5SAnurag S. Maskey 
3316ba597c5SAnurag S. Maskey fail:
3326ba597c5SAnurag S. Maskey 	free(oldfilename);
3336ba597c5SAnurag S. Maskey 	free(newfilename);
3346ba597c5SAnurag S. Maskey 	nwam_ncu_free(newncuh);
3356ba597c5SAnurag S. Maskey 	return (err);
3366ba597c5SAnurag S. Maskey }
3376ba597c5SAnurag S. Maskey 
3386ba597c5SAnurag S. Maskey nwam_error_t
3396ba597c5SAnurag S. Maskey nwam_ncp_copy(nwam_ncp_handle_t oldncph, const char *newname,
3406ba597c5SAnurag S. Maskey     nwam_ncp_handle_t *newncphp)
3416ba597c5SAnurag S. Maskey {
3426ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
3436ba597c5SAnurag S. Maskey 	nwam_error_t err;
3446ba597c5SAnurag S. Maskey 	int cb_ret;
3456ba597c5SAnurag S. Maskey 
3466ba597c5SAnurag S. Maskey 	assert(oldncph != NULL && newname != NULL && newncphp != NULL);
3476ba597c5SAnurag S. Maskey 
3486ba597c5SAnurag S. Maskey 	/* check if newname NCP already exists */
3496ba597c5SAnurag S. Maskey 	if (nwam_ncp_read(newname, 0,  &ncph) == NWAM_SUCCESS) {
3506ba597c5SAnurag S. Maskey 		nwam_ncp_free(ncph);
3516ba597c5SAnurag S. Maskey 		*newncphp = NULL;
3526ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
3536ba597c5SAnurag S. Maskey 	}
3546ba597c5SAnurag S. Maskey 
3556ba597c5SAnurag S. Maskey 	/* create new handle */
3566ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_create(newname, 0, newncphp)) != NWAM_SUCCESS)
3576ba597c5SAnurag S. Maskey 		return (err);
3586ba597c5SAnurag S. Maskey 
3596ba597c5SAnurag S. Maskey 	err = nwam_ncp_walk_ncus(oldncph, nwam_ncp_copy_callback, *newncphp,
3606ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_CLASS_ALL, &cb_ret);
3616ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
3626ba597c5SAnurag S. Maskey 		/* remove the NCP even if any NCU's had already been copied */
3636ba597c5SAnurag S. Maskey 		(void) nwam_ncp_destroy(*newncphp, 0);
3646ba597c5SAnurag S. Maskey 		*newncphp = NULL;
3656ba597c5SAnurag S. Maskey 		if (err == NWAM_WALK_HALTED)
3666ba597c5SAnurag S. Maskey 			return (cb_ret);
3676ba597c5SAnurag S. Maskey 		else
3686ba597c5SAnurag S. Maskey 			return (err);
3696ba597c5SAnurag S. Maskey 	}
3706ba597c5SAnurag S. Maskey 
3716ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
3726ba597c5SAnurag S. Maskey }
3736ba597c5SAnurag S. Maskey 
3746ba597c5SAnurag S. Maskey /*
3756ba597c5SAnurag S. Maskey  * Convert type to flag
3766ba597c5SAnurag S. Maskey  */
3776ba597c5SAnurag S. Maskey static uint64_t
3786ba597c5SAnurag S. Maskey nwam_ncu_type_to_flag(nwam_ncu_type_t type)
3796ba597c5SAnurag S. Maskey {
3806ba597c5SAnurag S. Maskey 	switch (type) {
3816ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_LINK:
3826ba597c5SAnurag S. Maskey 		return (NWAM_FLAG_NCU_TYPE_LINK);
3836ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_INTERFACE:
3846ba597c5SAnurag S. Maskey 		return (NWAM_FLAG_NCU_TYPE_INTERFACE);
3856ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_ANY:
3866ba597c5SAnurag S. Maskey 		return (NWAM_FLAG_NCU_TYPE_ALL);
3876ba597c5SAnurag S. Maskey 	default:
3886ba597c5SAnurag S. Maskey 		return (0);
3896ba597c5SAnurag S. Maskey 	}
3906ba597c5SAnurag S. Maskey }
3916ba597c5SAnurag S. Maskey 
3926ba597c5SAnurag S. Maskey /*
3936ba597c5SAnurag S. Maskey  * Convert class to flag
3946ba597c5SAnurag S. Maskey  */
3956ba597c5SAnurag S. Maskey uint64_t
3966ba597c5SAnurag S. Maskey nwam_ncu_class_to_flag(nwam_ncu_class_t class)
3976ba597c5SAnurag S. Maskey {
3986ba597c5SAnurag S. Maskey 	switch (class) {
3996ba597c5SAnurag S. Maskey 	case NWAM_NCU_CLASS_PHYS:
4006ba597c5SAnurag S. Maskey 		return (NWAM_FLAG_NCU_CLASS_PHYS);
4016ba597c5SAnurag S. Maskey 	case NWAM_NCU_CLASS_IP:
4026ba597c5SAnurag S. Maskey 		return (NWAM_FLAG_NCU_CLASS_IP);
4036ba597c5SAnurag S. Maskey 	case NWAM_NCU_CLASS_ANY:
4046ba597c5SAnurag S. Maskey 		return (NWAM_FLAG_NCU_CLASS_ALL);
4056ba597c5SAnurag S. Maskey 	default:
4066ba597c5SAnurag S. Maskey 		return (0);
4076ba597c5SAnurag S. Maskey 	}
4086ba597c5SAnurag S. Maskey }
4096ba597c5SAnurag S. Maskey 
4106ba597c5SAnurag S. Maskey /*
4116ba597c5SAnurag S. Maskey  * Infer NCU type from NCU class
4126ba597c5SAnurag S. Maskey  */
4136ba597c5SAnurag S. Maskey nwam_ncu_type_t
4146ba597c5SAnurag S. Maskey nwam_ncu_class_to_type(nwam_ncu_class_t class)
4156ba597c5SAnurag S. Maskey {
4166ba597c5SAnurag S. Maskey 	switch (class) {
4176ba597c5SAnurag S. Maskey 	case NWAM_NCU_CLASS_PHYS:
4186ba597c5SAnurag S. Maskey 		return (NWAM_NCU_TYPE_LINK);
4196ba597c5SAnurag S. Maskey 	case NWAM_NCU_CLASS_IP:
4206ba597c5SAnurag S. Maskey 		return (NWAM_NCU_TYPE_INTERFACE);
4216ba597c5SAnurag S. Maskey 	case NWAM_NCU_CLASS_ANY:
4226ba597c5SAnurag S. Maskey 		return (NWAM_NCU_TYPE_ANY);
4236ba597c5SAnurag S. Maskey 	default:
4246ba597c5SAnurag S. Maskey 		return (NWAM_NCU_TYPE_UNKNOWN);
4256ba597c5SAnurag S. Maskey 	}
4266ba597c5SAnurag S. Maskey }
4276ba597c5SAnurag S. Maskey 
4286ba597c5SAnurag S. Maskey /*
4296ba597c5SAnurag S. Maskey  * Make ncp active, deactivating any other active ncp.
4306ba597c5SAnurag S. Maskey  */
4316ba597c5SAnurag S. Maskey nwam_error_t
4326ba597c5SAnurag S. Maskey nwam_ncp_enable(nwam_ncp_handle_t ncph)
4336ba597c5SAnurag S. Maskey {
4346ba597c5SAnurag S. Maskey 	nwam_error_t err;
4356ba597c5SAnurag S. Maskey 	char *name;
4366ba597c5SAnurag S. Maskey 
4376ba597c5SAnurag S. Maskey 	assert(ncph != NULL);
4386ba597c5SAnurag S. Maskey 
4396ba597c5SAnurag S. Maskey 	err = nwam_enable(NULL, ncph);
4406ba597c5SAnurag S. Maskey 
4416ba597c5SAnurag S. Maskey 	if (err == NWAM_ERROR_BIND) {
4426ba597c5SAnurag S. Maskey 		/*
4436ba597c5SAnurag S. Maskey 		 * nwamd is not running, set active_ncp property so when
4446ba597c5SAnurag S. Maskey 		 * nwamd is next started, this NCP will be used.
4456ba597c5SAnurag S. Maskey 		 */
4466ba597c5SAnurag S. Maskey 		if ((err = nwam_ncp_get_name(ncph, &name)) != NWAM_SUCCESS)
4476ba597c5SAnurag S. Maskey 			return (err);
4486ba597c5SAnurag S. Maskey 
4496ba597c5SAnurag S. Maskey 		err = nwam_set_smf_string_property(NWAM_FMRI, NWAM_PG,
4506ba597c5SAnurag S. Maskey 		    NWAM_PROP_ACTIVE_NCP, name);
4516ba597c5SAnurag S. Maskey 		free(name);
4526ba597c5SAnurag S. Maskey 	}
4536ba597c5SAnurag S. Maskey 
4546ba597c5SAnurag S. Maskey 	return (err);
4556ba597c5SAnurag S. Maskey }
4566ba597c5SAnurag S. Maskey 
4576ba597c5SAnurag S. Maskey /* Compare NCP names c1 and c2 using strcasecmp() */
4586ba597c5SAnurag S. Maskey static int
4596ba597c5SAnurag S. Maskey ncpname_cmp(const void *c1, const void *c2)
4606ba597c5SAnurag S. Maskey {
4616ba597c5SAnurag S. Maskey 	return (strcasecmp(*(const char **)c1, *(const char **)c2));
4626ba597c5SAnurag S. Maskey }
4636ba597c5SAnurag S. Maskey 
4646ba597c5SAnurag S. Maskey /* ARGSUSED1 */
4656ba597c5SAnurag S. Maskey nwam_error_t
4666ba597c5SAnurag S. Maskey nwam_walk_ncps(int (*cb)(nwam_ncp_handle_t, void *), void *data,
4676ba597c5SAnurag S. Maskey     uint64_t flags, int *retp)
4686ba597c5SAnurag S. Maskey {
4696ba597c5SAnurag S. Maskey 	char *ncpname, **ncpfiles;
4706ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
4716ba597c5SAnurag S. Maskey 	nwam_error_t err;
4726ba597c5SAnurag S. Maskey 	nwam_value_t value;
4736ba597c5SAnurag S. Maskey 	void *objlist;
4746ba597c5SAnurag S. Maskey 	uint_t i, num_ncpfiles;
4756ba597c5SAnurag S. Maskey 	int ret = 0;
4766ba597c5SAnurag S. Maskey 
4776ba597c5SAnurag S. Maskey 	assert(cb != NULL);
4786ba597c5SAnurag S. Maskey 
4796ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
4806ba597c5SAnurag S. Maskey 		return (err);
4816ba597c5SAnurag S. Maskey 	/*
4826ba597c5SAnurag S. Maskey 	 * To get list of NCP files, call nwam_read_object_from_backend()
4836ba597c5SAnurag S. Maskey 	 * with "parent" argument set to NULL. We get back an object list
4846ba597c5SAnurag S. Maskey 	 * consisting of string arrays for each object type - NCP, ENM
4856ba597c5SAnurag S. Maskey 	 * and location. We retrieve the NCP list, which corresponds to
4866ba597c5SAnurag S. Maskey 	 * the set of NCP backend parent objects (these are files at present).
4876ba597c5SAnurag S. Maskey 	 */
4886ba597c5SAnurag S. Maskey 	if ((err = nwam_read_object_from_backend(NULL, NULL, flags,
4896ba597c5SAnurag S. Maskey 	    &objlist)) != NWAM_SUCCESS)
4906ba597c5SAnurag S. Maskey 		return (err);
4916ba597c5SAnurag S. Maskey 
4926ba597c5SAnurag S. Maskey 	if ((err = nwam_get_prop_value(objlist, NWAM_NCP_OBJECT_STRING, &value))
4936ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
4946ba597c5SAnurag S. Maskey 		nwam_free_object_list(objlist);
4956ba597c5SAnurag S. Maskey 		return (err);
4966ba597c5SAnurag S. Maskey 	}
4976ba597c5SAnurag S. Maskey 	if ((err = nwam_value_get_string_array(value, &ncpfiles,
4986ba597c5SAnurag S. Maskey 	    &num_ncpfiles)) != NWAM_SUCCESS) {
4996ba597c5SAnurag S. Maskey 		nwam_value_free(value);
5006ba597c5SAnurag S. Maskey 		nwam_free_object_list(objlist);
5016ba597c5SAnurag S. Maskey 		return (err);
5026ba597c5SAnurag S. Maskey 	}
5036ba597c5SAnurag S. Maskey 
5046ba597c5SAnurag S. Maskey 	/* sort the NCP names alphabetically */
5056ba597c5SAnurag S. Maskey 	qsort(ncpfiles, num_ncpfiles, sizeof (char *), ncpname_cmp);
5066ba597c5SAnurag S. Maskey 
5076ba597c5SAnurag S. Maskey 	for (i = 0; i < num_ncpfiles; i++) {
5086ba597c5SAnurag S. Maskey 		if (nwam_ncp_file_to_name(ncpfiles[i], &ncpname)
5096ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS)
5106ba597c5SAnurag S. Maskey 			continue;
5116ba597c5SAnurag S. Maskey 		if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, ncpname,
5126ba597c5SAnurag S. Maskey 		    &ncph)) != NWAM_SUCCESS) {
5136ba597c5SAnurag S. Maskey 			free(ncpname);
5146ba597c5SAnurag S. Maskey 			break;
5156ba597c5SAnurag S. Maskey 		}
5166ba597c5SAnurag S. Maskey 		ret = cb(ncph, data);
5176ba597c5SAnurag S. Maskey 		free(ncph);
5186ba597c5SAnurag S. Maskey 		free(ncpname);
5196ba597c5SAnurag S. Maskey 		if (ret != 0) {
5206ba597c5SAnurag S. Maskey 			err = NWAM_WALK_HALTED;
5216ba597c5SAnurag S. Maskey 			break;
5226ba597c5SAnurag S. Maskey 		}
5236ba597c5SAnurag S. Maskey 	}
5246ba597c5SAnurag S. Maskey 	nwam_value_free(value);
5256ba597c5SAnurag S. Maskey 	nwam_free_object_list(objlist);
5266ba597c5SAnurag S. Maskey 
5276ba597c5SAnurag S. Maskey 	if (retp != NULL)
5286ba597c5SAnurag S. Maskey 		*retp = ret;
5296ba597c5SAnurag S. Maskey 	return (err);
5306ba597c5SAnurag S. Maskey }
5316ba597c5SAnurag S. Maskey 
5326ba597c5SAnurag S. Maskey /*
5336ba597c5SAnurag S. Maskey  * Checks if NCP is read-only.  Only NWAM_NCP_NAME_AUTOMATIC is read-only
5346ba597c5SAnurag S. Maskey  * for all but the netadm user (which nwamd runs as).
5356ba597c5SAnurag S. Maskey  */
5366ba597c5SAnurag S. Maskey nwam_error_t
5376ba597c5SAnurag S. Maskey nwam_ncp_get_read_only(nwam_ncp_handle_t ncph, boolean_t *readp)
5386ba597c5SAnurag S. Maskey {
5396ba597c5SAnurag S. Maskey 	nwam_error_t err;
5406ba597c5SAnurag S. Maskey 	char *name;
5416ba597c5SAnurag S. Maskey 
5426ba597c5SAnurag S. Maskey 	assert(ncph != NULL && readp != NULL);
5436ba597c5SAnurag S. Maskey 
5446ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_get_name(ncph, &name)) != NWAM_SUCCESS)
5456ba597c5SAnurag S. Maskey 		return (err);
5466ba597c5SAnurag S. Maskey 
5476ba597c5SAnurag S. Maskey 	if (NWAM_NCP_AUTOMATIC(name))
548*69b43529SMichael Hunter 		*readp = !nwam_uid_is_special();
5496ba597c5SAnurag S. Maskey 	else
5506ba597c5SAnurag S. Maskey 		*readp = B_FALSE;
5516ba597c5SAnurag S. Maskey 
5526ba597c5SAnurag S. Maskey 	free(name);
5536ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
5546ba597c5SAnurag S. Maskey }
5556ba597c5SAnurag S. Maskey 
5566ba597c5SAnurag S. Maskey /* Checks if NCU is writable depending on its parent */
5576ba597c5SAnurag S. Maskey nwam_error_t
5586ba597c5SAnurag S. Maskey nwam_ncu_get_read_only(nwam_ncu_handle_t ncuh, boolean_t *readp)
5596ba597c5SAnurag S. Maskey {
5606ba597c5SAnurag S. Maskey 	nwam_error_t err;
5616ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
5626ba597c5SAnurag S. Maskey 
5636ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && readp != NULL);
5646ba597c5SAnurag S. Maskey 
5656ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_ncp(ncuh, &ncph)) != NWAM_SUCCESS)
5666ba597c5SAnurag S. Maskey 		return (err);
5676ba597c5SAnurag S. Maskey 
5686ba597c5SAnurag S. Maskey 	err = nwam_ncp_get_read_only(ncph, readp);
5696ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
5706ba597c5SAnurag S. Maskey 	return (err);
5716ba597c5SAnurag S. Maskey }
5726ba597c5SAnurag S. Maskey 
5736ba597c5SAnurag S. Maskey /* Returns true if the NCP is active */
5746ba597c5SAnurag S. Maskey static boolean_t
5756ba597c5SAnurag S. Maskey nwam_ncp_is_active(nwam_ncp_handle_t ncph)
5766ba597c5SAnurag S. Maskey {
5776ba597c5SAnurag S. Maskey 	char *active_ncp, *name;
5786ba597c5SAnurag S. Maskey 	boolean_t ret;
5796ba597c5SAnurag S. Maskey 
5806ba597c5SAnurag S. Maskey 	assert(ncph != NULL);
5816ba597c5SAnurag S. Maskey 
5826ba597c5SAnurag S. Maskey 	/*
5836ba597c5SAnurag S. Maskey 	 * Determine which NCP is active via the nwamd/active_ncp property
5846ba597c5SAnurag S. Maskey 	 * value.  This allows us to determine which NCP is active even
5856ba597c5SAnurag S. Maskey 	 * if nwamd is not running.
5866ba597c5SAnurag S. Maskey 	 */
5876ba597c5SAnurag S. Maskey 	if (nwam_ncp_get_name(ncph, &name) != NWAM_SUCCESS ||
5886ba597c5SAnurag S. Maskey 	    nwam_get_smf_string_property(NWAM_FMRI, NWAM_PG,
5896ba597c5SAnurag S. Maskey 	    NWAM_PROP_ACTIVE_NCP, &active_ncp) != NWAM_SUCCESS)
5906ba597c5SAnurag S. Maskey 		return (B_FALSE);
5916ba597c5SAnurag S. Maskey 
5926ba597c5SAnurag S. Maskey 	ret = (strcmp(name, active_ncp) == 0);
5936ba597c5SAnurag S. Maskey 
5946ba597c5SAnurag S. Maskey 	free(active_ncp);
5956ba597c5SAnurag S. Maskey 	free(name);
5966ba597c5SAnurag S. Maskey 
5976ba597c5SAnurag S. Maskey 	return (ret);
5986ba597c5SAnurag S. Maskey }
5996ba597c5SAnurag S. Maskey 
6006ba597c5SAnurag S. Maskey nwam_error_t
6016ba597c5SAnurag S. Maskey nwam_ncp_destroy(nwam_ncp_handle_t ncph, uint64_t flags)
6026ba597c5SAnurag S. Maskey {
6036ba597c5SAnurag S. Maskey 	char *filename;
6046ba597c5SAnurag S. Maskey 	nwam_error_t err;
6056ba597c5SAnurag S. Maskey 	boolean_t read_only;
6066ba597c5SAnurag S. Maskey 
6076ba597c5SAnurag S. Maskey 	assert(ncph != NULL);
6086ba597c5SAnurag S. Maskey 
6096ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_get_read_only(ncph, &read_only)) != NWAM_SUCCESS)
6106ba597c5SAnurag S. Maskey 		return (err);
6116ba597c5SAnurag S. Maskey 	if (read_only)
6126ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_NOT_DESTROYABLE);
6136ba597c5SAnurag S. Maskey 
6146ba597c5SAnurag S. Maskey 	if (nwam_ncp_is_active(ncph))
6156ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_IN_USE);
6166ba597c5SAnurag S. Maskey 
6176ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &filename))
6186ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
6196ba597c5SAnurag S. Maskey 		return (err);
6206ba597c5SAnurag S. Maskey 
6216ba597c5SAnurag S. Maskey 	err = nwam_destroy(filename, ncph, flags);
6226ba597c5SAnurag S. Maskey 	free(filename);
6236ba597c5SAnurag S. Maskey 
6246ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
6256ba597c5SAnurag S. Maskey }
6266ba597c5SAnurag S. Maskey 
6276ba597c5SAnurag S. Maskey static nwam_error_t
6286ba597c5SAnurag S. Maskey nwam_ncu_internal_name_to_name(const char *internalname,
6296ba597c5SAnurag S. Maskey     nwam_ncu_type_t *typep, char **namep)
6306ba597c5SAnurag S. Maskey {
6316ba597c5SAnurag S. Maskey 	char *prefixstr;
6326ba597c5SAnurag S. Maskey 
6336ba597c5SAnurag S. Maskey 	assert(internalname != NULL && namep != NULL);
6346ba597c5SAnurag S. Maskey 
6356ba597c5SAnurag S. Maskey 	if (strncasecmp(internalname, NWAM_NCU_LINK_NAME_PRE,
6366ba597c5SAnurag S. Maskey 	    strlen(NWAM_NCU_LINK_NAME_PRE)) == 0) {
6376ba597c5SAnurag S. Maskey 		prefixstr = NWAM_NCU_LINK_NAME_PRE;
6386ba597c5SAnurag S. Maskey 		*typep = NWAM_NCU_TYPE_LINK;
6396ba597c5SAnurag S. Maskey 	} else if (strncasecmp(internalname, NWAM_NCU_INTERFACE_NAME_PRE,
6406ba597c5SAnurag S. Maskey 	    strlen(NWAM_NCU_INTERFACE_NAME_PRE)) == 0) {
6416ba597c5SAnurag S. Maskey 		prefixstr = NWAM_NCU_INTERFACE_NAME_PRE;
6426ba597c5SAnurag S. Maskey 		*typep = NWAM_NCU_TYPE_INTERFACE;
6436ba597c5SAnurag S. Maskey 	} else {
6446ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
6456ba597c5SAnurag S. Maskey 	}
6466ba597c5SAnurag S. Maskey 
6476ba597c5SAnurag S. Maskey 	*namep = strdup(internalname + strlen(prefixstr));
6486ba597c5SAnurag S. Maskey 	if (*namep == NULL)
6496ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
6506ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
6516ba597c5SAnurag S. Maskey }
6526ba597c5SAnurag S. Maskey 
6536ba597c5SAnurag S. Maskey /* ARGSUSED2 */
6546ba597c5SAnurag S. Maskey static int
6556ba597c5SAnurag S. Maskey ncu_selectcb(struct nwam_handle *hp, uint64_t flags, void *data)
6566ba597c5SAnurag S. Maskey {
6576ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh = hp;
6586ba597c5SAnurag S. Maskey 	nwam_value_t typeval = NULL, classval = NULL;
6596ba597c5SAnurag S. Maskey 	uint64_t type, class, matchflags, walkfilter;
6606ba597c5SAnurag S. Maskey 
6616ba597c5SAnurag S. Maskey 	if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval)
6626ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
6636ba597c5SAnurag S. Maskey 	    nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS, &classval)
6646ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
6656ba597c5SAnurag S. Maskey 		if (typeval != NULL)
6666ba597c5SAnurag S. Maskey 			nwam_value_free(typeval);
6676ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
6686ba597c5SAnurag S. Maskey 	}
6696ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS ||
6706ba597c5SAnurag S. Maskey 	    nwam_value_get_uint64(classval, &class) != NWAM_SUCCESS) {
6716ba597c5SAnurag S. Maskey 		nwam_value_free(typeval);
6726ba597c5SAnurag S. Maskey 		nwam_value_free(classval);
6736ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
6746ba597c5SAnurag S. Maskey 	}
6756ba597c5SAnurag S. Maskey 
6766ba597c5SAnurag S. Maskey 	matchflags = nwam_ncu_type_to_flag(type) |
6776ba597c5SAnurag S. Maskey 	    nwam_ncu_class_to_flag(class);
6786ba597c5SAnurag S. Maskey 	nwam_value_free(typeval);
6796ba597c5SAnurag S. Maskey 	nwam_value_free(classval);
6806ba597c5SAnurag S. Maskey 
6816ba597c5SAnurag S. Maskey 	if ((walkfilter = (flags & NWAM_WALK_FILTER_MASK)) == 0)
6826ba597c5SAnurag S. Maskey 		walkfilter = NWAM_FLAG_NCU_TYPE_CLASS_ALL;
6836ba597c5SAnurag S. Maskey 
6846ba597c5SAnurag S. Maskey 	if (matchflags & walkfilter)
6856ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
6866ba597c5SAnurag S. Maskey 	return (NWAM_INVALID_ARG);
6876ba597c5SAnurag S. Maskey }
6886ba597c5SAnurag S. Maskey 
6896ba597c5SAnurag S. Maskey nwam_error_t
6906ba597c5SAnurag S. Maskey nwam_ncp_walk_ncus(nwam_ncp_handle_t ncph,
6916ba597c5SAnurag S. Maskey     int(*cb)(nwam_ncu_handle_t, void *), void *data, uint64_t flags, int *retp)
6926ba597c5SAnurag S. Maskey {
6936ba597c5SAnurag S. Maskey 	char *ncpfile;
6946ba597c5SAnurag S. Maskey 	nwam_error_t err;
6956ba597c5SAnurag S. Maskey 
6966ba597c5SAnurag S. Maskey 	assert(ncph != NULL && cb != NULL);
6976ba597c5SAnurag S. Maskey 
6986ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags,
6996ba597c5SAnurag S. Maskey 	    NWAM_FLAG_NCU_TYPE_CLASS_ALL | NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
7006ba597c5SAnurag S. Maskey 		return (err);
7016ba597c5SAnurag S. Maskey 
7026ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &ncpfile))
7036ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
7046ba597c5SAnurag S. Maskey 		return (err);
7056ba597c5SAnurag S. Maskey 
7066ba597c5SAnurag S. Maskey 	err = nwam_walk(NWAM_OBJECT_TYPE_NCU, ncpfile, cb, data, flags,
7076ba597c5SAnurag S. Maskey 	    retp, ncu_selectcb);
7086ba597c5SAnurag S. Maskey 	free(ncpfile);
7096ba597c5SAnurag S. Maskey 
7106ba597c5SAnurag S. Maskey 	return (err);
7116ba597c5SAnurag S. Maskey }
7126ba597c5SAnurag S. Maskey 
7136ba597c5SAnurag S. Maskey void
7146ba597c5SAnurag S. Maskey nwam_ncp_free(nwam_ncp_handle_t ncph)
7156ba597c5SAnurag S. Maskey {
7166ba597c5SAnurag S. Maskey 	nwam_free(ncph);
7176ba597c5SAnurag S. Maskey }
7186ba597c5SAnurag S. Maskey 
7196ba597c5SAnurag S. Maskey /*
7206ba597c5SAnurag S. Maskey  * Are ncu type and class compatible?
7216ba597c5SAnurag S. Maskey  */
7226ba597c5SAnurag S. Maskey static boolean_t
7236ba597c5SAnurag S. Maskey nwam_ncu_type_class_compatible(nwam_ncu_type_t type, nwam_ncu_class_t class)
7246ba597c5SAnurag S. Maskey {
7256ba597c5SAnurag S. Maskey 	switch (type) {
7266ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_LINK:
7276ba597c5SAnurag S. Maskey 		return (class == NWAM_NCU_CLASS_PHYS);
7286ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_INTERFACE:
7296ba597c5SAnurag S. Maskey 		return (class == NWAM_NCU_CLASS_IP);
7306ba597c5SAnurag S. Maskey 	default:
7316ba597c5SAnurag S. Maskey 		return (B_FALSE);
7326ba597c5SAnurag S. Maskey 	}
7336ba597c5SAnurag S. Maskey }
7346ba597c5SAnurag S. Maskey 
7356ba597c5SAnurag S. Maskey /* Name to validate may be internal name. If so, convert it before validating */
7366ba597c5SAnurag S. Maskey static boolean_t
7376ba597c5SAnurag S. Maskey valid_ncu_name(const char *name)
7386ba597c5SAnurag S. Maskey {
7396ba597c5SAnurag S. Maskey 	char *n;
7406ba597c5SAnurag S. Maskey 	boolean_t ret;
7416ba597c5SAnurag S. Maskey 	nwam_ncu_type_t type;
7426ba597c5SAnurag S. Maskey 
7436ba597c5SAnurag S. Maskey 	if (nwam_ncu_internal_name_to_name(name, &type, &n) == NWAM_SUCCESS) {
7446ba597c5SAnurag S. Maskey 
7456ba597c5SAnurag S. Maskey 		ret = dladm_valid_linkname(n);
7466ba597c5SAnurag S. Maskey 		free(n);
7476ba597c5SAnurag S. Maskey 	} else {
7486ba597c5SAnurag S. Maskey 		ret = dladm_valid_linkname(name);
7496ba597c5SAnurag S. Maskey 	}
7506ba597c5SAnurag S. Maskey 
7516ba597c5SAnurag S. Maskey 	return (ret);
7526ba597c5SAnurag S. Maskey }
7536ba597c5SAnurag S. Maskey 
7546ba597c5SAnurag S. Maskey nwam_error_t
7556ba597c5SAnurag S. Maskey nwam_ncu_create(nwam_ncp_handle_t ncph, const char *name,
7566ba597c5SAnurag S. Maskey     nwam_ncu_type_t type, nwam_ncu_class_t class, nwam_ncu_handle_t *ncuhp)
7576ba597c5SAnurag S. Maskey {
7586ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh;
7596ba597c5SAnurag S. Maskey 	nwam_value_t typeval = NULL, classval = NULL, parentval = NULL;
7606ba597c5SAnurag S. Maskey 	nwam_value_t enabledval = NULL;
7616ba597c5SAnurag S. Maskey 	nwam_error_t err;
7626ba597c5SAnurag S. Maskey 	boolean_t read_only;
7636ba597c5SAnurag S. Maskey 	char *typedname;
7646ba597c5SAnurag S. Maskey 
7656ba597c5SAnurag S. Maskey 	assert(ncph != NULL && name != NULL && ncuhp != NULL);
7666ba597c5SAnurag S. Maskey 
7676ba597c5SAnurag S. Maskey 	if (!valid_ncu_name(name))
7686ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
7696ba597c5SAnurag S. Maskey 
7706ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_get_read_only(ncph, &read_only)) != NWAM_SUCCESS)
7716ba597c5SAnurag S. Maskey 		return (err);
7726ba597c5SAnurag S. Maskey 	if (read_only)
7736ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_READ_ONLY);
7746ba597c5SAnurag S. Maskey 
7756ba597c5SAnurag S. Maskey 	if (nwam_ncu_read(ncph, name, type, 0, &ncuh) == NWAM_SUCCESS) {
7766ba597c5SAnurag S. Maskey 		nwam_ncu_free(ncuh);
7776ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
7786ba597c5SAnurag S. Maskey 	}
7796ba597c5SAnurag S. Maskey 
7806ba597c5SAnurag S. Maskey 	if (!valid_ncu_name(name) ||
7816ba597c5SAnurag S. Maskey 	    !nwam_ncu_type_class_compatible(type, class))
7826ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
7836ba597c5SAnurag S. Maskey 
7846ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_name_to_typed_name(name, type, &typedname))
7856ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
7866ba597c5SAnurag S. Maskey 		return (err);
7876ba597c5SAnurag S. Maskey 
7886ba597c5SAnurag S. Maskey 	/* Create handle */
7896ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, typedname, ncuhp))
7906ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
7916ba597c5SAnurag S. Maskey 		return (err);
7926ba597c5SAnurag S. Maskey 	free(typedname);
7936ba597c5SAnurag S. Maskey 
7946ba597c5SAnurag S. Maskey 	/*
7956ba597c5SAnurag S. Maskey 	 * Create new object list for NCU.  The new NCU is initialized with
7966ba597c5SAnurag S. Maskey 	 * the appropriate type and class.
7976ba597c5SAnurag S. Maskey 	 */
7986ba597c5SAnurag S. Maskey 	if ((err = nwam_alloc_object_list(&(*ncuhp)->nwh_data)) != NWAM_SUCCESS)
7996ba597c5SAnurag S. Maskey 		goto finish;
8006ba597c5SAnurag S. Maskey 
8016ba597c5SAnurag S. Maskey 	if ((err = nwam_value_create_uint64(type, &typeval))
8026ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
8036ba597c5SAnurag S. Maskey 	    (err = nwam_value_create_uint64(class, &classval))
8046ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
8056ba597c5SAnurag S. Maskey 	    (err = nwam_value_create_string(ncph->nwh_name, &parentval))
8066ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
8076ba597c5SAnurag S. Maskey 	    (err = nwam_value_create_boolean(B_TRUE, &enabledval))
8086ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
8096ba597c5SAnurag S. Maskey 		goto finish;
8106ba597c5SAnurag S. Maskey 	}
8116ba597c5SAnurag S. Maskey 	if ((err = nwam_set_prop_value((*ncuhp)->nwh_data, NWAM_NCU_PROP_TYPE,
8126ba597c5SAnurag S. Maskey 	    typeval)) != NWAM_SUCCESS ||
8136ba597c5SAnurag S. Maskey 	    (err = nwam_set_prop_value((*ncuhp)->nwh_data, NWAM_NCU_PROP_CLASS,
8146ba597c5SAnurag S. Maskey 	    classval)) != NWAM_SUCCESS ||
8156ba597c5SAnurag S. Maskey 	    (err = nwam_set_prop_value((*ncuhp)->nwh_data,
8166ba597c5SAnurag S. Maskey 	    NWAM_NCU_PROP_PARENT_NCP, parentval)) != NWAM_SUCCESS ||
8176ba597c5SAnurag S. Maskey 	    (err = nwam_set_prop_value((*ncuhp)->nwh_data,
8186ba597c5SAnurag S. Maskey 	    NWAM_NCU_PROP_ENABLED, enabledval)) != NWAM_SUCCESS) {
8196ba597c5SAnurag S. Maskey 		goto finish;
8206ba597c5SAnurag S. Maskey 	}
8216ba597c5SAnurag S. Maskey 
8226ba597c5SAnurag S. Maskey 	/* Set default IP, datalink properties */
8236ba597c5SAnurag S. Maskey 	if (type == NWAM_NCU_TYPE_INTERFACE && class == NWAM_NCU_CLASS_IP) {
8246ba597c5SAnurag S. Maskey 
8256ba597c5SAnurag S. Maskey 		uint64_t ver[] = { IPV4_VERSION, IPV6_VERSION };
8266ba597c5SAnurag S. Maskey 		uint64_t v6src[] = { NWAM_ADDRSRC_DHCP, NWAM_ADDRSRC_AUTOCONF };
8276ba597c5SAnurag S. Maskey 		uint_t vercnt = 2, v6srccnt = 2;
8286ba597c5SAnurag S. Maskey 		nwam_value_t ipver = NULL, v4addrsrc = NULL, v6addrsrc = NULL;
8296ba597c5SAnurag S. Maskey 
8306ba597c5SAnurag S. Maskey 		if ((err = nwam_value_create_uint64_array(ver, vercnt, &ipver))
8316ba597c5SAnurag S. Maskey 		    != NWAM_SUCCESS ||
8326ba597c5SAnurag S. Maskey 		    (err = nwam_value_create_uint64(NWAM_ADDRSRC_DHCP,
8336ba597c5SAnurag S. Maskey 		    &v4addrsrc)) != NWAM_SUCCESS ||
8346ba597c5SAnurag S. Maskey 		    (err = nwam_value_create_uint64_array(v6src, v6srccnt,
8356ba597c5SAnurag S. Maskey 		    &v6addrsrc)) != NWAM_SUCCESS) {
8366ba597c5SAnurag S. Maskey 			nwam_value_free(ipver);
8376ba597c5SAnurag S. Maskey 			nwam_value_free(v4addrsrc);
8386ba597c5SAnurag S. Maskey 			goto finish;
8396ba597c5SAnurag S. Maskey 		}
8406ba597c5SAnurag S. Maskey 		if ((err = nwam_set_prop_value((*ncuhp)->nwh_data,
8416ba597c5SAnurag S. Maskey 		    NWAM_NCU_PROP_IP_VERSION, ipver)) == NWAM_SUCCESS &&
8426ba597c5SAnurag S. Maskey 		    (err = nwam_set_prop_value((*ncuhp)->nwh_data,
8436ba597c5SAnurag S. Maskey 		    NWAM_NCU_PROP_IPV4_ADDRSRC, v4addrsrc)) == NWAM_SUCCESS) {
8446ba597c5SAnurag S. Maskey 			err = nwam_set_prop_value((*ncuhp)->nwh_data,
8456ba597c5SAnurag S. Maskey 			    NWAM_NCU_PROP_IPV6_ADDRSRC, v6addrsrc);
8466ba597c5SAnurag S. Maskey 		}
8476ba597c5SAnurag S. Maskey 		nwam_value_free(ipver);
8486ba597c5SAnurag S. Maskey 		nwam_value_free(v4addrsrc);
8496ba597c5SAnurag S. Maskey 		nwam_value_free(v6addrsrc);
8506ba597c5SAnurag S. Maskey 	} else {
8516ba597c5SAnurag S. Maskey 		nwam_value_t actval = NULL;
8526ba597c5SAnurag S. Maskey 		if ((err = nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL,
8536ba597c5SAnurag S. Maskey 		    &actval)) != NWAM_SUCCESS)
8546ba597c5SAnurag S. Maskey 			goto finish;
8556ba597c5SAnurag S. Maskey 		err = nwam_set_prop_value((*ncuhp)->nwh_data,
8566ba597c5SAnurag S. Maskey 		    NWAM_NCU_PROP_ACTIVATION_MODE, actval);
8576ba597c5SAnurag S. Maskey 		nwam_value_free(actval);
8586ba597c5SAnurag S. Maskey 	}
8596ba597c5SAnurag S. Maskey 
8606ba597c5SAnurag S. Maskey finish:
8616ba597c5SAnurag S. Maskey 	nwam_value_free(typeval);
8626ba597c5SAnurag S. Maskey 	nwam_value_free(classval);
8636ba597c5SAnurag S. Maskey 	nwam_value_free(parentval);
8646ba597c5SAnurag S. Maskey 	nwam_value_free(enabledval);
8656ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
8666ba597c5SAnurag S. Maskey 		nwam_ncu_free(*ncuhp);
8676ba597c5SAnurag S. Maskey 		*ncuhp = NULL;
8686ba597c5SAnurag S. Maskey 	}
8696ba597c5SAnurag S. Maskey 	return (err);
8706ba597c5SAnurag S. Maskey }
8716ba597c5SAnurag S. Maskey 
8726ba597c5SAnurag S. Maskey nwam_error_t
8736ba597c5SAnurag S. Maskey nwam_ncu_read(nwam_ncp_handle_t ncph, const char *name,
8746ba597c5SAnurag S. Maskey     nwam_ncu_type_t type, uint64_t flags, nwam_ncu_handle_t *ncuhp)
8756ba597c5SAnurag S. Maskey {
8766ba597c5SAnurag S. Maskey 	char *ncpfile, *typedname;
8776ba597c5SAnurag S. Maskey 	nwam_error_t err, err_ip, err_link;
8786ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh_ip, ncuh_link;
8796ba597c5SAnurag S. Maskey 
8806ba597c5SAnurag S. Maskey 	assert(ncph != NULL && name != NULL && ncuhp != NULL);
8816ba597c5SAnurag S. Maskey 
8826ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &ncpfile))
8836ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
8846ba597c5SAnurag S. Maskey 		return (err);
8856ba597c5SAnurag S. Maskey 
8866ba597c5SAnurag S. Maskey 	if (type == NWAM_NCU_TYPE_ANY) {
8876ba597c5SAnurag S. Maskey 
8886ba597c5SAnurag S. Maskey 		free(ncpfile);
8896ba597c5SAnurag S. Maskey 
8906ba597c5SAnurag S. Maskey 		/*
8916ba597c5SAnurag S. Maskey 		 * If we get to this point, we have discovered that no
8926ba597c5SAnurag S. Maskey 		 * NCU type is discernable from name or type arguments.
8936ba597c5SAnurag S. Maskey 		 * Either exactly one NCU called name must exist of either
8946ba597c5SAnurag S. Maskey 		 * type, or the operation should fail.
8956ba597c5SAnurag S. Maskey 		 */
8966ba597c5SAnurag S. Maskey 		err_ip = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_INTERFACE,
8976ba597c5SAnurag S. Maskey 		    flags, &ncuh_ip);
8986ba597c5SAnurag S. Maskey 		err_link = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK,
8996ba597c5SAnurag S. Maskey 		    flags, &ncuh_link);
9006ba597c5SAnurag S. Maskey 
9016ba597c5SAnurag S. Maskey 		*ncuhp = NULL;
9026ba597c5SAnurag S. Maskey 
9036ba597c5SAnurag S. Maskey 		if (err_ip == NWAM_SUCCESS && err_link == NWAM_SUCCESS) {
9046ba597c5SAnurag S. Maskey 			nwam_ncu_free(ncuh_ip);
9056ba597c5SAnurag S. Maskey 			nwam_ncu_free(ncuh_link);
9066ba597c5SAnurag S. Maskey 			err = NWAM_ENTITY_MULTIPLE_VALUES;
9076ba597c5SAnurag S. Maskey 		} else if (err_ip != NWAM_SUCCESS && err_link != NWAM_SUCCESS) {
9086ba597c5SAnurag S. Maskey 			err = NWAM_ENTITY_NOT_FOUND;
9096ba597c5SAnurag S. Maskey 		} else {
9106ba597c5SAnurag S. Maskey 			if (err_ip == NWAM_SUCCESS) {
9116ba597c5SAnurag S. Maskey 				*ncuhp = ncuh_ip;
9126ba597c5SAnurag S. Maskey 			} else {
9136ba597c5SAnurag S. Maskey 				*ncuhp = ncuh_link;
9146ba597c5SAnurag S. Maskey 			}
9156ba597c5SAnurag S. Maskey 			err = NWAM_SUCCESS;
9166ba597c5SAnurag S. Maskey 		}
9176ba597c5SAnurag S. Maskey 
9186ba597c5SAnurag S. Maskey 		return (err);
9196ba597c5SAnurag S. Maskey 	}
9206ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_name_to_typed_name(name, type, &typedname)) !=
9216ba597c5SAnurag S. Maskey 	    NWAM_SUCCESS) {
9226ba597c5SAnurag S. Maskey 		free(ncpfile);
9236ba597c5SAnurag S. Maskey 		return (err);
9246ba597c5SAnurag S. Maskey 	}
9256ba597c5SAnurag S. Maskey 	err = nwam_read(NWAM_OBJECT_TYPE_NCU, ncpfile, typedname, flags, ncuhp);
9266ba597c5SAnurag S. Maskey 
9276ba597c5SAnurag S. Maskey 	free(typedname);
9286ba597c5SAnurag S. Maskey 	free(ncpfile);
9296ba597c5SAnurag S. Maskey 
9306ba597c5SAnurag S. Maskey 	return (err);
9316ba597c5SAnurag S. Maskey }
9326ba597c5SAnurag S. Maskey 
9336ba597c5SAnurag S. Maskey nwam_error_t
9346ba597c5SAnurag S. Maskey nwam_ncu_get_name(nwam_ncu_handle_t ncuh, char **namep)
9356ba597c5SAnurag S. Maskey {
9366ba597c5SAnurag S. Maskey 	nwam_ncu_type_t type;
9376ba597c5SAnurag S. Maskey 
9386ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && namep != NULL);
9396ba597c5SAnurag S. Maskey 
9406ba597c5SAnurag S. Maskey 	return (nwam_ncu_internal_name_to_name(ncuh->nwh_name, &type, namep));
9416ba597c5SAnurag S. Maskey }
9426ba597c5SAnurag S. Maskey 
9436ba597c5SAnurag S. Maskey nwam_error_t
9446ba597c5SAnurag S. Maskey nwam_ncu_name_to_typed_name(const char *name, nwam_ncu_type_t type,
9456ba597c5SAnurag S. Maskey     char **typednamep)
9466ba597c5SAnurag S. Maskey {
9476ba597c5SAnurag S. Maskey 	char *prefixstr;
9486ba597c5SAnurag S. Maskey 	size_t typednamesz;
9496ba597c5SAnurag S. Maskey 
9506ba597c5SAnurag S. Maskey 	assert(name != NULL && typednamep != NULL);
9516ba597c5SAnurag S. Maskey 
9526ba597c5SAnurag S. Maskey 	switch (type) {
9536ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_INTERFACE:
9546ba597c5SAnurag S. Maskey 		prefixstr = NWAM_NCU_INTERFACE_NAME_PRE;
9556ba597c5SAnurag S. Maskey 		break;
9566ba597c5SAnurag S. Maskey 	case NWAM_NCU_TYPE_LINK:
9576ba597c5SAnurag S. Maskey 		prefixstr = NWAM_NCU_LINK_NAME_PRE;
9586ba597c5SAnurag S. Maskey 		break;
9596ba597c5SAnurag S. Maskey 	default:
9606ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
9616ba597c5SAnurag S. Maskey 	}
9626ba597c5SAnurag S. Maskey 	typednamesz = strlen(name) + strlen(prefixstr) + 1;
9636ba597c5SAnurag S. Maskey 	if ((*typednamep = malloc(typednamesz)) == NULL)
9646ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
9656ba597c5SAnurag S. Maskey 
9666ba597c5SAnurag S. Maskey 	/* Name may be already qualified by type */
9676ba597c5SAnurag S. Maskey 	if (strncasecmp(prefixstr, name, strlen(prefixstr)) == 0) {
9686ba597c5SAnurag S. Maskey 		(void) snprintf(*typednamep, typednamesz, "%s", name);
9696ba597c5SAnurag S. Maskey 	} else {
9706ba597c5SAnurag S. Maskey 		(void) snprintf(*typednamep, typednamesz, "%s%s",
9716ba597c5SAnurag S. Maskey 		    prefixstr, name);
9726ba597c5SAnurag S. Maskey 	}
9736ba597c5SAnurag S. Maskey 
9746ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
9756ba597c5SAnurag S. Maskey }
9766ba597c5SAnurag S. Maskey 
9776ba597c5SAnurag S. Maskey nwam_error_t
9786ba597c5SAnurag S. Maskey nwam_ncu_typed_name_to_name(const char *typed_name, nwam_ncu_type_t *typep,
9796ba597c5SAnurag S. Maskey     char **name)
9806ba597c5SAnurag S. Maskey {
9816ba597c5SAnurag S. Maskey 	return (nwam_ncu_internal_name_to_name(typed_name, typep, name));
9826ba597c5SAnurag S. Maskey }
9836ba597c5SAnurag S. Maskey 
9846ba597c5SAnurag S. Maskey void
9856ba597c5SAnurag S. Maskey nwam_ncu_free(nwam_ncu_handle_t ncuh)
9866ba597c5SAnurag S. Maskey {
9876ba597c5SAnurag S. Maskey 	nwam_free(ncuh);
9886ba597c5SAnurag S. Maskey }
9896ba597c5SAnurag S. Maskey 
9906ba597c5SAnurag S. Maskey nwam_error_t
9916ba597c5SAnurag S. Maskey nwam_ncu_copy(nwam_ncu_handle_t oldncuh, const char *newname,
9926ba597c5SAnurag S. Maskey     nwam_ncu_handle_t *newncuhp)
9936ba597c5SAnurag S. Maskey {
9946ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
9956ba597c5SAnurag S. Maskey 	nwam_ncu_handle_t ncuh;
9966ba597c5SAnurag S. Maskey 	nwam_error_t err;
9976ba597c5SAnurag S. Maskey 	nwam_value_t typeval;
9986ba597c5SAnurag S. Maskey 	uint64_t type;
9996ba597c5SAnurag S. Maskey 	char *typednewname;
10006ba597c5SAnurag S. Maskey 
10016ba597c5SAnurag S. Maskey 	assert(oldncuh != NULL && newname != NULL && newncuhp != NULL);
10026ba597c5SAnurag S. Maskey 
10036ba597c5SAnurag S. Maskey 	if (nwam_ncu_get_prop_value(oldncuh, NWAM_NCU_PROP_TYPE,
10046ba597c5SAnurag S. Maskey 	    &typeval) != NWAM_SUCCESS) {
10056ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
10066ba597c5SAnurag S. Maskey 	}
10076ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS) {
10086ba597c5SAnurag S. Maskey 		nwam_value_free(typeval);
10096ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
10106ba597c5SAnurag S. Maskey 	}
10116ba597c5SAnurag S. Maskey 	nwam_value_free(typeval);
10126ba597c5SAnurag S. Maskey 
10136ba597c5SAnurag S. Maskey 	/* check if newname NCU already exists */
10146ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_ncp(oldncuh, &ncph)) != NWAM_SUCCESS)
10156ba597c5SAnurag S. Maskey 		return (err);
10166ba597c5SAnurag S. Maskey 	if (nwam_ncu_read(ncph, newname, type, 0, &ncuh) == NWAM_SUCCESS) {
10176ba597c5SAnurag S. Maskey 		nwam_ncu_free(ncuh);
10186ba597c5SAnurag S. Maskey 		nwam_ncp_free(ncph);
10196ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
10206ba597c5SAnurag S. Maskey 	}
10216ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
10226ba597c5SAnurag S. Maskey 
10236ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_name_to_typed_name(newname, type, &typednewname))
10246ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
10256ba597c5SAnurag S. Maskey 		return (err);
10266ba597c5SAnurag S. Maskey 
10276ba597c5SAnurag S. Maskey 	err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, typednewname, newncuhp);
10286ba597c5SAnurag S. Maskey 	free(typednewname);
10296ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
10306ba597c5SAnurag S. Maskey 		return (err);
10316ba597c5SAnurag S. Maskey 	if ((err = nwam_dup_object_list(oldncuh->nwh_data,
10326ba597c5SAnurag S. Maskey 	    &((*newncuhp)->nwh_data))) != NWAM_SUCCESS) {
10336ba597c5SAnurag S. Maskey 		free(*newncuhp);
10346ba597c5SAnurag S. Maskey 		*newncuhp = NULL;
10356ba597c5SAnurag S. Maskey 		return (err);
10366ba597c5SAnurag S. Maskey 	}
10376ba597c5SAnurag S. Maskey 
10386ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
10396ba597c5SAnurag S. Maskey }
10406ba597c5SAnurag S. Maskey 
10416ba597c5SAnurag S. Maskey nwam_error_t
10426ba597c5SAnurag S. Maskey nwam_ncu_delete_prop(nwam_ncu_handle_t ncuh, const char *propname)
10436ba597c5SAnurag S. Maskey {
10446ba597c5SAnurag S. Maskey 	boolean_t ro_ncu, ro_prop;
10456ba597c5SAnurag S. Maskey 	nwam_error_t err;
10466ba597c5SAnurag S. Maskey 	void *olddata;
10476ba597c5SAnurag S. Maskey 
10486ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && propname != NULL);
10496ba597c5SAnurag S. Maskey 
10506ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_read_only(ncuh, &ro_ncu)) != NWAM_SUCCESS ||
10516ba597c5SAnurag S. Maskey 	    (err = nwam_ncu_prop_read_only(propname, &ro_prop)) != NWAM_SUCCESS)
10526ba597c5SAnurag S. Maskey 		return (err);
10536ba597c5SAnurag S. Maskey 	if (ro_ncu || ro_prop)
10546ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_READ_ONLY);
10556ba597c5SAnurag S. Maskey 
10566ba597c5SAnurag S. Maskey 	/*
10576ba597c5SAnurag S. Maskey 	 * Duplicate data, remove property and validate. If validation
10586ba597c5SAnurag S. Maskey 	 * fails, revert to data duplicated prior to remove.
10596ba597c5SAnurag S. Maskey 	 */
10606ba597c5SAnurag S. Maskey 	if ((err = nwam_dup_object_list(ncuh->nwh_data, &olddata))
10616ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
10626ba597c5SAnurag S. Maskey 		return (err);
10636ba597c5SAnurag S. Maskey 	if ((err = nwam_delete_prop(ncuh->nwh_data, propname))
10646ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
10656ba597c5SAnurag S. Maskey 		nwam_free_object_list(ncuh->nwh_data);
10666ba597c5SAnurag S. Maskey 		ncuh->nwh_data = olddata;
10676ba597c5SAnurag S. Maskey 		return (err);
10686ba597c5SAnurag S. Maskey 	}
10696ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_validate(ncuh, NULL)) != NWAM_SUCCESS) {
10706ba597c5SAnurag S. Maskey 		nwam_free_object_list(ncuh->nwh_data);
10716ba597c5SAnurag S. Maskey 		ncuh->nwh_data = olddata;
10726ba597c5SAnurag S. Maskey 		return (err);
10736ba597c5SAnurag S. Maskey 	}
10746ba597c5SAnurag S. Maskey 	nwam_free_object_list(olddata);
10756ba597c5SAnurag S. Maskey 
10766ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
10776ba597c5SAnurag S. Maskey }
10786ba597c5SAnurag S. Maskey 
10796ba597c5SAnurag S. Maskey nwam_error_t
10806ba597c5SAnurag S. Maskey nwam_ncu_set_prop_value(nwam_ncu_handle_t ncuh, const char *propname,
10816ba597c5SAnurag S. Maskey     nwam_value_t value)
10826ba597c5SAnurag S. Maskey {
10836ba597c5SAnurag S. Maskey 	boolean_t ro_ncu, ro_prop;
10846ba597c5SAnurag S. Maskey 	nwam_error_t err;
10856ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
10866ba597c5SAnurag S. Maskey 
10876ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && propname != NULL && value != NULL);
10886ba597c5SAnurag S. Maskey 
10896ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_read_only(ncuh, &ro_ncu)) != NWAM_SUCCESS ||
10906ba597c5SAnurag S. Maskey 	    (err = nwam_ncu_prop_read_only(propname, &ro_prop)) != NWAM_SUCCESS)
10916ba597c5SAnurag S. Maskey 		return (err);
10926ba597c5SAnurag S. Maskey 	if (ro_ncu || ro_prop)
10936ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_READ_ONLY);
10946ba597c5SAnurag S. Maskey 
10956ba597c5SAnurag S. Maskey 	err = nwam_ncu_get_ncp(ncuh, &ncph);
10966ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS && err != NWAM_INVALID_ARG) {
10976ba597c5SAnurag S. Maskey 		/*
10986ba597c5SAnurag S. Maskey 		 * If "parent" property doesn't exist, NWAM_INVALID_ARG
10996ba597c5SAnurag S. Maskey 		 * is returned.  Allow the setting to continue.
11006ba597c5SAnurag S. Maskey 		 */
11016ba597c5SAnurag S. Maskey 		return (err);
11026ba597c5SAnurag S. Maskey 	}
11036ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
11046ba597c5SAnurag S. Maskey 
11056ba597c5SAnurag S. Maskey 	/* Need to ensure property, type and value are valid */
11066ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_validate_prop(ncuh, propname, value))
11076ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
11086ba597c5SAnurag S. Maskey 		return (err);
11096ba597c5SAnurag S. Maskey 
11106ba597c5SAnurag S. Maskey 	return (nwam_set_prop_value(ncuh->nwh_data, propname, value));
11116ba597c5SAnurag S. Maskey }
11126ba597c5SAnurag S. Maskey 
11136ba597c5SAnurag S. Maskey nwam_error_t
11146ba597c5SAnurag S. Maskey nwam_ncu_get_prop_value(nwam_ncu_handle_t ncuh, const char *propname,
11156ba597c5SAnurag S. Maskey     nwam_value_t *valuep)
11166ba597c5SAnurag S. Maskey {
11176ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && propname != NULL && valuep != NULL);
11186ba597c5SAnurag S. Maskey 
11196ba597c5SAnurag S. Maskey 	return (nwam_get_prop_value(ncuh->nwh_data, propname, valuep));
11206ba597c5SAnurag S. Maskey }
11216ba597c5SAnurag S. Maskey 
11226ba597c5SAnurag S. Maskey nwam_error_t
11236ba597c5SAnurag S. Maskey nwam_ncu_walk_props(nwam_ncu_handle_t ncuh,
11246ba597c5SAnurag S. Maskey     int (*cb)(const char *, nwam_value_t, void *),
11256ba597c5SAnurag S. Maskey     void *data, uint64_t flags, int *retp)
11266ba597c5SAnurag S. Maskey {
11276ba597c5SAnurag S. Maskey 	return (nwam_walk_props(ncuh, cb, data, flags, retp));
11286ba597c5SAnurag S. Maskey }
11296ba597c5SAnurag S. Maskey 
11306ba597c5SAnurag S. Maskey nwam_error_t
11316ba597c5SAnurag S. Maskey nwam_ncu_get_ncp(nwam_ncu_handle_t ncuh, nwam_ncp_handle_t *ncphp)
11326ba597c5SAnurag S. Maskey {
11336ba597c5SAnurag S. Maskey 	nwam_error_t err;
11346ba597c5SAnurag S. Maskey 	char *parentname = NULL;
11356ba597c5SAnurag S. Maskey 
11366ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &parentname))
11376ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS ||
11386ba597c5SAnurag S. Maskey 	    (err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, parentname, ncphp))
11396ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
11406ba597c5SAnurag S. Maskey 		if (parentname != NULL)
11416ba597c5SAnurag S. Maskey 			free(parentname);
11426ba597c5SAnurag S. Maskey 		return (err);
11436ba597c5SAnurag S. Maskey 	}
11446ba597c5SAnurag S. Maskey 	free(parentname);
11456ba597c5SAnurag S. Maskey 
11466ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
11476ba597c5SAnurag S. Maskey }
11486ba597c5SAnurag S. Maskey 
11496ba597c5SAnurag S. Maskey nwam_error_t
11506ba597c5SAnurag S. Maskey nwam_ncu_commit(nwam_ncu_handle_t ncuh, uint64_t flags)
11516ba597c5SAnurag S. Maskey {
11526ba597c5SAnurag S. Maskey 	nwam_error_t err;
11536ba597c5SAnurag S. Maskey 	boolean_t read_only;
11546ba597c5SAnurag S. Maskey 	char *ncpfile, *ncpname;
11556ba597c5SAnurag S. Maskey 
11566ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && ncuh->nwh_data != NULL);
11576ba597c5SAnurag S. Maskey 
11586ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
11596ba597c5SAnurag S. Maskey 		return (err);
11606ba597c5SAnurag S. Maskey 	if (read_only)
11616ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_READ_ONLY);
11626ba597c5SAnurag S. Maskey 
11636ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_validate(ncuh, NULL)) != NWAM_SUCCESS ||
11646ba597c5SAnurag S. Maskey 	    (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
11656ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
11666ba597c5SAnurag S. Maskey 		return (err);
11676ba597c5SAnurag S. Maskey 
11686ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(ncpname, &ncpfile)) != NWAM_SUCCESS) {
11696ba597c5SAnurag S. Maskey 		free(ncpname);
11706ba597c5SAnurag S. Maskey 		return (err);
11716ba597c5SAnurag S. Maskey 	}
11726ba597c5SAnurag S. Maskey 
11736ba597c5SAnurag S. Maskey 	err = nwam_commit(ncpfile, ncuh, flags);
11746ba597c5SAnurag S. Maskey 
11756ba597c5SAnurag S. Maskey 	free(ncpname);
11766ba597c5SAnurag S. Maskey 	free(ncpfile);
11776ba597c5SAnurag S. Maskey 
11786ba597c5SAnurag S. Maskey 	return (err);
11796ba597c5SAnurag S. Maskey }
11806ba597c5SAnurag S. Maskey /* Get the NCU type */
11816ba597c5SAnurag S. Maskey nwam_error_t
11826ba597c5SAnurag S. Maskey nwam_ncu_get_ncu_type(nwam_ncu_handle_t ncuh, nwam_ncu_type_t *typep)
11836ba597c5SAnurag S. Maskey {
11846ba597c5SAnurag S. Maskey 	nwam_error_t err;
11856ba597c5SAnurag S. Maskey 	nwam_value_t typeval;
11866ba597c5SAnurag S. Maskey 	uint64_t type;
11876ba597c5SAnurag S. Maskey 
11886ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval))
11896ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
11906ba597c5SAnurag S. Maskey 		return (err);
11916ba597c5SAnurag S. Maskey 	err = nwam_value_get_uint64(typeval, &type);
11926ba597c5SAnurag S. Maskey 	nwam_value_free(typeval);
11936ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
11946ba597c5SAnurag S. Maskey 		return (err);
11956ba597c5SAnurag S. Maskey 
11966ba597c5SAnurag S. Maskey 	*typep = type;
11976ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
11986ba597c5SAnurag S. Maskey }
11996ba597c5SAnurag S. Maskey 
12006ba597c5SAnurag S. Maskey /* Get the NCU class */
12016ba597c5SAnurag S. Maskey nwam_error_t
12026ba597c5SAnurag S. Maskey nwam_ncu_get_ncu_class(nwam_ncu_handle_t ncuh, nwam_ncu_class_t *classp)
12036ba597c5SAnurag S. Maskey {
12046ba597c5SAnurag S. Maskey 	nwam_error_t err;
12056ba597c5SAnurag S. Maskey 	nwam_value_t classval;
12066ba597c5SAnurag S. Maskey 	uint64_t class;
12076ba597c5SAnurag S. Maskey 
12086ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS,
12096ba597c5SAnurag S. Maskey 	    &classval)) != NWAM_SUCCESS)
12106ba597c5SAnurag S. Maskey 		return (err);
12116ba597c5SAnurag S. Maskey 	err = nwam_value_get_uint64(classval, &class);
12126ba597c5SAnurag S. Maskey 	nwam_value_free(classval);
12136ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
12146ba597c5SAnurag S. Maskey 		return (err);
12156ba597c5SAnurag S. Maskey 
12166ba597c5SAnurag S. Maskey 	*classp = class;
12176ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
12186ba597c5SAnurag S. Maskey }
12196ba597c5SAnurag S. Maskey 
12206ba597c5SAnurag S. Maskey /*
12216ba597c5SAnurag S. Maskey  * Determine if the NCU has manual activation-mode or not.
12226ba597c5SAnurag S. Maskey  */
12236ba597c5SAnurag S. Maskey nwam_error_t
12246ba597c5SAnurag S. Maskey nwam_ncu_is_manual(nwam_ncu_handle_t ncuh, boolean_t *manualp)
12256ba597c5SAnurag S. Maskey {
12266ba597c5SAnurag S. Maskey 	nwam_error_t err;
12276ba597c5SAnurag S. Maskey 	nwam_value_t actval;
12286ba597c5SAnurag S. Maskey 	uint64_t activation;
12296ba597c5SAnurag S. Maskey 
12306ba597c5SAnurag S. Maskey 	assert(ncuh != NULL);
12316ba597c5SAnurag S. Maskey 
12326ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ACTIVATION_MODE,
12336ba597c5SAnurag S. Maskey 	    &actval)) != NWAM_SUCCESS)
12346ba597c5SAnurag S. Maskey 		return (err);
12356ba597c5SAnurag S. Maskey 	err = nwam_value_get_uint64(actval, &activation);
12366ba597c5SAnurag S. Maskey 	nwam_value_free(actval);
12376ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
12386ba597c5SAnurag S. Maskey 		return (err);
12396ba597c5SAnurag S. Maskey 
12406ba597c5SAnurag S. Maskey 	if (activation == NWAM_ACTIVATION_MODE_MANUAL)
12416ba597c5SAnurag S. Maskey 		*manualp = B_TRUE;
12426ba597c5SAnurag S. Maskey 	else
12436ba597c5SAnurag S. Maskey 		*manualp = B_FALSE;
12446ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
12456ba597c5SAnurag S. Maskey }
12466ba597c5SAnurag S. Maskey 
12476ba597c5SAnurag S. Maskey /* Determine if NCU is enabled or not */
12486ba597c5SAnurag S. Maskey static nwam_error_t
12496ba597c5SAnurag S. Maskey nwam_ncu_is_enabled(nwam_ncu_handle_t ncuh, boolean_t *enabledp)
12506ba597c5SAnurag S. Maskey {
12516ba597c5SAnurag S. Maskey 	nwam_error_t err;
12526ba597c5SAnurag S. Maskey 	nwam_value_t enabledval;
12536ba597c5SAnurag S. Maskey 
12546ba597c5SAnurag S. Maskey 	assert(ncuh != NULL);
12556ba597c5SAnurag S. Maskey 
12566ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ENABLED,
12576ba597c5SAnurag S. Maskey 	    &enabledval)) != NWAM_SUCCESS)
12586ba597c5SAnurag S. Maskey 		return (err);
12596ba597c5SAnurag S. Maskey 	err = nwam_value_get_boolean(enabledval, enabledp);
12606ba597c5SAnurag S. Maskey 	nwam_value_free(enabledval);
12616ba597c5SAnurag S. Maskey 	return (err);
12626ba597c5SAnurag S. Maskey }
12636ba597c5SAnurag S. Maskey 
12646ba597c5SAnurag S. Maskey /* Update the enabled property */
12656ba597c5SAnurag S. Maskey static nwam_error_t
12666ba597c5SAnurag S. Maskey nwam_ncu_update_enabled(nwam_ncu_handle_t ncuh, boolean_t enabled)
12676ba597c5SAnurag S. Maskey {
12686ba597c5SAnurag S. Maskey 	nwam_error_t err;
12696ba597c5SAnurag S. Maskey 	nwam_value_t enabledval;
12706ba597c5SAnurag S. Maskey 
12716ba597c5SAnurag S. Maskey 	if ((err = nwam_value_create_boolean(enabled, &enabledval))
12726ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
12736ba597c5SAnurag S. Maskey 		return (err);
12746ba597c5SAnurag S. Maskey 	err = nwam_set_prop_value(ncuh->nwh_data, NWAM_NCU_PROP_ENABLED,
12756ba597c5SAnurag S. Maskey 	    enabledval);
12766ba597c5SAnurag S. Maskey 	nwam_value_free(enabledval);
12776ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
12786ba597c5SAnurag S. Maskey 		return (err);
12796ba597c5SAnurag S. Maskey 	return (nwam_ncu_commit(ncuh, NWAM_FLAG_ENTITY_ENABLE));
12806ba597c5SAnurag S. Maskey }
12816ba597c5SAnurag S. Maskey 
12826ba597c5SAnurag S. Maskey /*
12836ba597c5SAnurag S. Maskey  * Make ncu active; fails if the NCU's parent NCP is not active.
12846ba597c5SAnurag S. Maskey  */
12856ba597c5SAnurag S. Maskey nwam_error_t
12866ba597c5SAnurag S. Maskey nwam_ncu_enable(nwam_ncu_handle_t ncuh)
12876ba597c5SAnurag S. Maskey {
12886ba597c5SAnurag S. Maskey 	char *ncpname = NULL;
12896ba597c5SAnurag S. Maskey 	nwam_error_t err;
12906ba597c5SAnurag S. Maskey 	nwam_ncu_type_t type;
12916ba597c5SAnurag S. Maskey 	boolean_t read_only, enabled, manual;
12926ba597c5SAnurag S. Maskey 
12936ba597c5SAnurag S. Maskey 	assert(ncuh != NULL);
12946ba597c5SAnurag S. Maskey 
12956ba597c5SAnurag S. Maskey 	/* Don't allow NCUs of Automatic NCP to be enabled */
12966ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
12976ba597c5SAnurag S. Maskey 		return (err);
12986ba597c5SAnurag S. Maskey 	if (read_only)
12996ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_NOT_MANUAL);
13006ba597c5SAnurag S. Maskey 
13016ba597c5SAnurag S. Maskey 	/* Link NCUs with manual activation-mode or IP NCUs can be enabled */
13026ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_ncu_type(ncuh, &type)) != NWAM_SUCCESS)
13036ba597c5SAnurag S. Maskey 		return (err);
13046ba597c5SAnurag S. Maskey 
13056ba597c5SAnurag S. Maskey 	if (type == NWAM_NCU_TYPE_LINK) {
13066ba597c5SAnurag S. Maskey 		if ((err = nwam_ncu_is_manual(ncuh, &manual)) != NWAM_SUCCESS)
13076ba597c5SAnurag S. Maskey 			return (err);
13086ba597c5SAnurag S. Maskey 		if (!manual)
13096ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NOT_MANUAL);
13106ba597c5SAnurag S. Maskey 	}
13116ba597c5SAnurag S. Maskey 
13126ba597c5SAnurag S. Maskey 	/* Make sure NCU is not enabled */
13136ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_is_enabled(ncuh, &enabled)) != NWAM_SUCCESS ||
13146ba597c5SAnurag S. Maskey 	    (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
13156ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
13166ba597c5SAnurag S. Maskey 		return (err);
13176ba597c5SAnurag S. Maskey 
13186ba597c5SAnurag S. Maskey 	if (enabled) {
13196ba597c5SAnurag S. Maskey 		free(ncpname);
13206ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
13216ba597c5SAnurag S. Maskey 	}
13226ba597c5SAnurag S. Maskey 
13236ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_update_enabled(ncuh, B_TRUE)) != NWAM_SUCCESS) {
13246ba597c5SAnurag S. Maskey 		free(ncpname);
13256ba597c5SAnurag S. Maskey 		return (err);
13266ba597c5SAnurag S. Maskey 	}
13276ba597c5SAnurag S. Maskey 
13286ba597c5SAnurag S. Maskey 	err = nwam_enable(ncpname, ncuh);
13296ba597c5SAnurag S. Maskey 	free(ncpname);
13306ba597c5SAnurag S. Maskey 
13316ba597c5SAnurag S. Maskey 	/* nwamd may not be running, that's okay. */
13326ba597c5SAnurag S. Maskey 	if (err == NWAM_ERROR_BIND)
13336ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
13346ba597c5SAnurag S. Maskey 	else
13356ba597c5SAnurag S. Maskey 		return (err);
13366ba597c5SAnurag S. Maskey }
13376ba597c5SAnurag S. Maskey 
13386ba597c5SAnurag S. Maskey /*
13396ba597c5SAnurag S. Maskey  * Disable ncu; fails if the NCU's parent NCP is not active, or if the
13406ba597c5SAnurag S. Maskey  * NCU is not currently active.
13416ba597c5SAnurag S. Maskey  */
13426ba597c5SAnurag S. Maskey nwam_error_t
13436ba597c5SAnurag S. Maskey nwam_ncu_disable(nwam_ncu_handle_t ncuh)
13446ba597c5SAnurag S. Maskey {
13456ba597c5SAnurag S. Maskey 	char *ncpname = NULL;
13466ba597c5SAnurag S. Maskey 	nwam_error_t err;
13476ba597c5SAnurag S. Maskey 	nwam_ncu_type_t type;
13486ba597c5SAnurag S. Maskey 	boolean_t read_only, enabled, manual;
13496ba597c5SAnurag S. Maskey 
13506ba597c5SAnurag S. Maskey 	assert(ncuh != NULL);
13516ba597c5SAnurag S. Maskey 
13526ba597c5SAnurag S. Maskey 	/* Don't allow NCUs of Automatic NCP to be disabled */
13536ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
13546ba597c5SAnurag S. Maskey 		return (err);
13556ba597c5SAnurag S. Maskey 	if (read_only)
13566ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_NOT_MANUAL);
13576ba597c5SAnurag S. Maskey 
13586ba597c5SAnurag S. Maskey 	/* Link NCUs with manual activation-mode or IP NCUs can be disabled */
13596ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_ncu_type(ncuh, &type)) != NWAM_SUCCESS)
13606ba597c5SAnurag S. Maskey 		return (err);
13616ba597c5SAnurag S. Maskey 
13626ba597c5SAnurag S. Maskey 	if (type == NWAM_NCU_TYPE_LINK) {
13636ba597c5SAnurag S. Maskey 		if ((err = nwam_ncu_is_manual(ncuh, &manual)) != NWAM_SUCCESS)
13646ba597c5SAnurag S. Maskey 			return (err);
13656ba597c5SAnurag S. Maskey 		if (!manual)
13666ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NOT_MANUAL);
13676ba597c5SAnurag S. Maskey 	}
13686ba597c5SAnurag S. Maskey 
13696ba597c5SAnurag S. Maskey 	/* Make sure NCU is enabled */
13706ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_is_enabled(ncuh, &enabled)) != NWAM_SUCCESS ||
13716ba597c5SAnurag S. Maskey 	    (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
13726ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
13736ba597c5SAnurag S. Maskey 		return (err);
13746ba597c5SAnurag S. Maskey 
13756ba597c5SAnurag S. Maskey 	if (!enabled) {
13766ba597c5SAnurag S. Maskey 		free(ncpname);
13776ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
13786ba597c5SAnurag S. Maskey 	}
13796ba597c5SAnurag S. Maskey 
13806ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_update_enabled(ncuh, B_FALSE)) != NWAM_SUCCESS) {
13816ba597c5SAnurag S. Maskey 		free(ncpname);
13826ba597c5SAnurag S. Maskey 		return (err);
13836ba597c5SAnurag S. Maskey 	}
13846ba597c5SAnurag S. Maskey 
13856ba597c5SAnurag S. Maskey 	err = nwam_disable(ncpname, ncuh);
13866ba597c5SAnurag S. Maskey 	free(ncpname);
13876ba597c5SAnurag S. Maskey 
13886ba597c5SAnurag S. Maskey 	/* nwamd may not be running, that's okay. */
13896ba597c5SAnurag S. Maskey 	if (err == NWAM_ERROR_BIND)
13906ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
13916ba597c5SAnurag S. Maskey 	else
13926ba597c5SAnurag S. Maskey 		return (err);
13936ba597c5SAnurag S. Maskey }
13946ba597c5SAnurag S. Maskey 
13956ba597c5SAnurag S. Maskey nwam_error_t
13966ba597c5SAnurag S. Maskey nwam_ncu_destroy(nwam_ncu_handle_t ncuh, uint64_t flags)
13976ba597c5SAnurag S. Maskey {
13986ba597c5SAnurag S. Maskey 	char *ncpname, *ncpfile;
13996ba597c5SAnurag S. Maskey 	boolean_t read_only;
14006ba597c5SAnurag S. Maskey 	nwam_error_t err;
14016ba597c5SAnurag S. Maskey 
14026ba597c5SAnurag S. Maskey 	assert(ncuh != NULL);
14036ba597c5SAnurag S. Maskey 
14046ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
14056ba597c5SAnurag S. Maskey 		return (err);
14066ba597c5SAnurag S. Maskey 	if (read_only)
14076ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_NOT_DESTROYABLE);
14086ba597c5SAnurag S. Maskey 
14096ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
14106ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
14116ba597c5SAnurag S. Maskey 		return (err);
14126ba597c5SAnurag S. Maskey 	if ((err = nwam_ncp_name_to_file(ncpname, &ncpfile))
14136ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
14146ba597c5SAnurag S. Maskey 		free(ncpname);
14156ba597c5SAnurag S. Maskey 		return (err);
14166ba597c5SAnurag S. Maskey 	}
14176ba597c5SAnurag S. Maskey 
14186ba597c5SAnurag S. Maskey 	err = nwam_destroy(ncpfile, ncuh, flags);
14196ba597c5SAnurag S. Maskey 
14206ba597c5SAnurag S. Maskey 	free(ncpname);
14216ba597c5SAnurag S. Maskey 	free(ncpfile);
14226ba597c5SAnurag S. Maskey 
14236ba597c5SAnurag S. Maskey 	return (err);
14246ba597c5SAnurag S. Maskey }
14256ba597c5SAnurag S. Maskey 
14266ba597c5SAnurag S. Maskey nwam_error_t
14276ba597c5SAnurag S. Maskey nwam_ncu_get_prop_description(const char *propname, const char **descriptionp)
14286ba597c5SAnurag S. Maskey {
14296ba597c5SAnurag S. Maskey 	return (nwam_get_prop_description(ncu_prop_table, propname,
14306ba597c5SAnurag S. Maskey 	    descriptionp));
14316ba597c5SAnurag S. Maskey }
14326ba597c5SAnurag S. Maskey 
14336ba597c5SAnurag S. Maskey /* Get expected property data type */
14346ba597c5SAnurag S. Maskey nwam_error_t
14356ba597c5SAnurag S. Maskey nwam_ncu_get_prop_type(const char *propname, nwam_value_type_t *typep)
14366ba597c5SAnurag S. Maskey {
14376ba597c5SAnurag S. Maskey 	return (nwam_get_prop_type(ncu_prop_table, propname, typep));
14386ba597c5SAnurag S. Maskey }
14396ba597c5SAnurag S. Maskey 
14406ba597c5SAnurag S. Maskey nwam_error_t
14416ba597c5SAnurag S. Maskey nwam_ncu_prop_read_only(const char *propname, boolean_t *readp)
14426ba597c5SAnurag S. Maskey {
14436ba597c5SAnurag S. Maskey 	if ((*readp = NWAM_NCU_PROP_SETONCE(propname)) == B_TRUE)
14446ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
14456ba597c5SAnurag S. Maskey 
14466ba597c5SAnurag S. Maskey 	return (nwam_prop_read_only(ncu_prop_table, propname, readp));
14476ba597c5SAnurag S. Maskey }
14486ba597c5SAnurag S. Maskey 
14496ba597c5SAnurag S. Maskey nwam_error_t
14506ba597c5SAnurag S. Maskey nwam_ncu_prop_multivalued(const char *propname, boolean_t *multip)
14516ba597c5SAnurag S. Maskey {
14526ba597c5SAnurag S. Maskey 	return (nwam_prop_multivalued(ncu_prop_table, propname, multip));
14536ba597c5SAnurag S. Maskey }
14546ba597c5SAnurag S. Maskey 
14556ba597c5SAnurag S. Maskey /*
14566ba597c5SAnurag S. Maskey  * Ensure that the properties in the ncu, determined by that ncu's
14576ba597c5SAnurag S. Maskey  * type and class, belong there.
14586ba597c5SAnurag S. Maskey  */
14596ba597c5SAnurag S. Maskey static nwam_error_t
14606ba597c5SAnurag S. Maskey nwam_ncu_validate_prop_membership(nwam_ncu_handle_t ncuh, const char *propname)
14616ba597c5SAnurag S. Maskey {
14626ba597c5SAnurag S. Maskey 	struct nwam_prop_table_entry *pte;
14636ba597c5SAnurag S. Maskey 	nwam_value_t typeval, classval;
14646ba597c5SAnurag S. Maskey 	uint64_t type, class;
14656ba597c5SAnurag S. Maskey 	uint64_t typeflags = 0, classflags = 0;
14666ba597c5SAnurag S. Maskey 
14676ba597c5SAnurag S. Maskey 	/* Get type/class from ncu */
14686ba597c5SAnurag S. Maskey 	if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval)
14696ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
14706ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
14716ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS) {
14726ba597c5SAnurag S. Maskey 		nwam_value_free(typeval);
14736ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
14746ba597c5SAnurag S. Maskey 	}
14756ba597c5SAnurag S. Maskey 	typeflags = nwam_ncu_type_to_flag((nwam_ncu_type_t)type);
14766ba597c5SAnurag S. Maskey 	nwam_value_free(typeval);
14776ba597c5SAnurag S. Maskey 
14786ba597c5SAnurag S. Maskey 	if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS, &classval)
14796ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
14806ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
14816ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(classval, &class) != NWAM_SUCCESS) {
14826ba597c5SAnurag S. Maskey 		nwam_value_free(classval);
14836ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
14846ba597c5SAnurag S. Maskey 	}
14856ba597c5SAnurag S. Maskey 	classflags = nwam_ncu_class_to_flag((nwam_ncu_class_t)class);
14866ba597c5SAnurag S. Maskey 	nwam_value_free(classval);
14876ba597c5SAnurag S. Maskey 
14886ba597c5SAnurag S. Maskey 	if ((pte = nwam_get_prop_table_entry(ncu_prop_table, propname)) == NULL)
14896ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
14906ba597c5SAnurag S. Maskey 
14916ba597c5SAnurag S. Maskey 	if (typeflags & pte->prop_type_membership &&
14926ba597c5SAnurag S. Maskey 	    classflags & pte->prop_class_membership) {
14936ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
14946ba597c5SAnurag S. Maskey 	} else {
14956ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_MEMBER);
14966ba597c5SAnurag S. Maskey 	}
14976ba597c5SAnurag S. Maskey }
14986ba597c5SAnurag S. Maskey 
14996ba597c5SAnurag S. Maskey /* Validate property's ncu membership and type, number and range of values */
15006ba597c5SAnurag S. Maskey nwam_error_t
15016ba597c5SAnurag S. Maskey nwam_ncu_validate_prop(nwam_ncu_handle_t ncuh, const char *propname,
15026ba597c5SAnurag S. Maskey     nwam_value_t value)
15036ba597c5SAnurag S. Maskey {
15046ba597c5SAnurag S. Maskey 	nwam_error_t err;
15056ba597c5SAnurag S. Maskey 
15066ba597c5SAnurag S. Maskey 	assert(ncuh != NULL && propname != NULL);
15076ba597c5SAnurag S. Maskey 
15086ba597c5SAnurag S. Maskey 	/* First, determine if this property is valid for this ncu */
15096ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_validate_prop_membership(ncuh, propname))
15106ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
15116ba597c5SAnurag S. Maskey 		return (err);
15126ba597c5SAnurag S. Maskey 
15136ba597c5SAnurag S. Maskey 	return (nwam_validate_prop(ncu_prop_table, ncuh, propname, value));
15146ba597c5SAnurag S. Maskey }
15156ba597c5SAnurag S. Maskey 
15166ba597c5SAnurag S. Maskey /* Property-specific value validation functions follow */
15176ba597c5SAnurag S. Maskey 
15186ba597c5SAnurag S. Maskey static nwam_error_t
15196ba597c5SAnurag S. Maskey valid_type(nwam_value_t value)
15206ba597c5SAnurag S. Maskey {
15216ba597c5SAnurag S. Maskey 	uint64_t type;
15226ba597c5SAnurag S. Maskey 
15236ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(value, &type) != NWAM_SUCCESS ||
15246ba597c5SAnurag S. Maskey 	    type > NWAM_NCU_TYPE_INTERFACE)
15256ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15266ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
15276ba597c5SAnurag S. Maskey }
15286ba597c5SAnurag S. Maskey 
15296ba597c5SAnurag S. Maskey static nwam_error_t
15306ba597c5SAnurag S. Maskey valid_class(nwam_value_t value)
15316ba597c5SAnurag S. Maskey {
15326ba597c5SAnurag S. Maskey 	uint64_t class;
15336ba597c5SAnurag S. Maskey 
15346ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(value, &class) != NWAM_SUCCESS ||
15356ba597c5SAnurag S. Maskey 	    class > NWAM_NCU_CLASS_IP)
15366ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15376ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
15386ba597c5SAnurag S. Maskey }
15396ba597c5SAnurag S. Maskey 
15406ba597c5SAnurag S. Maskey static nwam_error_t
15416ba597c5SAnurag S. Maskey valid_ncp(nwam_value_t value)
15426ba597c5SAnurag S. Maskey {
15436ba597c5SAnurag S. Maskey 	char *ncp;
15446ba597c5SAnurag S. Maskey 
15456ba597c5SAnurag S. Maskey 	if (nwam_value_get_string(value, &ncp) != NWAM_SUCCESS)
15466ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15476ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
15486ba597c5SAnurag S. Maskey }
15496ba597c5SAnurag S. Maskey 
15506ba597c5SAnurag S. Maskey static nwam_error_t
15516ba597c5SAnurag S. Maskey valid_priority_mode(nwam_value_t value)
15526ba597c5SAnurag S. Maskey {
15536ba597c5SAnurag S. Maskey 	uint64_t priority_mode;
15546ba597c5SAnurag S. Maskey 
15556ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(value, &priority_mode) != NWAM_SUCCESS ||
15566ba597c5SAnurag S. Maskey 	    priority_mode > NWAM_PRIORITY_MODE_ALL)
15576ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15586ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
15596ba597c5SAnurag S. Maskey }
15606ba597c5SAnurag S. Maskey 
15616ba597c5SAnurag S. Maskey static nwam_error_t
15626ba597c5SAnurag S. Maskey valid_ncu_activation_mode(nwam_value_t value)
15636ba597c5SAnurag S. Maskey {
15646ba597c5SAnurag S. Maskey 	uint64_t activation_mode;
15656ba597c5SAnurag S. Maskey 
15666ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64(value, &activation_mode) != NWAM_SUCCESS)
15676ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15686ba597c5SAnurag S. Maskey 
15696ba597c5SAnurag S. Maskey 	switch (activation_mode) {
15706ba597c5SAnurag S. Maskey 	case NWAM_ACTIVATION_MODE_MANUAL:
15716ba597c5SAnurag S. Maskey 	case NWAM_ACTIVATION_MODE_PRIORITIZED:
15726ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
15736ba597c5SAnurag S. Maskey 	}
15746ba597c5SAnurag S. Maskey 	return (NWAM_ENTITY_INVALID_VALUE);
15756ba597c5SAnurag S. Maskey }
15766ba597c5SAnurag S. Maskey 
15776ba597c5SAnurag S. Maskey /* ARGSUSED0 */
15786ba597c5SAnurag S. Maskey static nwam_error_t
15796ba597c5SAnurag S. Maskey valid_link_autopush(nwam_value_t value)
15806ba597c5SAnurag S. Maskey {
15816ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
15826ba597c5SAnurag S. Maskey }
15836ba597c5SAnurag S. Maskey 
15846ba597c5SAnurag S. Maskey static nwam_error_t
15856ba597c5SAnurag S. Maskey valid_ip_version(nwam_value_t value)
15866ba597c5SAnurag S. Maskey {
15876ba597c5SAnurag S. Maskey 	uint64_t *versions;
15886ba597c5SAnurag S. Maskey 	uint_t i, numvalues;
15896ba597c5SAnurag S. Maskey 
15906ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64_array(value, &versions, &numvalues)
15916ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
15926ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15936ba597c5SAnurag S. Maskey 
15946ba597c5SAnurag S. Maskey 	for (i = 0; i < numvalues; i++) {
15956ba597c5SAnurag S. Maskey 		if (versions[i] != IPV4_VERSION &&
15966ba597c5SAnurag S. Maskey 		    versions[i] != IPV6_VERSION)
15976ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
15986ba597c5SAnurag S. Maskey 	}
15996ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
16006ba597c5SAnurag S. Maskey }
16016ba597c5SAnurag S. Maskey 
16026ba597c5SAnurag S. Maskey static nwam_error_t
16036ba597c5SAnurag S. Maskey valid_addrsrc_v4(nwam_value_t value)
16046ba597c5SAnurag S. Maskey {
16056ba597c5SAnurag S. Maskey 	uint64_t *addrsrc;
16066ba597c5SAnurag S. Maskey 	uint_t i, numvalues;
16076ba597c5SAnurag S. Maskey 
16086ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64_array(value, &addrsrc, &numvalues)
16096ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
16106ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
16116ba597c5SAnurag S. Maskey 
16126ba597c5SAnurag S. Maskey 	for (i = 0; i < numvalues; i++) {
16136ba597c5SAnurag S. Maskey 		if (addrsrc[i] != NWAM_ADDRSRC_DHCP &&
16146ba597c5SAnurag S. Maskey 		    addrsrc[i] != NWAM_ADDRSRC_STATIC)
16156ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_INVALID_VALUE);
16166ba597c5SAnurag S. Maskey 	}
16176ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
16186ba597c5SAnurag S. Maskey }
16196ba597c5SAnurag S. Maskey 
16206ba597c5SAnurag S. Maskey static nwam_error_t
16216ba597c5SAnurag S. Maskey valid_addrsrc_v6(nwam_value_t value)
16226ba597c5SAnurag S. Maskey {
16236ba597c5SAnurag S. Maskey 	uint64_t *addrsrc;
16246ba597c5SAnurag S. Maskey 	uint_t i, numvalues;
16256ba597c5SAnurag S. Maskey 	boolean_t dhcp_found = B_FALSE, autoconf_found = B_FALSE;
16266ba597c5SAnurag S. Maskey 
16276ba597c5SAnurag S. Maskey 	if (nwam_value_get_uint64_array(value, &addrsrc, &numvalues)
16286ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
16296ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
16306ba597c5SAnurag S. Maskey 
16316ba597c5SAnurag S. Maskey 	for (i = 0; i < numvalues; i++) {
16326ba597c5SAnurag S. Maskey 		if (addrsrc[i] != NWAM_ADDRSRC_DHCP &&
16336ba597c5SAnurag S. Maskey 		    addrsrc[i] != NWAM_ADDRSRC_STATIC &&
16346ba597c5SAnurag S. Maskey 		    addrsrc[i] != NWAM_ADDRSRC_AUTOCONF)
16356ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_INVALID_VALUE);
16366ba597c5SAnurag S. Maskey 		if (addrsrc[i] == NWAM_ADDRSRC_DHCP)
16376ba597c5SAnurag S. Maskey 			dhcp_found = B_TRUE;
16386ba597c5SAnurag S. Maskey 		if (addrsrc[i] == NWAM_ADDRSRC_AUTOCONF)
16396ba597c5SAnurag S. Maskey 			autoconf_found = B_TRUE;
16406ba597c5SAnurag S. Maskey 	}
16416ba597c5SAnurag S. Maskey 	/*
16426ba597c5SAnurag S. Maskey 	 * DHCP and AUTOCONF need to be specified as v6 address sources
16436ba597c5SAnurag S. Maskey 	 * since there is no way to switch them off in NWAM at present.
16446ba597c5SAnurag S. Maskey 	 */
16456ba597c5SAnurag S. Maskey 	if (dhcp_found && autoconf_found)
16466ba597c5SAnurag S. Maskey 		return (NWAM_SUCCESS);
16476ba597c5SAnurag S. Maskey 	else
16486ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID_VALUE);
16496ba597c5SAnurag S. Maskey }
16506ba597c5SAnurag S. Maskey 
16516ba597c5SAnurag S. Maskey /* ARGSUSED0 */
16526ba597c5SAnurag S. Maskey static nwam_error_t
16536ba597c5SAnurag S. Maskey valid_link_mtu(nwam_value_t value)
16546ba597c5SAnurag S. Maskey {
16556ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
16566ba597c5SAnurag S. Maskey }
16576ba597c5SAnurag S. Maskey 
16586ba597c5SAnurag S. Maskey nwam_error_t
16596ba597c5SAnurag S. Maskey nwam_ncu_validate(nwam_ncu_handle_t ncuh, const char **errpropp)
16606ba597c5SAnurag S. Maskey {
16616ba597c5SAnurag S. Maskey 	return (nwam_validate(ncu_prop_table, ncuh, errpropp));
16626ba597c5SAnurag S. Maskey }
16636ba597c5SAnurag S. Maskey 
16646ba597c5SAnurag S. Maskey /*
16656ba597c5SAnurag S. Maskey  * Given the ncu type and ncu class, return the list of properties that needs
16666ba597c5SAnurag S. Maskey  * to be set. Note this list is a complete property list that includes both
16676ba597c5SAnurag S. Maskey  * the required ones and the optional ones. Caller needs to free prop_list.
16686ba597c5SAnurag S. Maskey  */
16696ba597c5SAnurag S. Maskey nwam_error_t
16706ba597c5SAnurag S. Maskey nwam_ncu_get_default_proplist(nwam_ncu_type_t type, nwam_ncu_class_t class,
16716ba597c5SAnurag S. Maskey     const char ***prop_list, uint_t *numvalues)
16726ba597c5SAnurag S. Maskey {
16736ba597c5SAnurag S. Maskey 	uint64_t typeflags = nwam_ncu_type_to_flag(type);
16746ba597c5SAnurag S. Maskey 	uint64_t classflags = nwam_ncu_class_to_flag(class);
16756ba597c5SAnurag S. Maskey 
16766ba597c5SAnurag S. Maskey 	return (nwam_get_default_proplist(ncu_prop_table, typeflags,
16776ba597c5SAnurag S. Maskey 	    classflags, prop_list, numvalues));
16786ba597c5SAnurag S. Maskey }
16796ba597c5SAnurag S. Maskey 
16806ba597c5SAnurag S. Maskey nwam_error_t
16816ba597c5SAnurag S. Maskey nwam_ncp_get_state(nwam_ncp_handle_t ncph, nwam_state_t *statep,
16826ba597c5SAnurag S. Maskey     nwam_aux_state_t *auxp)
16836ba597c5SAnurag S. Maskey {
16846ba597c5SAnurag S. Maskey 	return (nwam_get_state(ncph->nwh_name, ncph, statep, auxp));
16856ba597c5SAnurag S. Maskey }
16866ba597c5SAnurag S. Maskey 
16876ba597c5SAnurag S. Maskey nwam_error_t
16886ba597c5SAnurag S. Maskey nwam_ncu_get_state(nwam_ncu_handle_t ncuh, nwam_state_t *statep,
16896ba597c5SAnurag S. Maskey     nwam_aux_state_t *auxp)
16906ba597c5SAnurag S. Maskey {
16916ba597c5SAnurag S. Maskey 	nwam_ncp_handle_t ncph;
16926ba597c5SAnurag S. Maskey 	char *ncpname;
16936ba597c5SAnurag S. Maskey 	nwam_error_t err;
16946ba597c5SAnurag S. Maskey 
16956ba597c5SAnurag S. Maskey 	assert(ncuh != NULL);
16966ba597c5SAnurag S. Maskey 
16976ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_ncp(ncuh, &ncph)) != NWAM_SUCCESS)
16986ba597c5SAnurag S. Maskey 		return (err);
16996ba597c5SAnurag S. Maskey 	if (!nwam_ncp_is_active(ncph)) {
17006ba597c5SAnurag S. Maskey 		nwam_ncp_free(ncph);
17016ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_INVALID);
17026ba597c5SAnurag S. Maskey 	}
17036ba597c5SAnurag S. Maskey 	nwam_ncp_free(ncph);
17046ba597c5SAnurag S. Maskey 
17056ba597c5SAnurag S. Maskey 	if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
17066ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
17076ba597c5SAnurag S. Maskey 		return (err);
17086ba597c5SAnurag S. Maskey 
17096ba597c5SAnurag S. Maskey 	err = nwam_request_state(NWAM_OBJECT_TYPE_NCU, ncuh->nwh_name, ncpname,
17106ba597c5SAnurag S. Maskey 	    statep, auxp);
17116ba597c5SAnurag S. Maskey 	free(ncpname);
17126ba597c5SAnurag S. Maskey 	return (err);
17136ba597c5SAnurag S. Maskey }
17146ba597c5SAnurag S. Maskey 
17156ba597c5SAnurag S. Maskey nwam_error_t
17166ba597c5SAnurag S. Maskey nwam_ncp_get_active_priority_group(int64_t *priorityp)
17176ba597c5SAnurag S. Maskey {
17186ba597c5SAnurag S. Maskey 	return (nwam_request_active_priority_group(priorityp));
17196ba597c5SAnurag S. Maskey }
1720