4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
32 #include <sys/param.h>
33 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
45 #include "libnwam_impl.h"
46 #include <libnwam_priv.h>
50 * Functions to support creating, modifying, destroying, querying the
51 * state of and changing the state of NCP (Network Configuration Profiles)
52 * and the NCUs (Network Configuration Units) that are contained in those
53 * NCP objects. An NCP is simply a container for a set of NCUs which represent
54 * the datalink and interface configuration preferences for the system.
55 * An NCP can consist a set of prioritized link NCUs, e.g. wired links preferred
56 * over wireless, a set of manually enabled/diasbled NCUs, or a combination
57 * of both. Interface NCUs inherit activation from their underlying links,
58 * so if wired is preferred over wireless and a cable is plugged in,
59 * the wired link NCU will be active, as will the IP interface NCU above it.
63 * The NCU property table is used to mapping property types to property name
64 * strings, their associated value types etc. The table is used for validation
65 * purposes, and for commit()ing and read()ing NCUs.
68 static nwam_error_t
valid_type(nwam_value_t
);
69 static nwam_error_t
valid_class(nwam_value_t
);
70 static nwam_error_t
valid_ncp(nwam_value_t
);
71 static nwam_error_t
valid_priority_mode(nwam_value_t
);
72 static nwam_error_t
valid_ncu_activation_mode(nwam_value_t
);
73 static nwam_error_t
valid_link_autopush(nwam_value_t
);
74 static nwam_error_t
valid_link_mtu(nwam_value_t
);
75 static nwam_error_t
valid_ip_version(nwam_value_t
);
76 static nwam_error_t
valid_addrsrc_v4(nwam_value_t
);
77 static nwam_error_t
valid_addrsrc_v6(nwam_value_t
);
78 static nwam_error_t
valid_reqhost(nwam_value_t
);
80 struct nwam_prop_table_entry ncu_prop_table_entries
[] = {
81 {NWAM_NCU_PROP_TYPE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1, valid_type
,
82 "specifies the NCU type - valid values are \'datalink\' and \'ip\'",
83 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
84 {NWAM_NCU_PROP_CLASS
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1,
86 "specifies the NCU class - valid values are "
87 "\'phys\' and \'ip\'",
88 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
89 {NWAM_NCU_PROP_PARENT_NCP
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 1, 1,
91 "specifies the parent NCP name",
92 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
93 {NWAM_NCU_PROP_ACTIVATION_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1,
94 valid_ncu_activation_mode
,
95 "specifies the NCU activation mode - valid values are:\n"
96 "\'prioritized\' and \'manual\'",
97 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
98 {NWAM_NCU_PROP_ENABLED
, NWAM_VALUE_TYPE_BOOLEAN
, B_TRUE
, 0, 1,
100 "specifies if manual NCU is to be enabled",
101 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
102 {NWAM_NCU_PROP_PRIORITY_GROUP
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0, 1,
104 "specifies the priority grouping of NCUs - lower values are "
105 "prioritized, negative values are invalid",
106 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
107 {NWAM_NCU_PROP_PRIORITY_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0, 1,
109 "specifies the mode of prioritization - valid values are:\n"
110 "\'exclusive\', \'shared\' and \'all\'",
111 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
112 {NWAM_NCU_PROP_LINK_MAC_ADDR
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
114 "specifies MAC address of form aa:bb:cc:dd:ee:ff for the link",
115 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
116 {NWAM_NCU_PROP_LINK_AUTOPUSH
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
117 NWAM_MAX_NUM_VALUES
, valid_link_autopush
,
118 "specifies modules to autopush on link",
119 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
120 {NWAM_NCU_PROP_LINK_MTU
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0, 1,
122 "specifies MTU for link",
123 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
124 {NWAM_NCU_PROP_IP_VERSION
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0,
125 NWAM_MAX_NUM_VALUES
, valid_ip_version
,
126 "specifies IP versions for IP NCU - valid values are:\n"
127 "\'ipv4\' and \'ipv6\'",
128 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
129 {NWAM_NCU_PROP_IPV4_ADDRSRC
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0,
130 NWAM_MAX_NUM_VALUES
, valid_addrsrc_v4
,
131 "specifies IPv4 address source(s) - valid values are:\n"
132 "\'dhcp\' and \'static\'",
133 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
134 {NWAM_NCU_PROP_IPV4_ADDR
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
135 NWAM_MAX_NUM_VALUES
, nwam_valid_host_v4
,
136 "specifies static IPv4 host address(es)",
137 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
138 {NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
139 1, nwam_valid_route_v4
,
140 "specifies per-interface default IPv4 route",
141 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
142 {NWAM_NCU_PROP_IPV6_ADDRSRC
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0,
143 NWAM_MAX_NUM_VALUES
, valid_addrsrc_v6
,
144 "specifies IPv6 address source(s) - valid values are:\n"
145 "\'dhcp\', \'autoconf\' and \'static\'.\n"
146 "\'dhcp\' and \'autoconf\' are mandatory values.",
147 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
148 {NWAM_NCU_PROP_IPV6_ADDR
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
149 NWAM_MAX_NUM_VALUES
, nwam_valid_host_v6
,
150 "specifies static IPv6 host address(es)",
151 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
152 {NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
153 1, nwam_valid_route_v6
,
154 "specifies per-interface default IPv6 route",
155 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
156 {NWAM_NCU_PROP_IP_PRIMARY
, NWAM_VALUE_TYPE_BOOLEAN
, B_FALSE
, 0,
157 1, nwam_valid_boolean
,
158 "specifies the status of an interface as primary for the delivery"
159 " of client-wide configuration data",
160 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
161 {NWAM_NCU_PROP_IP_REQHOST
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
163 "specifies a requested hostname for the interface",
164 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
167 #define NWAM_NUM_NCU_PROPS (sizeof (ncu_prop_table_entries) / \
168 sizeof (*ncu_prop_table_entries))
170 struct nwam_prop_table ncu_prop_table
=
171 { NWAM_NUM_NCU_PROPS
, ncu_prop_table_entries
};
174 nwam_ncp_get_name(nwam_ncp_handle_t ncph
, char **namep
)
176 return (nwam_get_name(ncph
, namep
));
180 nwam_ncp_name_to_file(const char *name
, char **filename
)
182 assert(name
!= NULL
&& filename
!= NULL
);
184 if ((*filename
= malloc(MAXPATHLEN
)) == NULL
)
185 return (NWAM_NO_MEMORY
);
187 (void) snprintf(*filename
, MAXPATHLEN
, "%s%s%s%s", NWAM_CONF_DIR
,
188 NWAM_NCP_CONF_FILE_PRE
, name
, NWAM_NCP_CONF_FILE_SUF
);
190 return (NWAM_SUCCESS
);
195 nwam_ncp_create(const char *name
, uint64_t flags
, nwam_ncp_handle_t
*ncphp
)
200 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCP
, name
, ncphp
))
204 /* Create empty container for NCUs */
205 if ((err
= nwam_ncp_name_to_file(name
, &ncpfile
))
212 if ((err
= nwam_commit(ncpfile
, *ncphp
, flags
)) != NWAM_SUCCESS
) {
222 /* Used by libnwam_files.c */
224 nwam_ncp_file_to_name(const char *path
, char **name
)
226 char path_copy
[MAXPATHLEN
];
227 char *filename
, *suffix
;
229 assert(path
!= NULL
&& name
!= NULL
);
231 /* Make a copy as basename(3c) may modify string */
232 (void) strlcpy(path_copy
, path
, MAXPATHLEN
);
234 if ((*name
= malloc(NWAM_MAX_NAME_LEN
)) == NULL
)
235 return (NWAM_NO_MEMORY
);
237 if ((filename
= basename(path_copy
)) == NULL
) {
239 return (NWAM_ENTITY_INVALID
);
242 /* Ensure filename begins/ends with right prefix/suffix */
243 if (sscanf(filename
, NWAM_NCP_CONF_FILE_PRE
"%256[^\n]s", *name
) < 1) {
245 return (NWAM_ENTITY_INVALID
);
247 suffix
= *name
+ strlen(*name
) - strlen(NWAM_NCP_CONF_FILE_SUF
);
248 if (strstr(*name
, NWAM_NCP_CONF_FILE_SUF
) != suffix
) {
250 return (NWAM_ENTITY_INVALID
);
254 return (NWAM_SUCCESS
);
259 nwam_ncp_read(const char *name
, uint64_t flags
, nwam_ncp_handle_t
*ncphp
)
264 assert(name
!= NULL
&& ncphp
!= NULL
);
266 /* try to read the associated ncp configuration */
267 if ((err
= nwam_ncp_name_to_file(name
, &filename
)) != NWAM_SUCCESS
) {
272 err
= nwam_read(NWAM_OBJECT_TYPE_NCP
, filename
, name
, flags
, ncphp
);
278 nwam_ncu_get_parent_ncp_name(nwam_ncu_handle_t ncuh
, char **parentnamep
)
280 nwam_value_t parentval
= NULL
;
284 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_PARENT_NCP
,
285 &parentval
)) != NWAM_SUCCESS
||
286 (err
= nwam_value_get_string(parentval
, &parentname
))
288 (*parentnamep
= strdup(parentname
)) == NULL
) {
289 if (parentval
!= NULL
)
290 nwam_value_free(parentval
);
294 nwam_value_free(parentval
);
296 return (NWAM_SUCCESS
);
300 nwam_ncp_copy_callback(nwam_ncu_handle_t oldncuh
, void *arg
)
303 nwam_ncu_handle_t newncuh
= NULL
;
305 char *oldfilename
= NULL
, *newfilename
= NULL
;
306 nwam_ncp_handle_t newncph
= (nwam_ncp_handle_t
)arg
;
307 nwam_value_t newparentval
;
309 /* Get filenames for the new and old NCU's */
310 if ((err
= nwam_ncu_get_parent_ncp_name(oldncuh
, &oldparent
))
313 err
= nwam_ncp_name_to_file(oldparent
, &oldfilename
);
315 if (err
!= NWAM_SUCCESS
)
317 if ((err
= nwam_ncp_name_to_file(newncph
->nwh_name
, &newfilename
))
321 /* new NCU name (and typedname) is the same as the old name */
322 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCU
, oldncuh
->nwh_name
,
323 &newncuh
)) != NWAM_SUCCESS
)
325 /* Duplicate the old NCU's data */
326 if ((err
= nwam_dup_object_list(oldncuh
->nwh_data
,
327 &(newncuh
->nwh_data
))) != NWAM_SUCCESS
)
330 /* Update the parent property for the new NCU */
331 if ((err
= nwam_value_create_string(newncph
->nwh_name
, &newparentval
))
334 err
= nwam_set_prop_value(newncuh
->nwh_data
, NWAM_NCU_PROP_PARENT_NCP
,
336 nwam_value_free(newparentval
);
337 if (err
!= NWAM_SUCCESS
)
340 /* Save the new NCU */
341 err
= nwam_commit(newfilename
, newncuh
, 0);
346 nwam_ncu_free(newncuh
);
351 nwam_ncp_copy(nwam_ncp_handle_t oldncph
, const char *newname
,
352 nwam_ncp_handle_t
*newncphp
)
354 nwam_ncp_handle_t ncph
;
358 assert(oldncph
!= NULL
&& newname
!= NULL
&& newncphp
!= NULL
);
360 /* check if newname NCP already exists */
361 if (nwam_ncp_read(newname
, 0, &ncph
) == NWAM_SUCCESS
) {
364 return (NWAM_ENTITY_EXISTS
);
367 /* create new handle */
368 if ((err
= nwam_ncp_create(newname
, 0, newncphp
)) != NWAM_SUCCESS
)
371 err
= nwam_ncp_walk_ncus(oldncph
, nwam_ncp_copy_callback
, *newncphp
,
372 NWAM_FLAG_NCU_TYPE_CLASS_ALL
, &cb_ret
);
373 if (err
!= NWAM_SUCCESS
) {
374 /* remove the NCP even if any NCU's had already been copied */
375 (void) nwam_ncp_destroy(*newncphp
, 0);
377 if (err
== NWAM_WALK_HALTED
)
383 return (NWAM_SUCCESS
);
387 * Convert type to flag
390 nwam_ncu_type_to_flag(nwam_ncu_type_t type
)
393 case NWAM_NCU_TYPE_LINK
:
394 return (NWAM_FLAG_NCU_TYPE_LINK
);
395 case NWAM_NCU_TYPE_INTERFACE
:
396 return (NWAM_FLAG_NCU_TYPE_INTERFACE
);
397 case NWAM_NCU_TYPE_ANY
:
398 return (NWAM_FLAG_NCU_TYPE_ALL
);
405 * Convert class to flag
408 nwam_ncu_class_to_flag(nwam_ncu_class_t
class)
411 case NWAM_NCU_CLASS_PHYS
:
412 return (NWAM_FLAG_NCU_CLASS_PHYS
);
413 case NWAM_NCU_CLASS_IP
:
414 return (NWAM_FLAG_NCU_CLASS_IP
);
415 case NWAM_NCU_CLASS_ANY
:
416 return (NWAM_FLAG_NCU_CLASS_ALL
);
423 * Infer NCU type from NCU class
426 nwam_ncu_class_to_type(nwam_ncu_class_t
class)
429 case NWAM_NCU_CLASS_PHYS
:
430 return (NWAM_NCU_TYPE_LINK
);
431 case NWAM_NCU_CLASS_IP
:
432 return (NWAM_NCU_TYPE_INTERFACE
);
433 case NWAM_NCU_CLASS_ANY
:
434 return (NWAM_NCU_TYPE_ANY
);
436 return (NWAM_NCU_TYPE_UNKNOWN
);
441 * Make ncp active, deactivating any other active ncp.
444 nwam_ncp_enable(nwam_ncp_handle_t ncph
)
449 assert(ncph
!= NULL
);
451 err
= nwam_enable(NULL
, ncph
);
453 if (err
== NWAM_ERROR_BIND
) {
455 * nwamd is not running, set active_ncp property so when
456 * nwamd is next started, this NCP will be used.
458 if ((err
= nwam_ncp_get_name(ncph
, &name
)) != NWAM_SUCCESS
)
461 err
= nwam_set_smf_string_property(NWAM_FMRI
, NWAM_PG
,
462 NWAM_PROP_ACTIVE_NCP
, name
);
469 /* Compare NCP names c1 and c2 using strcasecmp() */
471 ncpname_cmp(const void *c1
, const void *c2
)
473 return (strcasecmp(*(const char **)c1
, *(const char **)c2
));
478 nwam_walk_ncps(int (*cb
)(nwam_ncp_handle_t
, void *), void *data
,
479 uint64_t flags
, int *retp
)
481 char *ncpname
, **ncpfiles
;
482 nwam_ncp_handle_t ncph
;
486 uint_t i
, num_ncpfiles
;
491 if ((err
= nwam_valid_flags(flags
, NWAM_FLAG_BLOCKING
)) != NWAM_SUCCESS
)
494 * To get list of NCP files, call nwam_read_object_from_backend()
495 * with "parent" argument set to NULL. We get back an object list
496 * consisting of string arrays for each object type - NCP, ENM
497 * and location. We retrieve the NCP list, which corresponds to
498 * the set of NCP backend parent objects (these are files at present).
500 if ((err
= nwam_read_object_from_backend(NULL
, NULL
, flags
,
501 &objlist
)) != NWAM_SUCCESS
)
504 if ((err
= nwam_get_prop_value(objlist
, NWAM_NCP_OBJECT_STRING
, &value
))
506 nwam_free_object_list(objlist
);
509 if ((err
= nwam_value_get_string_array(value
, &ncpfiles
,
510 &num_ncpfiles
)) != NWAM_SUCCESS
) {
511 nwam_value_free(value
);
512 nwam_free_object_list(objlist
);
516 /* sort the NCP names alphabetically */
517 qsort(ncpfiles
, num_ncpfiles
, sizeof (char *), ncpname_cmp
);
519 for (i
= 0; i
< num_ncpfiles
; i
++) {
520 if (nwam_ncp_file_to_name(ncpfiles
[i
], &ncpname
)
523 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCP
, ncpname
,
524 &ncph
)) != NWAM_SUCCESS
) {
528 ret
= cb(ncph
, data
);
532 err
= NWAM_WALK_HALTED
;
536 nwam_value_free(value
);
537 nwam_free_object_list(objlist
);
545 * Checks if NCP is read-only. Only NWAM_NCP_NAME_AUTOMATIC is read-only
546 * for all but the netadm user (which nwamd runs as).
549 nwam_ncp_get_read_only(nwam_ncp_handle_t ncph
, boolean_t
*readp
)
554 assert(ncph
!= NULL
&& readp
!= NULL
);
556 if ((err
= nwam_ncp_get_name(ncph
, &name
)) != NWAM_SUCCESS
)
559 if (NWAM_NCP_AUTOMATIC(name
))
560 *readp
= !nwam_uid_is_special();
565 return (NWAM_SUCCESS
);
568 /* Checks if NCU is writable depending on its parent */
570 nwam_ncu_get_read_only(nwam_ncu_handle_t ncuh
, boolean_t
*readp
)
573 nwam_ncp_handle_t ncph
;
575 assert(ncuh
!= NULL
&& readp
!= NULL
);
577 if ((err
= nwam_ncu_get_ncp(ncuh
, &ncph
)) != NWAM_SUCCESS
)
580 err
= nwam_ncp_get_read_only(ncph
, readp
);
585 /* Returns true if the NCP is active */
587 nwam_ncp_is_active(nwam_ncp_handle_t ncph
)
589 char *active_ncp
, *name
;
592 assert(ncph
!= NULL
);
595 * Determine which NCP is active via the nwamd/active_ncp property
596 * value. This allows us to determine which NCP is active even
597 * if nwamd is not running.
599 if (nwam_ncp_get_name(ncph
, &name
) != NWAM_SUCCESS
||
600 nwam_get_smf_string_property(NWAM_FMRI
, NWAM_PG
,
601 NWAM_PROP_ACTIVE_NCP
, &active_ncp
) != NWAM_SUCCESS
)
604 ret
= (strcmp(name
, active_ncp
) == 0);
613 nwam_ncp_destroy(nwam_ncp_handle_t ncph
, uint64_t flags
)
619 assert(ncph
!= NULL
);
621 if ((err
= nwam_ncp_get_read_only(ncph
, &read_only
)) != NWAM_SUCCESS
)
624 return (NWAM_ENTITY_NOT_DESTROYABLE
);
626 if (nwam_ncp_is_active(ncph
))
627 return (NWAM_ENTITY_IN_USE
);
629 if ((err
= nwam_ncp_name_to_file(ncph
->nwh_name
, &filename
))
633 err
= nwam_destroy(filename
, ncph
, flags
);
636 return (NWAM_SUCCESS
);
640 nwam_ncu_internal_name_to_name(const char *internalname
,
641 nwam_ncu_type_t
*typep
, char **namep
)
645 assert(internalname
!= NULL
&& namep
!= NULL
);
647 if (strncasecmp(internalname
, NWAM_NCU_LINK_NAME_PRE
,
648 strlen(NWAM_NCU_LINK_NAME_PRE
)) == 0) {
649 prefixstr
= NWAM_NCU_LINK_NAME_PRE
;
650 *typep
= NWAM_NCU_TYPE_LINK
;
651 } else if (strncasecmp(internalname
, NWAM_NCU_INTERFACE_NAME_PRE
,
652 strlen(NWAM_NCU_INTERFACE_NAME_PRE
)) == 0) {
653 prefixstr
= NWAM_NCU_INTERFACE_NAME_PRE
;
654 *typep
= NWAM_NCU_TYPE_INTERFACE
;
656 return (NWAM_INVALID_ARG
);
659 *namep
= strdup(internalname
+ strlen(prefixstr
));
661 return (NWAM_NO_MEMORY
);
662 return (NWAM_SUCCESS
);
667 ncu_selectcb(struct nwam_handle
*hp
, uint64_t flags
, void *data
)
669 nwam_ncu_handle_t ncuh
= hp
;
670 nwam_value_t typeval
= NULL
, classval
= NULL
;
671 uint64_t type
, class, matchflags
, walkfilter
;
673 if (nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_TYPE
, &typeval
)
675 nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_CLASS
, &classval
)
678 nwam_value_free(typeval
);
679 return (NWAM_INVALID_ARG
);
681 if (nwam_value_get_uint64(typeval
, &type
) != NWAM_SUCCESS
||
682 nwam_value_get_uint64(classval
, &class) != NWAM_SUCCESS
) {
683 nwam_value_free(typeval
);
684 nwam_value_free(classval
);
685 return (NWAM_INVALID_ARG
);
688 matchflags
= nwam_ncu_type_to_flag(type
) |
689 nwam_ncu_class_to_flag(class);
690 nwam_value_free(typeval
);
691 nwam_value_free(classval
);
693 if ((walkfilter
= (flags
& NWAM_WALK_FILTER_MASK
)) == 0)
694 walkfilter
= NWAM_FLAG_NCU_TYPE_CLASS_ALL
;
696 if (matchflags
& walkfilter
)
697 return (NWAM_SUCCESS
);
698 return (NWAM_INVALID_ARG
);
702 nwam_ncp_walk_ncus(nwam_ncp_handle_t ncph
,
703 int(*cb
)(nwam_ncu_handle_t
, void *), void *data
, uint64_t flags
, int *retp
)
708 assert(ncph
!= NULL
&& cb
!= NULL
);
710 if ((err
= nwam_valid_flags(flags
,
711 NWAM_FLAG_NCU_TYPE_CLASS_ALL
| NWAM_FLAG_BLOCKING
)) != NWAM_SUCCESS
)
714 if ((err
= nwam_ncp_name_to_file(ncph
->nwh_name
, &ncpfile
))
718 err
= nwam_walk(NWAM_OBJECT_TYPE_NCU
, ncpfile
, cb
, data
, flags
,
726 nwam_ncp_free(nwam_ncp_handle_t ncph
)
732 * Are ncu type and class compatible?
735 nwam_ncu_type_class_compatible(nwam_ncu_type_t type
, nwam_ncu_class_t
class)
738 case NWAM_NCU_TYPE_LINK
:
739 return (class == NWAM_NCU_CLASS_PHYS
);
740 case NWAM_NCU_TYPE_INTERFACE
:
741 return (class == NWAM_NCU_CLASS_IP
);
747 /* Name to validate may be internal name. If so, convert it before validating */
749 valid_ncu_name(const char *name
)
753 nwam_ncu_type_t type
;
755 if (nwam_ncu_internal_name_to_name(name
, &type
, &n
) == NWAM_SUCCESS
) {
757 ret
= dladm_valid_linkname(n
);
760 ret
= dladm_valid_linkname(name
);
767 nwam_ncu_create(nwam_ncp_handle_t ncph
, const char *name
,
768 nwam_ncu_type_t type
, nwam_ncu_class_t
class, nwam_ncu_handle_t
*ncuhp
)
770 nwam_ncu_handle_t ncuh
;
771 nwam_value_t typeval
= NULL
, classval
= NULL
, parentval
= NULL
;
772 nwam_value_t enabledval
= NULL
;
777 assert(ncph
!= NULL
&& name
!= NULL
&& ncuhp
!= NULL
);
779 if (!valid_ncu_name(name
))
780 return (NWAM_INVALID_ARG
);
782 if ((err
= nwam_ncp_get_read_only(ncph
, &read_only
)) != NWAM_SUCCESS
)
785 return (NWAM_ENTITY_READ_ONLY
);
787 if (nwam_ncu_read(ncph
, name
, type
, 0, &ncuh
) == NWAM_SUCCESS
) {
789 return (NWAM_ENTITY_EXISTS
);
792 if (!valid_ncu_name(name
) ||
793 !nwam_ncu_type_class_compatible(type
, class))
794 return (NWAM_INVALID_ARG
);
796 if ((err
= nwam_ncu_name_to_typed_name(name
, type
, &typedname
))
801 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCU
, typedname
, ncuhp
))
807 * Create new object list for NCU. The new NCU is initialized with
808 * the appropriate type and class.
810 if ((err
= nwam_alloc_object_list(&(*ncuhp
)->nwh_data
)) != NWAM_SUCCESS
)
813 if ((err
= nwam_value_create_uint64(type
, &typeval
))
815 (err
= nwam_value_create_uint64(class, &classval
))
817 (err
= nwam_value_create_string(ncph
->nwh_name
, &parentval
))
819 (err
= nwam_value_create_boolean(B_TRUE
, &enabledval
))
823 if ((err
= nwam_set_prop_value((*ncuhp
)->nwh_data
, NWAM_NCU_PROP_TYPE
,
824 typeval
)) != NWAM_SUCCESS
||
825 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
, NWAM_NCU_PROP_CLASS
,
826 classval
)) != NWAM_SUCCESS
||
827 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
828 NWAM_NCU_PROP_PARENT_NCP
, parentval
)) != NWAM_SUCCESS
||
829 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
830 NWAM_NCU_PROP_ENABLED
, enabledval
)) != NWAM_SUCCESS
) {
834 /* Set default IP, datalink properties */
835 if (type
== NWAM_NCU_TYPE_INTERFACE
&& class == NWAM_NCU_CLASS_IP
) {
837 uint64_t ver
[] = { IPV4_VERSION
, IPV6_VERSION
};
838 uint64_t v6src
[] = { NWAM_ADDRSRC_DHCP
, NWAM_ADDRSRC_AUTOCONF
};
839 uint_t vercnt
= 2, v6srccnt
= 2;
840 nwam_value_t ipver
= NULL
, v4addrsrc
= NULL
, v6addrsrc
= NULL
;
842 if ((err
= nwam_value_create_uint64_array(ver
, vercnt
, &ipver
))
844 (err
= nwam_value_create_uint64(NWAM_ADDRSRC_DHCP
,
845 &v4addrsrc
)) != NWAM_SUCCESS
||
846 (err
= nwam_value_create_uint64_array(v6src
, v6srccnt
,
847 &v6addrsrc
)) != NWAM_SUCCESS
) {
848 nwam_value_free(ipver
);
849 nwam_value_free(v4addrsrc
);
852 if ((err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
853 NWAM_NCU_PROP_IP_VERSION
, ipver
)) == NWAM_SUCCESS
&&
854 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
855 NWAM_NCU_PROP_IPV4_ADDRSRC
, v4addrsrc
)) == NWAM_SUCCESS
) {
856 err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
857 NWAM_NCU_PROP_IPV6_ADDRSRC
, v6addrsrc
);
859 nwam_value_free(ipver
);
860 nwam_value_free(v4addrsrc
);
861 nwam_value_free(v6addrsrc
);
863 nwam_value_t actval
= NULL
;
864 if ((err
= nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL
,
865 &actval
)) != NWAM_SUCCESS
)
867 err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
868 NWAM_NCU_PROP_ACTIVATION_MODE
, actval
);
869 nwam_value_free(actval
);
873 nwam_value_free(typeval
);
874 nwam_value_free(classval
);
875 nwam_value_free(parentval
);
876 nwam_value_free(enabledval
);
877 if (err
!= NWAM_SUCCESS
) {
878 nwam_ncu_free(*ncuhp
);
885 nwam_ncu_read(nwam_ncp_handle_t ncph
, const char *name
,
886 nwam_ncu_type_t type
, uint64_t flags
, nwam_ncu_handle_t
*ncuhp
)
888 char *ncpfile
, *typedname
;
889 nwam_error_t err
, err_ip
, err_link
;
890 nwam_ncu_handle_t ncuh_ip
, ncuh_link
;
892 assert(ncph
!= NULL
&& name
!= NULL
&& ncuhp
!= NULL
);
894 if ((err
= nwam_ncp_name_to_file(ncph
->nwh_name
, &ncpfile
))
898 if (type
== NWAM_NCU_TYPE_ANY
) {
903 * If we get to this point, we have discovered that no
904 * NCU type is discernable from name or type arguments.
905 * Either exactly one NCU called name must exist of either
906 * type, or the operation should fail.
908 err_ip
= nwam_ncu_read(ncph
, name
, NWAM_NCU_TYPE_INTERFACE
,
910 err_link
= nwam_ncu_read(ncph
, name
, NWAM_NCU_TYPE_LINK
,
915 if (err_ip
== NWAM_SUCCESS
&& err_link
== NWAM_SUCCESS
) {
916 nwam_ncu_free(ncuh_ip
);
917 nwam_ncu_free(ncuh_link
);
918 err
= NWAM_ENTITY_MULTIPLE_VALUES
;
919 } else if (err_ip
!= NWAM_SUCCESS
&& err_link
!= NWAM_SUCCESS
) {
920 err
= NWAM_ENTITY_NOT_FOUND
;
922 if (err_ip
== NWAM_SUCCESS
) {
932 if ((err
= nwam_ncu_name_to_typed_name(name
, type
, &typedname
)) !=
937 err
= nwam_read(NWAM_OBJECT_TYPE_NCU
, ncpfile
, typedname
, flags
, ncuhp
);
946 nwam_ncu_get_name(nwam_ncu_handle_t ncuh
, char **namep
)
948 nwam_ncu_type_t type
;
950 assert(ncuh
!= NULL
&& namep
!= NULL
);
952 return (nwam_ncu_internal_name_to_name(ncuh
->nwh_name
, &type
, namep
));
956 nwam_ncu_name_to_typed_name(const char *name
, nwam_ncu_type_t type
,
962 assert(name
!= NULL
&& typednamep
!= NULL
);
965 case NWAM_NCU_TYPE_INTERFACE
:
966 prefixstr
= NWAM_NCU_INTERFACE_NAME_PRE
;
968 case NWAM_NCU_TYPE_LINK
:
969 prefixstr
= NWAM_NCU_LINK_NAME_PRE
;
972 return (NWAM_INVALID_ARG
);
974 typednamesz
= strlen(name
) + strlen(prefixstr
) + 1;
975 if ((*typednamep
= malloc(typednamesz
)) == NULL
)
976 return (NWAM_NO_MEMORY
);
978 /* Name may be already qualified by type */
979 if (strncasecmp(prefixstr
, name
, strlen(prefixstr
)) == 0) {
980 (void) snprintf(*typednamep
, typednamesz
, "%s", name
);
982 (void) snprintf(*typednamep
, typednamesz
, "%s%s",
986 return (NWAM_SUCCESS
);
990 nwam_ncu_typed_name_to_name(const char *typed_name
, nwam_ncu_type_t
*typep
,
993 return (nwam_ncu_internal_name_to_name(typed_name
, typep
, name
));
997 nwam_ncu_free(nwam_ncu_handle_t ncuh
)
1003 nwam_ncu_copy(nwam_ncu_handle_t oldncuh
, const char *newname
,
1004 nwam_ncu_handle_t
*newncuhp
)
1006 nwam_ncp_handle_t ncph
;
1007 nwam_ncu_handle_t ncuh
;
1009 nwam_value_t typeval
;
1013 assert(oldncuh
!= NULL
&& newname
!= NULL
&& newncuhp
!= NULL
);
1015 if (nwam_ncu_get_prop_value(oldncuh
, NWAM_NCU_PROP_TYPE
,
1016 &typeval
) != NWAM_SUCCESS
) {
1017 return (NWAM_INVALID_ARG
);
1019 if (nwam_value_get_uint64(typeval
, &type
) != NWAM_SUCCESS
) {
1020 nwam_value_free(typeval
);
1021 return (NWAM_INVALID_ARG
);
1023 nwam_value_free(typeval
);
1025 /* check if newname NCU already exists */
1026 if ((err
= nwam_ncu_get_ncp(oldncuh
, &ncph
)) != NWAM_SUCCESS
)
1028 if (nwam_ncu_read(ncph
, newname
, type
, 0, &ncuh
) == NWAM_SUCCESS
) {
1029 nwam_ncu_free(ncuh
);
1030 nwam_ncp_free(ncph
);
1031 return (NWAM_ENTITY_EXISTS
);
1033 nwam_ncp_free(ncph
);
1035 if ((err
= nwam_ncu_name_to_typed_name(newname
, type
, &typednewname
))
1039 err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCU
, typednewname
, newncuhp
);
1041 if (err
!= NWAM_SUCCESS
)
1043 if ((err
= nwam_dup_object_list(oldncuh
->nwh_data
,
1044 &((*newncuhp
)->nwh_data
))) != NWAM_SUCCESS
) {
1050 return (NWAM_SUCCESS
);
1054 nwam_ncu_delete_prop(nwam_ncu_handle_t ncuh
, const char *propname
)
1056 boolean_t ro_ncu
, ro_prop
;
1060 assert(ncuh
!= NULL
&& propname
!= NULL
);
1062 if ((err
= nwam_ncu_get_read_only(ncuh
, &ro_ncu
)) != NWAM_SUCCESS
||
1063 (err
= nwam_ncu_prop_read_only(propname
, &ro_prop
)) != NWAM_SUCCESS
)
1065 if (ro_ncu
|| ro_prop
)
1066 return (NWAM_ENTITY_READ_ONLY
);
1069 * Duplicate data, remove property and validate. If validation
1070 * fails, revert to data duplicated prior to remove.
1072 if ((err
= nwam_dup_object_list(ncuh
->nwh_data
, &olddata
))
1075 if ((err
= nwam_delete_prop(ncuh
->nwh_data
, propname
))
1077 nwam_free_object_list(ncuh
->nwh_data
);
1078 ncuh
->nwh_data
= olddata
;
1081 if ((err
= nwam_ncu_validate(ncuh
, NULL
)) != NWAM_SUCCESS
) {
1082 nwam_free_object_list(ncuh
->nwh_data
);
1083 ncuh
->nwh_data
= olddata
;
1086 nwam_free_object_list(olddata
);
1088 return (NWAM_SUCCESS
);
1092 nwam_ncu_set_prop_value(nwam_ncu_handle_t ncuh
, const char *propname
,
1095 boolean_t ro_ncu
, ro_prop
;
1097 nwam_ncp_handle_t ncph
;
1099 assert(ncuh
!= NULL
&& propname
!= NULL
&& value
!= NULL
);
1101 if ((err
= nwam_ncu_get_read_only(ncuh
, &ro_ncu
)) != NWAM_SUCCESS
||
1102 (err
= nwam_ncu_prop_read_only(propname
, &ro_prop
)) != NWAM_SUCCESS
)
1104 if (ro_ncu
|| ro_prop
)
1105 return (NWAM_ENTITY_READ_ONLY
);
1107 err
= nwam_ncu_get_ncp(ncuh
, &ncph
);
1108 if (err
!= NWAM_SUCCESS
&& err
!= NWAM_INVALID_ARG
) {
1110 * If "parent" property doesn't exist, NWAM_INVALID_ARG
1111 * is returned. Allow the setting to continue.
1115 nwam_ncp_free(ncph
);
1117 /* Need to ensure property, type and value are valid */
1118 if ((err
= nwam_ncu_validate_prop(ncuh
, propname
, value
))
1122 return (nwam_set_prop_value(ncuh
->nwh_data
, propname
, value
));
1126 nwam_ncu_get_prop_value(nwam_ncu_handle_t ncuh
, const char *propname
,
1127 nwam_value_t
*valuep
)
1129 assert(ncuh
!= NULL
&& propname
!= NULL
&& valuep
!= NULL
);
1131 return (nwam_get_prop_value(ncuh
->nwh_data
, propname
, valuep
));
1135 nwam_ncu_walk_props(nwam_ncu_handle_t ncuh
,
1136 int (*cb
)(const char *, nwam_value_t
, void *),
1137 void *data
, uint64_t flags
, int *retp
)
1139 return (nwam_walk_props(ncuh
, cb
, data
, flags
, retp
));
1143 nwam_ncu_get_ncp(nwam_ncu_handle_t ncuh
, nwam_ncp_handle_t
*ncphp
)
1146 char *parentname
= NULL
;
1148 if ((err
= nwam_ncu_get_parent_ncp_name(ncuh
, &parentname
))
1150 (err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCP
, parentname
, ncphp
))
1157 return (NWAM_SUCCESS
);
1161 nwam_ncu_commit(nwam_ncu_handle_t ncuh
, uint64_t flags
)
1164 boolean_t read_only
;
1165 char *ncpfile
, *ncpname
;
1167 assert(ncuh
!= NULL
&& ncuh
->nwh_data
!= NULL
);
1169 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1172 return (NWAM_ENTITY_READ_ONLY
);
1174 if ((err
= nwam_ncu_validate(ncuh
, NULL
)) != NWAM_SUCCESS
||
1175 (err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1179 if ((err
= nwam_ncp_name_to_file(ncpname
, &ncpfile
)) != NWAM_SUCCESS
) {
1184 err
= nwam_commit(ncpfile
, ncuh
, flags
);
1191 /* Get the NCU type */
1193 nwam_ncu_get_ncu_type(nwam_ncu_handle_t ncuh
, nwam_ncu_type_t
*typep
)
1196 nwam_value_t typeval
;
1199 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_TYPE
, &typeval
))
1202 err
= nwam_value_get_uint64(typeval
, &type
);
1203 nwam_value_free(typeval
);
1204 if (err
!= NWAM_SUCCESS
)
1208 return (NWAM_SUCCESS
);
1211 /* Get the NCU class */
1213 nwam_ncu_get_ncu_class(nwam_ncu_handle_t ncuh
, nwam_ncu_class_t
*classp
)
1216 nwam_value_t classval
;
1219 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_CLASS
,
1220 &classval
)) != NWAM_SUCCESS
)
1222 err
= nwam_value_get_uint64(classval
, &class);
1223 nwam_value_free(classval
);
1224 if (err
!= NWAM_SUCCESS
)
1228 return (NWAM_SUCCESS
);
1232 * Determine if the NCU has manual activation-mode or not.
1235 nwam_ncu_is_manual(nwam_ncu_handle_t ncuh
, boolean_t
*manualp
)
1238 nwam_value_t actval
;
1239 uint64_t activation
;
1241 assert(ncuh
!= NULL
);
1243 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_ACTIVATION_MODE
,
1244 &actval
)) != NWAM_SUCCESS
)
1246 err
= nwam_value_get_uint64(actval
, &activation
);
1247 nwam_value_free(actval
);
1248 if (err
!= NWAM_SUCCESS
)
1251 if (activation
== NWAM_ACTIVATION_MODE_MANUAL
)
1255 return (NWAM_SUCCESS
);
1258 /* Determine if NCU is enabled or not */
1260 nwam_ncu_is_enabled(nwam_ncu_handle_t ncuh
, boolean_t
*enabledp
)
1263 nwam_value_t enabledval
;
1265 assert(ncuh
!= NULL
);
1267 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_ENABLED
,
1268 &enabledval
)) != NWAM_SUCCESS
)
1270 err
= nwam_value_get_boolean(enabledval
, enabledp
);
1271 nwam_value_free(enabledval
);
1275 /* Update the enabled property */
1277 nwam_ncu_update_enabled(nwam_ncu_handle_t ncuh
, boolean_t enabled
)
1280 nwam_value_t enabledval
;
1282 if ((err
= nwam_value_create_boolean(enabled
, &enabledval
))
1285 err
= nwam_set_prop_value(ncuh
->nwh_data
, NWAM_NCU_PROP_ENABLED
,
1287 nwam_value_free(enabledval
);
1288 if (err
!= NWAM_SUCCESS
)
1290 return (nwam_ncu_commit(ncuh
, NWAM_FLAG_ENTITY_ENABLE
));
1294 * Make ncu active; fails if the NCU's parent NCP is not active.
1297 nwam_ncu_enable(nwam_ncu_handle_t ncuh
)
1299 char *ncpname
= NULL
;
1301 nwam_ncu_type_t type
;
1302 boolean_t read_only
, enabled
, manual
;
1304 assert(ncuh
!= NULL
);
1306 /* Don't allow NCUs of Automatic NCP to be enabled */
1307 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1310 return (NWAM_ENTITY_NOT_MANUAL
);
1312 /* Link NCUs with manual activation-mode or IP NCUs can be enabled */
1313 if ((err
= nwam_ncu_get_ncu_type(ncuh
, &type
)) != NWAM_SUCCESS
)
1316 if (type
== NWAM_NCU_TYPE_LINK
) {
1317 if ((err
= nwam_ncu_is_manual(ncuh
, &manual
)) != NWAM_SUCCESS
)
1320 return (NWAM_ENTITY_NOT_MANUAL
);
1323 /* Make sure NCU is not enabled */
1324 if ((err
= nwam_ncu_is_enabled(ncuh
, &enabled
)) != NWAM_SUCCESS
||
1325 (err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1331 return (NWAM_SUCCESS
);
1334 if ((err
= nwam_ncu_update_enabled(ncuh
, B_TRUE
)) != NWAM_SUCCESS
) {
1339 err
= nwam_enable(ncpname
, ncuh
);
1342 /* nwamd may not be running, that's okay. */
1343 if (err
== NWAM_ERROR_BIND
)
1344 return (NWAM_SUCCESS
);
1350 * Disable ncu; fails if the NCU's parent NCP is not active, or if the
1351 * NCU is not currently active.
1354 nwam_ncu_disable(nwam_ncu_handle_t ncuh
)
1356 char *ncpname
= NULL
;
1358 nwam_ncu_type_t type
;
1359 boolean_t read_only
, enabled
, manual
;
1361 assert(ncuh
!= NULL
);
1363 /* Don't allow NCUs of Automatic NCP to be disabled */
1364 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1367 return (NWAM_ENTITY_NOT_MANUAL
);
1369 /* Link NCUs with manual activation-mode or IP NCUs can be disabled */
1370 if ((err
= nwam_ncu_get_ncu_type(ncuh
, &type
)) != NWAM_SUCCESS
)
1373 if (type
== NWAM_NCU_TYPE_LINK
) {
1374 if ((err
= nwam_ncu_is_manual(ncuh
, &manual
)) != NWAM_SUCCESS
)
1377 return (NWAM_ENTITY_NOT_MANUAL
);
1380 /* Make sure NCU is enabled */
1381 if ((err
= nwam_ncu_is_enabled(ncuh
, &enabled
)) != NWAM_SUCCESS
||
1382 (err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1388 return (NWAM_SUCCESS
);
1391 if ((err
= nwam_ncu_update_enabled(ncuh
, B_FALSE
)) != NWAM_SUCCESS
) {
1396 err
= nwam_disable(ncpname
, ncuh
);
1399 /* nwamd may not be running, that's okay. */
1400 if (err
== NWAM_ERROR_BIND
)
1401 return (NWAM_SUCCESS
);
1407 nwam_ncu_destroy(nwam_ncu_handle_t ncuh
, uint64_t flags
)
1409 char *ncpname
, *ncpfile
;
1410 boolean_t read_only
;
1413 assert(ncuh
!= NULL
);
1415 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1418 return (NWAM_ENTITY_NOT_DESTROYABLE
);
1420 if ((err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1423 if ((err
= nwam_ncp_name_to_file(ncpname
, &ncpfile
))
1429 err
= nwam_destroy(ncpfile
, ncuh
, flags
);
1438 nwam_ncu_get_prop_description(const char *propname
, const char **descriptionp
)
1440 return (nwam_get_prop_description(ncu_prop_table
, propname
,
1444 /* Get expected property data type */
1446 nwam_ncu_get_prop_type(const char *propname
, nwam_value_type_t
*typep
)
1448 return (nwam_get_prop_type(ncu_prop_table
, propname
, typep
));
1452 nwam_ncu_prop_read_only(const char *propname
, boolean_t
*readp
)
1454 if ((*readp
= NWAM_NCU_PROP_SETONCE(propname
)) == B_TRUE
)
1455 return (NWAM_SUCCESS
);
1457 return (nwam_prop_read_only(ncu_prop_table
, propname
, readp
));
1461 nwam_ncu_prop_multivalued(const char *propname
, boolean_t
*multip
)
1463 return (nwam_prop_multivalued(ncu_prop_table
, propname
, multip
));
1467 * Ensure that the properties in the ncu, determined by that ncu's
1468 * type and class, belong there.
1471 nwam_ncu_validate_prop_membership(nwam_ncu_handle_t ncuh
, const char *propname
)
1473 struct nwam_prop_table_entry
*pte
;
1474 nwam_value_t typeval
, classval
;
1475 uint64_t type
, class;
1476 uint64_t typeflags
= 0, classflags
= 0;
1478 /* Get type/class from ncu */
1479 if (nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_TYPE
, &typeval
)
1481 return (NWAM_ENTITY_INVALID
);
1482 if (nwam_value_get_uint64(typeval
, &type
) != NWAM_SUCCESS
) {
1483 nwam_value_free(typeval
);
1484 return (NWAM_ENTITY_INVALID
);
1486 typeflags
= nwam_ncu_type_to_flag((nwam_ncu_type_t
)type
);
1487 nwam_value_free(typeval
);
1489 if (nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_CLASS
, &classval
)
1491 return (NWAM_ENTITY_INVALID
);
1492 if (nwam_value_get_uint64(classval
, &class) != NWAM_SUCCESS
) {
1493 nwam_value_free(classval
);
1494 return (NWAM_ENTITY_INVALID
);
1496 classflags
= nwam_ncu_class_to_flag((nwam_ncu_class_t
)class);
1497 nwam_value_free(classval
);
1499 if ((pte
= nwam_get_prop_table_entry(ncu_prop_table
, propname
)) == NULL
)
1500 return (NWAM_INVALID_ARG
);
1502 if (typeflags
& pte
->prop_type_membership
&&
1503 classflags
& pte
->prop_class_membership
) {
1504 return (NWAM_SUCCESS
);
1506 return (NWAM_ENTITY_INVALID_MEMBER
);
1510 /* Validate property's ncu membership and type, number and range of values */
1512 nwam_ncu_validate_prop(nwam_ncu_handle_t ncuh
, const char *propname
,
1517 assert(ncuh
!= NULL
&& propname
!= NULL
);
1519 /* First, determine if this property is valid for this ncu */
1520 if ((err
= nwam_ncu_validate_prop_membership(ncuh
, propname
))
1524 return (nwam_validate_prop(ncu_prop_table
, ncuh
, propname
, value
));
1527 /* Property-specific value validation functions follow */
1530 valid_type(nwam_value_t value
)
1534 if (nwam_value_get_uint64(value
, &type
) != NWAM_SUCCESS
||
1535 type
> NWAM_NCU_TYPE_INTERFACE
)
1536 return (NWAM_ENTITY_INVALID_VALUE
);
1537 return (NWAM_SUCCESS
);
1541 valid_class(nwam_value_t value
)
1545 if (nwam_value_get_uint64(value
, &class) != NWAM_SUCCESS
||
1546 class > NWAM_NCU_CLASS_IP
)
1547 return (NWAM_ENTITY_INVALID_VALUE
);
1548 return (NWAM_SUCCESS
);
1552 valid_ncp(nwam_value_t value
)
1556 if (nwam_value_get_string(value
, &ncp
) != NWAM_SUCCESS
)
1557 return (NWAM_ENTITY_INVALID_VALUE
);
1558 return (NWAM_SUCCESS
);
1562 valid_priority_mode(nwam_value_t value
)
1564 uint64_t priority_mode
;
1566 if (nwam_value_get_uint64(value
, &priority_mode
) != NWAM_SUCCESS
||
1567 priority_mode
> NWAM_PRIORITY_MODE_ALL
)
1568 return (NWAM_ENTITY_INVALID_VALUE
);
1569 return (NWAM_SUCCESS
);
1573 valid_ncu_activation_mode(nwam_value_t value
)
1575 uint64_t activation_mode
;
1577 if (nwam_value_get_uint64(value
, &activation_mode
) != NWAM_SUCCESS
)
1578 return (NWAM_ENTITY_INVALID_VALUE
);
1580 switch (activation_mode
) {
1581 case NWAM_ACTIVATION_MODE_MANUAL
:
1582 case NWAM_ACTIVATION_MODE_PRIORITIZED
:
1583 return (NWAM_SUCCESS
);
1585 return (NWAM_ENTITY_INVALID_VALUE
);
1590 valid_link_autopush(nwam_value_t value
)
1592 return (NWAM_SUCCESS
);
1596 valid_ip_version(nwam_value_t value
)
1599 uint_t i
, numvalues
;
1601 if (nwam_value_get_uint64_array(value
, &versions
, &numvalues
)
1603 return (NWAM_ENTITY_INVALID_VALUE
);
1605 for (i
= 0; i
< numvalues
; i
++) {
1606 if (versions
[i
] != IPV4_VERSION
&&
1607 versions
[i
] != IPV6_VERSION
)
1608 return (NWAM_ENTITY_INVALID_VALUE
);
1610 return (NWAM_SUCCESS
);
1614 valid_addrsrc_v4(nwam_value_t value
)
1617 uint_t i
, numvalues
;
1619 if (nwam_value_get_uint64_array(value
, &addrsrc
, &numvalues
)
1621 return (NWAM_ENTITY_INVALID_VALUE
);
1623 for (i
= 0; i
< numvalues
; i
++) {
1624 if (addrsrc
[i
] != NWAM_ADDRSRC_DHCP
&&
1625 addrsrc
[i
] != NWAM_ADDRSRC_STATIC
)
1626 return (NWAM_ENTITY_INVALID_VALUE
);
1628 return (NWAM_SUCCESS
);
1632 valid_addrsrc_v6(nwam_value_t value
)
1635 uint_t i
, numvalues
;
1636 boolean_t dhcp_found
= B_FALSE
, autoconf_found
= B_FALSE
;
1638 if (nwam_value_get_uint64_array(value
, &addrsrc
, &numvalues
)
1640 return (NWAM_ENTITY_INVALID_VALUE
);
1642 for (i
= 0; i
< numvalues
; i
++) {
1643 if (addrsrc
[i
] != NWAM_ADDRSRC_DHCP
&&
1644 addrsrc
[i
] != NWAM_ADDRSRC_STATIC
&&
1645 addrsrc
[i
] != NWAM_ADDRSRC_AUTOCONF
)
1646 return (NWAM_ENTITY_INVALID_VALUE
);
1647 if (addrsrc
[i
] == NWAM_ADDRSRC_DHCP
)
1648 dhcp_found
= B_TRUE
;
1649 if (addrsrc
[i
] == NWAM_ADDRSRC_AUTOCONF
)
1650 autoconf_found
= B_TRUE
;
1653 * DHCP and AUTOCONF need to be specified as v6 address sources
1654 * since there is no way to switch them off in NWAM at present.
1656 if (dhcp_found
&& autoconf_found
)
1657 return (NWAM_SUCCESS
);
1659 return (NWAM_ENTITY_INVALID_VALUE
);
1663 valid_reqhost(nwam_value_t value
)
1667 if (nwam_value_get_string(value
, &hostname
) != NWAM_SUCCESS
)
1668 return (NWAM_ENTITY_INVALID_VALUE
);
1669 return (ipadm_is_valid_hostname(hostname
) ? NWAM_SUCCESS
1670 : NWAM_ENTITY_INVALID_VALUE
);
1675 valid_link_mtu(nwam_value_t value
)
1677 return (NWAM_SUCCESS
);
1681 nwam_ncu_validate(nwam_ncu_handle_t ncuh
, const char **errpropp
)
1683 return (nwam_validate(ncu_prop_table
, ncuh
, errpropp
));
1687 * Given the ncu type and ncu class, return the list of properties that needs
1688 * to be set. Note this list is a complete property list that includes both
1689 * the required ones and the optional ones. Caller needs to free prop_list.
1692 nwam_ncu_get_default_proplist(nwam_ncu_type_t type
, nwam_ncu_class_t
class,
1693 const char ***prop_list
, uint_t
*numvalues
)
1695 uint64_t typeflags
= nwam_ncu_type_to_flag(type
);
1696 uint64_t classflags
= nwam_ncu_class_to_flag(class);
1698 return (nwam_get_default_proplist(ncu_prop_table
, typeflags
,
1699 classflags
, prop_list
, numvalues
));
1703 nwam_ncp_get_state(nwam_ncp_handle_t ncph
, nwam_state_t
*statep
,
1704 nwam_aux_state_t
*auxp
)
1706 return (nwam_get_state(ncph
->nwh_name
, ncph
, statep
, auxp
));
1710 nwam_ncu_get_state(nwam_ncu_handle_t ncuh
, nwam_state_t
*statep
,
1711 nwam_aux_state_t
*auxp
)
1713 nwam_ncp_handle_t ncph
;
1717 assert(ncuh
!= NULL
);
1719 if ((err
= nwam_ncu_get_ncp(ncuh
, &ncph
)) != NWAM_SUCCESS
)
1721 if (!nwam_ncp_is_active(ncph
)) {
1722 nwam_ncp_free(ncph
);
1723 return (NWAM_ENTITY_INVALID
);
1725 nwam_ncp_free(ncph
);
1727 if ((err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1731 err
= nwam_request_state(NWAM_OBJECT_TYPE_NCU
, ncuh
->nwh_name
, ncpname
,
1738 nwam_ncp_get_active_priority_group(int64_t *priorityp
)
1740 return (nwam_request_active_priority_group(priorityp
));