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.
31 #include <sys/param.h>
32 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
43 #include "libnwam_impl.h"
44 #include <libnwam_priv.h>
48 * Functions to support creating, modifying, destroying, querying the
49 * state of and changing the state of NCP (Network Configuration Profiles)
50 * and the NCUs (Network Configuration Units) that are contained in those
51 * NCP objects. An NCP is simply a container for a set of NCUs which represent
52 * the datalink and interface configuration preferences for the system.
53 * An NCP can consist a set of prioritized link NCUs, e.g. wired links preferred
54 * over wireless, a set of manually enabled/diasbled NCUs, or a combination
55 * of both. Interface NCUs inherit activation from their underlying links,
56 * so if wired is preferred over wireless and a cable is plugged in,
57 * the wired link NCU will be active, as will the IP interface NCU above it.
61 * The NCU property table is used to mapping property types to property name
62 * strings, their associated value types etc. The table is used for validation
63 * purposes, and for commit()ing and read()ing NCUs.
66 static nwam_error_t
valid_type(nwam_value_t
);
67 static nwam_error_t
valid_class(nwam_value_t
);
68 static nwam_error_t
valid_ncp(nwam_value_t
);
69 static nwam_error_t
valid_priority_mode(nwam_value_t
);
70 static nwam_error_t
valid_ncu_activation_mode(nwam_value_t
);
71 static nwam_error_t
valid_link_autopush(nwam_value_t
);
72 static nwam_error_t
valid_link_mtu(nwam_value_t
);
73 static nwam_error_t
valid_ip_version(nwam_value_t
);
74 static nwam_error_t
valid_addrsrc_v4(nwam_value_t
);
75 static nwam_error_t
valid_addrsrc_v6(nwam_value_t
);
77 struct nwam_prop_table_entry ncu_prop_table_entries
[] = {
78 {NWAM_NCU_PROP_TYPE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1, valid_type
,
79 "specifies the NCU type - valid values are \'datalink\' and \'ip\'",
80 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
81 {NWAM_NCU_PROP_CLASS
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1,
83 "specifies the NCU class - valid values are "
84 "\'phys\' and \'ip\'",
85 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
86 {NWAM_NCU_PROP_PARENT_NCP
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 1, 1,
88 "specifies the parent NCP name",
89 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
90 {NWAM_NCU_PROP_ACTIVATION_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1,
91 valid_ncu_activation_mode
,
92 "specifies the NCU activation mode - valid values are:\n"
93 "\'prioritized\' and \'manual\'",
94 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
95 {NWAM_NCU_PROP_ENABLED
, NWAM_VALUE_TYPE_BOOLEAN
, B_TRUE
, 0, 1,
97 "specifies if manual NCU is to be enabled",
98 NWAM_FLAG_NCU_TYPE_ALL
, NWAM_FLAG_NCU_CLASS_ALL
},
99 {NWAM_NCU_PROP_PRIORITY_GROUP
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0, 1,
101 "specifies the priority grouping of NCUs - lower values are "
102 "prioritized, negative values are invalid",
103 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
104 {NWAM_NCU_PROP_PRIORITY_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0, 1,
106 "specifies the mode of prioritization - valid values are:\n"
107 "\'exclusive\', \'shared\' and \'all\'",
108 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
109 {NWAM_NCU_PROP_LINK_MAC_ADDR
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
111 "specifies MAC address of form aa:bb:cc:dd:ee:ff for the link",
112 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
113 {NWAM_NCU_PROP_LINK_AUTOPUSH
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
114 NWAM_MAX_NUM_VALUES
, valid_link_autopush
,
115 "specifies modules to autopush on link",
116 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
117 {NWAM_NCU_PROP_LINK_MTU
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0, 1,
119 "specifies MTU for link",
120 NWAM_FLAG_NCU_TYPE_LINK
, NWAM_FLAG_NCU_CLASS_ALL_LINK
},
121 {NWAM_NCU_PROP_IP_VERSION
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0,
122 NWAM_MAX_NUM_VALUES
, valid_ip_version
,
123 "specifies IP versions for IP NCU - valid values are:\n"
124 "\'ipv4\' and \'ipv6\'",
125 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
126 {NWAM_NCU_PROP_IPV4_ADDRSRC
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0,
127 NWAM_MAX_NUM_VALUES
, valid_addrsrc_v4
,
128 "specifies IPv4 address source(s) - valid values are:\n"
129 "\'dhcp\' and \'static\'",
130 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
131 {NWAM_NCU_PROP_IPV4_ADDR
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
132 NWAM_MAX_NUM_VALUES
, nwam_valid_host_v4
,
133 "specifies static IPv4 host address(es)",
134 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
135 {NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
136 1, nwam_valid_route_v4
,
137 "specifies per-interface default IPv4 route",
138 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
139 {NWAM_NCU_PROP_IPV6_ADDRSRC
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 0,
140 NWAM_MAX_NUM_VALUES
, valid_addrsrc_v6
,
141 "specifies IPv6 address source(s) - valid values are:\n"
142 "\'dhcp\', \'autoconf\' and \'static\'.\n"
143 "\'dhcp\' and \'autoconf\' are mandatory values.",
144 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
145 {NWAM_NCU_PROP_IPV6_ADDR
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
146 NWAM_MAX_NUM_VALUES
, nwam_valid_host_v6
,
147 "specifies static IPv6 host address(es)",
148 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
},
149 {NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
150 1, nwam_valid_route_v6
,
151 "specifies per-interface default IPv6 route",
152 NWAM_FLAG_NCU_TYPE_INTERFACE
, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE
}
155 #define NWAM_NUM_NCU_PROPS (sizeof (ncu_prop_table_entries) / \
156 sizeof (*ncu_prop_table_entries))
158 struct nwam_prop_table ncu_prop_table
=
159 { NWAM_NUM_NCU_PROPS
, ncu_prop_table_entries
};
162 nwam_ncp_get_name(nwam_ncp_handle_t ncph
, char **namep
)
164 return (nwam_get_name(ncph
, namep
));
168 nwam_ncp_name_to_file(const char *name
, char **filename
)
170 assert(name
!= NULL
&& filename
!= NULL
);
172 if ((*filename
= malloc(MAXPATHLEN
)) == NULL
)
173 return (NWAM_NO_MEMORY
);
175 (void) snprintf(*filename
, MAXPATHLEN
, "%s%s%s%s", NWAM_CONF_DIR
,
176 NWAM_NCP_CONF_FILE_PRE
, name
, NWAM_NCP_CONF_FILE_SUF
);
178 return (NWAM_SUCCESS
);
183 nwam_ncp_create(const char *name
, uint64_t flags
, nwam_ncp_handle_t
*ncphp
)
188 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCP
, name
, ncphp
))
192 /* Create empty container for NCUs */
193 if ((err
= nwam_ncp_name_to_file(name
, &ncpfile
))
200 if ((err
= nwam_commit(ncpfile
, *ncphp
, flags
)) != NWAM_SUCCESS
) {
210 /* Used by libnwam_files.c */
212 nwam_ncp_file_to_name(const char *path
, char **name
)
214 char path_copy
[MAXPATHLEN
];
215 char *filename
, *suffix
;
217 assert(path
!= NULL
&& name
!= NULL
);
219 /* Make a copy as basename(3c) may modify string */
220 (void) strlcpy(path_copy
, path
, MAXPATHLEN
);
222 if ((*name
= malloc(NWAM_MAX_NAME_LEN
)) == NULL
)
223 return (NWAM_NO_MEMORY
);
225 if ((filename
= basename(path_copy
)) == NULL
) {
227 return (NWAM_ENTITY_INVALID
);
230 /* Ensure filename begins/ends with right prefix/suffix */
231 if (sscanf(filename
, NWAM_NCP_CONF_FILE_PRE
"%256[^\n]s", *name
) < 1) {
233 return (NWAM_ENTITY_INVALID
);
235 suffix
= *name
+ strlen(*name
) - strlen(NWAM_NCP_CONF_FILE_SUF
);
236 if (strstr(*name
, NWAM_NCP_CONF_FILE_SUF
) != suffix
) {
238 return (NWAM_ENTITY_INVALID
);
242 return (NWAM_SUCCESS
);
247 nwam_ncp_read(const char *name
, uint64_t flags
, nwam_ncp_handle_t
*ncphp
)
252 assert(name
!= NULL
&& ncphp
!= NULL
);
254 /* try to read the associated ncp configuration */
255 if ((err
= nwam_ncp_name_to_file(name
, &filename
)) != NWAM_SUCCESS
) {
260 err
= nwam_read(NWAM_OBJECT_TYPE_NCP
, filename
, name
, flags
, ncphp
);
266 nwam_ncu_get_parent_ncp_name(nwam_ncu_handle_t ncuh
, char **parentnamep
)
268 nwam_value_t parentval
= NULL
;
272 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_PARENT_NCP
,
273 &parentval
)) != NWAM_SUCCESS
||
274 (err
= nwam_value_get_string(parentval
, &parentname
))
276 (*parentnamep
= strdup(parentname
)) == NULL
) {
277 if (parentval
!= NULL
)
278 nwam_value_free(parentval
);
282 nwam_value_free(parentval
);
284 return (NWAM_SUCCESS
);
288 nwam_ncp_copy_callback(nwam_ncu_handle_t oldncuh
, void *arg
)
291 nwam_ncu_handle_t newncuh
= NULL
;
293 char *oldfilename
= NULL
, *newfilename
= NULL
;
294 nwam_ncp_handle_t newncph
= (nwam_ncp_handle_t
)arg
;
295 nwam_value_t newparentval
;
297 /* Get filenames for the new and old NCU's */
298 if ((err
= nwam_ncu_get_parent_ncp_name(oldncuh
, &oldparent
))
301 err
= nwam_ncp_name_to_file(oldparent
, &oldfilename
);
303 if (err
!= NWAM_SUCCESS
)
305 if ((err
= nwam_ncp_name_to_file(newncph
->nwh_name
, &newfilename
))
309 /* new NCU name (and typedname) is the same as the old name */
310 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCU
, oldncuh
->nwh_name
,
311 &newncuh
)) != NWAM_SUCCESS
)
313 /* Duplicate the old NCU's data */
314 if ((err
= nwam_dup_object_list(oldncuh
->nwh_data
,
315 &(newncuh
->nwh_data
))) != NWAM_SUCCESS
)
318 /* Update the parent property for the new NCU */
319 if ((err
= nwam_value_create_string(newncph
->nwh_name
, &newparentval
))
322 err
= nwam_set_prop_value(newncuh
->nwh_data
, NWAM_NCU_PROP_PARENT_NCP
,
324 nwam_value_free(newparentval
);
325 if (err
!= NWAM_SUCCESS
)
328 /* Save the new NCU */
329 err
= nwam_commit(newfilename
, newncuh
, 0);
334 nwam_ncu_free(newncuh
);
339 nwam_ncp_copy(nwam_ncp_handle_t oldncph
, const char *newname
,
340 nwam_ncp_handle_t
*newncphp
)
342 nwam_ncp_handle_t ncph
;
346 assert(oldncph
!= NULL
&& newname
!= NULL
&& newncphp
!= NULL
);
348 /* check if newname NCP already exists */
349 if (nwam_ncp_read(newname
, 0, &ncph
) == NWAM_SUCCESS
) {
352 return (NWAM_ENTITY_EXISTS
);
355 /* create new handle */
356 if ((err
= nwam_ncp_create(newname
, 0, newncphp
)) != NWAM_SUCCESS
)
359 err
= nwam_ncp_walk_ncus(oldncph
, nwam_ncp_copy_callback
, *newncphp
,
360 NWAM_FLAG_NCU_TYPE_CLASS_ALL
, &cb_ret
);
361 if (err
!= NWAM_SUCCESS
) {
362 /* remove the NCP even if any NCU's had already been copied */
363 (void) nwam_ncp_destroy(*newncphp
, 0);
365 if (err
== NWAM_WALK_HALTED
)
371 return (NWAM_SUCCESS
);
375 * Convert type to flag
378 nwam_ncu_type_to_flag(nwam_ncu_type_t type
)
381 case NWAM_NCU_TYPE_LINK
:
382 return (NWAM_FLAG_NCU_TYPE_LINK
);
383 case NWAM_NCU_TYPE_INTERFACE
:
384 return (NWAM_FLAG_NCU_TYPE_INTERFACE
);
385 case NWAM_NCU_TYPE_ANY
:
386 return (NWAM_FLAG_NCU_TYPE_ALL
);
393 * Convert class to flag
396 nwam_ncu_class_to_flag(nwam_ncu_class_t
class)
399 case NWAM_NCU_CLASS_PHYS
:
400 return (NWAM_FLAG_NCU_CLASS_PHYS
);
401 case NWAM_NCU_CLASS_IP
:
402 return (NWAM_FLAG_NCU_CLASS_IP
);
403 case NWAM_NCU_CLASS_ANY
:
404 return (NWAM_FLAG_NCU_CLASS_ALL
);
411 * Infer NCU type from NCU class
414 nwam_ncu_class_to_type(nwam_ncu_class_t
class)
417 case NWAM_NCU_CLASS_PHYS
:
418 return (NWAM_NCU_TYPE_LINK
);
419 case NWAM_NCU_CLASS_IP
:
420 return (NWAM_NCU_TYPE_INTERFACE
);
421 case NWAM_NCU_CLASS_ANY
:
422 return (NWAM_NCU_TYPE_ANY
);
424 return (NWAM_NCU_TYPE_UNKNOWN
);
429 * Make ncp active, deactivating any other active ncp.
432 nwam_ncp_enable(nwam_ncp_handle_t ncph
)
437 assert(ncph
!= NULL
);
439 err
= nwam_enable(NULL
, ncph
);
441 if (err
== NWAM_ERROR_BIND
) {
443 * nwamd is not running, set active_ncp property so when
444 * nwamd is next started, this NCP will be used.
446 if ((err
= nwam_ncp_get_name(ncph
, &name
)) != NWAM_SUCCESS
)
449 err
= nwam_set_smf_string_property(NWAM_FMRI
, NWAM_PG
,
450 NWAM_PROP_ACTIVE_NCP
, name
);
457 /* Compare NCP names c1 and c2 using strcasecmp() */
459 ncpname_cmp(const void *c1
, const void *c2
)
461 return (strcasecmp(*(const char **)c1
, *(const char **)c2
));
466 nwam_walk_ncps(int (*cb
)(nwam_ncp_handle_t
, void *), void *data
,
467 uint64_t flags
, int *retp
)
469 char *ncpname
, **ncpfiles
;
470 nwam_ncp_handle_t ncph
;
474 uint_t i
, num_ncpfiles
;
479 if ((err
= nwam_valid_flags(flags
, NWAM_FLAG_BLOCKING
)) != NWAM_SUCCESS
)
482 * To get list of NCP files, call nwam_read_object_from_backend()
483 * with "parent" argument set to NULL. We get back an object list
484 * consisting of string arrays for each object type - NCP, ENM
485 * and location. We retrieve the NCP list, which corresponds to
486 * the set of NCP backend parent objects (these are files at present).
488 if ((err
= nwam_read_object_from_backend(NULL
, NULL
, flags
,
489 &objlist
)) != NWAM_SUCCESS
)
492 if ((err
= nwam_get_prop_value(objlist
, NWAM_NCP_OBJECT_STRING
, &value
))
494 nwam_free_object_list(objlist
);
497 if ((err
= nwam_value_get_string_array(value
, &ncpfiles
,
498 &num_ncpfiles
)) != NWAM_SUCCESS
) {
499 nwam_value_free(value
);
500 nwam_free_object_list(objlist
);
504 /* sort the NCP names alphabetically */
505 qsort(ncpfiles
, num_ncpfiles
, sizeof (char *), ncpname_cmp
);
507 for (i
= 0; i
< num_ncpfiles
; i
++) {
508 if (nwam_ncp_file_to_name(ncpfiles
[i
], &ncpname
)
511 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCP
, ncpname
,
512 &ncph
)) != NWAM_SUCCESS
) {
516 ret
= cb(ncph
, data
);
520 err
= NWAM_WALK_HALTED
;
524 nwam_value_free(value
);
525 nwam_free_object_list(objlist
);
533 * Checks if NCP is read-only. Only NWAM_NCP_NAME_AUTOMATIC is read-only
534 * for all but the netadm user (which nwamd runs as).
537 nwam_ncp_get_read_only(nwam_ncp_handle_t ncph
, boolean_t
*readp
)
542 assert(ncph
!= NULL
&& readp
!= NULL
);
544 if ((err
= nwam_ncp_get_name(ncph
, &name
)) != NWAM_SUCCESS
)
547 if (NWAM_NCP_AUTOMATIC(name
))
548 *readp
= !nwam_uid_is_special();
553 return (NWAM_SUCCESS
);
556 /* Checks if NCU is writable depending on its parent */
558 nwam_ncu_get_read_only(nwam_ncu_handle_t ncuh
, boolean_t
*readp
)
561 nwam_ncp_handle_t ncph
;
563 assert(ncuh
!= NULL
&& readp
!= NULL
);
565 if ((err
= nwam_ncu_get_ncp(ncuh
, &ncph
)) != NWAM_SUCCESS
)
568 err
= nwam_ncp_get_read_only(ncph
, readp
);
573 /* Returns true if the NCP is active */
575 nwam_ncp_is_active(nwam_ncp_handle_t ncph
)
577 char *active_ncp
, *name
;
580 assert(ncph
!= NULL
);
583 * Determine which NCP is active via the nwamd/active_ncp property
584 * value. This allows us to determine which NCP is active even
585 * if nwamd is not running.
587 if (nwam_ncp_get_name(ncph
, &name
) != NWAM_SUCCESS
||
588 nwam_get_smf_string_property(NWAM_FMRI
, NWAM_PG
,
589 NWAM_PROP_ACTIVE_NCP
, &active_ncp
) != NWAM_SUCCESS
)
592 ret
= (strcmp(name
, active_ncp
) == 0);
601 nwam_ncp_destroy(nwam_ncp_handle_t ncph
, uint64_t flags
)
607 assert(ncph
!= NULL
);
609 if ((err
= nwam_ncp_get_read_only(ncph
, &read_only
)) != NWAM_SUCCESS
)
612 return (NWAM_ENTITY_NOT_DESTROYABLE
);
614 if (nwam_ncp_is_active(ncph
))
615 return (NWAM_ENTITY_IN_USE
);
617 if ((err
= nwam_ncp_name_to_file(ncph
->nwh_name
, &filename
))
621 err
= nwam_destroy(filename
, ncph
, flags
);
624 return (NWAM_SUCCESS
);
628 nwam_ncu_internal_name_to_name(const char *internalname
,
629 nwam_ncu_type_t
*typep
, char **namep
)
633 assert(internalname
!= NULL
&& namep
!= NULL
);
635 if (strncasecmp(internalname
, NWAM_NCU_LINK_NAME_PRE
,
636 strlen(NWAM_NCU_LINK_NAME_PRE
)) == 0) {
637 prefixstr
= NWAM_NCU_LINK_NAME_PRE
;
638 *typep
= NWAM_NCU_TYPE_LINK
;
639 } else if (strncasecmp(internalname
, NWAM_NCU_INTERFACE_NAME_PRE
,
640 strlen(NWAM_NCU_INTERFACE_NAME_PRE
)) == 0) {
641 prefixstr
= NWAM_NCU_INTERFACE_NAME_PRE
;
642 *typep
= NWAM_NCU_TYPE_INTERFACE
;
644 return (NWAM_INVALID_ARG
);
647 *namep
= strdup(internalname
+ strlen(prefixstr
));
649 return (NWAM_NO_MEMORY
);
650 return (NWAM_SUCCESS
);
655 ncu_selectcb(struct nwam_handle
*hp
, uint64_t flags
, void *data
)
657 nwam_ncu_handle_t ncuh
= hp
;
658 nwam_value_t typeval
= NULL
, classval
= NULL
;
659 uint64_t type
, class, matchflags
, walkfilter
;
661 if (nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_TYPE
, &typeval
)
663 nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_CLASS
, &classval
)
666 nwam_value_free(typeval
);
667 return (NWAM_INVALID_ARG
);
669 if (nwam_value_get_uint64(typeval
, &type
) != NWAM_SUCCESS
||
670 nwam_value_get_uint64(classval
, &class) != NWAM_SUCCESS
) {
671 nwam_value_free(typeval
);
672 nwam_value_free(classval
);
673 return (NWAM_INVALID_ARG
);
676 matchflags
= nwam_ncu_type_to_flag(type
) |
677 nwam_ncu_class_to_flag(class);
678 nwam_value_free(typeval
);
679 nwam_value_free(classval
);
681 if ((walkfilter
= (flags
& NWAM_WALK_FILTER_MASK
)) == 0)
682 walkfilter
= NWAM_FLAG_NCU_TYPE_CLASS_ALL
;
684 if (matchflags
& walkfilter
)
685 return (NWAM_SUCCESS
);
686 return (NWAM_INVALID_ARG
);
690 nwam_ncp_walk_ncus(nwam_ncp_handle_t ncph
,
691 int(*cb
)(nwam_ncu_handle_t
, void *), void *data
, uint64_t flags
, int *retp
)
696 assert(ncph
!= NULL
&& cb
!= NULL
);
698 if ((err
= nwam_valid_flags(flags
,
699 NWAM_FLAG_NCU_TYPE_CLASS_ALL
| NWAM_FLAG_BLOCKING
)) != NWAM_SUCCESS
)
702 if ((err
= nwam_ncp_name_to_file(ncph
->nwh_name
, &ncpfile
))
706 err
= nwam_walk(NWAM_OBJECT_TYPE_NCU
, ncpfile
, cb
, data
, flags
,
714 nwam_ncp_free(nwam_ncp_handle_t ncph
)
720 * Are ncu type and class compatible?
723 nwam_ncu_type_class_compatible(nwam_ncu_type_t type
, nwam_ncu_class_t
class)
726 case NWAM_NCU_TYPE_LINK
:
727 return (class == NWAM_NCU_CLASS_PHYS
);
728 case NWAM_NCU_TYPE_INTERFACE
:
729 return (class == NWAM_NCU_CLASS_IP
);
735 /* Name to validate may be internal name. If so, convert it before validating */
737 valid_ncu_name(const char *name
)
741 nwam_ncu_type_t type
;
743 if (nwam_ncu_internal_name_to_name(name
, &type
, &n
) == NWAM_SUCCESS
) {
745 ret
= dladm_valid_linkname(n
);
748 ret
= dladm_valid_linkname(name
);
755 nwam_ncu_create(nwam_ncp_handle_t ncph
, const char *name
,
756 nwam_ncu_type_t type
, nwam_ncu_class_t
class, nwam_ncu_handle_t
*ncuhp
)
758 nwam_ncu_handle_t ncuh
;
759 nwam_value_t typeval
= NULL
, classval
= NULL
, parentval
= NULL
;
760 nwam_value_t enabledval
= NULL
;
765 assert(ncph
!= NULL
&& name
!= NULL
&& ncuhp
!= NULL
);
767 if (!valid_ncu_name(name
))
768 return (NWAM_INVALID_ARG
);
770 if ((err
= nwam_ncp_get_read_only(ncph
, &read_only
)) != NWAM_SUCCESS
)
773 return (NWAM_ENTITY_READ_ONLY
);
775 if (nwam_ncu_read(ncph
, name
, type
, 0, &ncuh
) == NWAM_SUCCESS
) {
777 return (NWAM_ENTITY_EXISTS
);
780 if (!valid_ncu_name(name
) ||
781 !nwam_ncu_type_class_compatible(type
, class))
782 return (NWAM_INVALID_ARG
);
784 if ((err
= nwam_ncu_name_to_typed_name(name
, type
, &typedname
))
789 if ((err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCU
, typedname
, ncuhp
))
795 * Create new object list for NCU. The new NCU is initialized with
796 * the appropriate type and class.
798 if ((err
= nwam_alloc_object_list(&(*ncuhp
)->nwh_data
)) != NWAM_SUCCESS
)
801 if ((err
= nwam_value_create_uint64(type
, &typeval
))
803 (err
= nwam_value_create_uint64(class, &classval
))
805 (err
= nwam_value_create_string(ncph
->nwh_name
, &parentval
))
807 (err
= nwam_value_create_boolean(B_TRUE
, &enabledval
))
811 if ((err
= nwam_set_prop_value((*ncuhp
)->nwh_data
, NWAM_NCU_PROP_TYPE
,
812 typeval
)) != NWAM_SUCCESS
||
813 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
, NWAM_NCU_PROP_CLASS
,
814 classval
)) != NWAM_SUCCESS
||
815 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
816 NWAM_NCU_PROP_PARENT_NCP
, parentval
)) != NWAM_SUCCESS
||
817 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
818 NWAM_NCU_PROP_ENABLED
, enabledval
)) != NWAM_SUCCESS
) {
822 /* Set default IP, datalink properties */
823 if (type
== NWAM_NCU_TYPE_INTERFACE
&& class == NWAM_NCU_CLASS_IP
) {
825 uint64_t ver
[] = { IPV4_VERSION
, IPV6_VERSION
};
826 uint64_t v6src
[] = { NWAM_ADDRSRC_DHCP
, NWAM_ADDRSRC_AUTOCONF
};
827 uint_t vercnt
= 2, v6srccnt
= 2;
828 nwam_value_t ipver
= NULL
, v4addrsrc
= NULL
, v6addrsrc
= NULL
;
830 if ((err
= nwam_value_create_uint64_array(ver
, vercnt
, &ipver
))
832 (err
= nwam_value_create_uint64(NWAM_ADDRSRC_DHCP
,
833 &v4addrsrc
)) != NWAM_SUCCESS
||
834 (err
= nwam_value_create_uint64_array(v6src
, v6srccnt
,
835 &v6addrsrc
)) != NWAM_SUCCESS
) {
836 nwam_value_free(ipver
);
837 nwam_value_free(v4addrsrc
);
840 if ((err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
841 NWAM_NCU_PROP_IP_VERSION
, ipver
)) == NWAM_SUCCESS
&&
842 (err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
843 NWAM_NCU_PROP_IPV4_ADDRSRC
, v4addrsrc
)) == NWAM_SUCCESS
) {
844 err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
845 NWAM_NCU_PROP_IPV6_ADDRSRC
, v6addrsrc
);
847 nwam_value_free(ipver
);
848 nwam_value_free(v4addrsrc
);
849 nwam_value_free(v6addrsrc
);
851 nwam_value_t actval
= NULL
;
852 if ((err
= nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL
,
853 &actval
)) != NWAM_SUCCESS
)
855 err
= nwam_set_prop_value((*ncuhp
)->nwh_data
,
856 NWAM_NCU_PROP_ACTIVATION_MODE
, actval
);
857 nwam_value_free(actval
);
861 nwam_value_free(typeval
);
862 nwam_value_free(classval
);
863 nwam_value_free(parentval
);
864 nwam_value_free(enabledval
);
865 if (err
!= NWAM_SUCCESS
) {
866 nwam_ncu_free(*ncuhp
);
873 nwam_ncu_read(nwam_ncp_handle_t ncph
, const char *name
,
874 nwam_ncu_type_t type
, uint64_t flags
, nwam_ncu_handle_t
*ncuhp
)
876 char *ncpfile
, *typedname
;
877 nwam_error_t err
, err_ip
, err_link
;
878 nwam_ncu_handle_t ncuh_ip
, ncuh_link
;
880 assert(ncph
!= NULL
&& name
!= NULL
&& ncuhp
!= NULL
);
882 if ((err
= nwam_ncp_name_to_file(ncph
->nwh_name
, &ncpfile
))
886 if (type
== NWAM_NCU_TYPE_ANY
) {
891 * If we get to this point, we have discovered that no
892 * NCU type is discernable from name or type arguments.
893 * Either exactly one NCU called name must exist of either
894 * type, or the operation should fail.
896 err_ip
= nwam_ncu_read(ncph
, name
, NWAM_NCU_TYPE_INTERFACE
,
898 err_link
= nwam_ncu_read(ncph
, name
, NWAM_NCU_TYPE_LINK
,
903 if (err_ip
== NWAM_SUCCESS
&& err_link
== NWAM_SUCCESS
) {
904 nwam_ncu_free(ncuh_ip
);
905 nwam_ncu_free(ncuh_link
);
906 err
= NWAM_ENTITY_MULTIPLE_VALUES
;
907 } else if (err_ip
!= NWAM_SUCCESS
&& err_link
!= NWAM_SUCCESS
) {
908 err
= NWAM_ENTITY_NOT_FOUND
;
910 if (err_ip
== NWAM_SUCCESS
) {
920 if ((err
= nwam_ncu_name_to_typed_name(name
, type
, &typedname
)) !=
925 err
= nwam_read(NWAM_OBJECT_TYPE_NCU
, ncpfile
, typedname
, flags
, ncuhp
);
934 nwam_ncu_get_name(nwam_ncu_handle_t ncuh
, char **namep
)
936 nwam_ncu_type_t type
;
938 assert(ncuh
!= NULL
&& namep
!= NULL
);
940 return (nwam_ncu_internal_name_to_name(ncuh
->nwh_name
, &type
, namep
));
944 nwam_ncu_name_to_typed_name(const char *name
, nwam_ncu_type_t type
,
950 assert(name
!= NULL
&& typednamep
!= NULL
);
953 case NWAM_NCU_TYPE_INTERFACE
:
954 prefixstr
= NWAM_NCU_INTERFACE_NAME_PRE
;
956 case NWAM_NCU_TYPE_LINK
:
957 prefixstr
= NWAM_NCU_LINK_NAME_PRE
;
960 return (NWAM_INVALID_ARG
);
962 typednamesz
= strlen(name
) + strlen(prefixstr
) + 1;
963 if ((*typednamep
= malloc(typednamesz
)) == NULL
)
964 return (NWAM_NO_MEMORY
);
966 /* Name may be already qualified by type */
967 if (strncasecmp(prefixstr
, name
, strlen(prefixstr
)) == 0) {
968 (void) snprintf(*typednamep
, typednamesz
, "%s", name
);
970 (void) snprintf(*typednamep
, typednamesz
, "%s%s",
974 return (NWAM_SUCCESS
);
978 nwam_ncu_typed_name_to_name(const char *typed_name
, nwam_ncu_type_t
*typep
,
981 return (nwam_ncu_internal_name_to_name(typed_name
, typep
, name
));
985 nwam_ncu_free(nwam_ncu_handle_t ncuh
)
991 nwam_ncu_copy(nwam_ncu_handle_t oldncuh
, const char *newname
,
992 nwam_ncu_handle_t
*newncuhp
)
994 nwam_ncp_handle_t ncph
;
995 nwam_ncu_handle_t ncuh
;
997 nwam_value_t typeval
;
1001 assert(oldncuh
!= NULL
&& newname
!= NULL
&& newncuhp
!= NULL
);
1003 if (nwam_ncu_get_prop_value(oldncuh
, NWAM_NCU_PROP_TYPE
,
1004 &typeval
) != NWAM_SUCCESS
) {
1005 return (NWAM_INVALID_ARG
);
1007 if (nwam_value_get_uint64(typeval
, &type
) != NWAM_SUCCESS
) {
1008 nwam_value_free(typeval
);
1009 return (NWAM_INVALID_ARG
);
1011 nwam_value_free(typeval
);
1013 /* check if newname NCU already exists */
1014 if ((err
= nwam_ncu_get_ncp(oldncuh
, &ncph
)) != NWAM_SUCCESS
)
1016 if (nwam_ncu_read(ncph
, newname
, type
, 0, &ncuh
) == NWAM_SUCCESS
) {
1017 nwam_ncu_free(ncuh
);
1018 nwam_ncp_free(ncph
);
1019 return (NWAM_ENTITY_EXISTS
);
1021 nwam_ncp_free(ncph
);
1023 if ((err
= nwam_ncu_name_to_typed_name(newname
, type
, &typednewname
))
1027 err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCU
, typednewname
, newncuhp
);
1029 if (err
!= NWAM_SUCCESS
)
1031 if ((err
= nwam_dup_object_list(oldncuh
->nwh_data
,
1032 &((*newncuhp
)->nwh_data
))) != NWAM_SUCCESS
) {
1038 return (NWAM_SUCCESS
);
1042 nwam_ncu_delete_prop(nwam_ncu_handle_t ncuh
, const char *propname
)
1044 boolean_t ro_ncu
, ro_prop
;
1048 assert(ncuh
!= NULL
&& propname
!= NULL
);
1050 if ((err
= nwam_ncu_get_read_only(ncuh
, &ro_ncu
)) != NWAM_SUCCESS
||
1051 (err
= nwam_ncu_prop_read_only(propname
, &ro_prop
)) != NWAM_SUCCESS
)
1053 if (ro_ncu
|| ro_prop
)
1054 return (NWAM_ENTITY_READ_ONLY
);
1057 * Duplicate data, remove property and validate. If validation
1058 * fails, revert to data duplicated prior to remove.
1060 if ((err
= nwam_dup_object_list(ncuh
->nwh_data
, &olddata
))
1063 if ((err
= nwam_delete_prop(ncuh
->nwh_data
, propname
))
1065 nwam_free_object_list(ncuh
->nwh_data
);
1066 ncuh
->nwh_data
= olddata
;
1069 if ((err
= nwam_ncu_validate(ncuh
, NULL
)) != NWAM_SUCCESS
) {
1070 nwam_free_object_list(ncuh
->nwh_data
);
1071 ncuh
->nwh_data
= olddata
;
1074 nwam_free_object_list(olddata
);
1076 return (NWAM_SUCCESS
);
1080 nwam_ncu_set_prop_value(nwam_ncu_handle_t ncuh
, const char *propname
,
1083 boolean_t ro_ncu
, ro_prop
;
1085 nwam_ncp_handle_t ncph
;
1087 assert(ncuh
!= NULL
&& propname
!= NULL
&& value
!= NULL
);
1089 if ((err
= nwam_ncu_get_read_only(ncuh
, &ro_ncu
)) != NWAM_SUCCESS
||
1090 (err
= nwam_ncu_prop_read_only(propname
, &ro_prop
)) != NWAM_SUCCESS
)
1092 if (ro_ncu
|| ro_prop
)
1093 return (NWAM_ENTITY_READ_ONLY
);
1095 err
= nwam_ncu_get_ncp(ncuh
, &ncph
);
1096 if (err
!= NWAM_SUCCESS
&& err
!= NWAM_INVALID_ARG
) {
1098 * If "parent" property doesn't exist, NWAM_INVALID_ARG
1099 * is returned. Allow the setting to continue.
1103 nwam_ncp_free(ncph
);
1105 /* Need to ensure property, type and value are valid */
1106 if ((err
= nwam_ncu_validate_prop(ncuh
, propname
, value
))
1110 return (nwam_set_prop_value(ncuh
->nwh_data
, propname
, value
));
1114 nwam_ncu_get_prop_value(nwam_ncu_handle_t ncuh
, const char *propname
,
1115 nwam_value_t
*valuep
)
1117 assert(ncuh
!= NULL
&& propname
!= NULL
&& valuep
!= NULL
);
1119 return (nwam_get_prop_value(ncuh
->nwh_data
, propname
, valuep
));
1123 nwam_ncu_walk_props(nwam_ncu_handle_t ncuh
,
1124 int (*cb
)(const char *, nwam_value_t
, void *),
1125 void *data
, uint64_t flags
, int *retp
)
1127 return (nwam_walk_props(ncuh
, cb
, data
, flags
, retp
));
1131 nwam_ncu_get_ncp(nwam_ncu_handle_t ncuh
, nwam_ncp_handle_t
*ncphp
)
1134 char *parentname
= NULL
;
1136 if ((err
= nwam_ncu_get_parent_ncp_name(ncuh
, &parentname
))
1138 (err
= nwam_handle_create(NWAM_OBJECT_TYPE_NCP
, parentname
, ncphp
))
1140 if (parentname
!= NULL
)
1146 return (NWAM_SUCCESS
);
1150 nwam_ncu_commit(nwam_ncu_handle_t ncuh
, uint64_t flags
)
1153 boolean_t read_only
;
1154 char *ncpfile
, *ncpname
;
1156 assert(ncuh
!= NULL
&& ncuh
->nwh_data
!= NULL
);
1158 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1161 return (NWAM_ENTITY_READ_ONLY
);
1163 if ((err
= nwam_ncu_validate(ncuh
, NULL
)) != NWAM_SUCCESS
||
1164 (err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1168 if ((err
= nwam_ncp_name_to_file(ncpname
, &ncpfile
)) != NWAM_SUCCESS
) {
1173 err
= nwam_commit(ncpfile
, ncuh
, flags
);
1180 /* Get the NCU type */
1182 nwam_ncu_get_ncu_type(nwam_ncu_handle_t ncuh
, nwam_ncu_type_t
*typep
)
1185 nwam_value_t typeval
;
1188 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_TYPE
, &typeval
))
1191 err
= nwam_value_get_uint64(typeval
, &type
);
1192 nwam_value_free(typeval
);
1193 if (err
!= NWAM_SUCCESS
)
1197 return (NWAM_SUCCESS
);
1200 /* Get the NCU class */
1202 nwam_ncu_get_ncu_class(nwam_ncu_handle_t ncuh
, nwam_ncu_class_t
*classp
)
1205 nwam_value_t classval
;
1208 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_CLASS
,
1209 &classval
)) != NWAM_SUCCESS
)
1211 err
= nwam_value_get_uint64(classval
, &class);
1212 nwam_value_free(classval
);
1213 if (err
!= NWAM_SUCCESS
)
1217 return (NWAM_SUCCESS
);
1221 * Determine if the NCU has manual activation-mode or not.
1224 nwam_ncu_is_manual(nwam_ncu_handle_t ncuh
, boolean_t
*manualp
)
1227 nwam_value_t actval
;
1228 uint64_t activation
;
1230 assert(ncuh
!= NULL
);
1232 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_ACTIVATION_MODE
,
1233 &actval
)) != NWAM_SUCCESS
)
1235 err
= nwam_value_get_uint64(actval
, &activation
);
1236 nwam_value_free(actval
);
1237 if (err
!= NWAM_SUCCESS
)
1240 if (activation
== NWAM_ACTIVATION_MODE_MANUAL
)
1244 return (NWAM_SUCCESS
);
1247 /* Determine if NCU is enabled or not */
1249 nwam_ncu_is_enabled(nwam_ncu_handle_t ncuh
, boolean_t
*enabledp
)
1252 nwam_value_t enabledval
;
1254 assert(ncuh
!= NULL
);
1256 if ((err
= nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_ENABLED
,
1257 &enabledval
)) != NWAM_SUCCESS
)
1259 err
= nwam_value_get_boolean(enabledval
, enabledp
);
1260 nwam_value_free(enabledval
);
1264 /* Update the enabled property */
1266 nwam_ncu_update_enabled(nwam_ncu_handle_t ncuh
, boolean_t enabled
)
1269 nwam_value_t enabledval
;
1271 if ((err
= nwam_value_create_boolean(enabled
, &enabledval
))
1274 err
= nwam_set_prop_value(ncuh
->nwh_data
, NWAM_NCU_PROP_ENABLED
,
1276 nwam_value_free(enabledval
);
1277 if (err
!= NWAM_SUCCESS
)
1279 return (nwam_ncu_commit(ncuh
, NWAM_FLAG_ENTITY_ENABLE
));
1283 * Make ncu active; fails if the NCU's parent NCP is not active.
1286 nwam_ncu_enable(nwam_ncu_handle_t ncuh
)
1288 char *ncpname
= NULL
;
1290 nwam_ncu_type_t type
;
1291 boolean_t read_only
, enabled
, manual
;
1293 assert(ncuh
!= NULL
);
1295 /* Don't allow NCUs of Automatic NCP to be enabled */
1296 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1299 return (NWAM_ENTITY_NOT_MANUAL
);
1301 /* Link NCUs with manual activation-mode or IP NCUs can be enabled */
1302 if ((err
= nwam_ncu_get_ncu_type(ncuh
, &type
)) != NWAM_SUCCESS
)
1305 if (type
== NWAM_NCU_TYPE_LINK
) {
1306 if ((err
= nwam_ncu_is_manual(ncuh
, &manual
)) != NWAM_SUCCESS
)
1309 return (NWAM_ENTITY_NOT_MANUAL
);
1312 /* Make sure NCU is not enabled */
1313 if ((err
= nwam_ncu_is_enabled(ncuh
, &enabled
)) != NWAM_SUCCESS
||
1314 (err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1320 return (NWAM_SUCCESS
);
1323 if ((err
= nwam_ncu_update_enabled(ncuh
, B_TRUE
)) != NWAM_SUCCESS
) {
1328 err
= nwam_enable(ncpname
, ncuh
);
1331 /* nwamd may not be running, that's okay. */
1332 if (err
== NWAM_ERROR_BIND
)
1333 return (NWAM_SUCCESS
);
1339 * Disable ncu; fails if the NCU's parent NCP is not active, or if the
1340 * NCU is not currently active.
1343 nwam_ncu_disable(nwam_ncu_handle_t ncuh
)
1345 char *ncpname
= NULL
;
1347 nwam_ncu_type_t type
;
1348 boolean_t read_only
, enabled
, manual
;
1350 assert(ncuh
!= NULL
);
1352 /* Don't allow NCUs of Automatic NCP to be disabled */
1353 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1356 return (NWAM_ENTITY_NOT_MANUAL
);
1358 /* Link NCUs with manual activation-mode or IP NCUs can be disabled */
1359 if ((err
= nwam_ncu_get_ncu_type(ncuh
, &type
)) != NWAM_SUCCESS
)
1362 if (type
== NWAM_NCU_TYPE_LINK
) {
1363 if ((err
= nwam_ncu_is_manual(ncuh
, &manual
)) != NWAM_SUCCESS
)
1366 return (NWAM_ENTITY_NOT_MANUAL
);
1369 /* Make sure NCU is enabled */
1370 if ((err
= nwam_ncu_is_enabled(ncuh
, &enabled
)) != NWAM_SUCCESS
||
1371 (err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1377 return (NWAM_SUCCESS
);
1380 if ((err
= nwam_ncu_update_enabled(ncuh
, B_FALSE
)) != NWAM_SUCCESS
) {
1385 err
= nwam_disable(ncpname
, ncuh
);
1388 /* nwamd may not be running, that's okay. */
1389 if (err
== NWAM_ERROR_BIND
)
1390 return (NWAM_SUCCESS
);
1396 nwam_ncu_destroy(nwam_ncu_handle_t ncuh
, uint64_t flags
)
1398 char *ncpname
, *ncpfile
;
1399 boolean_t read_only
;
1402 assert(ncuh
!= NULL
);
1404 if ((err
= nwam_ncu_get_read_only(ncuh
, &read_only
)) != NWAM_SUCCESS
)
1407 return (NWAM_ENTITY_NOT_DESTROYABLE
);
1409 if ((err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1412 if ((err
= nwam_ncp_name_to_file(ncpname
, &ncpfile
))
1418 err
= nwam_destroy(ncpfile
, ncuh
, flags
);
1427 nwam_ncu_get_prop_description(const char *propname
, const char **descriptionp
)
1429 return (nwam_get_prop_description(ncu_prop_table
, propname
,
1433 /* Get expected property data type */
1435 nwam_ncu_get_prop_type(const char *propname
, nwam_value_type_t
*typep
)
1437 return (nwam_get_prop_type(ncu_prop_table
, propname
, typep
));
1441 nwam_ncu_prop_read_only(const char *propname
, boolean_t
*readp
)
1443 if ((*readp
= NWAM_NCU_PROP_SETONCE(propname
)) == B_TRUE
)
1444 return (NWAM_SUCCESS
);
1446 return (nwam_prop_read_only(ncu_prop_table
, propname
, readp
));
1450 nwam_ncu_prop_multivalued(const char *propname
, boolean_t
*multip
)
1452 return (nwam_prop_multivalued(ncu_prop_table
, propname
, multip
));
1456 * Ensure that the properties in the ncu, determined by that ncu's
1457 * type and class, belong there.
1460 nwam_ncu_validate_prop_membership(nwam_ncu_handle_t ncuh
, const char *propname
)
1462 struct nwam_prop_table_entry
*pte
;
1463 nwam_value_t typeval
, classval
;
1464 uint64_t type
, class;
1465 uint64_t typeflags
= 0, classflags
= 0;
1467 /* Get type/class from ncu */
1468 if (nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_TYPE
, &typeval
)
1470 return (NWAM_ENTITY_INVALID
);
1471 if (nwam_value_get_uint64(typeval
, &type
) != NWAM_SUCCESS
) {
1472 nwam_value_free(typeval
);
1473 return (NWAM_ENTITY_INVALID
);
1475 typeflags
= nwam_ncu_type_to_flag((nwam_ncu_type_t
)type
);
1476 nwam_value_free(typeval
);
1478 if (nwam_ncu_get_prop_value(ncuh
, NWAM_NCU_PROP_CLASS
, &classval
)
1480 return (NWAM_ENTITY_INVALID
);
1481 if (nwam_value_get_uint64(classval
, &class) != NWAM_SUCCESS
) {
1482 nwam_value_free(classval
);
1483 return (NWAM_ENTITY_INVALID
);
1485 classflags
= nwam_ncu_class_to_flag((nwam_ncu_class_t
)class);
1486 nwam_value_free(classval
);
1488 if ((pte
= nwam_get_prop_table_entry(ncu_prop_table
, propname
)) == NULL
)
1489 return (NWAM_INVALID_ARG
);
1491 if (typeflags
& pte
->prop_type_membership
&&
1492 classflags
& pte
->prop_class_membership
) {
1493 return (NWAM_SUCCESS
);
1495 return (NWAM_ENTITY_INVALID_MEMBER
);
1499 /* Validate property's ncu membership and type, number and range of values */
1501 nwam_ncu_validate_prop(nwam_ncu_handle_t ncuh
, const char *propname
,
1506 assert(ncuh
!= NULL
&& propname
!= NULL
);
1508 /* First, determine if this property is valid for this ncu */
1509 if ((err
= nwam_ncu_validate_prop_membership(ncuh
, propname
))
1513 return (nwam_validate_prop(ncu_prop_table
, ncuh
, propname
, value
));
1516 /* Property-specific value validation functions follow */
1519 valid_type(nwam_value_t value
)
1523 if (nwam_value_get_uint64(value
, &type
) != NWAM_SUCCESS
||
1524 type
> NWAM_NCU_TYPE_INTERFACE
)
1525 return (NWAM_ENTITY_INVALID_VALUE
);
1526 return (NWAM_SUCCESS
);
1530 valid_class(nwam_value_t value
)
1534 if (nwam_value_get_uint64(value
, &class) != NWAM_SUCCESS
||
1535 class > NWAM_NCU_CLASS_IP
)
1536 return (NWAM_ENTITY_INVALID_VALUE
);
1537 return (NWAM_SUCCESS
);
1541 valid_ncp(nwam_value_t value
)
1545 if (nwam_value_get_string(value
, &ncp
) != NWAM_SUCCESS
)
1546 return (NWAM_ENTITY_INVALID_VALUE
);
1547 return (NWAM_SUCCESS
);
1551 valid_priority_mode(nwam_value_t value
)
1553 uint64_t priority_mode
;
1555 if (nwam_value_get_uint64(value
, &priority_mode
) != NWAM_SUCCESS
||
1556 priority_mode
> NWAM_PRIORITY_MODE_ALL
)
1557 return (NWAM_ENTITY_INVALID_VALUE
);
1558 return (NWAM_SUCCESS
);
1562 valid_ncu_activation_mode(nwam_value_t value
)
1564 uint64_t activation_mode
;
1566 if (nwam_value_get_uint64(value
, &activation_mode
) != NWAM_SUCCESS
)
1567 return (NWAM_ENTITY_INVALID_VALUE
);
1569 switch (activation_mode
) {
1570 case NWAM_ACTIVATION_MODE_MANUAL
:
1571 case NWAM_ACTIVATION_MODE_PRIORITIZED
:
1572 return (NWAM_SUCCESS
);
1574 return (NWAM_ENTITY_INVALID_VALUE
);
1579 valid_link_autopush(nwam_value_t value
)
1581 return (NWAM_SUCCESS
);
1585 valid_ip_version(nwam_value_t value
)
1588 uint_t i
, numvalues
;
1590 if (nwam_value_get_uint64_array(value
, &versions
, &numvalues
)
1592 return (NWAM_ENTITY_INVALID_VALUE
);
1594 for (i
= 0; i
< numvalues
; i
++) {
1595 if (versions
[i
] != IPV4_VERSION
&&
1596 versions
[i
] != IPV6_VERSION
)
1597 return (NWAM_ENTITY_INVALID_VALUE
);
1599 return (NWAM_SUCCESS
);
1603 valid_addrsrc_v4(nwam_value_t value
)
1606 uint_t i
, numvalues
;
1608 if (nwam_value_get_uint64_array(value
, &addrsrc
, &numvalues
)
1610 return (NWAM_ENTITY_INVALID_VALUE
);
1612 for (i
= 0; i
< numvalues
; i
++) {
1613 if (addrsrc
[i
] != NWAM_ADDRSRC_DHCP
&&
1614 addrsrc
[i
] != NWAM_ADDRSRC_STATIC
)
1615 return (NWAM_ENTITY_INVALID_VALUE
);
1617 return (NWAM_SUCCESS
);
1621 valid_addrsrc_v6(nwam_value_t value
)
1624 uint_t i
, numvalues
;
1625 boolean_t dhcp_found
= B_FALSE
, autoconf_found
= B_FALSE
;
1627 if (nwam_value_get_uint64_array(value
, &addrsrc
, &numvalues
)
1629 return (NWAM_ENTITY_INVALID_VALUE
);
1631 for (i
= 0; i
< numvalues
; i
++) {
1632 if (addrsrc
[i
] != NWAM_ADDRSRC_DHCP
&&
1633 addrsrc
[i
] != NWAM_ADDRSRC_STATIC
&&
1634 addrsrc
[i
] != NWAM_ADDRSRC_AUTOCONF
)
1635 return (NWAM_ENTITY_INVALID_VALUE
);
1636 if (addrsrc
[i
] == NWAM_ADDRSRC_DHCP
)
1637 dhcp_found
= B_TRUE
;
1638 if (addrsrc
[i
] == NWAM_ADDRSRC_AUTOCONF
)
1639 autoconf_found
= B_TRUE
;
1642 * DHCP and AUTOCONF need to be specified as v6 address sources
1643 * since there is no way to switch them off in NWAM at present.
1645 if (dhcp_found
&& autoconf_found
)
1646 return (NWAM_SUCCESS
);
1648 return (NWAM_ENTITY_INVALID_VALUE
);
1653 valid_link_mtu(nwam_value_t value
)
1655 return (NWAM_SUCCESS
);
1659 nwam_ncu_validate(nwam_ncu_handle_t ncuh
, const char **errpropp
)
1661 return (nwam_validate(ncu_prop_table
, ncuh
, errpropp
));
1665 * Given the ncu type and ncu class, return the list of properties that needs
1666 * to be set. Note this list is a complete property list that includes both
1667 * the required ones and the optional ones. Caller needs to free prop_list.
1670 nwam_ncu_get_default_proplist(nwam_ncu_type_t type
, nwam_ncu_class_t
class,
1671 const char ***prop_list
, uint_t
*numvalues
)
1673 uint64_t typeflags
= nwam_ncu_type_to_flag(type
);
1674 uint64_t classflags
= nwam_ncu_class_to_flag(class);
1676 return (nwam_get_default_proplist(ncu_prop_table
, typeflags
,
1677 classflags
, prop_list
, numvalues
));
1681 nwam_ncp_get_state(nwam_ncp_handle_t ncph
, nwam_state_t
*statep
,
1682 nwam_aux_state_t
*auxp
)
1684 return (nwam_get_state(ncph
->nwh_name
, ncph
, statep
, auxp
));
1688 nwam_ncu_get_state(nwam_ncu_handle_t ncuh
, nwam_state_t
*statep
,
1689 nwam_aux_state_t
*auxp
)
1691 nwam_ncp_handle_t ncph
;
1695 assert(ncuh
!= NULL
);
1697 if ((err
= nwam_ncu_get_ncp(ncuh
, &ncph
)) != NWAM_SUCCESS
)
1699 if (!nwam_ncp_is_active(ncph
)) {
1700 nwam_ncp_free(ncph
);
1701 return (NWAM_ENTITY_INVALID
);
1703 nwam_ncp_free(ncph
);
1705 if ((err
= nwam_ncu_get_parent_ncp_name(ncuh
, &ncpname
))
1709 err
= nwam_request_state(NWAM_OBJECT_TYPE_NCU
, ncuh
->nwh_name
, ncpname
,
1716 nwam_ncp_get_active_priority_group(int64_t *priorityp
)
1718 return (nwam_request_active_priority_group(priorityp
));