Version 2.6, 2008-Sep-29
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_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_WALK_HALTED, /* Callback function returned nonzero */
NWAM_ERROR_INTERNAL /* Internal error */
} nwam_error_t;
/* convert an error code to a localized string */
const char *nwam_strerror(nwam_error_t);
NWAM property values are stored in nwam_value_t structures. The
following data structures and functions are used to manage these objects.
/* property data types */
typedef enum {
NWAM_DATA_TYPE_BOOLEAN,
NWAM_DATA_TYPE_INT64,
NWAM_DATA_TYPE_STRING,
NWAM_DATA_TYPE_UNKNOWN
} nwam_data_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_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_string(nwam_value_t, char **);
nwam_error_t nwam_value_get_string_array(nwam_value_t, char ***, uint_t *);
nwam_error_t nwam_int64_get_value_string(const char *, int64_t, const char **);
nwam_error_t nwam_value_string_get_int64(const char *, const char *, int64_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_ALWAYS,
NWAM_ACTIVATION_MODE_NEVER,
NWAM_ACTIVATION_MODE_MANUAL,
NWAM_ACTIVATION_MODE_PRIORITIZED,
NWAM_ACTIVATION_MODE_CONDITIONAL
} nwam_activation_mode_t;
#define NWAM_ACTIVATION_MODE_ALWAYS_STRING "always"
#define NWAM_ACTIVATION_MODE_NEVER_STRING "never"
#define NWAM_ACTIVATION_MODE_MANUAL_STRING "manual"
#define NWAM_ACTIVATION_MODE_PRIORITIZED_STRING "prioritized"
#define NWAM_ACTIVATION_MODE_CONDITIONAL_STRING "conditional"
Miscellaneous global definitions:
#define NWAM_MAX_NAME_LEN 256 #define NWAM_MAX_VALUE_LEN 1024 #define NWAM_MAX_FMRI_LEN 256 #define NWAM_MAX_NUM_VALUES 64
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_ncp_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_load(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_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_activate(nwam_ncp_handle_t ncp); nwam_error_t nwam_ncp_deactivate(nwam_ncp_handle_t ncp);
As with NCPs, a local, in-memory representation of an NCU is associated with a handle:
struct nwam_ncu_handle; typedef struct nwam_ncu_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_load(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 0x00000001 << 32 #define NWAM_FLAG_NCU_TYPE_IP 0x00000002 << 32 #define NWAM_FLAG_NCU_TYPE_ALL (NWAM_FLAG_NCU_TYPE_LINK | \ NWAM_FLAG_NCU_TYPE_IP) #define NWAM_FLAG_NCU_CLASS_PHYS 0x00000100 << 32 #define NWAM_FLAG_NCU_CLASS_IPTUN 0x00000200 << 32 #define NWAM_FLAG_NCU_CLASS_IP 0x00010000 << 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);
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);
#define NWAM_NCU_PROP_READONLY(prop) \
(strcmp(prop, NWAM_NCU_PROP_TYPE) == 0 || \
strcmp(prop, NWAM_NCU_PROP_CLASS) == 0 || \
strcmp(prop, NWAM_NCU_PROP_PARENT_NCP) == 0)
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_CONDITION "condition"
#define NWAM_NCU_PROP_PRIORITY_GROUP "priority-group"
#define NWAM_NCU_PROP_PRIORITY_MODE "priority-mode"
#define NWAM_NCU_PROP_OVER "over"
#define NWAM_NCU_PROP_UNDER "under"
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_IPTUN,
NWAM_NCU_CLASS_IP,
NWAM_NCU_CLASS_ANY
} nwam_ncu_class_t;
#define NWAM_NCU_CLASS_PHYS_STRING "phys"
#define NWAM_NCU_CLASS_IPTUN_STRING "iptun"
#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_LINK_MAC_ADDR "link-mac-addr"
#define NWAM_NCU_PROP_LINK_AUTOPUSH "link-autopush"
#define NWAM_NCU_PROP_LINK_MTU "link-mtu"
#define NWAM_NCU_PROP_IPTUN_TYPE "iptun-type"
#define NWAM_NCU_PROP_IPTUN_TSRC "iptun-tsrc"
#define NWAM_NCU_PROP_IPTUN_TDST "iptun-tdst"
#define NWAM_NCU_PROP_IPTUN_ENCR "iptun-encr"
#define NWAM_NCU_PROP_IPTUN_ENCR_AUTH "iptun-encr-auth"
#define NWAM_NCU_PROP_IPTUN_AUTH "iptun-auth"
typedef enum {
NWAM_IPTUN_TYPE_IPV4,
NWAM_IPTUN_TYPE_IPV6,
NWAM_IPTUN_TYPE_6TO4
} nwam_iptun_type_t;
#define NWAM_IPTUN_TYPE_IPV4_STRING "ipv4"
#define NWAM_IPTUN_TYPE_IPV6_STRING "ipv6"
#define NWAM_IPTUN_TYPE_6TO4_STRING "6to4"
#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:
struct nwam_loc_handle; typedef struct nwam_loc_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_load(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 0x00000001 << 32 #define NWAM_FLAG_ACTIVATION_MODE_NEVER 0x00000002 << 32 #define NWAM_FLAG_ACTIVATION_MODE_MANUAL 0x00000004 << 32 #define NWAM_FLAG_ACTIVATION_MODE_PRIORITIZED 0x00000008 << 32 #define NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL 0x00000010 << 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_activate(nwam_loc_handle_t loc);
nwam_error_t nwam_loc_deactivate(nwam_loc_handle_t loc);
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_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_CONDITION "condition"
/* Nameservice location properties */
#define NWAM_LOC_PROP_NAMESERVICE_DISCOVER "nameservice-discover"
#define NWAM_LOC_PROP_NAMESERVICES "nameservices"
typedef enum {
NWAM_NAMESERVICES_DNS,
NWAM_NAMESERVICES_FILES,
NWAM_NAMESERVICES_NIS,
NWAM_NAMESERVICES_NISPLUS,
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_NISPLUS_STRING "nisplus"
#define NWAM_NAMESERVICES_LDAP_STRING "ldap"
#define NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE "nameservices-config-file"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS "dns-nameservice-servers"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN "dns-nameservice-domain"
#define NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH "dns-nameservice-search"
#define NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS "nis-nameservice-servers"
#define NWAM_LOC_PROP_NIS_NAMESERVICE_DOMAIN "nis-nameservice-domain"
#define NWAM_LOC_PROP_NISPLUS_NAMESERVICE_SERVERS \
"nisplus-nameservice-servers"
#define NWAM_LOC_PROP_NISPLUS_NAMESERVICE_DOMAIN \
"nisplus-nameservice-domain"
#define NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS "ldap-nameservice-servers"
#define NWAM_LOC_PROP_LDAP_NAMESERVICE_DOMAIN "ldap-nameservice-domain"
/* 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_IPSECKEY_CONFIG_FILE "ipseckey-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);
In addition to the "hardwired" properties defined above, SMF services may identify properties which should be included in an NWAM location. These "extensible" properties may be retrieved from the repository using a template mechanism.
These functions are not specific to a location; after finding out about all the existing templates, how do you associate values for the template properties with a particular location?
A service wishing to include properties in NWAM locations creates a property group which contains descriptive information. That information is available to consumers of libnwam via the nwam_loc_prop_template_t structure:
struct nwam_loc_prop_template; typedef struct nwam_loc_prop_template *nwam_loc_prop_template_t;
A location property template includes a set of descriptive properties:
#define NWAM_LOC_TEMPLATE_PROP_LOC "nwam_loc_property"
#define NWAM_LOC_TEMPLATE_PROP_GROUP "nwam_loc_property_group"
#define NWAM_LOC_TEMPLATE_PROP_NAME "nwam_loc_property_name"
#define NWAM_LOC_TEMPLATE_PROP_DESC "nwam_loc_property_description"
#define NWAM_LOC_TEMPLATE_PROP_DEFAULT "nwam_loc_property_default"
A set of functions is provided to access information about existing template properties.
nwam_error_t nwam_walk_loc_prop_templates(int (*cb)(nwam_loc_prop_template_t template, void *arg),
void *arg, uint64_t flags, int *cb_return);
nwam_error_t nwam_get_loc_prop_template(const char *name, nwam_loc_prop_template_t *template);
nwam_error_t nwam_loc_prop_template_get_fmri(nwam_loc_prop_template_t template, const char **fmri);
nwam_error_t nwam_loc_prop_template_get_prop_name(nwam_loc_prop_template_t template, const char **name);
nwam_error_t nwam_loc_prop_template_get_prop_group(nwam_loc_prop_template_t template, const char **group);
nwam_error_t nwam_loc_prop_template_get_prop_desc(nwam_loc_prop_template_t template, const char **desc);
nwam_error_t nwam_loc_prop_template_get_prop_default(nwam_loc_prop_template_t template, nwam_value_t *default_val);
void nwam_loc_prop_template_free(nwam_loc_prop_template_t template);
As with the preceding object types, ENMs are represented by an opaque handle:
struct nwam_enm_handle; typedef struct nwam_enm_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_load(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);
In addition to the global flag values defined in section 5.1, the flags
parameter to nwam_walk_enms() may also include any of the
following filtering values, which limit the ENMs returned based on state.
#define NWAM_FLAG_ENM_STATE_CREATED 0x00000001 << 32 #define NWAM_FLAG_ENM_STATE_ENABLED 0x00000002 << 32 #define NWAM_FLAG_ENM_STATE_DISABLED 0x00000004 << 32 #define NWAM_FLAG_ENM_STATE_MAINT 0x00000008 << 32 #define NWAM_FLAG_ENM_STATE_ALL (NWAM_FLAG_ENM_STATE_CREATED | \ NWAM_FLAG_ENM_STATE_ENABLED | \ NWAM_FLAG_ENM_STATE_DISABLED | \ NWAM_FLAG_ENM_STATE_MAINT)
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_activate(nwam_enm_handle_t enm);
nwam_error_t nwam_enm_deactivate(nwam_enm_handle_t enm);
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_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_CONDITION "condition"
#define NWAM_ENM_PROP_STATE "state"
typedef enum {
NWAM_ENM_STATE_CREATED,
NWAM_ENM_STATE_ENABLED,
NWAM_ENM_STATE_DISABLED,
NWAM_ENM_STATE_MAINT
} nwam_enm_state_t;
#define NWAM_ENM_STATE_CREATED_STRING "created"
#define NWAM_ENM_STATE_ENABLED_STRING "enabled"
#define NWAM_ENM_STATE_DISABLED_STRING "disabled"
#define NWAM_ENM_STATE_MAINT_STRING "maintenance"
/* 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);
#define NWAM_EVENTS_NOOP 0
#define NWAM_EVENTS_SOURCE_DEAD 1
#define NWAM_EVENTS_SOURCE_BACK 2
#define NWAM_EVENTS_NO_MAGIC 3
#define NWAM_EVENTS_INFO 4
#define NWAM_EVENTS_IF_STATE 5
#define NWAM_EVENTS_IF_REMOVED 6
#define NWAM_EVENTS_LINK_STATE 7
#define NWAM_EVENTS_LINK_REMOVED 8
#define NWAM_EVENTS_SCAN_REPORT 9
#define NWAM_EVENTS_STATUS_OK 0
#define NWAM_EVENTS_NOT_HANDLED 1
#define NWAM_NETWORK_OBJECT_UNDEFINED 0
#define NWAM_NETWORK_OBJECT_LINK 1
#define NWAM_NETWORK_OBJECT_INTERFACE 2
#define NWAM_REQ_UNDEFINED 0
#define NWAM_REQ_WLAN 1
#define NWAM_REQ_KEY 2
typedef struct {
char essid[DLADM_STRSIZE];
char bssid[DLADM_STRSIZE];
char signal_strength[DLADM_STRSIZE];
uint32_t security_mode; /* a dladm_wlan_secmode_t */
} nwam_events_wlan_t;
typedef struct nwam_events_msg nwam_events_msg_t;
struct nwam_events_msg {
nwam_events_msg_t *next;
int32_t type;
int32_t size;
union {
struct {
int32_t obj_type; /* NWAM_NETWORK* */
char name[NWAM_NAMESIZE];
int32_t req_type;
} no_magic;
struct {
char message[80]; /* can be longer, must allocate structure */
} info;
struct {
/* assumed NWAM_NETWORK_OBJECT_IF */
char name[NWAM_NAMESIZE];
uint32_t flags;
uint32_t index;
uint32_t addr_valid; /* boolean */
struct sockaddr addr;
/* might be longer then sizeof(if_state) for addr */
} if_state;
struct {
/* assumed NWAM_NETWORK_OBJECT_LINK */
char name[NWAM_NAMESIZE];
int32_t link_state; /* link_state_t from sys/mac.h */
} link_state;
struct {
/* object referred to by message type has been removed */
char name[NWAM_NAMESIZE];
} removed;
struct {
/* assumed NWAM_NETWORK_OBJECT_LINK */
char name[NWAM_NAMESIZE];
uint16_t num_wlans;
nwam_events_wlan_t wlans[1];
/* space is allocated by user here for the number of wlans */
} wlan_scan;
} data;
};
Note: I think
we need to distinguish different NO_MAGIC events based on their type. For
example, we can have a NO_MAGIC event because we don't have any
previously-visited WLANs to connect to in a set of WLANs returned from
a scan, and we can have a NO_MAGIC event if we have a secured WLAN to connect
to, but no key. More specification of NO_MAGIC event.
typedef int (*nwam_events_callback_t)(nwam_events_msg_t *msg, int msg_size, int flags);
int nwam_events_register(nwam_events_callback_t cb, pthread_t *ptid);
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 |