xref: /onnv-gate/usr/src/cmd/cmd-inet/lib/nwamd/loc.c (revision 12923:eb113dc3db0b)
111767SAnurag.Maskey@Sun.COM /*
211767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
311767SAnurag.Maskey@Sun.COM  *
411767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
511767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
611767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
711767SAnurag.Maskey@Sun.COM  *
811767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
1111767SAnurag.Maskey@Sun.COM  * and limitations under the License.
1211767SAnurag.Maskey@Sun.COM  *
1311767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811767SAnurag.Maskey@Sun.COM  *
1911767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
2011767SAnurag.Maskey@Sun.COM  */
2111767SAnurag.Maskey@Sun.COM 
2211767SAnurag.Maskey@Sun.COM /*
2312274SAnurag.Maskey@Oracle.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2411767SAnurag.Maskey@Sun.COM  */
2511767SAnurag.Maskey@Sun.COM 
2611767SAnurag.Maskey@Sun.COM #include <arpa/inet.h>
2711767SAnurag.Maskey@Sun.COM #include <errno.h>
2811767SAnurag.Maskey@Sun.COM #include <inet/ip.h>
2911767SAnurag.Maskey@Sun.COM #include <libdladm.h>
3011767SAnurag.Maskey@Sun.COM #include <libdllink.h>
3111767SAnurag.Maskey@Sun.COM #include <libdlwlan.h>
3211767SAnurag.Maskey@Sun.COM #include <libscf.h>
3311767SAnurag.Maskey@Sun.COM #include <limits.h>
3411767SAnurag.Maskey@Sun.COM #include <netdb.h>
3511767SAnurag.Maskey@Sun.COM #include <netinet/in.h>
3611767SAnurag.Maskey@Sun.COM #include <stdio.h>
3711767SAnurag.Maskey@Sun.COM #include <stdlib.h>
3811767SAnurag.Maskey@Sun.COM #include <string.h>
3911767SAnurag.Maskey@Sun.COM #include <sys/socket.h>
4011767SAnurag.Maskey@Sun.COM #include <sys/types.h>
4111767SAnurag.Maskey@Sun.COM 
4211767SAnurag.Maskey@Sun.COM #include <libnwam.h>
4311767SAnurag.Maskey@Sun.COM #include "conditions.h"
4411767SAnurag.Maskey@Sun.COM #include "events.h"
4511767SAnurag.Maskey@Sun.COM #include "objects.h"
4611767SAnurag.Maskey@Sun.COM #include "util.h"
4711767SAnurag.Maskey@Sun.COM 
4811767SAnurag.Maskey@Sun.COM /*
4911767SAnurag.Maskey@Sun.COM  * loc.c - contains routines which handle location abstraction.
5011767SAnurag.Maskey@Sun.COM  */
5111767SAnurag.Maskey@Sun.COM 
5211767SAnurag.Maskey@Sun.COM pthread_mutex_t active_loc_mutex = PTHREAD_MUTEX_INITIALIZER;
5311767SAnurag.Maskey@Sun.COM char active_loc[NWAM_MAX_NAME_LEN];
5411767SAnurag.Maskey@Sun.COM 
5511767SAnurag.Maskey@Sun.COM static int
loc_create_init_fini_event(nwam_loc_handle_t loch,void * data)5611767SAnurag.Maskey@Sun.COM loc_create_init_fini_event(nwam_loc_handle_t loch, void *data)
5711767SAnurag.Maskey@Sun.COM {
5811767SAnurag.Maskey@Sun.COM 	boolean_t *init = data;
5911767SAnurag.Maskey@Sun.COM 	char *name;
6011767SAnurag.Maskey@Sun.COM 	nwamd_event_t event;
6111767SAnurag.Maskey@Sun.COM 
6211767SAnurag.Maskey@Sun.COM 	if (nwam_loc_get_name(loch, &name) != NWAM_SUCCESS) {
6311767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "loc_init_fini: could not get loc name");
6411767SAnurag.Maskey@Sun.COM 		return (0);
6511767SAnurag.Maskey@Sun.COM 	}
6611767SAnurag.Maskey@Sun.COM 
6711767SAnurag.Maskey@Sun.COM 	event = nwamd_event_init(*init ?
6811767SAnurag.Maskey@Sun.COM 	    NWAM_EVENT_TYPE_OBJECT_INIT : NWAM_EVENT_TYPE_OBJECT_FINI,
6911767SAnurag.Maskey@Sun.COM 	    NWAM_OBJECT_TYPE_LOC, 0, name);
7011767SAnurag.Maskey@Sun.COM 	if (event != NULL)
7111767SAnurag.Maskey@Sun.COM 		nwamd_event_enqueue(event);
7211767SAnurag.Maskey@Sun.COM 	free(name);
7311767SAnurag.Maskey@Sun.COM 
7411767SAnurag.Maskey@Sun.COM 	return (0);
7511767SAnurag.Maskey@Sun.COM }
7611767SAnurag.Maskey@Sun.COM 
7711767SAnurag.Maskey@Sun.COM /*
7811767SAnurag.Maskey@Sun.COM  * Walk all locs, creating init events for each.
7911767SAnurag.Maskey@Sun.COM  */
8011767SAnurag.Maskey@Sun.COM void
nwamd_init_locs(void)8111767SAnurag.Maskey@Sun.COM nwamd_init_locs(void)
8211767SAnurag.Maskey@Sun.COM {
8311767SAnurag.Maskey@Sun.COM 	boolean_t init = B_TRUE;
8411767SAnurag.Maskey@Sun.COM 
8511767SAnurag.Maskey@Sun.COM 	/* Unset active location */
8611767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&active_loc_mutex);
8711767SAnurag.Maskey@Sun.COM 	active_loc[0] = '\0';
8811767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&active_loc_mutex);
8911767SAnurag.Maskey@Sun.COM 	(void) nwam_walk_locs(loc_create_init_fini_event, &init, 0, NULL);
9011767SAnurag.Maskey@Sun.COM }
9111767SAnurag.Maskey@Sun.COM 
9211767SAnurag.Maskey@Sun.COM /*
9311767SAnurag.Maskey@Sun.COM  * Walk all locs, creating fini events for each.
9411767SAnurag.Maskey@Sun.COM  */
9511767SAnurag.Maskey@Sun.COM void
nwamd_fini_locs(void)9611767SAnurag.Maskey@Sun.COM nwamd_fini_locs(void)
9711767SAnurag.Maskey@Sun.COM {
9811767SAnurag.Maskey@Sun.COM 	boolean_t init = B_FALSE;
9911767SAnurag.Maskey@Sun.COM 
10011767SAnurag.Maskey@Sun.COM 	(void) nwam_walk_locs(loc_create_init_fini_event, &init, 0, NULL);
10111767SAnurag.Maskey@Sun.COM }
10211767SAnurag.Maskey@Sun.COM 
10311767SAnurag.Maskey@Sun.COM static boolean_t
loc_is_enabled(nwam_loc_handle_t loch)10411767SAnurag.Maskey@Sun.COM loc_is_enabled(nwam_loc_handle_t loch)
10511767SAnurag.Maskey@Sun.COM {
10611767SAnurag.Maskey@Sun.COM 	nwam_value_t enabledval;
10711767SAnurag.Maskey@Sun.COM 	boolean_t enabled = B_FALSE;
10811767SAnurag.Maskey@Sun.COM 
10911767SAnurag.Maskey@Sun.COM 	if (nwam_loc_get_prop_value(loch, NWAM_LOC_PROP_ENABLED,
11011767SAnurag.Maskey@Sun.COM 	    &enabledval) != NWAM_SUCCESS) {
11111767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "loc_is_enabled: could not retrieve "
11211767SAnurag.Maskey@Sun.COM 		    "enabled value");
11311767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
11411767SAnurag.Maskey@Sun.COM 	}
11511767SAnurag.Maskey@Sun.COM 	if (nwam_value_get_boolean(enabledval, &enabled)
11611767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
11711767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "loc_is_enabled: could not retrieve "
11811767SAnurag.Maskey@Sun.COM 		    "enabled value");
11911767SAnurag.Maskey@Sun.COM 		nwam_value_free(enabledval);
12011767SAnurag.Maskey@Sun.COM 		return (B_FALSE);
12111767SAnurag.Maskey@Sun.COM 	}
12211767SAnurag.Maskey@Sun.COM 	nwam_value_free(enabledval);
12311767SAnurag.Maskey@Sun.COM 	return (enabled);
12411767SAnurag.Maskey@Sun.COM }
12511767SAnurag.Maskey@Sun.COM 
12611767SAnurag.Maskey@Sun.COM static int64_t
loc_get_activation_mode(nwam_loc_handle_t loch)12711767SAnurag.Maskey@Sun.COM loc_get_activation_mode(nwam_loc_handle_t loch)
12811767SAnurag.Maskey@Sun.COM {
12911767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
13011767SAnurag.Maskey@Sun.COM 	uint64_t activation;
13111767SAnurag.Maskey@Sun.COM 	nwam_value_t activationval;
13211767SAnurag.Maskey@Sun.COM 
13311767SAnurag.Maskey@Sun.COM 	if (nwam_loc_get_prop_value(loch, NWAM_LOC_PROP_ACTIVATION_MODE,
13411767SAnurag.Maskey@Sun.COM 	    &activationval)  != NWAM_SUCCESS) {
13511767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "loc_get_activation_mode: could not retrieve "
13611767SAnurag.Maskey@Sun.COM 		    "activation mode value");
13711767SAnurag.Maskey@Sun.COM 		return (-1);
13811767SAnurag.Maskey@Sun.COM 	}
13911767SAnurag.Maskey@Sun.COM 	err = nwam_value_get_uint64(activationval, &activation);
14011767SAnurag.Maskey@Sun.COM 	nwam_value_free(activationval);
14111767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
14211767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "loc_get_activation_mode: could not retrieve "
14311767SAnurag.Maskey@Sun.COM 		    "activation mode value");
14411767SAnurag.Maskey@Sun.COM 		return (-1);
14511767SAnurag.Maskey@Sun.COM 	}
14611767SAnurag.Maskey@Sun.COM 
14711767SAnurag.Maskey@Sun.COM 	return ((int64_t)activation);
14811767SAnurag.Maskey@Sun.COM }
14911767SAnurag.Maskey@Sun.COM 
15011767SAnurag.Maskey@Sun.COM /* Enables the location. */
15111767SAnurag.Maskey@Sun.COM static void
nwamd_loc_activate(const char * object_name)15211767SAnurag.Maskey@Sun.COM nwamd_loc_activate(const char *object_name)
15311767SAnurag.Maskey@Sun.COM {
15411767SAnurag.Maskey@Sun.COM 	char *enabled;
15511767SAnurag.Maskey@Sun.COM 
15611767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG, "nwamd_loc_activate: activating loc %s",
15711767SAnurag.Maskey@Sun.COM 	    object_name);
15811767SAnurag.Maskey@Sun.COM 
15911767SAnurag.Maskey@Sun.COM 	/*
16011767SAnurag.Maskey@Sun.COM 	 * Find currently enabled location and change its state to disabled
16111767SAnurag.Maskey@Sun.COM 	 * if it is a manual location, or offline (if it is not).
16211767SAnurag.Maskey@Sun.COM 	 * Only manual locations reach disabled, since conditional and
16311767SAnurag.Maskey@Sun.COM 	 * system locations which are manually disabled simply revert to
16411767SAnurag.Maskey@Sun.COM 	 * their conditions for activation.
16511767SAnurag.Maskey@Sun.COM 	 */
16611767SAnurag.Maskey@Sun.COM 	if ((enabled = malloc(NWAM_MAX_NAME_LEN)) != NULL &&
16711767SAnurag.Maskey@Sun.COM 	    nwamd_lookup_string_property(NET_LOC_FMRI, NET_LOC_PG,
16811767SAnurag.Maskey@Sun.COM 	    NET_LOC_SELECTED_PROP, enabled, NWAM_MAX_NAME_LEN) == 0) {
16911767SAnurag.Maskey@Sun.COM 		/* Only change state if current != new */
17011767SAnurag.Maskey@Sun.COM 		if (strcmp(enabled, object_name) != 0) {
17111767SAnurag.Maskey@Sun.COM 			boolean_t do_disable = B_FALSE;
17211767SAnurag.Maskey@Sun.COM 			nwamd_object_t eobj = nwamd_object_find
17311767SAnurag.Maskey@Sun.COM 			    (NWAM_OBJECT_TYPE_LOC, enabled);
17411767SAnurag.Maskey@Sun.COM 			if (eobj == NULL) {
17512274SAnurag.Maskey@Oracle.COM 				nlog(LOG_INFO, "nwamd_loc_activate: could not "
17611767SAnurag.Maskey@Sun.COM 				    "find old location %s", enabled);
17712274SAnurag.Maskey@Oracle.COM 				goto skip_disable;
17811767SAnurag.Maskey@Sun.COM 			}
17911767SAnurag.Maskey@Sun.COM 			/*
18011767SAnurag.Maskey@Sun.COM 			 * Disable if the old location was manual, since the
18111767SAnurag.Maskey@Sun.COM 			 * only way a manual location can deactivate is if
18211767SAnurag.Maskey@Sun.COM 			 * it is disabled.
18311767SAnurag.Maskey@Sun.COM 			 */
18411767SAnurag.Maskey@Sun.COM 			do_disable =
18511767SAnurag.Maskey@Sun.COM 			    (loc_get_activation_mode(eobj->nwamd_object_handle)
18611767SAnurag.Maskey@Sun.COM 			    == (int64_t)NWAM_ACTIVATION_MODE_MANUAL);
18711767SAnurag.Maskey@Sun.COM 			nwamd_object_release(eobj);
18811767SAnurag.Maskey@Sun.COM 
18911767SAnurag.Maskey@Sun.COM 			if (do_disable) {
19011767SAnurag.Maskey@Sun.COM 				nlog(LOG_DEBUG, "nwamd_loc_activate: "
19111767SAnurag.Maskey@Sun.COM 				    "disable needed for old location %s",
19211767SAnurag.Maskey@Sun.COM 				    enabled);
19311767SAnurag.Maskey@Sun.COM 				nwamd_object_set_state
19411767SAnurag.Maskey@Sun.COM 				    (NWAM_OBJECT_TYPE_LOC, enabled,
19511767SAnurag.Maskey@Sun.COM 				    NWAM_STATE_DISABLED,
19611767SAnurag.Maskey@Sun.COM 				    NWAM_AUX_STATE_MANUAL_DISABLE);
19711767SAnurag.Maskey@Sun.COM 			} else {
19811767SAnurag.Maskey@Sun.COM 				nlog(LOG_DEBUG, "nwamd_loc_activate: "
19911767SAnurag.Maskey@Sun.COM 				    "offline needed for old location %s",
20011767SAnurag.Maskey@Sun.COM 				    enabled);
20111767SAnurag.Maskey@Sun.COM 				nwamd_object_set_state
20211767SAnurag.Maskey@Sun.COM 				    (NWAM_OBJECT_TYPE_LOC, enabled,
20311767SAnurag.Maskey@Sun.COM 				    NWAM_STATE_OFFLINE,
20411767SAnurag.Maskey@Sun.COM 				    NWAM_AUX_STATE_CONDITIONS_NOT_MET);
20511767SAnurag.Maskey@Sun.COM 			}
20611767SAnurag.Maskey@Sun.COM 		}
20711767SAnurag.Maskey@Sun.COM 	}
20812274SAnurag.Maskey@Oracle.COM skip_disable:
20911767SAnurag.Maskey@Sun.COM 	free(enabled);
21011767SAnurag.Maskey@Sun.COM 
21111767SAnurag.Maskey@Sun.COM 	if (nwamd_set_string_property(NET_LOC_FMRI, NET_LOC_PG,
21211767SAnurag.Maskey@Sun.COM 	    NET_LOC_SELECTED_PROP, object_name) == 0) {
21311767SAnurag.Maskey@Sun.COM 		char *state = smf_get_state(NET_LOC_FMRI);
21412274SAnurag.Maskey@Oracle.COM 		nlog(LOG_INFO, "nwamd_loc_activate: set %s/%s to %s; "
21511767SAnurag.Maskey@Sun.COM 		    "service is in %s state", NET_LOC_PG, NET_LOC_SELECTED_PROP,
21611767SAnurag.Maskey@Sun.COM 		    object_name, state == NULL ? "unknown" : state);
21711767SAnurag.Maskey@Sun.COM 		free(state);
21811767SAnurag.Maskey@Sun.COM 		(void) smf_restore_instance(NET_LOC_FMRI);
21911767SAnurag.Maskey@Sun.COM 		if (smf_refresh_instance(NET_LOC_FMRI) == 0) {
22011767SAnurag.Maskey@Sun.COM 			(void) pthread_mutex_lock(&active_loc_mutex);
22111767SAnurag.Maskey@Sun.COM 			(void) strlcpy(active_loc, object_name,
22211767SAnurag.Maskey@Sun.COM 			    sizeof (active_loc));
22311767SAnurag.Maskey@Sun.COM 			(void) pthread_mutex_unlock(&active_loc_mutex);
22411767SAnurag.Maskey@Sun.COM 			nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
22511767SAnurag.Maskey@Sun.COM 			    object_name,
22611767SAnurag.Maskey@Sun.COM 			    NWAM_STATE_ONLINE, NWAM_AUX_STATE_ACTIVE);
22711767SAnurag.Maskey@Sun.COM 		} else {
22811767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_loc_activate: "
22911767SAnurag.Maskey@Sun.COM 			    "%s could not be refreshed", NET_LOC_FMRI);
23011767SAnurag.Maskey@Sun.COM 			nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
23111767SAnurag.Maskey@Sun.COM 			    object_name,
23211767SAnurag.Maskey@Sun.COM 			    NWAM_STATE_MAINTENANCE,
23311767SAnurag.Maskey@Sun.COM 			    NWAM_AUX_STATE_METHOD_FAILED);
23411767SAnurag.Maskey@Sun.COM 		}
23511767SAnurag.Maskey@Sun.COM 	}
23611767SAnurag.Maskey@Sun.COM }
23711767SAnurag.Maskey@Sun.COM 
23811767SAnurag.Maskey@Sun.COM struct nwamd_loc_check_walk_arg {
23911767SAnurag.Maskey@Sun.COM 	nwamd_object_t winning_object;
24011767SAnurag.Maskey@Sun.COM 	uint64_t winning_rating;
24111767SAnurag.Maskey@Sun.COM };
24211767SAnurag.Maskey@Sun.COM 
24311767SAnurag.Maskey@Sun.COM /*
24411767SAnurag.Maskey@Sun.COM  * Determine which location should be activated.
24511767SAnurag.Maskey@Sun.COM  */
24611767SAnurag.Maskey@Sun.COM static int
nwamd_loc_check(nwamd_object_t object,void * data)24711767SAnurag.Maskey@Sun.COM nwamd_loc_check(nwamd_object_t object, void *data)
24811767SAnurag.Maskey@Sun.COM {
24911767SAnurag.Maskey@Sun.COM 	struct nwamd_loc_check_walk_arg *wa = data;
25011767SAnurag.Maskey@Sun.COM 	nwam_loc_handle_t loch = object->nwamd_object_handle;
25111767SAnurag.Maskey@Sun.COM 	nwam_value_t conditionval;
25211767SAnurag.Maskey@Sun.COM 	int64_t lactivation;
25311767SAnurag.Maskey@Sun.COM 	uint64_t rating, activation;
25411767SAnurag.Maskey@Sun.COM 	boolean_t satisfied;
25511767SAnurag.Maskey@Sun.COM 	char **conditions;
25611767SAnurag.Maskey@Sun.COM 	uint_t nelem;
25711767SAnurag.Maskey@Sun.COM 
25811767SAnurag.Maskey@Sun.COM 	lactivation = loc_get_activation_mode(object->nwamd_object_handle);
25911767SAnurag.Maskey@Sun.COM 
26011767SAnurag.Maskey@Sun.COM 	if (lactivation == -1)
26111767SAnurag.Maskey@Sun.COM 		return (0);
26211767SAnurag.Maskey@Sun.COM 
26311767SAnurag.Maskey@Sun.COM 	activation = (uint64_t)lactivation;
26411767SAnurag.Maskey@Sun.COM 	switch (activation) {
26511767SAnurag.Maskey@Sun.COM 	case NWAM_ACTIVATION_MODE_MANUAL:
26611767SAnurag.Maskey@Sun.COM 		if (loc_is_enabled(loch)) {
26711767SAnurag.Maskey@Sun.COM 			/* Manually enabled locations should always win out. */
26811767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_loc_check: %s is enabled",
26911767SAnurag.Maskey@Sun.COM 			    object->nwamd_object_name);
27011767SAnurag.Maskey@Sun.COM 			wa->winning_object = object;
27111767SAnurag.Maskey@Sun.COM 			wa->winning_rating = UINT64_MAX;
27211767SAnurag.Maskey@Sun.COM 		} else {
27311767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_loc_check: %s is disabled",
27411767SAnurag.Maskey@Sun.COM 			    object->nwamd_object_name);
27511767SAnurag.Maskey@Sun.COM 			if (object->nwamd_object_state != NWAM_STATE_DISABLED) {
27611767SAnurag.Maskey@Sun.COM 				nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
27711767SAnurag.Maskey@Sun.COM 				    object->nwamd_object_name,
27811767SAnurag.Maskey@Sun.COM 				    NWAM_STATE_DISABLED,
27911767SAnurag.Maskey@Sun.COM 				    NWAM_AUX_STATE_MANUAL_DISABLE);
28011767SAnurag.Maskey@Sun.COM 			}
28111767SAnurag.Maskey@Sun.COM 		}
28211767SAnurag.Maskey@Sun.COM 
28311767SAnurag.Maskey@Sun.COM 		return (0);
28411767SAnurag.Maskey@Sun.COM 
28511767SAnurag.Maskey@Sun.COM 	case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY:
28611767SAnurag.Maskey@Sun.COM 	case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL:
28711767SAnurag.Maskey@Sun.COM 		if (loc_is_enabled(loch)) {
28811767SAnurag.Maskey@Sun.COM 			/* Manually enabled locations should always win out. */
28911767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_loc_check: %s is enabled",
29011767SAnurag.Maskey@Sun.COM 			    object->nwamd_object_name);
29111767SAnurag.Maskey@Sun.COM 			wa->winning_object = object;
29211767SAnurag.Maskey@Sun.COM 			wa->winning_rating = UINT64_MAX;
29311767SAnurag.Maskey@Sun.COM 		}
29411767SAnurag.Maskey@Sun.COM 
29511767SAnurag.Maskey@Sun.COM 		if (nwam_loc_get_prop_value(loch,
29611767SAnurag.Maskey@Sun.COM 		    NWAM_LOC_PROP_CONDITIONS, &conditionval) != NWAM_SUCCESS) {
29711767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_loc_check: could not retrieve "
29811767SAnurag.Maskey@Sun.COM 			    "condition value");
29911767SAnurag.Maskey@Sun.COM 			return (0);
30011767SAnurag.Maskey@Sun.COM 		}
30111767SAnurag.Maskey@Sun.COM 		if (nwam_value_get_string_array(conditionval,
30211767SAnurag.Maskey@Sun.COM 		    &conditions, &nelem) != NWAM_SUCCESS) {
30311767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_loc_check: could not retrieve "
30411767SAnurag.Maskey@Sun.COM 			    "condition value");
30511767SAnurag.Maskey@Sun.COM 			nwam_value_free(conditionval);
30611767SAnurag.Maskey@Sun.COM 			return (0);
30711767SAnurag.Maskey@Sun.COM 		}
30811767SAnurag.Maskey@Sun.COM 		satisfied = nwamd_check_conditions(activation, conditions,
30911767SAnurag.Maskey@Sun.COM 		    nelem);
31011767SAnurag.Maskey@Sun.COM 
31111767SAnurag.Maskey@Sun.COM 		if (satisfied) {
31211767SAnurag.Maskey@Sun.COM 			rating = nwamd_rate_conditions(activation,
31311767SAnurag.Maskey@Sun.COM 			    conditions, nelem);
31411767SAnurag.Maskey@Sun.COM 			if (rating > wa->winning_rating) {
31511767SAnurag.Maskey@Sun.COM 				wa->winning_object = object;
31611767SAnurag.Maskey@Sun.COM 				wa->winning_rating = rating;
31711767SAnurag.Maskey@Sun.COM 			}
31811767SAnurag.Maskey@Sun.COM 		}
31911767SAnurag.Maskey@Sun.COM 		nwam_value_free(conditionval);
32011767SAnurag.Maskey@Sun.COM 		return (0);
32111767SAnurag.Maskey@Sun.COM 
32211767SAnurag.Maskey@Sun.COM 	case NWAM_ACTIVATION_MODE_SYSTEM:
32311767SAnurag.Maskey@Sun.COM 		if (loc_is_enabled(loch)) {
32411767SAnurag.Maskey@Sun.COM 			/* Manually enabled locations should always win out. */
32511767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_loc_check: %s is enabled",
32611767SAnurag.Maskey@Sun.COM 			    object->nwamd_object_name);
32711767SAnurag.Maskey@Sun.COM 			wa->winning_object = object;
32811767SAnurag.Maskey@Sun.COM 			wa->winning_rating = UINT64_MAX;
32911767SAnurag.Maskey@Sun.COM 		}
33011767SAnurag.Maskey@Sun.COM 
33111767SAnurag.Maskey@Sun.COM 		/* Either NoNet, Automatic or Legacy location, so skip. */
33211767SAnurag.Maskey@Sun.COM 
33311767SAnurag.Maskey@Sun.COM 		return (0);
33411767SAnurag.Maskey@Sun.COM 	default:
33511767SAnurag.Maskey@Sun.COM 		return (0);
33611767SAnurag.Maskey@Sun.COM 	}
33711767SAnurag.Maskey@Sun.COM 	/*NOTREACHED*/
33811767SAnurag.Maskey@Sun.COM 	return (0);
33911767SAnurag.Maskey@Sun.COM }
34011767SAnurag.Maskey@Sun.COM 
34111767SAnurag.Maskey@Sun.COM static int
nwamd_ncu_online_check(nwamd_object_t object,void * data)34211767SAnurag.Maskey@Sun.COM nwamd_ncu_online_check(nwamd_object_t object, void *data)
34311767SAnurag.Maskey@Sun.COM {
34411767SAnurag.Maskey@Sun.COM 	boolean_t *online = data;
34511767SAnurag.Maskey@Sun.COM 	nwamd_ncu_t *ncu_data = object->nwamd_object_data;
34611767SAnurag.Maskey@Sun.COM 
34711767SAnurag.Maskey@Sun.COM 	if (ncu_data->ncu_type != NWAM_NCU_TYPE_INTERFACE)
34811767SAnurag.Maskey@Sun.COM 		return (0);
34911767SAnurag.Maskey@Sun.COM 
35011767SAnurag.Maskey@Sun.COM 	if (object->nwamd_object_state == NWAM_STATE_ONLINE) {
35111767SAnurag.Maskey@Sun.COM 		/* An online IP NCU found, stop walk */
35211767SAnurag.Maskey@Sun.COM 		*online = B_TRUE;
35311767SAnurag.Maskey@Sun.COM 		return (1);
35411767SAnurag.Maskey@Sun.COM 	}
35511767SAnurag.Maskey@Sun.COM 	return (0);
35611767SAnurag.Maskey@Sun.COM }
35711767SAnurag.Maskey@Sun.COM 
35811767SAnurag.Maskey@Sun.COM void
nwamd_loc_check_conditions(void)35911767SAnurag.Maskey@Sun.COM nwamd_loc_check_conditions(void)
36011767SAnurag.Maskey@Sun.COM {
36111767SAnurag.Maskey@Sun.COM 	struct nwamd_loc_check_walk_arg wa = { NULL, 0 };
36211767SAnurag.Maskey@Sun.COM 	const char *winning_loc;
36311767SAnurag.Maskey@Sun.COM 	boolean_t ncu_online = B_FALSE;
36411767SAnurag.Maskey@Sun.COM 	boolean_t is_active;
36511767SAnurag.Maskey@Sun.COM 
36611767SAnurag.Maskey@Sun.COM 	/*
36711767SAnurag.Maskey@Sun.COM 	 * Walk the NCUs to find out if at least one IP NCU is online.  If so,
36811767SAnurag.Maskey@Sun.COM 	 * check the activation-mode and conditions.  If not, enable the NoNet
36911767SAnurag.Maskey@Sun.COM 	 * location.
37011767SAnurag.Maskey@Sun.COM 	 */
37111767SAnurag.Maskey@Sun.COM 	(void) nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU, nwamd_ncu_online_check,
37211767SAnurag.Maskey@Sun.COM 	    &ncu_online);
37311767SAnurag.Maskey@Sun.COM 
37411767SAnurag.Maskey@Sun.COM 	if (!ncu_online) {
37511767SAnurag.Maskey@Sun.COM 		winning_loc = NWAM_LOC_NAME_NO_NET;
37611767SAnurag.Maskey@Sun.COM 	} else {
37711767SAnurag.Maskey@Sun.COM 		(void) nwamd_walk_objects(NWAM_OBJECT_TYPE_LOC, nwamd_loc_check,
37811767SAnurag.Maskey@Sun.COM 		    &wa);
37911767SAnurag.Maskey@Sun.COM 		if (wa.winning_object != NULL)
38011767SAnurag.Maskey@Sun.COM 			winning_loc = wa.winning_object->nwamd_object_name;
38111767SAnurag.Maskey@Sun.COM 		else
38211767SAnurag.Maskey@Sun.COM 			winning_loc = NWAM_LOC_NAME_AUTOMATIC;
38311767SAnurag.Maskey@Sun.COM 	}
384*12923SRenee.Sommerfeld@Oracle.COM 	nlog(LOG_DEBUG, "nwamd_loc_check_conditions: winning loc is %s",
38511767SAnurag.Maskey@Sun.COM 	    winning_loc);
38611767SAnurag.Maskey@Sun.COM 
38711767SAnurag.Maskey@Sun.COM 	/* If the winning location is already active, do nothing */
38811767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&active_loc_mutex);
38911767SAnurag.Maskey@Sun.COM 	is_active = (strcmp(active_loc, winning_loc) == 0);
39011767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&active_loc_mutex);
39111767SAnurag.Maskey@Sun.COM 	if (is_active)
39211767SAnurag.Maskey@Sun.COM 		return;
39311767SAnurag.Maskey@Sun.COM 
39411767SAnurag.Maskey@Sun.COM 	nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC, winning_loc,
39511767SAnurag.Maskey@Sun.COM 	    NWAM_STATE_OFFLINE_TO_ONLINE, NWAM_AUX_STATE_METHOD_RUNNING);
39611767SAnurag.Maskey@Sun.COM }
39711767SAnurag.Maskey@Sun.COM 
39811767SAnurag.Maskey@Sun.COM int
nwamd_loc_action(const char * loc,nwam_action_t action)39911767SAnurag.Maskey@Sun.COM nwamd_loc_action(const char *loc, nwam_action_t action)
40011767SAnurag.Maskey@Sun.COM {
40111767SAnurag.Maskey@Sun.COM 	nwamd_event_t event = nwamd_event_init_object_action
40211767SAnurag.Maskey@Sun.COM 	    (NWAM_OBJECT_TYPE_LOC, loc, NULL, action);
40311767SAnurag.Maskey@Sun.COM 	if (event == NULL)
40411767SAnurag.Maskey@Sun.COM 		return (1);
40511767SAnurag.Maskey@Sun.COM 	nwamd_event_enqueue(event);
40611767SAnurag.Maskey@Sun.COM 	return (0);
40711767SAnurag.Maskey@Sun.COM }
40811767SAnurag.Maskey@Sun.COM 
40911767SAnurag.Maskey@Sun.COM /*
41011767SAnurag.Maskey@Sun.COM  * Event handling functions.
41111767SAnurag.Maskey@Sun.COM  */
41211767SAnurag.Maskey@Sun.COM 
41311767SAnurag.Maskey@Sun.COM /* Handle loc initialization/refresh event */
41411767SAnurag.Maskey@Sun.COM void
nwamd_loc_handle_init_event(nwamd_event_t event)41511767SAnurag.Maskey@Sun.COM nwamd_loc_handle_init_event(nwamd_event_t event)
41611767SAnurag.Maskey@Sun.COM {
41711767SAnurag.Maskey@Sun.COM 	nwamd_object_t object;
41811767SAnurag.Maskey@Sun.COM 	nwam_loc_handle_t loch;
41911767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
42012526SAnurag.Maskey@Oracle.COM 	boolean_t new_enabled, old_enabled = B_FALSE;
42111767SAnurag.Maskey@Sun.COM 	nwam_state_t state;
42211767SAnurag.Maskey@Sun.COM 
42311767SAnurag.Maskey@Sun.COM 	if ((err = nwam_loc_read(event->event_object, 0, &loch))
42411767SAnurag.Maskey@Sun.COM 	    != NWAM_SUCCESS) {
42511767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_loc_handle_init_event: could not "
42611767SAnurag.Maskey@Sun.COM 		    "read object '%s': %s", event->event_object,
42711767SAnurag.Maskey@Sun.COM 		    nwam_strerror(err));
42811767SAnurag.Maskey@Sun.COM 		nwamd_event_do_not_send(event);
42911767SAnurag.Maskey@Sun.COM 		return;
43011767SAnurag.Maskey@Sun.COM 	}
43111767SAnurag.Maskey@Sun.COM 	if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_LOC,
43211767SAnurag.Maskey@Sun.COM 	    event->event_object)) != NULL) {
43312526SAnurag.Maskey@Oracle.COM 		old_enabled = loc_is_enabled(object->nwamd_object_handle);
43411767SAnurag.Maskey@Sun.COM 		nwam_loc_free(object->nwamd_object_handle);
43511767SAnurag.Maskey@Sun.COM 		object->nwamd_object_handle = loch;
43611767SAnurag.Maskey@Sun.COM 	} else {
43711767SAnurag.Maskey@Sun.COM 		object = nwamd_object_init(NWAM_OBJECT_TYPE_LOC,
43811767SAnurag.Maskey@Sun.COM 		    event->event_object, loch, NULL);
43911767SAnurag.Maskey@Sun.COM 		object->nwamd_object_state = NWAM_STATE_OFFLINE;
44011767SAnurag.Maskey@Sun.COM 		object->nwamd_object_aux_state =
44111767SAnurag.Maskey@Sun.COM 		    NWAM_AUX_STATE_CONDITIONS_NOT_MET;
44211767SAnurag.Maskey@Sun.COM 	}
44312526SAnurag.Maskey@Oracle.COM 	new_enabled = loc_is_enabled(loch);
44411767SAnurag.Maskey@Sun.COM 	state = object->nwamd_object_state;
44511767SAnurag.Maskey@Sun.COM 	nwamd_object_release(object);
44611767SAnurag.Maskey@Sun.COM 
44711767SAnurag.Maskey@Sun.COM 	/*
44812526SAnurag.Maskey@Oracle.COM 	 * If this location is ONLINE and the value of the "enabled" property
44912526SAnurag.Maskey@Oracle.COM 	 * has not changed, then this location is getting refreshed because it
45012526SAnurag.Maskey@Oracle.COM 	 * was committed with changes.  Change states to re-activate itself.
45112526SAnurag.Maskey@Oracle.COM 	 * If the "enabled" property has changed, then this location is
45212526SAnurag.Maskey@Oracle.COM 	 * getting refreshed as part of a enable/disable action and there is
45312526SAnurag.Maskey@Oracle.COM 	 * no need to change states here.
45411767SAnurag.Maskey@Sun.COM 	 */
45512526SAnurag.Maskey@Oracle.COM 	if (state == NWAM_STATE_ONLINE && old_enabled == new_enabled) {
45611767SAnurag.Maskey@Sun.COM 		nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
45711767SAnurag.Maskey@Sun.COM 		    event->event_object, NWAM_STATE_OFFLINE_TO_ONLINE,
45811767SAnurag.Maskey@Sun.COM 		    NWAM_AUX_STATE_METHOD_RUNNING);
45911767SAnurag.Maskey@Sun.COM 	}
46011767SAnurag.Maskey@Sun.COM }
46111767SAnurag.Maskey@Sun.COM 
46211767SAnurag.Maskey@Sun.COM /* Handle loc finish event */
46311767SAnurag.Maskey@Sun.COM void
nwamd_loc_handle_fini_event(nwamd_event_t event)46411767SAnurag.Maskey@Sun.COM nwamd_loc_handle_fini_event(nwamd_event_t event)
46511767SAnurag.Maskey@Sun.COM {
46611767SAnurag.Maskey@Sun.COM 	nwamd_object_t object;
46711767SAnurag.Maskey@Sun.COM 
46811767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG, "nwamd_loc_handle_fini_event(%s)",
46911767SAnurag.Maskey@Sun.COM 	    event->event_object);
47011767SAnurag.Maskey@Sun.COM 
47111767SAnurag.Maskey@Sun.COM 	/* Don't disable the location, as this can enable the Automatic loc */
47211767SAnurag.Maskey@Sun.COM 	if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_LOC,
47311767SAnurag.Maskey@Sun.COM 	    event->event_object)) == NULL) {
474*12923SRenee.Sommerfeld@Oracle.COM 		nlog(LOG_INFO, "nwamd_loc_handle_fini_event: "
47511767SAnurag.Maskey@Sun.COM 		    "loc %s not found", event->event_object);
47611767SAnurag.Maskey@Sun.COM 		nwamd_event_do_not_send(event);
47711767SAnurag.Maskey@Sun.COM 		return;
47811767SAnurag.Maskey@Sun.COM 	}
47911767SAnurag.Maskey@Sun.COM 	nwamd_object_release_and_destroy(object);
48011767SAnurag.Maskey@Sun.COM }
48111767SAnurag.Maskey@Sun.COM 
48211767SAnurag.Maskey@Sun.COM void
nwamd_loc_handle_action_event(nwamd_event_t event)48311767SAnurag.Maskey@Sun.COM nwamd_loc_handle_action_event(nwamd_event_t event)
48411767SAnurag.Maskey@Sun.COM {
48511767SAnurag.Maskey@Sun.COM 	nwamd_object_t object;
48611767SAnurag.Maskey@Sun.COM 
48711767SAnurag.Maskey@Sun.COM 	switch (event->event_msg->nwe_data.nwe_object_action.nwe_action) {
48811767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ENABLE:
48911767SAnurag.Maskey@Sun.COM 		object = nwamd_object_find(NWAM_OBJECT_TYPE_LOC,
49011767SAnurag.Maskey@Sun.COM 		    event->event_object);
49111767SAnurag.Maskey@Sun.COM 		if (object == NULL) {
49211767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_loc_handle_action_event: "
49311767SAnurag.Maskey@Sun.COM 			    "could not find location %s", event->event_object);
49411767SAnurag.Maskey@Sun.COM 			nwamd_event_do_not_send(event);
49511767SAnurag.Maskey@Sun.COM 			return;
49611767SAnurag.Maskey@Sun.COM 		}
49711767SAnurag.Maskey@Sun.COM 		if (object->nwamd_object_state == NWAM_STATE_ONLINE) {
49811767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_loc_handle_action_event: "
49911767SAnurag.Maskey@Sun.COM 			    "location %s already online, nothing to do",
50011767SAnurag.Maskey@Sun.COM 			    event->event_object);
50111767SAnurag.Maskey@Sun.COM 			nwamd_object_release(object);
50211767SAnurag.Maskey@Sun.COM 			return;
50311767SAnurag.Maskey@Sun.COM 		}
50411767SAnurag.Maskey@Sun.COM 		nwamd_object_release(object);
50511767SAnurag.Maskey@Sun.COM 
50611767SAnurag.Maskey@Sun.COM 		nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
50711767SAnurag.Maskey@Sun.COM 		    event->event_object, NWAM_STATE_OFFLINE_TO_ONLINE,
50811767SAnurag.Maskey@Sun.COM 		    NWAM_AUX_STATE_METHOD_RUNNING);
50911767SAnurag.Maskey@Sun.COM 		break;
51011767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DISABLE:
51111767SAnurag.Maskey@Sun.COM 		object = nwamd_object_find(NWAM_OBJECT_TYPE_LOC,
51211767SAnurag.Maskey@Sun.COM 		    event->event_object);
51311767SAnurag.Maskey@Sun.COM 		if (object == NULL) {
51411767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_loc_handle_action_event: "
51511767SAnurag.Maskey@Sun.COM 			    "could not find location %s", event->event_object);
51611767SAnurag.Maskey@Sun.COM 			nwamd_event_do_not_send(event);
51711767SAnurag.Maskey@Sun.COM 			return;
51811767SAnurag.Maskey@Sun.COM 		}
51911767SAnurag.Maskey@Sun.COM 		if (object->nwamd_object_state == NWAM_STATE_DISABLED) {
52011767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_loc_handle_action_event: "
52111767SAnurag.Maskey@Sun.COM 			    "location %s already disabled, nothing to do",
52211767SAnurag.Maskey@Sun.COM 			    event->event_object);
52311767SAnurag.Maskey@Sun.COM 			nwamd_object_release(object);
52411767SAnurag.Maskey@Sun.COM 			return;
52511767SAnurag.Maskey@Sun.COM 		}
52611767SAnurag.Maskey@Sun.COM 		nwamd_object_release(object);
52711767SAnurag.Maskey@Sun.COM 
52811767SAnurag.Maskey@Sun.COM 		nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
52911767SAnurag.Maskey@Sun.COM 		    event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
53011767SAnurag.Maskey@Sun.COM 		    NWAM_AUX_STATE_MANUAL_DISABLE);
53111767SAnurag.Maskey@Sun.COM 		break;
53211767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ADD:
53311767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_REFRESH:
53411767SAnurag.Maskey@Sun.COM 		nwamd_loc_handle_init_event(event);
53511767SAnurag.Maskey@Sun.COM 		break;
53611767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DESTROY:
53711767SAnurag.Maskey@Sun.COM 		nwamd_loc_handle_fini_event(event);
53811767SAnurag.Maskey@Sun.COM 		break;
53911767SAnurag.Maskey@Sun.COM 	default:
54011767SAnurag.Maskey@Sun.COM 		nlog(LOG_INFO, "nwam_loc_handle_action_event: "
54111767SAnurag.Maskey@Sun.COM 		    "unexpected action");
54211767SAnurag.Maskey@Sun.COM 		break;
54311767SAnurag.Maskey@Sun.COM 	}
54411767SAnurag.Maskey@Sun.COM }
54511767SAnurag.Maskey@Sun.COM 
54611767SAnurag.Maskey@Sun.COM void
nwamd_loc_handle_state_event(nwamd_event_t event)54711767SAnurag.Maskey@Sun.COM nwamd_loc_handle_state_event(nwamd_event_t event)
54811767SAnurag.Maskey@Sun.COM {
54911767SAnurag.Maskey@Sun.COM 	nwamd_object_t object;
55011767SAnurag.Maskey@Sun.COM 	nwam_state_t new_state;
55111767SAnurag.Maskey@Sun.COM 	nwam_aux_state_t new_aux_state;
55211767SAnurag.Maskey@Sun.COM 
55311767SAnurag.Maskey@Sun.COM 	if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_LOC,
55411767SAnurag.Maskey@Sun.COM 	    event->event_object)) == NULL) {
555*12923SRenee.Sommerfeld@Oracle.COM 		nlog(LOG_INFO, "nwamd_loc_handle_state_event: "
55611767SAnurag.Maskey@Sun.COM 		    "state event for nonexistent loc %s", event->event_object);
55711767SAnurag.Maskey@Sun.COM 		nwamd_event_do_not_send(event);
55811767SAnurag.Maskey@Sun.COM 		return;
55911767SAnurag.Maskey@Sun.COM 	}
56011767SAnurag.Maskey@Sun.COM 	new_state = event->event_msg->nwe_data.nwe_object_state.nwe_state;
56111767SAnurag.Maskey@Sun.COM 	new_aux_state =
56211767SAnurag.Maskey@Sun.COM 	    event->event_msg->nwe_data.nwe_object_state.nwe_aux_state;
56311767SAnurag.Maskey@Sun.COM 
56411767SAnurag.Maskey@Sun.COM 	if (new_state == object->nwamd_object_state &&
56511767SAnurag.Maskey@Sun.COM 	    new_aux_state == object->nwamd_object_aux_state) {
56611767SAnurag.Maskey@Sun.COM 		nlog(LOG_DEBUG, "nwamd_loc_handle_state_event: "
56711767SAnurag.Maskey@Sun.COM 		    "loc %s already in state (%s , %s)",
56811767SAnurag.Maskey@Sun.COM 		    object->nwamd_object_name,
56911767SAnurag.Maskey@Sun.COM 		    nwam_state_to_string(new_state),
57011767SAnurag.Maskey@Sun.COM 		    nwam_aux_state_to_string(new_aux_state));
57111767SAnurag.Maskey@Sun.COM 		nwamd_object_release(object);
57211767SAnurag.Maskey@Sun.COM 		return;
57311767SAnurag.Maskey@Sun.COM 	}
57411767SAnurag.Maskey@Sun.COM 
57511767SAnurag.Maskey@Sun.COM 	object->nwamd_object_state = new_state;
57611767SAnurag.Maskey@Sun.COM 	object->nwamd_object_aux_state = new_aux_state;
57711767SAnurag.Maskey@Sun.COM 
57811767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG, "nwamd_loc_handle_state_event: changing state for loc "
57911767SAnurag.Maskey@Sun.COM 	    "%s to (%s , %s)", object->nwamd_object_name,
58011767SAnurag.Maskey@Sun.COM 	    nwam_state_to_string(object->nwamd_object_state),
58111767SAnurag.Maskey@Sun.COM 	    nwam_aux_state_to_string(object->nwamd_object_aux_state));
58211767SAnurag.Maskey@Sun.COM 
58311767SAnurag.Maskey@Sun.COM 	nwamd_object_release(object);
58411767SAnurag.Maskey@Sun.COM 
58511767SAnurag.Maskey@Sun.COM 	/*
58611767SAnurag.Maskey@Sun.COM 	 * State machine for location.
58711767SAnurag.Maskey@Sun.COM 	 */
58811767SAnurag.Maskey@Sun.COM 	switch (new_state) {
58911767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_OFFLINE_TO_ONLINE:
59011767SAnurag.Maskey@Sun.COM 		nwamd_loc_activate(event->event_object);
59111767SAnurag.Maskey@Sun.COM 		break;
59211767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_ONLINE_TO_OFFLINE:
59311767SAnurag.Maskey@Sun.COM 		/*
59411767SAnurag.Maskey@Sun.COM 		 * Don't need to deactivate current location - condition check
59512526SAnurag.Maskey@Oracle.COM 		 * will activate another.  If the currently active location is
59612526SAnurag.Maskey@Oracle.COM 		 * being deactivated, then it is being manually deactivated;
59712526SAnurag.Maskey@Oracle.COM 		 * so also clear active_loc so condition checking is not
59812526SAnurag.Maskey@Oracle.COM 		 * confused.
59911767SAnurag.Maskey@Sun.COM 		 */
60012526SAnurag.Maskey@Oracle.COM 		(void) pthread_mutex_lock(&active_loc_mutex);
60112526SAnurag.Maskey@Oracle.COM 		if (strcmp(event->event_object, active_loc) == 0)
60212526SAnurag.Maskey@Oracle.COM 			active_loc[0] = '\0';
60312526SAnurag.Maskey@Oracle.COM 		(void) pthread_mutex_unlock(&active_loc_mutex);
60411767SAnurag.Maskey@Sun.COM 		nwamd_loc_check_conditions();
60511767SAnurag.Maskey@Sun.COM 		break;
60611767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_DISABLED:
60711767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_OFFLINE:
60811767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_UNINITIALIZED:
60911767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_MAINTENANCE:
61011767SAnurag.Maskey@Sun.COM 	case NWAM_STATE_DEGRADED:
61111767SAnurag.Maskey@Sun.COM 	default:
61211767SAnurag.Maskey@Sun.COM 		/* do nothing */
61311767SAnurag.Maskey@Sun.COM 		break;
61411767SAnurag.Maskey@Sun.COM 	}
61511767SAnurag.Maskey@Sun.COM }
616