2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <assert.h>
2N/A#include <ctype.h>
2N/A#include <libnetcfg.h>
2N/A#include "libnwam_impl.h"
2N/A#include <libnwam_priv.h>
2N/A#include <libnwam.h>
2N/A#include <libscf.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <strings.h>
2N/A#include <sys/param.h>
2N/A#include <sys/stat.h>
2N/A#include <sys/types.h>
2N/A#include <unistd.h>
2N/A
2N/A/*
2N/A * Functions to support creating, modifying, destroying, querying the
2N/A * state of and changing the state of ENM (External Network Modifier)
2N/A * objects. ENMs represent services or scripts that can be enabled
2N/A * either manually or conditionally for a combination of the set of
2N/A * available conditions (an IP address is present, a location is active etc).
2N/A */
2N/A
2N/Atypedef nwam_error_t (*nwam_enm_prop_validate_func_t)(nwam_value_t);
2N/A
2N/Astatic nwam_error_t valid_enm_activation_mode(nwam_value_t);
2N/A
2N/Astruct nwam_prop_table_entry enm_prop_table_entries[] = {
2N/A {NWAM_ENM_PROP_ACTIVATION_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
2N/A valid_enm_activation_mode,
2N/A "specifies the ENM activation mode - valid values are:\n"
2N/A "\'manual\', \'conditional-any\' and \'conditional-all\'",
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY},
2N/A {NWAM_ENM_PROP_CONDITIONS, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
2N/A NWAM_MAX_NUM_VALUES, nwam_valid_condition,
2N/A "specifies the activation condition. Conditions are of the form:\n"
2N/A "ncp|ncu|enm|loc name is|is-not active\n"
2N/A "ip-address is|is-not|is-in-range|is-not-in-range| 1.2.3.4[/24]\n"
2N/A "advertised-domain is|is-not|contains|does-not-contain string\n"
2N/A "system-domain is|is-not|contains|does-not-contain string\n"
2N/A "essid is|is-not|contains|does-not-contain string\n"
2N/A "bssid is|is-not string",
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY},
2N/A {NWAM_ENM_PROP_ENABLED, NWAM_VALUE_TYPE_BOOLEAN, B_TRUE, 0, 1,
2N/A nwam_valid_boolean,
2N/A "specifies if manual ENM is to be enabled",
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY},
2N/A {NWAM_ENM_PROP_FMRI, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
2N/A nwam_valid_fmri,
2N/A "specifies SMF FMRI of service to be enabled on ENM activation",
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY},
2N/A {NWAM_ENM_PROP_START, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
2N/A nwam_valid_file,
2N/A "specifies absolute path to start script to be run on ENM "
2N/A "activation",
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY},
2N/A {NWAM_ENM_PROP_STOP, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
2N/A nwam_valid_file,
2N/A "specifies absolute path to stop script to be run on ENM "
2N/A "deactivation",
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY}
2N/A};
2N/A
2N/A#define NWAM_NUM_ENM_PROPS (sizeof (enm_prop_table_entries) / \
2N/A sizeof (*enm_prop_table_entries))
2N/A
2N/Astruct nwam_prop_table enm_prop_table =
2N/A { NWAM_NUM_ENM_PROPS, enm_prop_table_entries };
2N/A
2N/Astatic uint64_t
2N/Anwam_enm_activation_to_flag(nwam_activation_mode_t activation)
2N/A{
2N/A switch (activation) {
2N/A case NWAM_ACTIVATION_MODE_MANUAL:
2N/A return (NWAM_FLAG_ACTIVATION_MODE_MANUAL);
2N/A case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY:
2N/A return (NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL_ANY);
2N/A case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL:
2N/A return (NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL_ALL);
2N/A default:
2N/A return (0);
2N/A }
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_read(const char *name, uint64_t flags, nwam_enm_handle_t *enmhp)
2N/A{
2N/A return (nwam_read(NWAM_OBJECT_TYPE_ENM, NWAM_ENM_CONF_FILE, name,
2N/A flags, enmhp));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_create(const char *name, const char *fmri, nwam_enm_handle_t *enmhp)
2N/A{
2N/A nwam_error_t err;
2N/A nwam_value_t actval = NULL, falseval = NULL, fmrival = NULL;
2N/A
2N/A assert(enmhp != NULL && name != NULL);
2N/A
2N/A if ((err = nwam_create(NWAM_OBJECT_TYPE_ENM, NWAM_ENM_CONF_FILE, name,
2N/A enmhp)) != NWAM_SUCCESS)
2N/A return (err);
2N/A
2N/A /*
2N/A * The initial activation mode is set, and the FMRI property is set,
2N/A * if specified.
2N/A */
2N/A if ((err = nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL,
2N/A &actval)) != NWAM_SUCCESS ||
2N/A ((fmri != NULL) &&
2N/A (err = nwam_value_create_string((char *)fmri, &fmrival))
2N/A != NWAM_SUCCESS) ||
2N/A (err = nwam_value_create_boolean(B_FALSE, &falseval))
2N/A != NWAM_SUCCESS) {
2N/A goto finish;
2N/A }
2N/A if ((err = nwam_set_prop_value((*enmhp)->nwh_data,
2N/A NWAM_ENM_PROP_ACTIVATION_MODE, actval)) == NWAM_SUCCESS &&
2N/A (err = nwam_set_prop_value((*enmhp)->nwh_data,
2N/A NWAM_ENM_PROP_ENABLED, falseval)) == NWAM_SUCCESS) {
2N/A if (fmri != NULL) {
2N/A err = nwam_set_prop_value((*enmhp)->nwh_data,
2N/A NWAM_ENM_PROP_FMRI, fmrival);
2N/A }
2N/A }
2N/A
2N/Afinish:
2N/A nwam_value_free(actval);
2N/A nwam_value_free(falseval);
2N/A if (fmrival != NULL)
2N/A nwam_value_free(fmrival);
2N/A
2N/A if (err != NWAM_SUCCESS) {
2N/A nwam_enm_free(*enmhp);
2N/A *enmhp = NULL;
2N/A }
2N/A
2N/A return (err);
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_add_data(nwam_enm_handle_t enmh, nvlist_t *data)
2N/A{
2N/A int err = 0;
2N/A
2N/A assert(enmh != NULL);
2N/A
2N/A if (enmh->nwh_data != NULL)
2N/A err = nvlist_merge(enmh->nwh_data, data, 0);
2N/A else
2N/A enmh->nwh_data = data;
2N/A
2N/A return (nwam_errno_to_nwam_error(err));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_get_name(nwam_enm_handle_t enmh, char **namep)
2N/A{
2N/A return (nwam_get_name(enmh, namep));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_set_name(nwam_enm_handle_t enmh, const char *name)
2N/A{
2N/A return (nwam_set_name(enmh, name));
2N/A}
2N/A
2N/Aboolean_t
2N/Anwam_enm_can_set_name(nwam_enm_handle_t enmh)
2N/A{
2N/A assert(enmh != NULL);
2N/A
2N/A return (!enmh->nwh_committed);
2N/A}
2N/A
2N/A/* ARGSUSED3 */
2N/Astatic int
2N/Aenm_selectcb(nvlist_t *idp, nvlist_t *objp, uint64_t flags, void **cbobj)
2N/A{
2N/A nwam_enm_handle_t enmh;
2N/A uint64_t activation, actflag, walkfilter;
2N/A nwam_value_t actval;
2N/A nwam_error_t err;
2N/A
2N/A if ((err = nwam_lists_to_handle(idp, objp, NWAM_OBJECT_TYPE_ENM, &enmh))
2N/A != NWAM_SUCCESS)
2N/A return (err);
2N/A
2N/A /*
2N/A * Get a bitmapped flag value corresponding to this enm's
2N/A * activation value - if the activation value is not recognized,
2N/A * actflag will be set to 0, and will thus fail to match
2N/A * any bit flag passed in by the caller.
2N/A */
2N/A if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ACTIVATION_MODE,
2N/A &actval) != NWAM_SUCCESS) {
2N/A nwam_free(enmh, B_FALSE);
2N/A return (NWAM_INVALID_ARG);
2N/A }
2N/A if (nwam_value_get_uint64(actval, &activation) != NWAM_SUCCESS) {
2N/A nwam_value_free(actval);
2N/A nwam_free(enmh, B_FALSE);
2N/A return (NWAM_INVALID_ARG);
2N/A }
2N/A
2N/A actflag = nwam_enm_activation_to_flag(activation);
2N/A nwam_value_free(actval);
2N/A if ((walkfilter = flags & NWAM_WALK_FILTER_MASK) == 0)
2N/A walkfilter = NWAM_FLAG_ACTIVATION_MODE_ALL;
2N/A if (actflag & walkfilter) {
2N/A *cbobj = enmh;
2N/A return (NWAM_SUCCESS);
2N/A }
2N/A nwam_free(enmh, B_FALSE);
2N/A return (NWAM_INVALID_ARG);
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_walk_enms(int(*cb)(nwam_enm_handle_t, void *), void *data, uint64_t flags,
2N/A int *retp)
2N/A{
2N/A netcfg_walkcb_t *nccb = (netcfg_walkcb_t *)cb;
2N/A
2N/A nwam_error_t err = nwam_valid_flags(flags,
2N/A NWAM_FLAG_ACTIVATION_MODE_ALL);
2N/A
2N/A if (err != NWAM_SUCCESS)
2N/A return (err);
2N/A
2N/A return (nwam_walk(NWAM_ENM_CONF_FILE, nccb, data, flags, retp,
2N/A enm_selectcb));
2N/A}
2N/A
2N/Avoid
2N/Anwam_enm_free(nwam_enm_handle_t enmh)
2N/A{
2N/A nwam_free(enmh, B_TRUE);
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_copy(nwam_enm_handle_t oldenmh, const char *newname,
2N/A nwam_enm_handle_t *newenmhp)
2N/A{
2N/A return (nwam_copy(NWAM_ENM_CONF_FILE, oldenmh, newname, newenmhp));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_delete_prop(nwam_enm_handle_t enmh, const char *propname,
2N/A uint64_t flags)
2N/A{
2N/A nwam_error_t err;
2N/A boolean_t ro;
2N/A void *olddata;
2N/A boolean_t manual;
2N/A
2N/A assert(enmh != NULL && propname != NULL);
2N/A
2N/A if ((err = nwam_enm_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (ro && !nwam_override_readonly(flags)) {
2N/A /*
2N/A * If the activation-mode is not manual, allow the enabled
2N/A * property to be deleted.
2N/A */
2N/A if (strcmp(propname, NWAM_ENM_PROP_ENABLED) != 0)
2N/A return (NWAM_ENTITY_READ_ONLY);
2N/A
2N/A if ((err = nwam_enm_is_manual(enmh, &manual)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (manual)
2N/A return (NWAM_ENTITY_READ_ONLY);
2N/A }
2N/A
2N/A /*
2N/A * Duplicate data, remove property and validate. If validation
2N/A * fails, revert to data duplicated prior to remove.
2N/A */
2N/A if ((err = nwam_dup_object_list(enmh->nwh_data, &olddata))
2N/A != NWAM_SUCCESS)
2N/A return (err);
2N/A if ((err = nwam_delete_prop(enmh->nwh_data, propname))
2N/A != NWAM_SUCCESS) {
2N/A nwam_free_object_list(enmh->nwh_data);
2N/A enmh->nwh_data = olddata;
2N/A return (err);
2N/A }
2N/A if ((err = nwam_enm_validate(enmh, NULL)) != NWAM_SUCCESS) {
2N/A nwam_free_object_list(enmh->nwh_data);
2N/A enmh->nwh_data = olddata;
2N/A return (err);
2N/A }
2N/A nwam_free_object_list(olddata);
2N/A
2N/A return (NWAM_SUCCESS);
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_set_prop_value(nwam_enm_handle_t enmh, const char *propname,
2N/A nwam_value_t value, uint64_t flags)
2N/A{
2N/A nwam_error_t err;
2N/A boolean_t ro;
2N/A
2N/A assert(enmh != NULL && propname != NULL && value != NULL);
2N/A
2N/A if ((err = nwam_enm_validate_prop(enmh, propname, value))
2N/A != NWAM_SUCCESS ||
2N/A (err = nwam_enm_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (ro && !nwam_override_readonly(flags))
2N/A return (NWAM_ENTITY_READ_ONLY);
2N/A
2N/A return (nwam_set_prop_value(enmh->nwh_data, propname, value));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_get_prop_value(nwam_enm_handle_t enmh, const char *propname,
2N/A nwam_value_t *valuep)
2N/A{
2N/A assert(enmh != NULL);
2N/A
2N/A return (nwam_get_prop_value(enmh->nwh_data, propname, valuep));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_walk_props(nwam_enm_handle_t enmh,
2N/A int (*cb)(const char *, nwam_value_t, void *),
2N/A void *data, uint64_t flags, int *retp)
2N/A{
2N/A return (nwam_walk_props(enmh, cb, data, flags, retp));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_commit(nwam_enm_handle_t enmh, uint64_t flags)
2N/A{
2N/A nwam_error_t err;
2N/A
2N/A assert(enmh != NULL && enmh->nwh_data != NULL);
2N/A
2N/A if ((err = nwam_enm_validate(enmh, NULL)) != NWAM_SUCCESS)
2N/A return (err);
2N/A
2N/A return (nwam_commit(NWAM_ENM_CONF_FILE, enmh, flags));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_destroy(nwam_enm_handle_t enmh, uint64_t flags)
2N/A{
2N/A return (nwam_destroy(NWAM_ENM_CONF_FILE, enmh, flags));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_get_prop_description(const char *propname, const char **descriptionp)
2N/A{
2N/A return (nwam_get_prop_description(enm_prop_table, propname,
2N/A descriptionp));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_prop_read_only(const char *propname, boolean_t *readp)
2N/A{
2N/A return (nwam_prop_read_only(enm_prop_table, propname, readp));
2N/A}
2N/A
2N/A/* Property-specific value validation functions follow */
2N/A
2N/Astatic nwam_error_t
2N/Avalid_enm_activation_mode(nwam_value_t value)
2N/A{
2N/A uint64_t activation_mode;
2N/A
2N/A if (nwam_value_get_uint64(value, &activation_mode) != NWAM_SUCCESS)
2N/A return (NWAM_ENTITY_INVALID_VALUE);
2N/A
2N/A switch (activation_mode) {
2N/A case NWAM_ACTIVATION_MODE_MANUAL:
2N/A case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY:
2N/A case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL:
2N/A return (NWAM_SUCCESS);
2N/A }
2N/A return (NWAM_ENTITY_INVALID_VALUE);
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_validate(nwam_enm_handle_t enmh, const char **errpropp)
2N/A{
2N/A uint64_t activation;
2N/A nwam_value_t activationval, enabledval, fmrival = NULL, startval = NULL;
2N/A nwam_value_t conditionval = NULL;
2N/A char **conditions, *name;
2N/A uint_t i, numvalues;
2N/A nwam_condition_object_type_t object_type;
2N/A nwam_condition_t condition;
2N/A
2N/A assert(enmh != NULL);
2N/A
2N/A /*
2N/A * Make sure enm is internally consistent: must have either
2N/A * an fmri or a start string; and if activation type is conditional,
2N/A * the condition string must be specified.
2N/A */
2N/A if ((nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_FMRI, &fmrival)
2N/A != NWAM_SUCCESS) &&
2N/A (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_START, &startval)
2N/A != NWAM_SUCCESS)) {
2N/A if (fmrival != NULL) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_START;
2N/A nwam_value_free(fmrival);
2N/A } else {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_FMRI;
2N/A }
2N/A return (NWAM_ENTITY_MISSING_MEMBER);
2N/A }
2N/A if (fmrival != NULL)
2N/A nwam_value_free(fmrival);
2N/A if (startval != NULL)
2N/A nwam_value_free(startval);
2N/A
2N/A if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ACTIVATION_MODE,
2N/A &activationval) != NWAM_SUCCESS) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_ACTIVATION_MODE;
2N/A return (NWAM_ENTITY_MISSING_MEMBER);
2N/A }
2N/A if (nwam_value_get_uint64(activationval, &activation)
2N/A != NWAM_SUCCESS) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_ACTIVATION_MODE;
2N/A return (NWAM_ENTITY_INVALID_VALUE);
2N/A }
2N/A nwam_value_free(activationval);
2N/A
2N/A if (activation == NWAM_ACTIVATION_MODE_CONDITIONAL_ANY ||
2N/A activation == NWAM_ACTIVATION_MODE_CONDITIONAL_ALL) {
2N/A if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_CONDITIONS,
2N/A &conditionval) != NWAM_SUCCESS) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_CONDITIONS;
2N/A return (NWAM_ENTITY_MISSING_MEMBER);
2N/A }
2N/A /*
2N/A * Are conditions self-referential? In other words, do any
2N/A * of the activation conditions refer to this ENM?
2N/A */
2N/A if (nwam_value_get_string_array(conditionval, &conditions,
2N/A &numvalues) != NWAM_SUCCESS) {
2N/A nwam_value_free(conditionval);
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_CONDITIONS;
2N/A return (NWAM_ENTITY_INVALID_VALUE);
2N/A }
2N/A if (nwam_enm_get_name(enmh, &name) != NWAM_SUCCESS) {
2N/A nwam_value_free(conditionval);
2N/A return (NWAM_INVALID_ARG);
2N/A }
2N/A for (i = 0; i < numvalues; i++) {
2N/A char *object_name = NULL;
2N/A
2N/A if (nwam_condition_string_to_condition(conditions[i],
2N/A &object_type, &condition, &object_name)
2N/A != NWAM_SUCCESS) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_CONDITIONS;
2N/A free(name);
2N/A nwam_value_free(conditionval);
2N/A return (NWAM_ENTITY_INVALID_VALUE);
2N/A }
2N/A if (object_name != NULL &&
2N/A object_type == NWAM_CONDITION_OBJECT_TYPE_ENM &&
2N/A strcmp(object_name, name) == 0) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_CONDITIONS;
2N/A free(name);
2N/A free(object_name);
2N/A nwam_value_free(conditionval);
2N/A return (NWAM_ENTITY_INVALID_VALUE);
2N/A }
2N/A free(object_name);
2N/A }
2N/A free(name);
2N/A nwam_value_free(conditionval);
2N/A }
2N/A
2N/A if (activation == NWAM_ACTIVATION_MODE_MANUAL) {
2N/A if (nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ENABLED,
2N/A &enabledval) != NWAM_SUCCESS) {
2N/A if (errpropp != NULL)
2N/A *errpropp = NWAM_ENM_PROP_ENABLED;
2N/A return (NWAM_ENTITY_MISSING_MEMBER);
2N/A }
2N/A nwam_value_free(enabledval);
2N/A }
2N/A
2N/A return (nwam_validate(enm_prop_table, enmh, errpropp));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_validate_prop(nwam_enm_handle_t enmh, const char *propname,
2N/A nwam_value_t value)
2N/A{
2N/A return (nwam_validate_prop(enm_prop_table, enmh, propname, value));
2N/A}
2N/A
2N/A/*
2N/A * Given a property, return expected property data type
2N/A */
2N/Anwam_error_t
2N/Anwam_enm_get_prop_type(const char *propname, nwam_value_type_t *typep)
2N/A{
2N/A return (nwam_get_prop_type(enm_prop_table, propname, typep));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_prop_multivalued(const char *propname, boolean_t *multip)
2N/A{
2N/A return (nwam_prop_multivalued(enm_prop_table, propname, multip));
2N/A}
2N/A
2N/A/*
2N/A * Determine if the ENM has manual activation-mode or not.
2N/A */
2N/Anwam_error_t
2N/Anwam_enm_is_manual(nwam_enm_handle_t enmh, boolean_t *manualp)
2N/A{
2N/A nwam_error_t err;
2N/A nwam_value_t actval;
2N/A uint64_t activation;
2N/A
2N/A assert(enmh != NULL);
2N/A
2N/A if ((err = nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ACTIVATION_MODE,
2N/A &actval)) != NWAM_SUCCESS)
2N/A return (err);
2N/A err = nwam_value_get_uint64(actval, &activation);
2N/A nwam_value_free(actval);
2N/A if (err != NWAM_SUCCESS)
2N/A return (err);
2N/A
2N/A if (activation == NWAM_ACTIVATION_MODE_MANUAL)
2N/A *manualp = B_TRUE;
2N/A else
2N/A *manualp = B_FALSE;
2N/A return (NWAM_SUCCESS);
2N/A}
2N/A
2N/A/* Determine if ENM is enabled or not */
2N/Astatic nwam_error_t
2N/Anwam_enm_is_enabled(nwam_enm_handle_t enmh, boolean_t *enabledp)
2N/A{
2N/A nwam_error_t err;
2N/A nwam_value_t enabledval;
2N/A
2N/A assert(enmh != NULL);
2N/A
2N/A if ((err = nwam_enm_get_prop_value(enmh, NWAM_ENM_PROP_ENABLED,
2N/A &enabledval)) != NWAM_SUCCESS)
2N/A return (err);
2N/A err = nwam_value_get_boolean(enabledval, enabledp);
2N/A nwam_value_free(enabledval);
2N/A return (err);
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_enable(nwam_enm_handle_t enmh)
2N/A{
2N/A nwam_error_t err;
2N/A boolean_t manual, enabled;
2N/A
2N/A assert(enmh != NULL);
2N/A
2N/A /* Only enms with manual activation-mode can be enabled */
2N/A if ((err = nwam_enm_is_manual(enmh, &manual)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (!manual)
2N/A return (NWAM_ENTITY_NOT_MANUAL);
2N/A
2N/A /* Make sure ENM is not enabled */
2N/A if ((err = nwam_enm_is_enabled(enmh, &enabled)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (enabled)
2N/A return (NWAM_ENTITY_ENABLED);
2N/A
2N/A return (nwam_enable(NULL, enmh));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_disable(nwam_enm_handle_t enmh)
2N/A{
2N/A nwam_error_t err;
2N/A boolean_t manual, enabled;
2N/A
2N/A assert(enmh != NULL);
2N/A
2N/A /* Only enms with manual activation-mode can be disabled */
2N/A if ((err = nwam_enm_is_manual(enmh, &manual)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (!manual)
2N/A return (NWAM_ENTITY_NOT_MANUAL);
2N/A
2N/A /* Make sure ENM is enabled */
2N/A if ((err = nwam_enm_is_enabled(enmh, &enabled)) != NWAM_SUCCESS)
2N/A return (err);
2N/A if (!enabled)
2N/A return (NWAM_ENTITY_DISABLED);
2N/A
2N/A return (nwam_disable(NULL, enmh));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_get_default_proplist(const char ***prop_list, uint_t *numvaluesp)
2N/A{
2N/A return (nwam_get_default_proplist(enm_prop_table,
2N/A NWAM_TYPE_ANY, NWAM_CLASS_ANY, prop_list, numvaluesp));
2N/A}
2N/A
2N/Anwam_error_t
2N/Anwam_enm_get_state(nwam_enm_handle_t enmh, nwam_state_t *statep,
2N/A nwam_aux_state_t *auxp)
2N/A{
2N/A return (nwam_get_state(NULL, enmh, statep, auxp));
2N/A}