Version 2.12, 2009-Mar-17
It is the job of libnwam to store, retrieve and operate on configuration preferences for network (auto)configuration. It is important to stress that it is not libnwam's job to actually apply changes to the system, just to store and retrieve them, and facilitate communication with the NWAM daemon (nwamd). To actually effect changes to datalinks and IP interfaces, or to query their current state (as opposed to their configuration preferences), libdladm and libinetcfg will be used.
Global flags used for functions that access persistent storage:
NWAM_ENTITY_IN_USE)
if the object being written is already locked.NWAM_ENTITY_EXISTS) if the
object being written already exists.#define NWAM_FLAG_BLOCKING 0x00000001 #define NWAM_FLAG_CREATE 0x00000002 #define NWAM_FLAG_DO_NOT_FREE 0x00000004
Most libnwam functions return an nwam_error_t; the type is defined
as follows.
typedef enum {
NWAM_SUCCESS, /* No error occurred */
NWAM_LIST_END, /* End of list reached */
NWAM_INVALID_HANDLE, /* Entity handle is invalid */
NWAM_HANDLE_UNBOUND, /* Handle not bound to entity */
NWAM_INVALID_ARG, /* Argument is invalid */
NWAM_PERMISSION_DENIED, /* Insufficient privileges for action */
NWAM_NO_MEMORY, /* Out of memory */
NWAM_ENTITY_EXISTS, /* Entity already exists */
NWAM_ENTITY_IN_USE, /* Entity in use */
NWAM_ENTITY_COMMITTED, /* Entity already committed */
NWAM_ENTITY_NOT_FOUND, /* Entity not found */
NWAM_ENTITY_TYPE_MISMATCH, /* Entity type mismatch */
NWAM_ENTITY_INVALID, /* Validation of entity failed */
NWAM_ENTITY_INVALID_MEMBER, /* Entity member invalid */
NWAM_ENTITY_INVALID_STATE, /* Entity is not in appropriate state */
NWAM_ENTITY_INVALID_VALUE, /* Validation of entity value failed */
NWAM_ENTITY_MISSING_MEMBER, /* Required member is missing */
NWAM_ENTITY_NO_VALUE, /* No value associated with entity */
NWAM_ENTITY_MULTIPLE_VALUES, /* Multiple values for entity */
NWAM_ENTITY_READ_ONLY, /* Entity is marked read only */
NWAM_ENTITY_NOT_MANUAL, /* Entity cannot be manually enabled */
NWAM_WALK_HALTED, /* Callback function returned nonzero */
NWAM_ERROR_BIND, /* Could not bind to backend */
NWAM_ERROR_BACKEND_INIT, /* Could not initialized backend */
NWAM_ERROR_INTERNAL /* Internal error */
} nwam_error_t;
/* convert an error code to a localized string */
const char *nwam_strerror(nwam_error_t);
The NWAM library operates on NWAM Profile objects identified by handles. A common opaque type is defined for object handles.
struct nwam_handle;
A common attribute of NWAM Profile objects is the current state, which may be obtained via this API. Common values are defined for use with object-specific functions.
typedef enum {
NWAM_STATE_UNINITIALIZED = 0.0,
NWAM_STATE_OFFLINE = 0x1,
NWAM_STATE_ONLINE = 0x2,
NWAM_STATE_MAINTENANCE = 0x4,
NWAM_STATE_DEGRADED = 0x8,
NWAM_STATE_DISABLED = 0x10
} nwam_state_t;
#define NWAM_STATE_ANY (NWAM_STATE_UNINITIALIZED | \
NWAM_STATE_OFFLINE | \
NWAM_STATE_ONLINE | \
NWAM_STATE_MAINTENANCE | \
NWAM_STATE_DEGRADED | \
NWAM_STATE_DISABLED)
#define NWAM_STATE_UNINITIALIZED_STRING "uninitialized"
#define NWAM_STATE_OFFLINE_STRING "offline"
#define NWAM_STATE_ONLINE_STRING "online"
#define NWAM_STATE_MAINTENANCE_STRING "maintenance"
#define NWAM_STATE_DEGRADED_STRING "degraded"
#define NWAM_STATE_DISABLED_STRING "disabled"
NWAM property values are stored in nwam_value_t structures. The
following data structures and functions are used to manage these objects.
/* property value types */
typedef enum {
NWAM_VALUE_TYPE_BOOLEAN,
NWAM_VALUE_TYPE_INT64,
NWAM_VALUE_TYPE_UINT64,
NWAM_VALUE_TYPE_STRING,
NWAM_VALUE_TYPE_UNKNOWN
} nwam_value_type_t;
/* generic property value holder */
struct nwam_value;
typedef struct nwam_value *nwam_value_t;
/* functions that manipulate property values */
nwam_error_t nwam_value_create_boolean(boolean_t, nwam_value_t *);
nwam_error_t nwam_value_create_boolean_array(boolean_t *, uint_t, nwam_value_t *);
nwam_error_t nwam_value_create_int64(int64_t, nwam_value_t *);
nwam_error_t nwam_value_create_int64_array(int64_t *, uint_t, nwam_value_t *);
nwam_error_t nwam_value_create_uint64(uint64_t, nwam_value_t *);
nwam_error_t nwam_value_create_uint64_array(uint64_t *, uint_t, nwam_value_t *);
nwam_error_t nwam_value_create_string(char *, nwam_value_t *);
nwam_error_t nwam_value_create_string_array(char **, uint_t, nwam_value_t *);
nwam_error_t nwam_value_get_type(nwam_value_t, nwam_value_type_t *);
nwam_error_t nwam_value_get_numvalues(nwam_value_t, uint_t *);
nwam_error_t nwam_value_get_boolean(nwam_value_t, boolean_t *);
nwam_error_t nwam_value_get_boolean_array(nwam_value_t, boolean_t **, uint_t *);
nwam_error_t nwam_value_get_int64(nwam_value_t, int64_t *);
nwam_error_t nwam_value_get_int64_array(nwam_value_t, int64_t **, uint_t *);
nwam_error_t nwam_value_get_uint64(nwam_value_t, uint64_t *);
nwam_error_t nwam_value_get_uint64_array(nwam_value_t, uint64_t **, uint_t *);
nwam_error_t nwam_value_get_string(nwam_value_t, char **);
nwam_error_t nwam_value_get_string_array(nwam_value_t, char ***, uint_t *);
nwam_error_t nwam_uint64_t_get_value_string(const char *, uint64_t, const char **);
nwam_error_t nwam_value_string_get_uint64(const char *, const char *, uint64_t *);
nwam_error_t nwam_value_copy(nwam_value_t, nwam_value_t *);
void nwam_value_free(nwam_value_t);
NCUs, Locations, and ENMs all have activation-mode properties; though the allowed values for each object type are different, this enumeration includes all possible values and is used by all three objects. The validation function for each object will verify that the value being used is one of the allowed values for that object.
typedef enum {
NWAM_ACTIVATION_MODE_MANUAL,
NWAM_ACTIVATION_MODE_SYSTEM,
NWAM_ACTIVATION_MODE_CONDITIONAL_ANY,
NWAM_ACTIVATION_MODE_CONDITIONAL_ALL,
NWAM_ACTIVATION_MODE_PRIORITIZED,
} nwam_activation_mode_t;
#define NWAM_ACTIVATION_MODE_MANUAL_STRING "manual"
#define NWAM_ACTIVATION_MODE_SYSTEM_STRING "system"
#define NWAM_ACTIVATION_MODE_CONDITIONAL_ANY_STRING "conditional-any"
#define NWAM_ACTIVATION_MODE_CONDITIONAL_ALL_STRING "conditional-all"
#define NWAM_ACTIVATION_MODE_PRIORITIZED_STRING "prioritized"
For conditional activation, the condition property is a formatted string:
| Object Type | Object | Condition |
|---|---|---|
| NCU|ENM|Location | name | is/is-not active |
| Object Type | Condition | Object |
| WLAN/ESSID | is/is-not/contains/does-not-contain | name string |
| BSSID | is/is-not | bssid string |
| ip-address | is/is-not | IPv4 or IPv6 address |
| ip-address | is-in-range/is-not-in-range | IPv4 or IPv6 address plus netmask/prefixlen |
| advertised-domain | is/is-not/contains/does-not-contain | name string |
| system-domain | is/is-not/contains/does-not-contain | name string |
typedef enum {
NWAM_CONDITION_IS,
NWAM_CONDITION_IS_NOT,
NWAM_CONDITION_IS_IN_RANGE,
NWAM_CONDITION_IS_NOT_IN_RANGE,
NWAM_CONDITION_CONTAINS,
NWAM_CONDITION_DOES_NOT_CONTAIN
} nwam_condition_t;
#define NWAM_CONDITION_IS_STRING "is"
#define NWAM_CONDITION_IS_NOT_STRING "is-not"
#define NWAM_CONDITION_IS_IN_RANGE_STRING "is-in-range"
#define NWAM_CONDITION_IS_NOT_IN_RANGE_STRING "is-not-in-range"
#define NWAM_CONDITION_CONTAINS_STRING "contains"
#define NWAM_CONDITION_DOES_NOT_CONTAIN_STRING "does-not-contain"
typedef enum {
NWAM_CONDITION_OBJECT_TYPE_NCU,
NWAM_CONDITION_OBJECT_TYPE_ENM,
NWAM_CONDITION_OBJECT_TYPE_LOC,
NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS,
NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN,
NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN,
NWAM_CONDITION_OBJECT_TYPE_ESSID,
NWAM_CONDITION_OBJECT_TYPE_BSSID
} nwam_condition_object_type_t;
#define NWAM_CONDITION_OBJECT_TYPE_NCU_STRING "ncu"
#define NWAM_CONDITION_OBJECT_TYPE_ENM_STRING "enm"
#define NWAM_CONDITION_OBJECT_TYPE_LOC_STRING "loc"
#define NWAM_CONDITION_OBJECT_TYPE_IP_ADDRESS_STRING "ip-address"
#define NWAM_CONDITION_OBJECT_TYPE_ADV_DOMAIN_STRING "advertised-domain"
#define NWAM_CONDITION_OBJECT_TYPE_SYS_DOMAIN_STRING "system-domain"
#define NWAM_CONDITION_OBJECT_TYPE_ESSID_STRING "essid"
#define NWAM_CONDITION_OBJECT_TYPE_BSSID_STRING "bssid"
#define NWAM_CONDITION_ACTIVE_STRING "active"
nwam_error_t nwam_condition_to_condition_string(nwam_condition_object_type_t,
nwam_condition_t, const char *, char **);
nwam_error_t nwam_condition_string_to_condition(const char *,
nwam_condition_object_type_t *, nwam_condition_t *, char **);
Miscellaneous global definitions:
#define NWAM_MAX_NAME_LEN 128 #define NWAM_MAX_VALUE_LEN 1024 #define NWAM_MAX_FMRI_LEN 256 #define NWAM_MAX_NUM_VALUES 32
There are currently only two possible NCPs, the automatic NCP, made up of automatically created NCUs associated with the hardware discovered in the system, and the user NCP, made up of the user's configured NCU settings. These NCPs have hardwired names which can used to obtain an opaque handle, which is linked to an in-memory representation of the NCP.
#define NWAM_NCP_NAME_AUTOMATIC "Automatic" #define NWAM_NCP_NAME_USER "User" typedef struct nwam_handle *nwam_ncp_handle_t;
Handles may be obtained either by looking up a specific name, or by walking all NCPs; the walk function will call the user-specified callback once for each NCP, passing in the NCP handle. When finished with the handle, the local memory should be freed.
Note that create and destroy functions are defined for NCPs; however, the use of these beyond the internal nwam implementation is not supported. In the future, when nwam supports multiple NCPs, these functions will be available to external entities as well.
nwam_error_t nwam_ncp_read(const char *name, uint64_t flags, nwam_ncp_handle_t *ncpp); nwam_error_t nwam_walk_ncps(int (*cb)(nwam_ncp_handle_t ncp, void *arg), void *arg, uint64_t flags, int *cb_return); nwam_error_t nwam_ncp_create(const char *name, uint64_t flags, nwam_ncp_handle_t *ncpp); nwam_error_t nwam_ncp_copy(nwam_ncp_handle_t orig_ncp, const char *copy_name, nwam_ncp_handle_t *copy_ncpp); nwam_error_t nwam_ncp_destroy(nwam_ncp_handle_t ncp, uint64_t flags); void nwam_ncp_free(nwam_ncp_handle_t ncp);
Given an NCP handle, information may be obtained about, and actions may be taken on, the NCP.
nwam_error_t nwam_ncp_get_name(nwam_ncp_handle_t ncp, char **name); nwam_error_t nwam_ncp_get_read_only(nwam_ncp_handle_t ncp, boolean_t *readonly); nwam_error_t nwam_ncp_get_state(nwam_ncp_handle_t ncp, nwam_state_t *state); nwam_error_t nwam_ncp_enable(nwam_ncp_handle_t ncp);
As with NCPs, a local, in-memory representation of an NCU is associated with a handle:
typedef struct nwam_handle *nwam_ncu_handle_t;
The first step in operating on an NCU is therefore to load the NCU into memory (or allocate memory for a new NCU) and obtain its handle. There are several ways to do this:
nwam_error_t nwam_ncp_walk_ncus(nwam_ncp_handle_t ncp,
int(*cb)(nwam_ncu_handle_t ncp, void *arg), void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_ncu_create(nwam_ncp_handle_t ncp, const char *name,
nwam_ncu_type_t type, nwam_ncu_class_t class, nwam_ncu_handle_t *ncup);
nwam_error_t nwam_ncu_read(nwam_ncp_handle_t ncp, const char *name,
nwam_ncu_type_t type, uint64_t flags, nwam_ncu_handle_t *ncup);
nwam_error_t nwam_ncu_copy(nwam_ncu_handle_t orig_ncu, const char *copy_name,
nwam_ncu_handle_t *copy_ncup);
In addition to the global flag values defined in section 5.1, the flags
parameter to nwam_ncp_walk_ncus() may also include any of the
following filtering values, which control the type and class of NCUs that are
returned from the walk. If no filtering flags are specified, or if the _ALL
flag is specified, all NCUs will be returned.
Note about the flags parameter: this 64-bit parameter can include
both the global flags (defined in section 5.1) and walk-specific flags such as
the following list. The global flags defined in section 5.1, and any others
that may be added in the future, will occupy the lower 32 bits of the
flags parameter, and will be interpreted in the same way by all libnwam
functions with a flags parameter. These walking-related flags
will occupy the upper 32 bits, and will be interpreted only in the appropriate
walkers; i.e. this set is unique only in the nwam_ncp_walk_ncus()
function, while a different set will be defined in the same bit-space for the
nwam_walk_locs() function.
#define NWAM_FLAG_NCU_TYPE_LINK 0x00000001ULL << 32 #define NWAM_FLAG_NCU_TYPE_IP 0x00000002ULL << 32 #define NWAM_FLAG_NCU_TYPE_ALL (NWAM_FLAG_NCU_TYPE_LINK | \ NWAM_FLAG_NCU_TYPE_IP) #define NWAM_FLAG_NCU_CLASS_PHYS 0x00000100ULL << 32 #define NWAM_FLAG_NCU_CLASS_IPTUN 0x00000200ULL << 32 #define NWAM_FLAG_NCU_CLASS_IP 0x00010000ULL << 32 #define NWAM_FLAG_NCU_CLASS_ALL_LINK (NWAM_FLAG_NCU_CLASS_PHYS | \ NWAM_FLAG_NCU_CLASS_IPTUN) #define NWAM_FLAG_NCU_CLASS_ALL_IP NWAM_FLAG_NCU_CLASS_IP #define NWAM_FLAG_NCU_CLASS_ALL (NWAM_FLAG_NCU_CLASS_ALL_LINK | \ NWAM_FLAG_NCU_CLASS_ALL_IP) #define NWAM_FLAG_NCU_TYPE_CLASS_ALL (NWAM_FLAG_NCU_TYPE_ALL | \ NWAM_FLAG_NCU_CLASS_ALL)
Once an NCU handle has been obtained, various operations are allowed on the NCU.
nwam_error_t nwam_ncu_get_name(nwam_ncu_handle_t ncup, char **name);
nwam_error_t nwam_ncu_set_name(nwam_ncu_handle_t ncup, const char *name);
nwam_error_t nwam_ncu_name_to_typed_name(const char *name, nwam_ncu_type_t type,
char **typednamep);
nwam_error_t nwam_ncu_get_ncp(nwam_ncu_handle_t ncup, nwam_ncp_handle_t *ncpp);
nwam_error_t nwam_ncu_get_read_only(nwam_ncu_handle_t ncup, boolean_t *readonly);
nwam_error_t nwam_ncu_prop_read_only(const char *propname, boolean_t *readonly);
nwam_error_t nwam_ncu_enable(nwam_ncu_handle_t ncu);
nwam_error_t nwam_ncu_disable(nwam_ncu_handle_t ncu);
nwam_error_t nwam_ncu_get_state(nwam_ncu_handle_t ncu, nwam_state_t *state);
The following functions may be used to manipulate NCU properties.
nwam_error_t nwam_ncu_get_default_proplist(nwam_ncu_type_t type,
nwam_ncu_class_t class, const char ***proplist, uint_t *numvalues);
cb_return parameter.
nwam_error_t nwam_ncu_walk_props(nwam_ncu_handle_t ncu,
int (*cb)(const char *propname, nwam_value_t propval, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_ncu_get_prop_type(const char *propname, nwam_value_type_t *type);
nwam_error_t nwam_ncu_get_prop_description(const char *propname, const char **desc);
nwam_error_t nwam_ncu_get_prop_value(nwam_ncu_handle_t ncu,
const char *propname, nwam_value_t *propval);
nwam_error_t nwam_ncu_set_prop_value(nwam_ncu_handle_t ncu,
const char *propname, nwam_value_t propval);
nwam_error_t nwam_ncu_delete_prop(nwam_ncu_handle_t ncu, const char *propname);
The following structures and definitions are used to identify NCU properties.
Each property has a string name which maps to an identifier of the form
NWAM_NCU_PROP_<foo>. Additionally, for each property whose
values are enumerated, there is an nwam_ncu_<foo>_t
structure, and additional NWAM_NCU_<FOO>_<BAR>_STRING
defines for each possible value.
#define NWAM_NCU_PROP_TYPE "type"
#define NWAM_NCU_PROP_CLASS "class"
#define NWAM_NCU_PROP_PARENT_NCP "parent"
#define NWAM_NCU_PROP_ACTIVATION_MODE "activation-mode"
#define NWAM_NCU_PROP_PRIORITY_GROUP "priority-group"
#define NWAM_NCU_PROP_PRIORITY_MODE "priority-mode"
#define NWAM_NCU_PROP_ENABLED "enabled"
#define NWAM_NCU_PROP_LINK_MAC_ADDR "link-mac-addr"
#define NWAM_NCU_PROP_LINK_AUTOPUSH "link-autopush"
#define NWAM_NCU_PROP_LINK_MTU "link-mtu"
typedef enum {
NWAM_NCU_TYPE_LINK,
NWAM_NCU_TYPE_IP,
NWAM_NCU_TYPE_ANY
} nwam_ncu_type_t;
#define NWAM_NCU_TYPE_LINK_STRING "link"
#define NWAM_NCU_TYPE_IP_STRING "ip"
typedef enum {
NWAM_NCU_CLASS_PHYS,
NWAM_NCU_CLASS_IP,
NWAM_NCU_CLASS_ANY
} nwam_ncu_class_t;
#define NWAM_NCU_CLASS_PHYS_STRING "phys"
#define NWAM_NCU_CLASS_IP_STRING "ip"
typedef enum {
NWAM_PRIORITY_MODE_EXCLUSIVE,
NWAM_PRIORITY_MODE_SHARED,
NWAM_PRIORITY_MODE_ALL
} nwam_priority_mode_t;
#define NWAM_PRIORITY_MODE_EXCLUSIVE_STRING "exclusive"
#define NWAM_PRIORITY_MODE_SHARED_STRING "shared"
#define NWAM_PRIORITY_MODE_ALL_STRING "all"
#define NWAM_NCU_PROP_IP_VERSION "ip-version"
#define NWAM_NCU_PROP_IPV4_ADDRSRC "ipv4-addrsrc"
#define NWAM_NCU_PROP_IPV4_ADDR "ipv4-addr"
#define NWAM_NCU_PROP_IPV6_ADDRSRC "ipv6-addrsrc"
#define NWAM_NCU_PROP_IPV6_ADDR "ipv6-addr"
typedef enum {
NWAM_IP_VERSION_IPV4,
NWAM_IP_VERSION_IPV6,
NWAM_IP_VERSION_ALL
} nwam_ip_version_t;
#define NWAM_IP_VERSION_IPV4_STRING "ipv4"
#define NWAM_IP_VERSION_IPV6_STRING "ipv6"
#define NWAM_IP_VERSION_ALL_STRING "all"
typedef enum {
NWAM_ADDRSRC_DHCP,
NWAM_ADDRSRC_DHCPV6,
NWAM_ADDRSRC_AUTOCONF,
NWAM_ADDRSRC_STATIC
} nwam_addrsrc_t;
#define NWAM_ADDRSRC_DHCP_STRING "dhcp"
#define NWAM_ADDRSRC_DHCPV6_STRING "dhcpv6"
#define NWAM_ADDRSRC_AUTOCONF_STRING "autoconf"
#define NWAM_ADDRSRC_STATIC_STRING "static"
Individual properties as well as complete NCUs may be validated. When an NCU is validated, the first property with an incorrect value is returned in the propname parameter.
nwam_error_t nwam_ncu_validate_prop(nwam_ncu_handle_t ncu, const char *propname, nwam_value_t propval); nwam_error_t nwam_ncu_validate(nwam_ncu_handle_t ncu, const char **invalid_prop);
When finished with the NCU, the following clean-up options are available.
nwam_error_t nwam_ncu_commit(nwam_ncu_handle_t ncu, uint64_t flags);
void nwam_ncu_free(nwam_ncu_handle_t ncu);
nwam_error_t nwam_ncu_destroy(nwam_ncu_handle_t ncu, uint64_t flags);
As with NCPs and NCUs, locations are represented by an opaque handle. There are three system-created locations with defined names; these names may be used to load or copy the location. The Automatic and NoNet location may also be modified by the user.
#define NWAM_LOC_NAME_AUTOMATIC "Automatic" #define NWAM_LOC_NAME_NO_NET "NoNet" #define NWAM_LOC_NAME_LEGACY "Legacy" typedef struct nwam_handle *nwam_loc_handle_t;
Locations are also manipulated in much the same way as NCUs. You must begin by loading the location into memory (or allocating memory for a new location) and obtaining its handle. There are several ways to do this:
nwam_error_t nwam_walk_locs(int (*cb)(nwam_loc_handle_t loc, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_loc_create(const char *name, nwam_loc_handle_t *locp);
nwam_error_t nwam_loc_read(const char *name, uint64_t flags, nwam_loc_handle_t *locp);
nwam_error_t nwam_loc_copy(nwam_loc_handle_t orig_loc, const char *copy_name,
nwam_loc_handle_t *copy_locp);
In addition to the global flag values defined in section 5.1, the flags
parameter to nwam_walk_locs() may also include any of the
following filtering values, which limit the locations returned based on
the activation mode property.
#define NWAM_FLAG_ACTIVATION_MODE_ALWAYS 0x00000001ULL << 32 #define NWAM_FLAG_ACTIVATION_MODE_NEVER 0x00000002ULL << 32 #define NWAM_FLAG_ACTIVATION_MODE_MANUAL 0x00000004ULL << 32 #define NWAM_FLAG_ACTIVATION_MODE_PRIORITIZED 0x00000008ULL << 32 #define NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL 0x00000010ULL << 32 #define NWAM_FLAG_ACTIVATION_MODE_ALL (NWAM_FLAG_ACTIVATION_MODE_ALWAYS | \ NWAM_FLAG_ACTIVATION_MODE_NEVER | \ NWAM_FLAG_ACTIVATION_MODE_MANUAL | \ NWAM_FLAG_ACTIVATION_MODE_PRIORITIZED | \ NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL)
Once a location handle has been obtained, various operations are allowed on the location.
nwam_error_t nwam_loc_get_name(nwam_loc_handle_t loc, char **namep);
nwam_error_t nwam_loc_set_name(nwam_loc_handle_t loc, const char *name);
nwam_error_t nwam_loc_enable(nwam_loc_handle_t loc);
nwam_error_t nwam_loc_disable(nwam_loc_handle_t loc);
nwam_error_t nwam_loc_get_state(nwam_loc_handle_t loc, nwam_state_t *state);
The following functions may be used to manipulate location properties.
nwam_error_t nwam_loc_get_default_proplist(const char ***proplist, uint_t *numvalues);
cb_return parameter.
nwam_error_t nwam_loc_walk_props(nwam_loc_handle_t loc,
int (*cb)(const char *propname, nwam_value_t propval, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_loc_get_prop_type(const char *propname, nwam_value_type_t *type);
nwam_error_t nwam_loc_get_prop_description(const char *propname, const char **desc);
nwam_error_t nwam_loc_get_prop_value(nwam_loc_handle_t loc,
const char *propname, nwam_value_t *propval);
nwam_error_t nwam_loc_set_prop_value(nwam_loc_handle_t loc,
const char *propname, nwam_value_t propval);
nwam_error_t nwam_loc_delete_prop(nwam_loc_handle_t loc, const char *propname);
The following structures and definitions are used to identify location
properties. Each property has a string name which maps to an identifier of
the form NWAM_LOC_PROP_<foo>. Additionally, for each
property whose values are enumerated, there is an nwam_loc_<foo>_t
structure, and additional NWAM_LOC_<FOO>_<BAR>_STRING
defines for each possible value.
#define NWAM_LOC_PROP_ACTIVATION_MODE "activation-mode"
#define NWAM_LOC_PROP_CONDITIONS "conditions"
#define NWAM_LOC_PROP_ENABLED "enabled"
/* Nameservice location properties */
#define NWAM_LOC_PROP_NAMESERVICES "nameservices"
#define NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE "nameservices-config-file"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC "dns-nameservice-configsrc"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN "dns-nameservice-domain"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS "dns-nameservice-servers"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH "dns-nameservice-search"
#define NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC "nis-nameservice-configsrc"
#define NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS "nis-nameservice-servers"
#define NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC "ldap-nameservice-configsrc"
#define NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS "ldap-nameservice-servers"
#define NWAM_LOC_PROP_DEFAULT_DOMAIN "default-domain"
typedef enum {
NWAM_NAMESERVICES_DNS,
NWAM_NAMESERVICES_FILES,
NWAM_NAMESERVICES_NIS,
NWAM_NAMESERVICES_LDAP
} nwam_nameservices_t;
#define NWAM_NAMESERVICES_DNS_STRING "dns"
#define NWAM_NAMESERVICES_FILES_STRING "files"
#define NWAM_NAMESERVICES_NIS_STRING "nis"
#define NWAM_NAMESERVICES_LDAP_STRING "ldap"
typedef enum {
NWAM_CONFIGSRC_MANUAL,
NWAM_CONFIGSRC_DHCP
} nwam_configsrc_t;
#define NWAM_CONFIGSRC_MANUAL_STRING "manual"
#define NWAM_CONFIGSRC_DHCP_STRING "dhcp"
/* Path to hosts/ipnodes database */
#define NWAM_LOC_PROP_HOSTS_FILE "hosts-file"
/* NFSv4 domain */
#define NWAM_LOC_PROP_NFSV4_DOMAIN "nfsv4-domain"
/* IPFilter configuration */
#define NWAM_LOC_PROP_IPFILTER_CONFIG_FILE "ipfilter-config-file"
#define NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE "ipfilter-v6-config-file"
#define NWAM_LOC_PROP_IPNAT_CONFIG_FILE "ipnat-config-file"
#define NWAM_LOC_PROP_IPPOOL_CONFIG_FILE "ippool-config-file"
/* IPsec configuration */
#define NWAM_LOC_PROP_IKE_CONFIG_FILE "ike-config-file"
#define NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE "ipsecpolicy-config-file"
/* List of SMF services to enable/disable */
#define NWAM_LOC_PROP_SVCS_ENABLE "svcs-enable"
#define NWAM_LOC_PROP_SVCS_DISABLE "svcs-disable"
Individual property settings as well as complete locations may be validated. When a location is validated, the first property with an incorrect value is returned in the propname parameter.
nwam_error_t nwam_loc_validate_prop(nwam_loc_handle_t loc, const char *propname, nwam_value_t propval); nwam_error_t nwam_loc_validate(nwam_loc_handle_t loc, const char **invalid_prop);
When finished with the location, the following clean-up options are available.
nwam_error_t nwam_loc_commit(nwam_loc_handle_t loc, uint64_t flags);
void nwam_loc_free(nwam_loc_handle_t loc);
nwam_error_t nwam_loc_destroy(nwam_loc_handle_t loc, uint64_t flags);
As with the preceding object types, ENMs are represented by an opaque handle:
typedef struct nwam_handle *nwam_enm_handle_t;
ENMs are also manipulated in much the same way as the other object types. You must begin by loading an ENM into memory (or allocating memory for a new ENM) and obtaining its handle. There are several ways to do this:
NWAM_SUCCESS, the walk is halted immediately, and the walk
function returns NWAM_WALK_HALTED, with the callback
function's return value stored in the cb_return parameter.
nwam_error_t nwam_walk_enms(int (*cb)(nwam_enm_handle_t enm, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_enm_create(const char *name, const char *fmri, nwam_enm_handle_t *enmp);
nwam_error_t nwam_enm_read(const char *name, uint64_t flags, nwam_enm_handle_t *enmp);
nwam_error_t nwam_enm_copy(nwam_enm_handle_t orig_enm, const char *copy_name,
nwam_enm_handle_t *copy_enmp);
Once an ENM handle has been obtained, various operations are allowed on the ENM.
nwam_error_t nwam_enm_get_name(nwam_enm_handle_t enm, char **namep);
nwam_error_t nwam_enm_set_name(nwam_enm_handle_t enm, const char *name);
nwam_error_t nwam_enm_enable(nwam_enm_handle_t enm);
nwam_error_t nwam_enm_disable(nwam_enm_handle_t enm);
nwam_error_t nwam_enm_get_state(nwam_enm_handle_t enm, nwam_state_t *state);
nwam_error_t nwam_enm_is_manual(nwam_enm_handle_t enm, boolean_t *ismanual);
The following functions may be used to manipulate ENM properties.
nwam_error_t nwam_enm_get_default_proplist(const char ***proplist, uint_t *numvalues);
NWAM_SUCCESS,
the walk will halt immediately, and the walk function will return
NWAM_WALK_HALTED, with the callback return value stored in
the cb_return parameter.
nwam_error_t nwam_enm_walk_props(nwam_enm_handle_t enm,
int (*cb)(const char *propname, nwam_value_t propval, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_enm_get_prop_type(const char *propname, nwam_value_type_t *type);
nwam_error_t nwam_enm_get_prop_description(const char *propname, const char **desc);
nwam_error_t nwam_enm_get_prop_value(nwam_enm_handle_t enm,
const char *propname, nwam_value_t * propval);
nwam_error_t nwam_enm_set_prop_value(nwam_enm_handle_t enm,
const char *propname, nwam_value_t propval);
nwam_error_t nwam_enm_delete_prop(nwam_enm_handle_t enm, const char *propname);
The following structures and definitions are used to identify ENM properties.
Each property has a string name which maps to an identifier of the form
NWAM_ENM_PROP_<foo>. Additionally, for each property whose
values are enumerated, there is an nwam_enm_<foo>_t
structure, and additional NWAM_ENM_<FOO>_<BAR>_STRING
defines for each possible value.
#define NWAM_ENM_PROP_ACTIVATION_MODE "activation-mode" #define NWAM_ENM_PROP_CONDITIONS "conditions" #define NWAM_ENM_PROP_ENABLED "enabled" /* FMRI associated with the ENM */ #define NWAM_ENM_PROP_FMRI "fmri" /* Start/Stop scripts associated with the ENM */ #define NWAM_ENM_PROP_START "start" #define NWAM_ENM_PROP_STOP "stop"
Note that the FMRI and START/STOP properties of an ENM are mutually exclusive; if the FMRI property is defined, that service's start and stop methods will be used to start and stop the ENM; if the FMRI property is not defined, the START and STOP properties must be defined, and will be used to start and stop the ENM.
Individual property settings as well as complete ENMs may be validated. When
an ENM is validated, the first property with an invalid value is returned in
the propname parameter.
nwam_error_t nwam_enm_validate_prop(nwam_enm_handle_t enm, const char *propname, nwam_value_t propval); nwam_error_t nwam_enm_validate(nwam_enm_handle_t enm, const char **invalid_prop);
When finished with the ENM, the following clean-up options are available.
nwam_error_t nwam_enm_commit(nwam_enm_handle_t enm, uint64_t flags);
void nwam_enm_free(nwam_enm_handle_t enm);
nwam_error_t nwam_enm_destroy(nwam_enm_handle_t enm, uint64_t flags);
As with the other object types, Known WLANs are represented by an opaque handle:
typedef struct nwam_handle *nwam_known_wlan_handle_t;
Known WLANs are manipulated in much the same way as the other object types. You must begin by loading a Known WLAN into memory, or allocating memory for a new Known WLAN, and obtaining its handle. There are several ways to do this:
nwam_error_t nwam_walk_known_wlans(int (*cb)(nwam_known_wlan_handle_t kwh, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_known_wlan_create(const char *name, nwam_known_wlan_handle_t *kwhp);
nwam_error_t nwam_known_wlan_read(const char *name, uint64_t flags,
nwam_known_wlan_handle_t *kwhp);
nwam_error_t nwam_known_wlan_copy(nwam_known_wlan_handle_t orig_kwh, const char *copy_name, nwam_known_wlan_handle_t *copy_kwhp);
Once a Known WLAN handle has been obtained, the following operations are allowed on the Known WLAN.
nwam_error_t nwam_known_wlan_get_name(nwam_known_wlan_handle_t kwh, char **namep);
nwam_error_t nwam_known_wlan_set_name(nwam_known_wlan_handle_t kwh, const char *name);
The following functions may be used to manipulate a Known WLAN's properties.
nwam_error_t nwam_known_wlan_get_default_proplist(const char ***proplist, uint_t *numvalues);
nwam_error_t nwam_known_wlan_walk_props(nwam_known_wlan_handle_t kwh,
int (*cb)(const char *propname, nwam_value_t propval, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_known_wlan_get_prop_type(const char *propname, nwam_value_type_t *type);
nwam_error_t nwam_known_wlan_get_prop_description(const char *propname, const char **desc);
nwam_error_t nwam_known_wlan_get_prop_value(nwam_known_wlan_handle_t kwh,
const char *propname, nwam_value_t *propval);
nwam_error_t nwam_known_wlan_set_prop_value(nwam_known_wlan_handle_t kwh,
const char *propname, nwam_value_t propval);
nwam_error_t nwam_known_wlan_delete_prop(nwam_known_wlan_handle_t kwh, const char *propname);
nwam_error_t nwam_known_wlan_add_to_known_wlan(const char *name, const char *bssid);
nwam_error_t nwam_known_wlan_remove_from_known_wlan(const char *name, const char *bssid);
The following structures and definitions are used to identify Known WLAN
properties. Each property has a string name which maps to an identifier of
the form NWAM_KNOWN_WLAN_PROP_<foo>.
#define NWAM_KNOWN_WLAN_PROP_BSSIDS "bssids" #define NWAM_KNOWN_WLAN_PROP_PRIORITY "priority" #define NWAM_KNOWN_WLAN_PROP_KEYNAME "keyname"
Individual property settings as well as complete Known WLANs may be validated. When a Known WLAN is validated, the first property with an invalid value is returned in the propname parameter.
nwam_error_t nwam_known_wlan_validate_prop(nwam_known_wlan_handle_t kwh, const char *propname, nwam_value_t propval); nwam_error_t nwam_known_wlan_validate(nwam_known_wlan_handle_t kwh, const char **invalid_prop);
When finished with the Known WLAN, the following clean-up options are available.
nwam_error_t nwam_known_wlan_commit(nwam_known_wlan_handle_t kwh, uint64_t flags);
void nwam_known_wlan_free(nwam_known_wlan_handle_t kwh);
nwam_error_t nwam_known_wlan_destroy(nwam_known_wlan_handle_t kwh, uint64_t flags);
#define NWAM_EVENT_TYPE_NOOP 0
#define NWAM_EVENT_TYPE_INIT 1
#define NWAM_EVENT_TYPE_SHUTDOWN 2
#define NWAM_EVENT_TYPE_OBJECT_ACTION 3
#define NWAM_EVENT_TYPE_OBJECT_STATE 4
#define NWAM_EVENT_TYPE_INFO 5
#define NWAM_EVENT_TYPE_WLAN_SCAN_REPORT 6
#define NWAM_EVENT_TYPE_WLAN_NEED_CHOICE 7
#define NWAM_EVENT_TYPE_WLAN_NEED_KEY 8
#define NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT 9
#define NWAM_EVENT_TYPE_IF_ACTION 10
#define NWAM_EVENT_TYPE_IF_STATE 11
#define NWAM_EVENT_TYPE_LINK_ACTION 12
#define NWAM_EVENT_TYPE_LINK_STATE 13
#define NWAM_EVENT_STATUS_OK 0
#define NWAM_EVENT_STATUS_NOT_HANDLED 1
#define NWAM_EVENT_NETWORK_OBJECT_UNDEFINED 0
#define NWAM_EVENT_NETWORK_OBJECT_LINK 1
#define NWAM_EVENT_NETWORK_OBJECT_INTERFACE 2
#define NWAM_EVENT_REQUEST_UNDEFINED 0
#define NWAM_EVENT_REQUEST_WLAN 1
#define NWAM_EVENT_REQUEST_KEY 2
typedef struct {
char essid[NWAM_MAX_NAME_LEN];
char bssid[NWAM_MAX_NAME_LEN];
char signal_strength[NWAM_MAX_NAME_LEN];
uint32_t security_mode; /* a dladm_wlan_secmode_t */
uint32_t channel; /* a dladm_wlan_channel_t */
} nwam_event_wlan_t;
typedef enum {
NWAM_ACTION_NONE = -1,
NWAM_ACTION_ADD,
NWAM_ACTION_REMOVE,
NWAM_ACTION_REFRESH,
NWAM_ACTION_REQUEST_STATE,
NWAM_ACTION_ENABLE,
NWAM_ACTION_DISABLE,
NWAM_ACTION_RENAME,
NWAM_ACTION_DESTROY
} nwam_action_t;
typedef enum {
NWAM_OBJECT_TYPE_NONE = -1,
NWAM_OBJECT_TYPE_NCP = 0,
NWAM_OBJECT_TYPE_NCU = 1,
NWAM_OBJECT_TYPE_LOC = 2,
NWAM_OBJECT_TYPE_ENM = 3,
NWAM_OBJECT_TYPE_KNOWN_WLAN = 4
} nwam_object_type_t;
typedef struct nwam_event *nwam_event_t;
struct nwam_event {
int type;
uint32_t size;
union {
struct {
nwam_object_type_t object_type;
char name[NWAM_MAX_NAME_LEN];
nwam_action_t action;
} object_action;
struct {
nwam_object_type_t object_type;
char name[NWAM_MAX_NAME_LEN];
nwam_state_t state;
} object_state;
struct {
char message[NWAM_MAX_VALUE_LEN];
} info;
/*
* wlan_info stores both scan results and the single WLAN
* we require a key for in the case of _WLAN_NEED_KEY
* events. For _WLAN_CONNECT_FAILED events, it stores the
* WLAN for which the connection failed.
*/
struct {
char name[NWAM_MAX_NAME_LEN];
uint16_t num_wlans;
nwam_event_wlan_t wlans[1];
/*
* space may be allocated by user here for the
* number of wlans.
*/
} wlan_info;
struct {
char name[NWAM_MAX_NAME_LEN];
nwam_action_t action;
} if_action;
struct {
char name[NWAM_MAX_NAME_LEN];
uint32_t flags;
uint32_t index;
uint32_t addr_valid; /* boolean */
struct sockaddr addr;
/* might be longer than sizeof (if_state) for addr */
} if_state;
struct {
char name[NWAM_MAX_NAME_LEN];
int32_t link_state; /* link_state_t from sys/mac.h */
} link_state;
struct {
char name[NWAM_MAX_NAME_LEN];
nwam_action_t action;
} link_action;
} data;
};
nwam_error_t nwam_events_init(void); void nwam_events_fini(void); nwam_error_t nwam_event_wait(nwam_event_t *eventp); void nwam_event_free(nwam_event_t event);
nwam_error_t nwam_event_send(nwam_event_t event); void nwam_event_send_fini(void); nwam_error_t nwam_event_queue_init(const char *eventmsgfile); void nwam_event_queue_fini(const char *eventmsgfile);
const char *nwam_action_to_string(nwam_action_t action); const char *nwam_event_type_to_string(int evtype); const char *nwam_state_to_string(nwam_state_t state); const char *nwam_object_type_to_string(nwam_object_type_t object);
The libnwam model is transactional - that is data is read from backend storage atomically, modified and then committed atomically. In order to do this, we require an in-memory representation of data associated with an entity, which can be tied to that entity's handle. The suggested approach is to use libnvpair(3LIB) to store in-memory representations, specifically using nvlists for property lists associated with NWAM objects. This solution is attractive, since libnvpair already provides functionality to manipulate name-value pair lists, to duplicate them, traverse them etc.
Concretely, a given object handle will have a nvlist associated with it, which
is allocated on object creation. If an object is read in from persistent
storage, the nvlist is populated with appropriate name-value pairs, each of
which has an associated array of 64 bit integer (signed or unsigned), boolean,
or string values (added via nvlist_add_uint64_array() etc). Names of each
nvlist element will correspond to property names. When a property is set, it
will replace any existing instance of that property in the nvlist (the lists
are of NV_UNIQUE_TYPE). At commit time, we walk the list via
nvlist_next_nvpair(), translating each property into the
persistent storage equivalent.
Note also that the nvlist representation is also amenable to SMF (instances could be represented as an nvlist of property groups, each of which is an nvlist of propertyname-value pairs, so this solution fits with the future direction of libnwam also.
| Revision | Date | Changes |
|---|---|---|
| 2.1 | 2008-Feb-28 | using files rather than smf; library clean-up |
| 2.2 | 2008-Mar-05 | add revision history; fix formatting nits; add some ToDo items |
| 2.3 | 2008-Mar-12 | add section on repository transactions; add some ToDo items |
| 2.4 | 2008-Apr-03 | update intro |
| 2.5 | 2008-Sep-19 | update based on implementation experience |
| 2.6 | 2008-Sep-29 | fix a few more details |
| 2.7 | 2009-Jan-07 | remove location templates; add Known WLAN section |
| 2.8 | 2009-Jan-27 | miscellaneous clean-up |
| 2.9 | 2009-Feb-13 | Design review feedback; more implementation changes |
| 2.10 | 2009-Feb-27 | more tweaks of nameservice properties |
| 2.11 | 2009-Mar-11 | re-sync with source code; update event interfaces |
| 2.12 | 2009-Mar-17 | pre-psarc review feedback |