5. Network Auto-Magic Data Structures & APIs

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.

5.1 Common Definitions, Data Structures and Functions

Global flags used for functions that access persistent storage:

#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
The following functions and definitions are provided to build and parse these strings.

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

5.2 NCPs and NCUs

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:

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.

The following functions may be used to manipulate NCU properties.

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.

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.

5.3 Locations

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:

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.

The following functions may be used to manipulate location properties.

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.

5.4 External Network Modifiers (ENMs)

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:

Once an ENM handle has been obtained, various operations are allowed on the ENM.

The following functions may be used to manipulate ENM properties.

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.

5.5 Known WLANs

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:

Once a Known WLAN handle has been obtained, the following operations are allowed on the Known WLAN.

The following functions may be used to manipulate a Known WLAN's properties.

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.

5.6 Event Notifications

5.7 Internal API Framework: Repository Transactions

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 History

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