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.
29 #include <sys/param.h>
30 #include <sys/types.h>
37 #include "libnwam_impl.h"
38 #include <libnwam_priv.h>
42 * Functions to support creating, modifying, destroying, querying the
43 * state of and changing the state of ENM (External Network Modifier)
44 * objects. ENMs represent services or scripts that can be enabled
45 * either manually or conditionally for a combination of the set of
46 * available conditions (an IP address is present, a location is active etc).
49 typedef nwam_error_t (*nwam_enm_prop_validate_func_t
)(nwam_value_t
);
51 static nwam_error_t
valid_enm_activation_mode(nwam_value_t
);
53 struct nwam_prop_table_entry enm_prop_table_entries
[] = {
54 {NWAM_ENM_PROP_ACTIVATION_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1,
55 valid_enm_activation_mode
,
56 "specifies the ENM activation mode - valid values are:\n"
57 "\'manual\', \'conditional-any\' and \'conditional-all\'",
58 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
59 {NWAM_ENM_PROP_CONDITIONS
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
60 NWAM_MAX_NUM_VALUES
, nwam_valid_condition
,
61 "specifies the activation condition. Conditions are of the form:\n"
62 "ncp|ncu|enm|loc name is|is-not active\n"
63 "ip-address is|is-not|is-in-range|is-not-in-range| 1.2.3.4[/24]\n"
64 "advertised-domain is|is-not|contains|does-not-contain string\n"
65 "system-domain is|is-not|contains|does-not-contain string\n"
66 "essid is|is-not|contains|does-not-contain string\n"
67 "bssid is|is-not string",
68 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
69 {NWAM_ENM_PROP_ENABLED
, NWAM_VALUE_TYPE_BOOLEAN
, B_TRUE
, 0, 1,
71 "specifies if manual ENM is to be enabled",
72 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
73 {NWAM_ENM_PROP_FMRI
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
75 "specifies SMF FMRI of service to be enabled on ENM activation",
76 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
77 {NWAM_ENM_PROP_START
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
79 "specifies absolute path to start script to be run on ENM "
81 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
82 {NWAM_ENM_PROP_STOP
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
84 "specifies absolute path to stop script to be run on ENM "
86 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
}
89 #define NWAM_NUM_ENM_PROPS (sizeof (enm_prop_table_entries) / \
90 sizeof (*enm_prop_table_entries))
92 struct nwam_prop_table enm_prop_table
=
93 { NWAM_NUM_ENM_PROPS
, enm_prop_table_entries
};
96 nwam_enm_activation_to_flag(nwam_activation_mode_t activation
)
99 case NWAM_ACTIVATION_MODE_MANUAL
:
100 return (NWAM_FLAG_ACTIVATION_MODE_MANUAL
);
101 case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
:
102 return (NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL_ANY
);
103 case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
:
104 return (NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL_ALL
);
111 nwam_enm_read(const char *name
, uint64_t flags
, nwam_enm_handle_t
*enmhp
)
113 return (nwam_read(NWAM_OBJECT_TYPE_ENM
, NWAM_ENM_CONF_FILE
, name
,
118 nwam_enm_create(const char *name
, const char *fmri
, nwam_enm_handle_t
*enmhp
)
121 nwam_value_t actval
= NULL
, falseval
= NULL
, fmrival
= NULL
;
123 assert(enmhp
!= NULL
&& name
!= NULL
);
125 if ((err
= nwam_create(NWAM_OBJECT_TYPE_ENM
, NWAM_ENM_CONF_FILE
, name
,
126 enmhp
)) != NWAM_SUCCESS
)
130 * Create new object list for ENM. The initial activation mode is set,
131 * and the FMRI property is set, if specified.
133 if ((err
= nwam_alloc_object_list(&((*enmhp
)->nwh_data
)))
137 if ((err
= nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL
,
138 &actval
)) != NWAM_SUCCESS
||
140 (err
= nwam_value_create_string((char *)fmri
, &fmrival
))
142 (err
= nwam_value_create_boolean(B_FALSE
, &falseval
))
146 if ((err
= nwam_set_prop_value((*enmhp
)->nwh_data
,
147 NWAM_ENM_PROP_ACTIVATION_MODE
, actval
)) == NWAM_SUCCESS
&&
148 (err
= nwam_set_prop_value((*enmhp
)->nwh_data
,
149 NWAM_ENM_PROP_ENABLED
, falseval
)) == NWAM_SUCCESS
) {
151 err
= nwam_set_prop_value((*enmhp
)->nwh_data
,
152 NWAM_ENM_PROP_FMRI
, fmrival
);
157 nwam_value_free(actval
);
158 nwam_value_free(falseval
);
160 nwam_value_free(fmrival
);
162 if (err
!= NWAM_SUCCESS
) {
163 nwam_enm_free(*enmhp
);
171 nwam_enm_get_name(nwam_enm_handle_t enmh
, char **namep
)
173 return (nwam_get_name(enmh
, namep
));
177 nwam_enm_set_name(nwam_enm_handle_t enmh
, const char *name
)
179 return (nwam_set_name(enmh
, name
));
183 nwam_enm_can_set_name(nwam_enm_handle_t enmh
)
185 return (!enmh
->nwh_committed
);
190 enm_selectcb(struct nwam_handle
*hp
, uint64_t flags
, void *data
)
192 nwam_enm_handle_t enmh
= hp
;
193 uint64_t activation
, actflag
, walkfilter
;
197 * Get a bitmapped flag value corresponding to this enm's
198 * activation value - if the activation value is not recognized,
199 * actflag will be set to 0, and will thus fail to match
200 * any bit flag passed in by the caller.
202 if (nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_ACTIVATION_MODE
,
203 &actval
) != NWAM_SUCCESS
) {
204 return (NWAM_INVALID_ARG
);
206 if (nwam_value_get_uint64(actval
, &activation
) != NWAM_SUCCESS
) {
207 nwam_value_free(actval
);
208 return (NWAM_INVALID_ARG
);
211 actflag
= nwam_enm_activation_to_flag(activation
);
212 nwam_value_free(actval
);
213 if ((walkfilter
= flags
& NWAM_WALK_FILTER_MASK
) == 0)
214 walkfilter
= NWAM_FLAG_ACTIVATION_MODE_ALL
;
215 if (actflag
& walkfilter
)
216 return (NWAM_SUCCESS
);
217 return (NWAM_INVALID_ARG
);
221 nwam_walk_enms(int(*cb
)(nwam_enm_handle_t
, void *), void *data
, uint64_t flags
,
224 nwam_error_t err
= nwam_valid_flags(flags
,
225 NWAM_FLAG_ACTIVATION_MODE_ALL
| NWAM_FLAG_BLOCKING
);
227 if (err
!= NWAM_SUCCESS
)
230 return (nwam_walk(NWAM_OBJECT_TYPE_ENM
, NWAM_ENM_CONF_FILE
,
231 cb
, data
, flags
, retp
, enm_selectcb
));
235 nwam_enm_free(nwam_enm_handle_t enmh
)
241 nwam_enm_copy(nwam_enm_handle_t oldenmh
, const char *newname
,
242 nwam_enm_handle_t
*newenmhp
)
244 return (nwam_copy(NWAM_ENM_CONF_FILE
, oldenmh
, newname
, newenmhp
));
248 nwam_enm_delete_prop(nwam_enm_handle_t enmh
, const char *propname
)
255 assert(enmh
!= NULL
&& propname
!= NULL
);
257 if ((err
= nwam_enm_prop_read_only(propname
, &ro
)) != NWAM_SUCCESS
)
261 * If the activation-mode is not manual, allow the enabled
262 * property to be deleted.
264 if (strcmp(propname
, NWAM_ENM_PROP_ENABLED
) != 0)
265 return (NWAM_ENTITY_READ_ONLY
);
267 if ((err
= nwam_enm_is_manual(enmh
, &manual
)) != NWAM_SUCCESS
)
270 return (NWAM_ENTITY_READ_ONLY
);
274 * Duplicate data, remove property and validate. If validation
275 * fails, revert to data duplicated prior to remove.
277 if ((err
= nwam_dup_object_list(enmh
->nwh_data
, &olddata
))
280 if ((err
= nwam_delete_prop(enmh
->nwh_data
, propname
))
282 nwam_free_object_list(enmh
->nwh_data
);
283 enmh
->nwh_data
= olddata
;
286 if ((err
= nwam_enm_validate(enmh
, NULL
)) != NWAM_SUCCESS
) {
287 nwam_free_object_list(enmh
->nwh_data
);
288 enmh
->nwh_data
= olddata
;
291 nwam_free_object_list(olddata
);
293 return (NWAM_SUCCESS
);
297 nwam_enm_set_prop_value(nwam_enm_handle_t enmh
, const char *propname
,
303 assert(enmh
!= NULL
&& propname
!= NULL
&& value
!= NULL
);
305 if ((err
= nwam_enm_validate_prop(enmh
, propname
, value
))
307 (err
= nwam_enm_prop_read_only(propname
, &ro
)) != NWAM_SUCCESS
)
310 return (NWAM_ENTITY_READ_ONLY
);
312 return (nwam_set_prop_value(enmh
->nwh_data
, propname
, value
));
316 nwam_enm_get_prop_value(nwam_enm_handle_t enmh
, const char *propname
,
317 nwam_value_t
*valuep
)
319 return (nwam_get_prop_value(enmh
->nwh_data
, propname
, valuep
));
323 nwam_enm_walk_props(nwam_enm_handle_t enmh
,
324 int (*cb
)(const char *, nwam_value_t
, void *),
325 void *data
, uint64_t flags
, int *retp
)
327 return (nwam_walk_props(enmh
, cb
, data
, flags
, retp
));
331 nwam_enm_commit(nwam_enm_handle_t enmh
, uint64_t flags
)
335 assert(enmh
!= NULL
&& enmh
->nwh_data
!= NULL
);
337 if ((err
= nwam_enm_validate(enmh
, NULL
)) != NWAM_SUCCESS
)
340 return (nwam_commit(NWAM_ENM_CONF_FILE
, enmh
, flags
));
344 nwam_enm_destroy(nwam_enm_handle_t enmh
, uint64_t flags
)
346 return (nwam_destroy(NWAM_ENM_CONF_FILE
, enmh
, flags
));
350 nwam_enm_get_prop_description(const char *propname
, const char **descriptionp
)
352 return (nwam_get_prop_description(enm_prop_table
, propname
,
357 nwam_enm_prop_read_only(const char *propname
, boolean_t
*readp
)
359 return (nwam_prop_read_only(enm_prop_table
, propname
, readp
));
362 /* Property-specific value validation functions follow */
365 valid_enm_activation_mode(nwam_value_t value
)
367 uint64_t activation_mode
;
369 if (nwam_value_get_uint64(value
, &activation_mode
) != NWAM_SUCCESS
)
370 return (NWAM_ENTITY_INVALID_VALUE
);
372 switch (activation_mode
) {
373 case NWAM_ACTIVATION_MODE_MANUAL
:
374 case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
:
375 case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
:
376 return (NWAM_SUCCESS
);
378 return (NWAM_ENTITY_INVALID_VALUE
);
382 nwam_enm_validate(nwam_enm_handle_t enmh
, const char **errpropp
)
385 nwam_value_t activationval
, enabledval
, fmrival
= NULL
, startval
= NULL
;
386 nwam_value_t conditionval
= NULL
;
387 char **conditions
, *name
;
389 nwam_condition_object_type_t object_type
;
390 nwam_condition_t condition
;
392 assert(enmh
!= NULL
);
395 * Make sure enm is internally consistent: must have either
396 * an fmri or a start string; and if activation type is conditional,
397 * the condition string must be specified.
399 if ((nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_FMRI
, &fmrival
)
401 (nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_START
, &startval
)
403 if (fmrival
!= NULL
) {
404 if (errpropp
!= NULL
)
405 *errpropp
= NWAM_ENM_PROP_START
;
406 nwam_value_free(fmrival
);
408 if (errpropp
!= NULL
)
409 *errpropp
= NWAM_ENM_PROP_FMRI
;
411 return (NWAM_ENTITY_MISSING_MEMBER
);
414 nwam_value_free(fmrival
);
415 if (startval
!= NULL
)
416 nwam_value_free(startval
);
418 if (nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_ACTIVATION_MODE
,
419 &activationval
) != NWAM_SUCCESS
) {
420 if (errpropp
!= NULL
)
421 *errpropp
= NWAM_ENM_PROP_ACTIVATION_MODE
;
422 return (NWAM_ENTITY_MISSING_MEMBER
);
424 if (nwam_value_get_uint64(activationval
, &activation
)
426 if (errpropp
!= NULL
)
427 *errpropp
= NWAM_ENM_PROP_ACTIVATION_MODE
;
428 return (NWAM_ENTITY_INVALID_VALUE
);
430 nwam_value_free(activationval
);
432 if (activation
== NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
||
433 activation
== NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
) {
434 if (nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_CONDITIONS
,
435 &conditionval
) != NWAM_SUCCESS
) {
436 if (errpropp
!= NULL
)
437 *errpropp
= NWAM_ENM_PROP_CONDITIONS
;
438 return (NWAM_ENTITY_MISSING_MEMBER
);
441 * Are conditions self-referential? In other words, do any
442 * of the activation conditions refer to this ENM?
444 if (nwam_value_get_string_array(conditionval
, &conditions
,
445 &numvalues
) != NWAM_SUCCESS
) {
446 nwam_value_free(conditionval
);
447 if (errpropp
!= NULL
)
448 *errpropp
= NWAM_ENM_PROP_CONDITIONS
;
449 return (NWAM_ENTITY_INVALID_VALUE
);
451 if (nwam_enm_get_name(enmh
, &name
) != NWAM_SUCCESS
) {
452 nwam_value_free(conditionval
);
453 return (NWAM_INVALID_ARG
);
455 for (i
= 0; i
< numvalues
; i
++) {
456 char *object_name
= NULL
;
458 if (nwam_condition_string_to_condition(conditions
[i
],
459 &object_type
, &condition
, &object_name
)
461 if (errpropp
!= NULL
)
462 *errpropp
= NWAM_ENM_PROP_CONDITIONS
;
464 nwam_value_free(conditionval
);
465 return (NWAM_ENTITY_INVALID_VALUE
);
467 if (object_name
!= NULL
&&
468 object_type
== NWAM_CONDITION_OBJECT_TYPE_ENM
&&
469 strcmp(object_name
, name
) == 0) {
470 if (errpropp
!= NULL
)
471 *errpropp
= NWAM_ENM_PROP_CONDITIONS
;
474 nwam_value_free(conditionval
);
475 return (NWAM_ENTITY_INVALID_VALUE
);
480 nwam_value_free(conditionval
);
483 if (activation
== NWAM_ACTIVATION_MODE_MANUAL
) {
484 if (nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_ENABLED
,
485 &enabledval
) != NWAM_SUCCESS
) {
486 if (errpropp
!= NULL
)
487 *errpropp
= NWAM_ENM_PROP_ENABLED
;
488 return (NWAM_ENTITY_MISSING_MEMBER
);
490 nwam_value_free(enabledval
);
493 return (nwam_validate(enm_prop_table
, enmh
, errpropp
));
497 nwam_enm_validate_prop(nwam_enm_handle_t enmh
, const char *propname
,
500 assert(enmh
!= NULL
);
502 return (nwam_validate_prop(enm_prop_table
, enmh
, propname
, value
));
506 * Given a property, return expected property data type
509 nwam_enm_get_prop_type(const char *propname
, nwam_value_type_t
*typep
)
511 return (nwam_get_prop_type(enm_prop_table
, propname
, typep
));
515 nwam_enm_prop_multivalued(const char *propname
, boolean_t
*multip
)
517 return (nwam_prop_multivalued(enm_prop_table
, propname
, multip
));
521 * Determine if the ENM has manual activation-mode or not.
524 nwam_enm_is_manual(nwam_enm_handle_t enmh
, boolean_t
*manualp
)
530 assert(enmh
!= NULL
);
532 if ((err
= nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_ACTIVATION_MODE
,
533 &actval
)) != NWAM_SUCCESS
)
535 err
= nwam_value_get_uint64(actval
, &activation
);
536 nwam_value_free(actval
);
537 if (err
!= NWAM_SUCCESS
)
540 if (activation
== NWAM_ACTIVATION_MODE_MANUAL
)
544 return (NWAM_SUCCESS
);
547 /* Determine if ENM is enabled or not */
549 nwam_enm_is_enabled(nwam_enm_handle_t enmh
, boolean_t
*enabledp
)
552 nwam_value_t enabledval
;
554 assert(enmh
!= NULL
);
556 if ((err
= nwam_enm_get_prop_value(enmh
, NWAM_ENM_PROP_ENABLED
,
557 &enabledval
)) != NWAM_SUCCESS
)
559 err
= nwam_value_get_boolean(enabledval
, enabledp
);
560 nwam_value_free(enabledval
);
564 /* Update the enabled property */
566 nwam_enm_update_enabled(nwam_enm_handle_t enmh
, boolean_t enabled
)
569 nwam_value_t enabledval
;
571 if ((err
= nwam_value_create_boolean(enabled
, &enabledval
))
574 err
= nwam_set_prop_value(enmh
->nwh_data
, NWAM_ENM_PROP_ENABLED
,
576 nwam_value_free(enabledval
);
577 if (err
!= NWAM_SUCCESS
)
579 return (nwam_enm_commit(enmh
, NWAM_FLAG_ENTITY_ENABLE
));
583 nwam_enm_enable(nwam_enm_handle_t enmh
)
586 boolean_t manual
, enabled
;
588 assert(enmh
!= NULL
);
590 /* Only enms with manual activation-mode can be enabled */
591 if ((err
= nwam_enm_is_manual(enmh
, &manual
)) != NWAM_SUCCESS
)
594 return (NWAM_ENTITY_NOT_MANUAL
);
596 /* Make sure ENM is not enabled */
597 if ((err
= nwam_enm_is_enabled(enmh
, &enabled
)) != NWAM_SUCCESS
)
600 return (NWAM_SUCCESS
);
602 if ((err
= nwam_enm_update_enabled(enmh
, B_TRUE
)) != NWAM_SUCCESS
)
605 err
= nwam_enable(NULL
, enmh
);
607 /* nwamd may not be running, that's okay. */
608 if (err
== NWAM_ERROR_BIND
)
609 return (NWAM_SUCCESS
);
615 nwam_enm_disable(nwam_enm_handle_t enmh
)
618 boolean_t manual
, enabled
;
620 assert(enmh
!= NULL
);
622 /* Only enms with manual activation-mode can be disabled */
623 if ((err
= nwam_enm_is_manual(enmh
, &manual
)) != NWAM_SUCCESS
)
626 return (NWAM_ENTITY_NOT_MANUAL
);
628 /* Make sure ENM is enabled */
629 if ((err
= nwam_enm_is_enabled(enmh
, &enabled
)) != NWAM_SUCCESS
)
632 return (NWAM_SUCCESS
);
634 if ((err
= nwam_enm_update_enabled(enmh
, B_FALSE
)) != NWAM_SUCCESS
)
637 err
= nwam_disable(NULL
, enmh
);
639 /* nwamd may not be running, that's okay. */
640 if (err
== NWAM_ERROR_BIND
)
641 return (NWAM_SUCCESS
);
647 nwam_enm_get_default_proplist(const char ***prop_list
, uint_t
*numvaluesp
)
649 return (nwam_get_default_proplist(enm_prop_table
,
650 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
, prop_list
, numvaluesp
));
654 nwam_enm_get_state(nwam_enm_handle_t enmh
, nwam_state_t
*statep
,
655 nwam_aux_state_t
*auxp
)
657 return (nwam_get_state(NULL
, enmh
, statep
, auxp
));