6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * CDDL HEADER START
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * The contents of this file are subject to the terms of the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Common Development and Distribution License (the "License").
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * You may not use this file except in compliance with the License.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * or http://www.opensolaris.org/os/licensing.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * See the License for the specific language governing permissions
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * and limitations under the License.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * When distributing Covered Code, include this CDDL HEADER in each
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If applicable, add the following below this CDDL HEADER, with the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * fields enclosed by brackets "[]" replaced with your own identifying
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * information: Portions Copyright [yyyy] [name of copyright owner]
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * CDDL HEADER END
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * ncu.c - handles various NCU tasks - intialization/refresh, state machine
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * for NCUs etc.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskeystatic void populate_ip_ncu_properties(nwam_ncu_handle_t, nwamd_ncu_t *);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Find ncu of specified type for link/interface name.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_object_find(nwam_ncu_type_t type, const char *name)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_name_to_typed_name(name, type, &object_name))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_find: nwam_ncu_name_to_typed_name "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey ncu_obj = nwamd_object_find(NWAM_OBJECT_TYPE_NCU, object_name);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_set_ncu_string(nwam_ncu_handle_t ncuh, char **strval, uint_t cnt,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_value_create_string_array(strval, cnt, &val))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey err = nwam_ncu_set_prop_value(ncuh, prop, val);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_set_ncu_uint(nwam_ncu_handle_t ncuh, uint64_t *uintval, uint_t cnt,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_value_create_uint64_array(uintval, cnt, &val))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey err = nwam_ncu_set_prop_value(ncuh, prop, val);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_get_ncu_string(nwam_ncu_handle_t ncuh, nwam_value_t *val, char ***strval,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_get_prop_value(ncuh, prop, val)) != NWAM_SUCCESS)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey return (nwam_value_get_string_array(*val, strval, cnt));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_get_ncu_uint(nwam_ncu_handle_t ncuh, nwam_value_t *val,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey uint64_t **uintval, uint_t *cnt, const char *prop)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_get_prop_value(ncuh, prop, val)) != NWAM_SUCCESS)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey return (nwam_value_get_uint64_array(*val, uintval, cnt));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Run link/interface state machine in response to a state change
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * or enable/disable action event.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_state_machine(const char *object_name)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU, object_name))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "request for nonexistent NCU %s", object_name);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * For wired/wireless links, need to get link
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * up/down events and even if these are not supported,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * dlpi_open()ing the link prevents the driver from
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * being unloaded.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * First, if we're unexpectedly connected,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * disconnect.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "nwamd_ncu_state_machine: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "WiFi unexpectedly connected, "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "disconnecting...");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* move to scanning aux state */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If initial wired link state is unknown, we
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * will need to assume the link is up, since
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * we won´t get DL_NOTE_LINK_UP/DOWN events.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * In the current implementation, initialization has to
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * start from scratch since the complexity of minimizing
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * configuration change is considerable (e.g. if we
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * refresh and had DHCP running on the physical
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * interface, and now have changed to static assignment,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * we need to remove DHCP etc). To avoid all this,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * unplumb before re-plumbing the protocols and
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * addresses we wish to configure. In the future, it
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * would be good to try and minimize configuration
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * We may be restarting the state machine. Re-read
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * the IP NCU properties as the ipadm_addrobj_t in
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * nwamd_if_address should not be reused.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey populate_ip_ncu_properties(object->nwamd_object_handle,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Enqueue a WAITING_FOR_ADDR aux state change so that
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * we are eligible to receive the IF_STATE events
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * associated with static, DHCP, DHCPv6 and autoconf
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * address assignment. The latter two can happen
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * quite quickly after plumbing so we need to be ready.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey /* Configure addresses */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * nothing to do here - RTM_NEWADDRs will trigger IF_STATE
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * events to move us online.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* launch scan thread */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name, sizeof (linkname));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Create periodic scan event */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_ncu_create_periodic_scan_event(object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey case NWAM_AUX_STATE_LINK_WIFI_NEED_SELECTION:
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* send "need choice" event */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (ncu->ncu_name, NWAM_EVENT_TYPE_WLAN_NEED_CHOICE, B_FALSE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr_num);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_set_selected_connected(ncu, B_FALSE, B_FALSE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Send "need key" event. Set selected to true, connected
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * and have_key to false. Do not fill in WLAN details as
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * multiple WLANs may match the ESSID name, and each may
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * have a different speed and channel.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(key_wlan.nww_essid, link->nwamd_link_wifi_essid,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(key_wlan.nww_bssid, link->nwamd_link_wifi_bssid,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (ncu->ncu_name, NWAM_EVENT_TYPE_WLAN_NEED_KEY, B_FALSE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name, sizeof (linkname));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey up = (object->nwamd_object_aux_state == NWAM_AUX_STATE_UP);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * connection report.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_set_selected_connected(ncu, B_TRUE, up);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT, up,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If disconnected, restart the state machine
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * for the WiFi link (WiFi is always trying
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * to connect).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If connected, start signal strength
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * monitoring thread.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "nwamd_ncu_state_machine: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "wifi disconnect - start over "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "after %dsec interval",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* propogate down event to IP NCU */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "nwamd_ncu_state_machine: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "wifi connected, start monitoring");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* If not in ONLINE/OFFLINE state yet, change state */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((up && object->nwamd_object_state != NWAM_STATE_ONLINE) ||
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (!up && object->nwamd_object_state != NWAM_STATE_OFFLINE)) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_state_machine: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey up ? NWAM_STATE_ONLINE : NWAM_STATE_OFFLINE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey up ? NWAM_AUX_STATE_UP : NWAM_AUX_STATE_DOWN);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_INTERFACE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Moving online, add v4/v6 default
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * routes (if any).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If this is an interface NCU and we
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * got a down event, it is a consequence
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * of NCU refresh, so reapply addresses
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * by reinitializing.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_state_machine: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * NCU is UP or DOWN, trigger all condition checking, even if
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * the NCU is already in the ONLINE state - an ENM may depend
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * on NCU activity.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_create_triggered_condition_check_event(NEXT_FEW_SECONDS);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Link/interface is moving offline. Nothing to do except
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * for WiFi, where we disconnect. Don't unplumb IP on
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * a link since it may be a transient change.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Unplumb here. In the future we may elaborate on
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * the approach used and not unplumb for WiFi
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * until we reconnect to a different WLAN (i.e. with
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * a different ESSID).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state != NWAM_STATE_OFFLINE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Manual disable, set enabled state appropriately. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* FALLTHROUGH */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Link/interface NCU has been disabled/deactivated/removed.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * For WiFi links disconnect, and for IP interfaces we unplumb.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Unplumb here. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* trigger location condition checking */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_create_triggered_condition_check_event(0);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Change state to DISABLED if manually disabled */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Note that NCU has been disabled */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Change state to UNINITIALIZED for device removal */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_state_machine: unexpected state");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyncu_create_init_fini_event(nwam_ncu_handle_t ncuh, void *data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (nwam_ncu_get_name(ncuh, &name) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "ncu_create_init_fini_event: could not get NCU name");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "ncu_create_init_fini_event(%s, %p)", name, data);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &typeval, &type, &numvalues,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "ncu_create_init_fini_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not get NCU type: %s", nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* convert name to typedname for event */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_name_to_typed_name(name, *type, &typedname))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "ncu_create_init_fini_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "NCU name translation failed: %s", nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_EVENT_TYPE_OBJECT_INIT : NWAM_EVENT_TYPE_OBJECT_FINI,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Initialization - walk the NCUs, creating initialization events for each
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * NCU. nwamd_ncu_handle_init_event() will check if the associated
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * physical link exists or not.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "(re)intializing NCUs for NCP %s", active_ncp);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey ncu_create_init_fini_event, &init, NWAM_FLAG_NCU_TYPE_ALL,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* We may not have an active NCP on initialization, so skip fini */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_fini_ncus: deinitializing NCUs for %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey ncu_create_init_fini_event, &init, NWAM_FLAG_NCU_TYPE_ALL,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Most properties of this type don't need to be cached locally. Only those
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * interesting to the daemon are stored in an nwamd_ncu_t.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeypopulate_common_ncu_properties(nwam_ncu_handle_t ncuh, nwamd_ncu_t *ncu_data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ENABLED,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) nwam_ncu_name_to_typed_name(ncu_data->ncu_name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwam_ncu_get_prop_value %s ENABLED failed: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_value_get_boolean(ncu_prop, &enablevalue)) !=
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwam_value_get_boolean ENABLED failed: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &parent,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_PARENT_NCP)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwam_ncu_get_prop_value %s PARENT failed: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(ncu_data->ncu_parent, parent[0],
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Read in link properties.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeypopulate_link_ncu_properties(nwam_ncu_handle_t ncuh, nwamd_ncu_t *ncu_data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* activation-mode */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval, &numvalues,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_ACTIVATION_MODE)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_ACTIVATION_MODE, nwam_strerror(err));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_activation_mode = uintval[0];
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* priority-group and priority-mode for prioritized activation */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey if (ncu_data->ncu_link.nwamd_link_activation_mode ==
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* ncus with prioritized activation are always enabled */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "populate_link_ncu_properties: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_PRIORITY_MODE, nwam_strerror(err));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_priority_mode =
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "populate_link_ncu_properties: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_PRIORITY_GROUP, nwam_strerror(err));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_priority_group =
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* link-mac-addr */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &mac_addr, &numvalues,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_LINK_MAC_ADDR)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_LINK_MAC_ADDR, nwam_strerror(err));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_mac_addr = NULL;
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_mac_addr = strdup(*mac_addr);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_mac_addr_len = strlen(*mac_addr);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* link-mtu */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval, &numvalues,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_LINK_MTU)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_LINK_MTU, nwam_strerror(err));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_mtu = uintval[0];
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* link-autopush */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop,
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey &ncu_data->ncu_link.nwamd_link_num_autopush,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_LINK_AUTOPUSH)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_LINK_AUTOPUSH, nwam_strerror(err));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu_data->ncu_link.nwamd_link_num_autopush = 0;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeypopulate_ip_ncu_properties(nwam_ncu_handle_t ncuh, nwamd_ncu_t *ncu_data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey struct nwamd_if_address **nifa, *nifai, *nifait;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_stateful_requested = B_FALSE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_stateless_requested = B_FALSE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_ipv4_default_route_set = B_FALSE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_ipv6_default_route_set = B_FALSE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* ip-version */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &ipversion, &numvalues,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_IP_VERSION)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_ip_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_IP_VERSION, nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (i = 0; i < numvalues; i++) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Free the old list. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (nifai = nif->nwamd_if_list; nifai != NULL; nifai = nifait) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* ipv4-addrsrc */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &addrsrcvalue,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV4_ADDRSRC)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(nif->nwamd_if_ipv4 ? LOG_ERR : LOG_DEBUG,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_ip_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_IPV4_ADDRSRC, nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (i = 0; i < numvalues; i++) {
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_create_addrobj(IPADM_ADDR_DHCP,
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_create_addrobj failed for v4 dhcp: %s",
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_set_wait_time(ipaddr, ncu_wait_time);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_set_wait_time failed for v4 dhcp: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((*nifa = calloc(sizeof (**nifa), 1)) != NULL) {
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "couldn't allocate nwamd address for v4 dhcp: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* ipv4-addr */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV4_ADDR)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not get %s value; %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_IPV4_ADDR, nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (i = 0; i < numvalues; i++) {
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_create_addrobj failed "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey /* ipadm_set_addr takes <addr>[/<mask>] */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_set_addr(ipaddr, addrvalue[i],
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_set_addr failed for %s: %s",
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "couldn't allocate nwamd address "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* get default route, if any */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE)) == NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Only one default route is allowed. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_ipv4_default_route.sin_family = AF_INET;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &(nif->nwamd_if_ipv4_default_route.sin_addr));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_ipv4_default_route_set = B_TRUE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* ipv6-addrsrc */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &addrsrcvalue,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV6_ADDRSRC)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(nif->nwamd_if_ipv6 ? LOG_ERR : LOG_DEBUG,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "populate_ip_ncu_properties: could not get %s value: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_IPV6_ADDRSRC, nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (i = 0; i < numvalues; i++) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_stateless_requested = B_TRUE;
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * Both stateful and stateless share the same nwamd_if_address because
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * only one ipaddr for both of these addresses can be created.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey * ipadm_create_addr() adds both addresses from the same ipaddr.
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_create_addrobj(IPADM_ADDR_IPV6_ADDRCONF,
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_create_addrobj failed for v6 "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey /* create_addrobj sets both stateless and stateful to B_TRUE */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_set_stateful(ipaddr, B_FALSE);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_set_stateful failed for v6: %s",
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_set_stateless(ipaddr, B_FALSE);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_set_stateless failed for v6: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((*nifa = calloc(sizeof (**nifa), 1)) != NULL) {
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey (*nifa)->ipaddr_atype = IPADM_ADDR_IPV6_ADDRCONF;
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "couldn't allocate nwamd address for "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "v6 stateless/stateful: %s", strerror(errno));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* ipv6-addr */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV6_ADDR)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not get %s value; %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_IPV6_ADDR, nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (i = 0; i < numvalues; i++) {
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_create_addrobj failed "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey /* ipadm_set_addr takes <addr>[/<mask>] */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ipstatus = ipadm_set_addr(ipaddr, addrvalue[i],
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "ipadm_set_addr failed for %s: %s",
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "populate_ip_ncu_properties: "
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey "couldn't allocate nwamd address "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* get default route, if any */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE)) == NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Only one default route is allowed. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_ipv6_default_route.sin6_family = AF_INET6;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey &(nif->nwamd_if_ipv6_default_route.sin6_addr));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nif->nwamd_if_ipv6_default_route_set = B_TRUE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_init(nwam_ncu_type_t ncu_type, const char *name)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_init(%d, %s)", ncu_type, name);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((rv = calloc(1, sizeof (*rv))) == NULL)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Initialize link/interface-specific data */
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey (void) bzero(&rv->ncu_link, sizeof (nwamd_link_t));
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey &rv->ncu_link.nwamd_link_wifi_mutex, NULL);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey rv->ncu_link.nwamd_link_wifi_priority = MAXINT;
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey (void) bzero(&rv->ncu_if, sizeof (nwamd_if_t));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey assert(ncu->ncu_type == NWAM_NCU_TYPE_LINK ||
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey for (i = 0; i < l->nwamd_link_num_autopush; i++)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey } else if (ncu->ncu_type == NWAM_NCU_TYPE_INTERFACE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_display(nwamd_object_t ncu_obj, void *data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_ncu_t *ncu = (nwamd_ncu_t *)ncu_obj->nwamd_object_data;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "NCU (%p) %s state %s, %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwam_state_to_string(ncu_obj->nwamd_object_state),
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwam_aux_state_to_string(ncu_obj->nwamd_object_aux_state));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU, nwamd_ncu_display,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_action(const char *ncu, const char *parent, nwam_action_t action)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_event_t ncu_event = nwamd_event_init_object_action
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (NWAM_OBJECT_TYPE_NCU, ncu, parent, action);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyadd_phys_ncu_to_ncp(nwam_ncp_handle_t ncph, const char *name)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((dlrtn = dladm_name2info(dld_handle, name, NULL, NULL, NULL,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "failed to get media type for %s: %s", name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_create(ncph, name, NWAM_NCU_TYPE_LINK,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_CLASS_PHYS, &ncuh)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "failed to create link ncu for %s: %s", name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Root filesystem may be read-only, retry in
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * a few seconds.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "Retrying addition of phys ncu for %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey retry_event = nwamd_event_init_link_action(name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey uintval = NWAM_ACTIVATION_MODE_PRIORITIZED;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_set_ncu_uint(ncuh, &uintval, 1,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_ACTIVATION_MODE)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_set_ncu_uint(ncuh, &uintval, 1,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_PRIORITY_GROUP)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey uintval = is_wireless ? NWAM_PRIORITY_MODE_EXCLUSIVE :
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwamd_set_ncu_uint(ncuh, &uintval, 1,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_PROP_PRIORITY_MODE)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "failed to create automatic link ncu for %s: %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyadd_ip_ncu_to_ncp(nwam_ncp_handle_t ncph, const char *name)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_create(ncph, name, NWAM_NCU_TYPE_INTERFACE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_NCU_CLASS_IP, &ncuh)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "failed to create ip ncu for %s: %s", name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Root filesystem may be read-only, but no need to
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * retry here since add_phys_ncu_to_ncp() enqueues
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * a retry event which will lead to add_ip_ncu_to_ncp()
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * being called.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* IP NCU has the default values, so nothing else to do */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "failed to create ip ncu for %s: %s", name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyremove_ncu_from_ncp(nwam_ncp_handle_t ncph, const char *name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_read(ncph, name, type, 0, &ncuh)) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "failed to read automatic ncu %s: %s", name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "failed to delete automatic ncu %s: %s", name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Device represented by NCU has been added or removed for the active
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * User NCP. If an associated NCU of the given type is found, transition it
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * to the appropriate state.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyncu_action_change_state(nwam_action_t action, nwam_ncu_type_t type,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((ncu_obj = nwamd_ncu_object_find(type, name)) == NULL)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If device has been added, transition from uninitialized to offline.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If device has been removed, transition to uninitialized (via online*
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * if the NCU is currently enabled in order to tear down config).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey NWAM_STATE_OFFLINE, NWAM_AUX_STATE_CONDITIONS_NOT_MET);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Called with hotplug sysevent or when nwam is started and walking the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * physical interfaces. Add/remove both link and interface NCUs from the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Automatic NCP. Assumes that both link and interface NCUs don't exist.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_handle_link_action_event(nwamd_event_t event)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_msg->nwe_data.nwe_link_action.nwe_action;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (action != NWAM_ACTION_ADD && action != NWAM_ACTION_REMOVE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "invalid link action %s", nwam_action_to_string(action));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_link_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "link action '%s' event on %s", nwam_action_to_string(action),
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_object[0] == 0 ? "n/a" : event->event_object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncu_typed_name_to_name(event->event_object, &type,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "translation from typedname error: %s", nwam_strerror(err));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (strcmp(active_ncp, NWAM_NCP_NAME_AUTOMATIC) == 0 &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * We could use active_ncph for cases where the Automatic NCP is active,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * but that would involve holding the active_ncp_mutex for too long.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((err = nwam_ncp_read(NWAM_NCP_NAME_AUTOMATIC, 0, &ncph))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Automatic NCP doesn't exist, create it */
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey err = nwam_ncp_create(NWAM_NCP_NAME_AUTOMATIC, 0, &ncph);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* add or remove NCUs from Automatic NCP */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Order is important here, remove IP NCU first to prevent
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * propogation of down event from link to IP. No need to
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * create REFRESH or DESTROY events. They are generated by
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * nwam_ncu_commit() and nwam_ncu_destroy().
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey remove_ncu_from_ncp(ncph, name, NWAM_NCU_TYPE_INTERFACE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey remove_ncu_from_ncp(ncph, name, NWAM_NCU_TYPE_LINK);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If the Automatic NCP is not active, and the associated NCUs
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * exist, they must be moved into the appropriate states given the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * action that has occurred.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey ncu_action_change_state(action, NWAM_NCU_TYPE_INTERFACE, name);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey ncu_action_change_state(action, NWAM_NCU_TYPE_LINK, name);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Need NCU check to evaluate state in light of added/removed NCUs */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (!nwamd_event_enqueued(NWAM_EVENT_TYPE_NCU_CHECK,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_create_ncu_check_event(NEXT_FEW_SECONDS);
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey nwamd_event_t retry_event = nwamd_event_init_link_action(name,
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey "could not create retry event to read/create "
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey "could not read/create %s NCP, retrying in %d seconds",
71ed50cf049ab14d8e0ef8d48ba17d91223e81e7Anurag S. Maskey NWAM_NCP_NAME_AUTOMATIC, NWAMD_READONLY_RETRY_INTERVAL);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Figure out if this link is part of an aggregation. This is fairly
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * inefficient since we generate this list for every query and search
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * linearly. A better way would be to generate the list of links in an
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * aggregation once and then check each link against it.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyncu_aggr_search(const char *name, void *data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (dladm_name2info(dld_handle, name, &linkid, NULL, NULL, NULL) !=
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (dladm_aggr_info(dld_handle, linkid, &ginfo, DLADM_OPT_ACTIVE)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey != DLADM_STATUS_OK || ginfo.lg_nports == 0)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (lasd->linkid == ginfo.lg_ports[i].lp_linkid) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_link_belongs_to_an_aggr(const char *name)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (dladm_name2info(dld_handle, name, &lasd.linkid, NULL, NULL, NULL)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) dladm_walk(ncu_aggr_search, dld_handle, &lasd,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If NCU doesn't exist for interface with given name, enqueue a ADD
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * LINK_ACTION event.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeyncu_create_link_action_event(const char *name, void *data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Do not generate an event if this is a VirtualBox interface. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (strncmp(name, VBOX_IFACE_PREFIX, strlen(VBOX_IFACE_PREFIX)) == 0)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Do not generate an event if this link belongs to another zone. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (!nwamd_link_belongs_to_this_zone(name))
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Do not generate an event if this link belongs to an aggregation. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Don't create an event if the NCU already exists. */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (ncph != NULL && nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK, 0,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "ncu_create_link_action_event: adding ncus for %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey link_event = nwamd_event_init_link_action(name, NWAM_ACTION_ADD);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Check if interface exists for this NCU. If not, enqueue a REMOVE
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * LINK_ACTION event.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey/* ARGSUSED */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_destroy_ncu(nwam_ncu_handle_t ncuh, void *data)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (nwam_ncu_get_name(ncuh, &name) != NWAM_SUCCESS) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_destroy_ncu: could not get NCU name");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Interfaces that exist return DLADM_OPT_ACTIVE flag */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((dladm_name2info(dld_handle, name, NULL, &flags, NULL, NULL)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_destroy_ncu: destroying ncus for %s", name);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey link_event = nwamd_event_init_link_action(name, NWAM_ACTION_REMOVE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Called when nwamd is starting up.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Walk all NCUs and destroy any NCU from the Automatic NCP without an
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * underlying interface (assumption here is that the interface was removed
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * when nwam was disabled).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Walk the physical interfaces and create ADD LINK_ACTION event, which
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * will create appropriate interface and link NCUs in the Automatic NCP.
f689bed18bbb72c93b14a451e959b18f7ccfb7d1Rishi Srivatsavai datalink_class_t dlclass = DATALINK_CLASS_PHYS;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (strcmp(active_ncp, NWAM_NCP_NAME_AUTOMATIC) == 0 &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (nwam_ncp_read(NWAM_NCP_NAME_AUTOMATIC, 0, &ncph)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* destroy NCUs for interfaces that don't exist */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) nwam_ncp_walk_ncus(ncph, nwamd_destroy_ncu, NULL,
f689bed18bbb72c93b14a451e959b18f7ccfb7d1Rishi Srivatsavai /* In non-global zones NWAM can support VNICs */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* create NCUs for interfaces without NCUs */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) dladm_walk(ncu_create_link_action_event, dld_handle, ncph,
f689bed18bbb72c93b14a451e959b18f7ccfb7d1Rishi Srivatsavai dlclass, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (strcmp(active_ncp, NWAM_NCP_NAME_AUTOMATIC) != 0 ||
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Handle NCU initialization/refresh event.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_handle_init_event(nwamd_event_t event)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_init_event(%s)",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Get base linkname rather than interface:linkname or link:linkname */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey err = nwam_ncu_typed_name_to_name(event->event_object,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_init_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "nwam_ncu_typed_name_to_name returned %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "nwamd_ncu_handle_init_event: active NCP handle NULL");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey err = nwam_ncu_read(active_ncph, event->event_object,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_init_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not read object '%s': %s",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * For new NCUs, or interface NCUs, we (re)initialize data from scratch.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * For link NCUs, we want to retain object data.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwam_ncu_free(object->nwamd_object_handle);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwam_ncu_free(object->nwamd_object_handle);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "unknown ncu type %d", type);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_init_event: didn't find "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object = nwamd_object_init(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_init_event: refreshing "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If the physical link for this NCU doesn't exist in the system,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * the state should be UNINITIALIZED/NOT_FOUND. Interfaces that
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * exist return DLADM_OPT_ACTIVE flag.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (dladm_name2info(dld_handle, name, NULL, &flags, NULL, NULL)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey != DLADM_STATUS_OK || !(flags & DLADM_OPT_ACTIVE)) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwam_ncu_handle_init_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "interface for NCU %s doesn't exist",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_name, NWAM_STATE_UNINITIALIZED,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If NCU is being initialized (rather than refreshed), the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * object_state is INITIALIZED (from nwamd_object_init()).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_INITIALIZED) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If the NCU is disabled, initial state should be DISABLED.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Otherwise, the initial state will be
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * OFFLINE/CONDITIONS_NOT_MET, and the link selection
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * algorithm will do the rest.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_state = NWAM_STATE_DISABLED;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_state = NWAM_STATE_OFFLINE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Refresh NCU. Deal with disabled cases first, moving NCUs
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * that are not disabled - but have the enabled value set - to
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * the disabled state. Then handle cases where the NCU was
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * disabled but is no longer. Finally, deal with refresh of
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * link and interface NCUs, as these are handled differently.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state != NWAM_STATE_DISABLED) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_DISABLED) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Try to activate the NCU if manual or
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * prioritized (when priority <= current).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey if (ncu->ncu_link.nwamd_link_media == DL_WIFI) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Do rescan. If the current state and the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * active priority-group do not allow wireless
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * network selection, then it won't happen.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If interface NCU is offline*, online or in
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * maintenance, mark it down (from there, it will be
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * reinitialized to reapply addresses).
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state != NWAM_STATE_OFFLINE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_state = NWAM_STATE_OFFLINE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey !nwamd_event_enqueued(NWAM_EVENT_TYPE_NCU_CHECK,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_create_ncu_check_event(NEXT_FEW_SECONDS);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_handle_fini_event(nwamd_event_t event)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_fini_event(%s)",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Simulate a state event so that the state machine can correctly
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * disable the NCU. Then free up allocated objects.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey state_event = nwamd_event_init_object_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
f6904bc3cbac0d84f41b1eb2ed9489a8f221695cRenee Danson Sommerfeld nlog(LOG_INFO, "nwamd_ncu_handle_fini_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_handle_action_event(nwamd_event_t event)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (strcmp(event->event_msg->nwe_data.nwe_object_action.nwe_parent,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_action_event: action for "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "inactive NCP %s, nothing to do",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_msg->nwe_data.nwe_object_action.nwe_parent);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey switch (event->event_msg->nwe_data.nwe_object_action.nwe_action) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not find ncu %s", event->event_object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_ONLINE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "ncu %s already online, nothing to do",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_object, NWAM_STATE_OFFLINE_TO_ONLINE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "could not find ncu %s", event->event_object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_DISABLED) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "ncu %s already disabled, nothing to do",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_INFO, "nwam_ncu_handle_action_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "unexpected action");
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskeynwamd_ncu_handle_state_event(nwamd_event_t event)
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey boolean_t is_link, enabled, prioritized = B_FALSE;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
f6904bc3cbac0d84f41b1eb2ed9489a8f221695cRenee Danson Sommerfeld nlog(LOG_INFO, "nwamd_ncu_handle_state_event %lld: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "state event for nonexistent NCU %s", event->event_id,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey new_state = event->event_msg->nwe_data.nwe_object_state.nwe_state;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey event->event_msg->nwe_data.nwe_object_state.nwe_aux_state;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * For NCU state changes, we need to supply the parent NCP name also,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * regardless of whether the event is handled or not. It is best to
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * fill this in here as we have the object lock - when we create
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * object state events we sometimes do not have the object lock, but
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * at this point in consuming the events (and prior to the associated
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * event message being sent out) we do.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(m->nwe_data.nwe_object_state.nwe_parent, ncu->ncu_parent,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey sizeof (m->nwe_data.nwe_object_state.nwe_parent));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * If we receive a state change event moving this NCU to
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * DHCP_TIMED_OUT or UP state but this NCU is already ONLINE, then
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * ignore this state change event.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((new_aux_state == NWAM_AUX_STATE_IF_DHCP_TIMED_OUT ||
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_state == NWAM_STATE_ONLINE) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_INFO, "nwamd_ncu_handle_state_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "NCU %s already online, not going to '%s' state",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (new_state == object->nwamd_object_state &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey new_aux_state == object->nwamd_object_aux_state) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "NCU %s already in state (%s, %s)",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_name, nwam_state_to_string(new_state),
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (new_state == NWAM_STATE_OFFLINE_TO_ONLINE &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey new_aux_state != NWAM_AUX_STATE_INITIALIZED))) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "NCU %s cannot transition from state %s to state (%s, %s)",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_name, nwam_state_to_string(old_state),
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey object->nwamd_object_aux_state = new_aux_state;
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: changing state for NCU "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "%s to (%s, %s)", object->nwamd_object_name,
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwam_state_to_string(object->nwamd_object_state),
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwam_aux_state_to_string(object->nwamd_object_aux_state));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey is_link = (ncu->ncu_type == NWAM_NCU_TYPE_LINK);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name, sizeof (linkname));
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey prioritized = (ncu->ncu_type == NWAM_NCU_TYPE_LINK &&
f6da83d4178694e7113b71d1e452f15b296f73d8Anurag S. Maskey ncu->ncu_link.nwamd_link_activation_mode ==
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * State machine for NCUs
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_ncu_state_machine(event->event_object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: "
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey "cannot move disabled NCU %s online",
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_ncu_state_machine(event->event_object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * We usually don't need to do anything when we're in the
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * ONLINE state. However, for WiFi we can be in INIT or
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * SCAN aux states while being ONLINE.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_ncu_state_machine(event->event_object);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* Reassess priority group now member is offline */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* do nothing */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if ((new_state == NWAM_STATE_ONLINE_TO_OFFLINE &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey new_aux_state != NWAM_AUX_STATE_UNINITIALIZED &&
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey new_aux_state != NWAM_AUX_STATE_NOT_FOUND) ||
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Going offline, propogate down event to IP NCU. Do
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * not propogate event if new aux state is uninitialized
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * or not found as these auxiliary states signify
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * that an NCP switch/device removal is in progress.
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_propogate_link_up_down_to_ip(linkname, B_FALSE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* gone online, propogate up event to IP NCU */
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey nwamd_propogate_link_up_down_to_ip(linkname, B_TRUE);
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey /* If IP NCU is online, reasses priority group */