8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libnwam / common / libnwam_enm.c
blob8967496e63adee448784316956b49dfba6e8d06c
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <assert.h>
28 #include <ctype.h>
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <strings.h>
35 #include <unistd.h>
36 #include <libscf.h>
37 #include "libnwam_impl.h"
38 #include <libnwam_priv.h>
39 #include <libnwam.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,
70 nwam_valid_boolean,
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,
74 nwam_valid_fmri,
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,
78 nwam_valid_file,
79 "specifies absolute path to start script to be run on ENM "
80 "activation",
81 NWAM_TYPE_ANY, NWAM_CLASS_ANY},
82 {NWAM_ENM_PROP_STOP, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
83 nwam_valid_file,
84 "specifies absolute path to stop script to be run on ENM "
85 "deactivation",
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 };
95 static uint64_t
96 nwam_enm_activation_to_flag(nwam_activation_mode_t activation)
98 switch (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);
105 default:
106 return (0);
110 nwam_error_t
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,
114 flags, enmhp));
117 nwam_error_t
118 nwam_enm_create(const char *name, const char *fmri, nwam_enm_handle_t *enmhp)
120 nwam_error_t err;
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)
127 return (err);
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)))
134 != NWAM_SUCCESS)
135 goto finish;
137 if ((err = nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL,
138 &actval)) != NWAM_SUCCESS ||
139 ((fmri != NULL) &&
140 (err = nwam_value_create_string((char *)fmri, &fmrival))
141 != NWAM_SUCCESS) ||
142 (err = nwam_value_create_boolean(B_FALSE, &falseval))
143 != NWAM_SUCCESS) {
144 goto finish;
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) {
150 if (fmri != NULL) {
151 err = nwam_set_prop_value((*enmhp)->nwh_data,
152 NWAM_ENM_PROP_FMRI, fmrival);
156 finish:
157 nwam_value_free(actval);
158 nwam_value_free(falseval);
159 if (fmrival != NULL)
160 nwam_value_free(fmrival);
162 if (err != NWAM_SUCCESS) {
163 nwam_enm_free(*enmhp);
164 *enmhp = NULL;
167 return (err);
170 nwam_error_t
171 nwam_enm_get_name(nwam_enm_handle_t enmh, char **namep)
173 return (nwam_get_name(enmh, namep));
176 nwam_error_t
177 nwam_enm_set_name(nwam_enm_handle_t enmh, const char *name)
179 return (nwam_set_name(enmh, name));
182 boolean_t
183 nwam_enm_can_set_name(nwam_enm_handle_t enmh)
185 return (!enmh->nwh_committed);
188 /* ARGSUSED2 */
189 static int
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;
194 nwam_value_t actval;
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);
220 nwam_error_t
221 nwam_walk_enms(int(*cb)(nwam_enm_handle_t, void *), void *data, uint64_t flags,
222 int *retp)
224 nwam_error_t err = nwam_valid_flags(flags,
225 NWAM_FLAG_ACTIVATION_MODE_ALL | NWAM_FLAG_BLOCKING);
227 if (err != NWAM_SUCCESS)
228 return (err);
230 return (nwam_walk(NWAM_OBJECT_TYPE_ENM, NWAM_ENM_CONF_FILE,
231 cb, data, flags, retp, enm_selectcb));
234 void
235 nwam_enm_free(nwam_enm_handle_t enmh)
237 nwam_free(enmh);
240 nwam_error_t
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));
247 nwam_error_t
248 nwam_enm_delete_prop(nwam_enm_handle_t enmh, const char *propname)
250 nwam_error_t err;
251 boolean_t ro;
252 void *olddata;
253 boolean_t manual;
255 assert(enmh != NULL && propname != NULL);
257 if ((err = nwam_enm_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
258 return (err);
259 if (ro) {
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)
268 return (err);
269 if (manual)
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))
278 != NWAM_SUCCESS)
279 return (err);
280 if ((err = nwam_delete_prop(enmh->nwh_data, propname))
281 != NWAM_SUCCESS) {
282 nwam_free_object_list(enmh->nwh_data);
283 enmh->nwh_data = olddata;
284 return (err);
286 if ((err = nwam_enm_validate(enmh, NULL)) != NWAM_SUCCESS) {
287 nwam_free_object_list(enmh->nwh_data);
288 enmh->nwh_data = olddata;
289 return (err);
291 nwam_free_object_list(olddata);
293 return (NWAM_SUCCESS);
296 nwam_error_t
297 nwam_enm_set_prop_value(nwam_enm_handle_t enmh, const char *propname,
298 nwam_value_t value)
300 nwam_error_t err;
301 boolean_t ro;
303 assert(enmh != NULL && propname != NULL && value != NULL);
305 if ((err = nwam_enm_validate_prop(enmh, propname, value))
306 != NWAM_SUCCESS ||
307 (err = nwam_enm_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
308 return (err);
309 if (ro)
310 return (NWAM_ENTITY_READ_ONLY);
312 return (nwam_set_prop_value(enmh->nwh_data, propname, value));
315 nwam_error_t
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));
322 nwam_error_t
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));
330 nwam_error_t
331 nwam_enm_commit(nwam_enm_handle_t enmh, uint64_t flags)
333 nwam_error_t err;
335 assert(enmh != NULL && enmh->nwh_data != NULL);
337 if ((err = nwam_enm_validate(enmh, NULL)) != NWAM_SUCCESS)
338 return (err);
340 return (nwam_commit(NWAM_ENM_CONF_FILE, enmh, flags));
343 nwam_error_t
344 nwam_enm_destroy(nwam_enm_handle_t enmh, uint64_t flags)
346 return (nwam_destroy(NWAM_ENM_CONF_FILE, enmh, flags));
349 nwam_error_t
350 nwam_enm_get_prop_description(const char *propname, const char **descriptionp)
352 return (nwam_get_prop_description(enm_prop_table, propname,
353 descriptionp));
356 nwam_error_t
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 */
364 static nwam_error_t
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);
381 nwam_error_t
382 nwam_enm_validate(nwam_enm_handle_t enmh, const char **errpropp)
384 uint64_t activation;
385 nwam_value_t activationval, enabledval, fmrival = NULL, startval = NULL;
386 nwam_value_t conditionval = NULL;
387 char **conditions, *name;
388 uint_t i, numvalues;
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)
400 != NWAM_SUCCESS) &&
401 (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_START, &startval)
402 != NWAM_SUCCESS)) {
403 if (fmrival != NULL) {
404 if (errpropp != NULL)
405 *errpropp = NWAM_ENM_PROP_START;
406 nwam_value_free(fmrival);
407 } else {
408 if (errpropp != NULL)
409 *errpropp = NWAM_ENM_PROP_FMRI;
411 return (NWAM_ENTITY_MISSING_MEMBER);
413 if (fmrival != NULL)
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)
425 != NWAM_SUCCESS) {
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)
460 != NWAM_SUCCESS) {
461 if (errpropp != NULL)
462 *errpropp = NWAM_ENM_PROP_CONDITIONS;
463 free(name);
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;
472 free(name);
473 free(object_name);
474 nwam_value_free(conditionval);
475 return (NWAM_ENTITY_INVALID_VALUE);
477 free(object_name);
479 free(name);
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));
496 nwam_error_t
497 nwam_enm_validate_prop(nwam_enm_handle_t enmh, const char *propname,
498 nwam_value_t value)
500 assert(enmh != NULL);
502 return (nwam_validate_prop(enm_prop_table, enmh, propname, value));
506 * Given a property, return expected property data type
508 nwam_error_t
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));
514 nwam_error_t
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.
523 nwam_error_t
524 nwam_enm_is_manual(nwam_enm_handle_t enmh, boolean_t *manualp)
526 nwam_error_t err;
527 nwam_value_t actval;
528 uint64_t activation;
530 assert(enmh != NULL);
532 if ((err = nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ACTIVATION_MODE,
533 &actval)) != NWAM_SUCCESS)
534 return (err);
535 err = nwam_value_get_uint64(actval, &activation);
536 nwam_value_free(actval);
537 if (err != NWAM_SUCCESS)
538 return (err);
540 if (activation == NWAM_ACTIVATION_MODE_MANUAL)
541 *manualp = B_TRUE;
542 else
543 *manualp = B_FALSE;
544 return (NWAM_SUCCESS);
547 /* Determine if ENM is enabled or not */
548 static nwam_error_t
549 nwam_enm_is_enabled(nwam_enm_handle_t enmh, boolean_t *enabledp)
551 nwam_error_t err;
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)
558 return (err);
559 err = nwam_value_get_boolean(enabledval, enabledp);
560 nwam_value_free(enabledval);
561 return (err);
564 /* Update the enabled property */
565 static nwam_error_t
566 nwam_enm_update_enabled(nwam_enm_handle_t enmh, boolean_t enabled)
568 nwam_error_t err;
569 nwam_value_t enabledval;
571 if ((err = nwam_value_create_boolean(enabled, &enabledval))
572 != NWAM_SUCCESS)
573 return (err);
574 err = nwam_set_prop_value(enmh->nwh_data, NWAM_ENM_PROP_ENABLED,
575 enabledval);
576 nwam_value_free(enabledval);
577 if (err != NWAM_SUCCESS)
578 return (err);
579 return (nwam_enm_commit(enmh, NWAM_FLAG_ENTITY_ENABLE));
582 nwam_error_t
583 nwam_enm_enable(nwam_enm_handle_t enmh)
585 nwam_error_t err;
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)
592 return (err);
593 if (!manual)
594 return (NWAM_ENTITY_NOT_MANUAL);
596 /* Make sure ENM is not enabled */
597 if ((err = nwam_enm_is_enabled(enmh, &enabled)) != NWAM_SUCCESS)
598 return (err);
599 if (enabled)
600 return (NWAM_SUCCESS);
602 if ((err = nwam_enm_update_enabled(enmh, B_TRUE)) != NWAM_SUCCESS)
603 return (err);
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);
610 else
611 return (err);
614 nwam_error_t
615 nwam_enm_disable(nwam_enm_handle_t enmh)
617 nwam_error_t err;
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)
624 return (err);
625 if (!manual)
626 return (NWAM_ENTITY_NOT_MANUAL);
628 /* Make sure ENM is enabled */
629 if ((err = nwam_enm_is_enabled(enmh, &enabled)) != NWAM_SUCCESS)
630 return (err);
631 if (!enabled)
632 return (NWAM_SUCCESS);
634 if ((err = nwam_enm_update_enabled(enmh, B_FALSE)) != NWAM_SUCCESS)
635 return (err);
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);
642 else
643 return (err);
646 nwam_error_t
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));
653 nwam_error_t
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));