16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey * CDDL HEADER START
36ba597c5SAnurag S. Maskey *
46ba597c5SAnurag S. Maskey * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey *
86ba597c5SAnurag S. Maskey * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey * and limitations under the License.
126ba597c5SAnurag S. Maskey *
136ba597c5SAnurag S. Maskey * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey *
196ba597c5SAnurag S. Maskey * CDDL HEADER END
206ba597c5SAnurag S. Maskey */
216ba597c5SAnurag S. Maskey
226ba597c5SAnurag S. Maskey /*
2371ed50cfSAnurag S. Maskey * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*b31320a7SChris Fraire * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
256ba597c5SAnurag S. Maskey */
266ba597c5SAnurag S. Maskey
276ba597c5SAnurag S. Maskey #include <arpa/inet.h>
286ba597c5SAnurag S. Maskey #include <assert.h>
296ba597c5SAnurag S. Maskey #include <libdlaggr.h>
306ba597c5SAnurag S. Maskey #include <libdllink.h>
316ba597c5SAnurag S. Maskey #include <libdlstat.h>
326ba597c5SAnurag S. Maskey #include <libnwam.h>
336ba597c5SAnurag S. Maskey #include <libscf.h>
346ba597c5SAnurag S. Maskey #include <netinet/in.h>
356ba597c5SAnurag S. Maskey #include <stdlib.h>
366ba597c5SAnurag S. Maskey #include <strings.h>
37*b31320a7SChris Fraire #include <sys/param.h>
386ba597c5SAnurag S. Maskey #include <sys/socket.h>
396ba597c5SAnurag S. Maskey #include <sys/time.h>
406ba597c5SAnurag S. Maskey #include <sys/types.h>
416ba597c5SAnurag S. Maskey #include <values.h>
42f689bed1SRishi Srivatsavai #include <zone.h>
436ba597c5SAnurag S. Maskey
446ba597c5SAnurag S. Maskey #include "conditions.h"
456ba597c5SAnurag S. Maskey #include "events.h"
466ba597c5SAnurag S. Maskey #include "objects.h"
476ba597c5SAnurag S. Maskey #include "ncp.h"
486ba597c5SAnurag S. Maskey #include "util.h"
496ba597c5SAnurag S. Maskey
506ba597c5SAnurag S. Maskey /*
516ba597c5SAnurag S. Maskey * ncu.c - handles various NCU tasks - intialization/refresh, state machine
526ba597c5SAnurag S. Maskey * for NCUs etc.
536ba597c5SAnurag S. Maskey */
546ba597c5SAnurag S. Maskey
556ba597c5SAnurag S. Maskey #define VBOX_IFACE_PREFIX "vboxnet"
566ba597c5SAnurag S. Maskey
57f6da83d4SAnurag S. Maskey static void populate_ip_ncu_properties(nwam_ncu_handle_t, nwamd_ncu_t *);
58f6da83d4SAnurag S. Maskey
596ba597c5SAnurag S. Maskey /*
606ba597c5SAnurag S. Maskey * Find ncu of specified type for link/interface name.
616ba597c5SAnurag S. Maskey */
626ba597c5SAnurag S. Maskey nwamd_object_t
nwamd_ncu_object_find(nwam_ncu_type_t type,const char * name)636ba597c5SAnurag S. Maskey nwamd_ncu_object_find(nwam_ncu_type_t type, const char *name)
646ba597c5SAnurag S. Maskey {
656ba597c5SAnurag S. Maskey nwam_error_t err;
666ba597c5SAnurag S. Maskey char *object_name;
676ba597c5SAnurag S. Maskey nwamd_object_t ncu_obj = NULL;
686ba597c5SAnurag S. Maskey
696ba597c5SAnurag S. Maskey if ((err = nwam_ncu_name_to_typed_name(name, type, &object_name))
706ba597c5SAnurag S. Maskey != NWAM_SUCCESS) {
716ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_find: nwam_ncu_name_to_typed_name "
726ba597c5SAnurag S. Maskey "returned %s", nwam_strerror(err));
736ba597c5SAnurag S. Maskey return (NULL);
746ba597c5SAnurag S. Maskey }
756ba597c5SAnurag S. Maskey ncu_obj = nwamd_object_find(NWAM_OBJECT_TYPE_NCU, object_name);
766ba597c5SAnurag S. Maskey
776ba597c5SAnurag S. Maskey free(object_name);
786ba597c5SAnurag S. Maskey return (ncu_obj);
796ba597c5SAnurag S. Maskey }
806ba597c5SAnurag S. Maskey
816ba597c5SAnurag S. Maskey nwam_error_t
nwamd_set_ncu_string(nwam_ncu_handle_t ncuh,char ** strval,uint_t cnt,const char * prop)826ba597c5SAnurag S. Maskey nwamd_set_ncu_string(nwam_ncu_handle_t ncuh, char **strval, uint_t cnt,
836ba597c5SAnurag S. Maskey const char *prop)
846ba597c5SAnurag S. Maskey {
856ba597c5SAnurag S. Maskey nwam_error_t err;
866ba597c5SAnurag S. Maskey nwam_value_t val;
876ba597c5SAnurag S. Maskey
886ba597c5SAnurag S. Maskey if ((err = nwam_value_create_string_array(strval, cnt, &val))
896ba597c5SAnurag S. Maskey != NWAM_SUCCESS)
906ba597c5SAnurag S. Maskey return (err);
916ba597c5SAnurag S. Maskey err = nwam_ncu_set_prop_value(ncuh, prop, val);
926ba597c5SAnurag S. Maskey nwam_value_free(val);
936ba597c5SAnurag S. Maskey return (err);
946ba597c5SAnurag S. Maskey }
956ba597c5SAnurag S. Maskey
966ba597c5SAnurag S. Maskey nwam_error_t
nwamd_set_ncu_uint(nwam_ncu_handle_t ncuh,uint64_t * uintval,uint_t cnt,const char * prop)976ba597c5SAnurag S. Maskey nwamd_set_ncu_uint(nwam_ncu_handle_t ncuh, uint64_t *uintval, uint_t cnt,
986ba597c5SAnurag S. Maskey const char *prop)
996ba597c5SAnurag S. Maskey {
1006ba597c5SAnurag S. Maskey nwam_error_t err;
1016ba597c5SAnurag S. Maskey nwam_value_t val;
1026ba597c5SAnurag S. Maskey
1036ba597c5SAnurag S. Maskey if ((err = nwam_value_create_uint64_array(uintval, cnt, &val))
1046ba597c5SAnurag S. Maskey != NWAM_SUCCESS)
1056ba597c5SAnurag S. Maskey return (err);
1066ba597c5SAnurag S. Maskey err = nwam_ncu_set_prop_value(ncuh, prop, val);
1076ba597c5SAnurag S. Maskey nwam_value_free(val);
1086ba597c5SAnurag S. Maskey return (err);
1096ba597c5SAnurag S. Maskey }
1106ba597c5SAnurag S. Maskey
1116ba597c5SAnurag S. Maskey nwam_error_t
nwamd_get_ncu_string(nwam_ncu_handle_t ncuh,nwam_value_t * val,char *** strval,uint_t * cnt,const char * prop)1126ba597c5SAnurag S. Maskey nwamd_get_ncu_string(nwam_ncu_handle_t ncuh, nwam_value_t *val, char ***strval,
1136ba597c5SAnurag S. Maskey uint_t *cnt, const char *prop)
1146ba597c5SAnurag S. Maskey {
1156ba597c5SAnurag S. Maskey nwam_error_t err;
1166ba597c5SAnurag S. Maskey
1176ba597c5SAnurag S. Maskey if ((err = nwam_ncu_get_prop_value(ncuh, prop, val)) != NWAM_SUCCESS)
1186ba597c5SAnurag S. Maskey return (err);
1196ba597c5SAnurag S. Maskey return (nwam_value_get_string_array(*val, strval, cnt));
1206ba597c5SAnurag S. Maskey }
1216ba597c5SAnurag S. Maskey
1226ba597c5SAnurag S. Maskey nwam_error_t
nwamd_get_ncu_uint(nwam_ncu_handle_t ncuh,nwam_value_t * val,uint64_t ** uintval,uint_t * cnt,const char * prop)1236ba597c5SAnurag S. Maskey nwamd_get_ncu_uint(nwam_ncu_handle_t ncuh, nwam_value_t *val,
1246ba597c5SAnurag S. Maskey uint64_t **uintval, uint_t *cnt, const char *prop)
1256ba597c5SAnurag S. Maskey {
1266ba597c5SAnurag S. Maskey nwam_error_t err;
1276ba597c5SAnurag S. Maskey
1286ba597c5SAnurag S. Maskey if ((err = nwam_ncu_get_prop_value(ncuh, prop, val)) != NWAM_SUCCESS)
1296ba597c5SAnurag S. Maskey return (err);
1306ba597c5SAnurag S. Maskey return (nwam_value_get_uint64_array(*val, uintval, cnt));
1316ba597c5SAnurag S. Maskey }
1326ba597c5SAnurag S. Maskey
133*b31320a7SChris Fraire nwam_error_t
nwamd_get_ncu_boolean(nwam_ncu_handle_t ncuh,nwam_value_t * val,boolean_t ** boolval,uint_t * cnt,const char * prop)134*b31320a7SChris Fraire nwamd_get_ncu_boolean(nwam_ncu_handle_t ncuh, nwam_value_t *val,
135*b31320a7SChris Fraire boolean_t **boolval, uint_t *cnt, const char *prop)
136*b31320a7SChris Fraire {
137*b31320a7SChris Fraire nwam_error_t err;
138*b31320a7SChris Fraire
139*b31320a7SChris Fraire if ((err = nwam_ncu_get_prop_value(ncuh, prop, val)) != NWAM_SUCCESS)
140*b31320a7SChris Fraire return (err);
141*b31320a7SChris Fraire return (nwam_value_get_boolean_array(*val, boolval, cnt));
142*b31320a7SChris Fraire }
143*b31320a7SChris Fraire
1446ba597c5SAnurag S. Maskey /*
1456ba597c5SAnurag S. Maskey * Run link/interface state machine in response to a state change
1466ba597c5SAnurag S. Maskey * or enable/disable action event.
1476ba597c5SAnurag S. Maskey */
1486ba597c5SAnurag S. Maskey static void
nwamd_ncu_state_machine(const char * object_name)1496ba597c5SAnurag S. Maskey nwamd_ncu_state_machine(const char *object_name)
1506ba597c5SAnurag S. Maskey {
1516ba597c5SAnurag S. Maskey nwamd_object_t object;
1526ba597c5SAnurag S. Maskey nwamd_ncu_t *ncu;
1536ba597c5SAnurag S. Maskey link_state_t link_state;
1546ba597c5SAnurag S. Maskey nwamd_event_t event;
1556ba597c5SAnurag S. Maskey nwam_wlan_t key_wlan, connected_wlan;
1566ba597c5SAnurag S. Maskey nwamd_link_t *link;
1576ba597c5SAnurag S. Maskey char linkname[NWAM_MAX_NAME_LEN];
1586ba597c5SAnurag S. Maskey boolean_t up;
1596ba597c5SAnurag S. Maskey
1606ba597c5SAnurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU, object_name))
1616ba597c5SAnurag S. Maskey == NULL) {
1626ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_state_machine: "
1636ba597c5SAnurag S. Maskey "request for nonexistent NCU %s", object_name);
1646ba597c5SAnurag S. Maskey return;
1656ba597c5SAnurag S. Maskey }
1666ba597c5SAnurag S. Maskey
1676ba597c5SAnurag S. Maskey ncu = object->nwamd_object_data;
168f6da83d4SAnurag S. Maskey link = &ncu->ncu_link;
1696ba597c5SAnurag S. Maskey
1706ba597c5SAnurag S. Maskey switch (object->nwamd_object_aux_state) {
1716ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_INITIALIZED:
1726ba597c5SAnurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_LINK) {
1736ba597c5SAnurag S. Maskey /*
1746ba597c5SAnurag S. Maskey * For wired/wireless links, need to get link
1756ba597c5SAnurag S. Maskey * up/down events and even if these are not supported,
1766ba597c5SAnurag S. Maskey * dlpi_open()ing the link prevents the driver from
1776ba597c5SAnurag S. Maskey * being unloaded.
1786ba597c5SAnurag S. Maskey */
1796ba597c5SAnurag S. Maskey nwamd_dlpi_add_link(object);
1806ba597c5SAnurag S. Maskey
1816ba597c5SAnurag S. Maskey if (link->nwamd_link_media == DL_WIFI) {
1826ba597c5SAnurag S. Maskey /*
1836ba597c5SAnurag S. Maskey * First, if we're unexpectedly connected,
1846ba597c5SAnurag S. Maskey * disconnect.
1856ba597c5SAnurag S. Maskey */
1866ba597c5SAnurag S. Maskey if (!link->nwamd_link_wifi_connected &&
1876ba597c5SAnurag S. Maskey nwamd_wlan_connected(object)) {
1886ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
1896ba597c5SAnurag S. Maskey "nwamd_ncu_state_machine: "
1906ba597c5SAnurag S. Maskey "WiFi unexpectedly connected, "
1916ba597c5SAnurag S. Maskey "disconnecting...");
1926ba597c5SAnurag S. Maskey (void) dladm_wlan_disconnect(dld_handle,
1936ba597c5SAnurag S. Maskey link->nwamd_link_id);
1946ba597c5SAnurag S. Maskey nwamd_set_selected_connected(ncu,
1956ba597c5SAnurag S. Maskey B_FALSE, B_FALSE);
1966ba597c5SAnurag S. Maskey }
1976ba597c5SAnurag S. Maskey /* move to scanning aux state */
1986ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
1996ba597c5SAnurag S. Maskey object_name, object->nwamd_object_state,
2006ba597c5SAnurag S. Maskey NWAM_AUX_STATE_LINK_WIFI_SCANNING);
2016ba597c5SAnurag S. Maskey } else {
2026ba597c5SAnurag S. Maskey /*
2036ba597c5SAnurag S. Maskey * If initial wired link state is unknown, we
2046ba597c5SAnurag S. Maskey * will need to assume the link is up, since
2056ba597c5SAnurag S. Maskey * we won´t get DL_NOTE_LINK_UP/DOWN events.
2066ba597c5SAnurag S. Maskey */
2076ba597c5SAnurag S. Maskey link_state = nwamd_get_link_state
2086ba597c5SAnurag S. Maskey (ncu->ncu_name);
2096ba597c5SAnurag S. Maskey if (link_state == LINK_STATE_UP ||
2106ba597c5SAnurag S. Maskey link_state == LINK_STATE_UNKNOWN) {
2116ba597c5SAnurag S. Maskey nwamd_object_set_state
2126ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU,
2136ba597c5SAnurag S. Maskey object_name, NWAM_STATE_ONLINE,
2146ba597c5SAnurag S. Maskey NWAM_AUX_STATE_UP);
2156ba597c5SAnurag S. Maskey } else {
2166ba597c5SAnurag S. Maskey nwamd_object_set_state
2176ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU,
2186ba597c5SAnurag S. Maskey object_name,
2196ba597c5SAnurag S. Maskey NWAM_STATE_ONLINE_TO_OFFLINE,
2206ba597c5SAnurag S. Maskey NWAM_AUX_STATE_DOWN);
2216ba597c5SAnurag S. Maskey }
2226ba597c5SAnurag S. Maskey }
2236ba597c5SAnurag S. Maskey } else {
2246ba597c5SAnurag S. Maskey /*
2256ba597c5SAnurag S. Maskey * In the current implementation, initialization has to
2266ba597c5SAnurag S. Maskey * start from scratch since the complexity of minimizing
2276ba597c5SAnurag S. Maskey * configuration change is considerable (e.g. if we
2286ba597c5SAnurag S. Maskey * refresh and had DHCP running on the physical
2296ba597c5SAnurag S. Maskey * interface, and now have changed to static assignment,
2306ba597c5SAnurag S. Maskey * we need to remove DHCP etc). To avoid all this,
2316ba597c5SAnurag S. Maskey * unplumb before re-plumbing the protocols and
2326ba597c5SAnurag S. Maskey * addresses we wish to configure. In the future, it
2336ba597c5SAnurag S. Maskey * would be good to try and minimize configuration
2346ba597c5SAnurag S. Maskey * changes.
2356ba597c5SAnurag S. Maskey */
236f6da83d4SAnurag S. Maskey nwamd_unplumb_interface(ncu, AF_INET);
237f6da83d4SAnurag S. Maskey nwamd_unplumb_interface(ncu, AF_INET6);
238f6da83d4SAnurag S. Maskey
239f6da83d4SAnurag S. Maskey /*
240f6da83d4SAnurag S. Maskey * We may be restarting the state machine. Re-read
241f6da83d4SAnurag S. Maskey * the IP NCU properties as the ipadm_addrobj_t in
242f6da83d4SAnurag S. Maskey * nwamd_if_address should not be reused.
243f6da83d4SAnurag S. Maskey */
244f6da83d4SAnurag S. Maskey populate_ip_ncu_properties(object->nwamd_object_handle,
245f6da83d4SAnurag S. Maskey ncu);
2466ba597c5SAnurag S. Maskey
2476ba597c5SAnurag S. Maskey /*
2486ba597c5SAnurag S. Maskey * Enqueue a WAITING_FOR_ADDR aux state change so that
2496ba597c5SAnurag S. Maskey * we are eligible to receive the IF_STATE events
2506ba597c5SAnurag S. Maskey * associated with static, DHCP, DHCPv6 and autoconf
2516ba597c5SAnurag S. Maskey * address assignment. The latter two can happen
2526ba597c5SAnurag S. Maskey * quite quickly after plumbing so we need to be ready.
2536ba597c5SAnurag S. Maskey */
2546ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
2556ba597c5SAnurag S. Maskey object_name, NWAM_STATE_OFFLINE_TO_ONLINE,
2566ba597c5SAnurag S. Maskey NWAM_AUX_STATE_IF_WAITING_FOR_ADDR);
2576ba597c5SAnurag S. Maskey
258f6da83d4SAnurag S. Maskey if (ncu->ncu_if.nwamd_if_ipv4)
259f6da83d4SAnurag S. Maskey nwamd_plumb_interface(ncu, AF_INET);
2606ba597c5SAnurag S. Maskey
261f6da83d4SAnurag S. Maskey if (ncu->ncu_if.nwamd_if_ipv6)
262f6da83d4SAnurag S. Maskey nwamd_plumb_interface(ncu, AF_INET6);
2636ba597c5SAnurag S. Maskey
264f6da83d4SAnurag S. Maskey /* Configure addresses */
2656ba597c5SAnurag S. Maskey nwamd_configure_interface_addresses(ncu);
2666ba597c5SAnurag S. Maskey }
2676ba597c5SAnurag S. Maskey break;
2686ba597c5SAnurag S. Maskey
2696ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_IF_DHCP_TIMED_OUT:
2706ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_IF_WAITING_FOR_ADDR:
2716ba597c5SAnurag S. Maskey /*
2726ba597c5SAnurag S. Maskey * nothing to do here - RTM_NEWADDRs will trigger IF_STATE
2736ba597c5SAnurag S. Maskey * events to move us online.
2746ba597c5SAnurag S. Maskey */
2756ba597c5SAnurag S. Maskey break;
2766ba597c5SAnurag S. Maskey
2776ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_LINK_WIFI_SCANNING:
2786ba597c5SAnurag S. Maskey /* launch scan thread */
2796ba597c5SAnurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name, sizeof (linkname));
2806ba597c5SAnurag S. Maskey (void) nwamd_wlan_scan(linkname);
2816ba597c5SAnurag S. Maskey /* Create periodic scan event */
2826ba597c5SAnurag S. Maskey nwamd_ncu_create_periodic_scan_event(object);
2836ba597c5SAnurag S. Maskey break;
2846ba597c5SAnurag S. Maskey
2856ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_LINK_WIFI_NEED_SELECTION:
2866ba597c5SAnurag S. Maskey /* send "need choice" event */
2876ba597c5SAnurag S. Maskey event = nwamd_event_init_wlan
2886ba597c5SAnurag S. Maskey (ncu->ncu_name, NWAM_EVENT_TYPE_WLAN_NEED_CHOICE, B_FALSE,
2896ba597c5SAnurag S. Maskey link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr,
2906ba597c5SAnurag S. Maskey link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr_num);
2916ba597c5SAnurag S. Maskey if (event == NULL)
2926ba597c5SAnurag S. Maskey break;
2936ba597c5SAnurag S. Maskey nwamd_event_enqueue(event);
2946ba597c5SAnurag S. Maskey nwamd_set_selected_connected(ncu, B_FALSE, B_FALSE);
2956ba597c5SAnurag S. Maskey break;
2966ba597c5SAnurag S. Maskey
2976ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_LINK_WIFI_NEED_KEY:
2986ba597c5SAnurag S. Maskey /*
2996ba597c5SAnurag S. Maskey * Send "need key" event. Set selected to true, connected
3006ba597c5SAnurag S. Maskey * and have_key to false. Do not fill in WLAN details as
3016ba597c5SAnurag S. Maskey * multiple WLANs may match the ESSID name, and each may
3026ba597c5SAnurag S. Maskey * have a different speed and channel.
3036ba597c5SAnurag S. Maskey */
3046ba597c5SAnurag S. Maskey bzero(&key_wlan, sizeof (key_wlan));
3056ba597c5SAnurag S. Maskey (void) strlcpy(key_wlan.nww_essid, link->nwamd_link_wifi_essid,
3066ba597c5SAnurag S. Maskey sizeof (key_wlan.nww_essid));
3076ba597c5SAnurag S. Maskey (void) strlcpy(key_wlan.nww_bssid, link->nwamd_link_wifi_bssid,
3086ba597c5SAnurag S. Maskey sizeof (key_wlan.nww_bssid));
3096ba597c5SAnurag S. Maskey key_wlan.nww_security_mode =
3106ba597c5SAnurag S. Maskey link->nwamd_link_wifi_security_mode;
3116ba597c5SAnurag S. Maskey key_wlan.nww_selected = B_TRUE;
3126ba597c5SAnurag S. Maskey key_wlan.nww_connected = B_FALSE;
3136ba597c5SAnurag S. Maskey key_wlan.nww_have_key = B_FALSE;
3146ba597c5SAnurag S. Maskey event = nwamd_event_init_wlan
3156ba597c5SAnurag S. Maskey (ncu->ncu_name, NWAM_EVENT_TYPE_WLAN_NEED_KEY, B_FALSE,
3166ba597c5SAnurag S. Maskey &key_wlan, 1);
3176ba597c5SAnurag S. Maskey if (event == NULL)
3186ba597c5SAnurag S. Maskey break;
3196ba597c5SAnurag S. Maskey nwamd_event_enqueue(event);
3206ba597c5SAnurag S. Maskey break;
3216ba597c5SAnurag S. Maskey
3226ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_LINK_WIFI_CONNECTING:
3236ba597c5SAnurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name, sizeof (linkname));
3246ba597c5SAnurag S. Maskey nwamd_wlan_connect(linkname);
3256ba597c5SAnurag S. Maskey break;
3266ba597c5SAnurag S. Maskey
3276ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_UP:
3286ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_DOWN:
3296ba597c5SAnurag S. Maskey up = (object->nwamd_object_aux_state == NWAM_AUX_STATE_UP);
3306ba597c5SAnurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_LINK) {
3316ba597c5SAnurag S. Maskey if (link->nwamd_link_media == DL_WIFI) {
3326ba597c5SAnurag S. Maskey /*
3336ba597c5SAnurag S. Maskey * Connected/disconnected - send WLAN
3346ba597c5SAnurag S. Maskey * connection report.
3356ba597c5SAnurag S. Maskey */
3366ba597c5SAnurag S. Maskey link->nwamd_link_wifi_connected = up;
3376ba597c5SAnurag S. Maskey nwamd_set_selected_connected(ncu, B_TRUE, up);
3386ba597c5SAnurag S. Maskey
3396ba597c5SAnurag S. Maskey (void) strlcpy(connected_wlan.nww_essid,
3406ba597c5SAnurag S. Maskey link->nwamd_link_wifi_essid,
3416ba597c5SAnurag S. Maskey sizeof (connected_wlan.nww_essid));
3426ba597c5SAnurag S. Maskey (void) strlcpy(connected_wlan.nww_bssid,
3436ba597c5SAnurag S. Maskey link->nwamd_link_wifi_bssid,
3446ba597c5SAnurag S. Maskey sizeof (connected_wlan.nww_bssid));
3456ba597c5SAnurag S. Maskey connected_wlan.nww_security_mode =
3466ba597c5SAnurag S. Maskey link->nwamd_link_wifi_security_mode;
3476ba597c5SAnurag S. Maskey event = nwamd_event_init_wlan
3486ba597c5SAnurag S. Maskey (ncu->ncu_name,
3496ba597c5SAnurag S. Maskey NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT, up,
3506ba597c5SAnurag S. Maskey &connected_wlan, 1);
3516ba597c5SAnurag S. Maskey if (event == NULL)
3526ba597c5SAnurag S. Maskey break;
3536ba597c5SAnurag S. Maskey nwamd_event_enqueue(event);
3546ba597c5SAnurag S. Maskey
3556ba597c5SAnurag S. Maskey /*
3566ba597c5SAnurag S. Maskey * If disconnected, restart the state machine
3576ba597c5SAnurag S. Maskey * for the WiFi link (WiFi is always trying
3586ba597c5SAnurag S. Maskey * to connect).
3596ba597c5SAnurag S. Maskey *
3606ba597c5SAnurag S. Maskey * If connected, start signal strength
3616ba597c5SAnurag S. Maskey * monitoring thread.
3626ba597c5SAnurag S. Maskey */
3636ba597c5SAnurag S. Maskey if (!up && ncu->ncu_enabled) {
3646ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
3656ba597c5SAnurag S. Maskey "nwamd_ncu_state_machine: "
3666ba597c5SAnurag S. Maskey "wifi disconnect - start over "
3676ba597c5SAnurag S. Maskey "after %dsec interval",
3686ba597c5SAnurag S. Maskey WIRELESS_RETRY_INTERVAL);
3696ba597c5SAnurag S. Maskey link->nwamd_link_wifi_connected =
3706ba597c5SAnurag S. Maskey B_FALSE;
3716ba597c5SAnurag S. Maskey /* propogate down event to IP NCU */
3726ba597c5SAnurag S. Maskey nwamd_propogate_link_up_down_to_ip
3736ba597c5SAnurag S. Maskey (ncu->ncu_name, B_FALSE);
3746ba597c5SAnurag S. Maskey nwamd_object_set_state_timed
3756ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU, object_name,
3766ba597c5SAnurag S. Maskey NWAM_STATE_OFFLINE_TO_ONLINE,
3776ba597c5SAnurag S. Maskey NWAM_AUX_STATE_INITIALIZED,
3786ba597c5SAnurag S. Maskey WIRELESS_RETRY_INTERVAL);
3796ba597c5SAnurag S. Maskey } else {
3806ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
3816ba597c5SAnurag S. Maskey "nwamd_ncu_state_machine: "
3826ba597c5SAnurag S. Maskey "wifi connected, start monitoring");
3836ba597c5SAnurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name,
3846ba597c5SAnurag S. Maskey sizeof (linkname));
3856ba597c5SAnurag S. Maskey nwamd_wlan_monitor_signal(linkname);
3866ba597c5SAnurag S. Maskey }
3876ba597c5SAnurag S. Maskey }
3886ba597c5SAnurag S. Maskey }
3896ba597c5SAnurag S. Maskey
3906ba597c5SAnurag S. Maskey /* If not in ONLINE/OFFLINE state yet, change state */
3916ba597c5SAnurag S. Maskey if ((up && object->nwamd_object_state != NWAM_STATE_ONLINE) ||
3926ba597c5SAnurag S. Maskey (!up && object->nwamd_object_state != NWAM_STATE_OFFLINE)) {
3936ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_state_machine: "
3946ba597c5SAnurag S. Maskey "%s is moving %s", object_name,
3956ba597c5SAnurag S. Maskey up ? "online" : "offline");
3966ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
3976ba597c5SAnurag S. Maskey object_name,
3986ba597c5SAnurag S. Maskey up ? NWAM_STATE_ONLINE : NWAM_STATE_OFFLINE,
3996ba597c5SAnurag S. Maskey up ? NWAM_AUX_STATE_UP : NWAM_AUX_STATE_DOWN);
4006ba597c5SAnurag S. Maskey
4016ba597c5SAnurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_INTERFACE) {
4026ba597c5SAnurag S. Maskey if (up) {
4036ba597c5SAnurag S. Maskey /*
4046ba597c5SAnurag S. Maskey * Moving online, add v4/v6 default
4056ba597c5SAnurag S. Maskey * routes (if any).
4066ba597c5SAnurag S. Maskey */
4076ba597c5SAnurag S. Maskey nwamd_add_default_routes(ncu);
4086ba597c5SAnurag S. Maskey } else {
4096ba597c5SAnurag S. Maskey /*
4106ba597c5SAnurag S. Maskey * If this is an interface NCU and we
4116ba597c5SAnurag S. Maskey * got a down event, it is a consequence
4126ba597c5SAnurag S. Maskey * of NCU refresh, so reapply addresses
4136ba597c5SAnurag S. Maskey * by reinitializing.
4146ba597c5SAnurag S. Maskey */
4156ba597c5SAnurag S. Maskey nwamd_object_set_state
4166ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU, object_name,
4176ba597c5SAnurag S. Maskey NWAM_STATE_OFFLINE_TO_ONLINE,
4186ba597c5SAnurag S. Maskey NWAM_AUX_STATE_INITIALIZED);
4196ba597c5SAnurag S. Maskey }
4206ba597c5SAnurag S. Maskey }
4216ba597c5SAnurag S. Maskey } else {
4226ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_state_machine: "
4236ba597c5SAnurag S. Maskey "%s is %s", object_name,
4246ba597c5SAnurag S. Maskey up ? "online" : "offline");
4256ba597c5SAnurag S. Maskey }
4266ba597c5SAnurag S. Maskey /*
4276ba597c5SAnurag S. Maskey * NCU is UP or DOWN, trigger all condition checking, even if
4286ba597c5SAnurag S. Maskey * the NCU is already in the ONLINE state - an ENM may depend
4296ba597c5SAnurag S. Maskey * on NCU activity.
4306ba597c5SAnurag S. Maskey */
4316ba597c5SAnurag S. Maskey nwamd_create_triggered_condition_check_event(NEXT_FEW_SECONDS);
4326ba597c5SAnurag S. Maskey break;
4336ba597c5SAnurag S. Maskey
4346ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_CONDITIONS_NOT_MET:
4356ba597c5SAnurag S. Maskey /*
4366ba597c5SAnurag S. Maskey * Link/interface is moving offline. Nothing to do except
4376ba597c5SAnurag S. Maskey * for WiFi, where we disconnect. Don't unplumb IP on
4386ba597c5SAnurag S. Maskey * a link since it may be a transient change.
4396ba597c5SAnurag S. Maskey */
4406ba597c5SAnurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_LINK) {
4416ba597c5SAnurag S. Maskey if (link->nwamd_link_media == DL_WIFI) {
4426ba597c5SAnurag S. Maskey (void) dladm_wlan_disconnect(dld_handle,
4436ba597c5SAnurag S. Maskey link->nwamd_link_id);
4446ba597c5SAnurag S. Maskey link->nwamd_link_wifi_connected = B_FALSE;
4456ba597c5SAnurag S. Maskey nwamd_set_selected_connected(ncu, B_FALSE,
4466ba597c5SAnurag S. Maskey B_FALSE);
4476ba597c5SAnurag S. Maskey }
4486ba597c5SAnurag S. Maskey } else {
4496ba597c5SAnurag S. Maskey /*
4506ba597c5SAnurag S. Maskey * Unplumb here. In the future we may elaborate on
4516ba597c5SAnurag S. Maskey * the approach used and not unplumb for WiFi
4526ba597c5SAnurag S. Maskey * until we reconnect to a different WLAN (i.e. with
4536ba597c5SAnurag S. Maskey * a different ESSID).
4546ba597c5SAnurag S. Maskey */
455f6da83d4SAnurag S. Maskey nwamd_unplumb_interface(ncu, AF_INET);
456f6da83d4SAnurag S. Maskey nwamd_unplumb_interface(ncu, AF_INET6);
4576ba597c5SAnurag S. Maskey }
4586ba597c5SAnurag S. Maskey if (object->nwamd_object_state != NWAM_STATE_OFFLINE) {
4596ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
4606ba597c5SAnurag S. Maskey object_name, NWAM_STATE_OFFLINE,
4616ba597c5SAnurag S. Maskey NWAM_AUX_STATE_CONDITIONS_NOT_MET);
4626ba597c5SAnurag S. Maskey }
4636ba597c5SAnurag S. Maskey break;
4646ba597c5SAnurag S. Maskey
4656ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_MANUAL_DISABLE:
4666ba597c5SAnurag S. Maskey /* Manual disable, set enabled state appropriately. */
4676ba597c5SAnurag S. Maskey ncu->ncu_enabled = B_FALSE;
4686ba597c5SAnurag S. Maskey /* FALLTHROUGH */
4696ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_UNINITIALIZED:
4706ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_NOT_FOUND:
4716ba597c5SAnurag S. Maskey /*
4726ba597c5SAnurag S. Maskey * Link/interface NCU has been disabled/deactivated/removed.
4736ba597c5SAnurag S. Maskey * For WiFi links disconnect, and for IP interfaces we unplumb.
4746ba597c5SAnurag S. Maskey */
4756ba597c5SAnurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_LINK) {
4766ba597c5SAnurag S. Maskey if (link->nwamd_link_media == DL_WIFI) {
4776ba597c5SAnurag S. Maskey (void) dladm_wlan_disconnect(dld_handle,
4786ba597c5SAnurag S. Maskey link->nwamd_link_id);
4796ba597c5SAnurag S. Maskey link->nwamd_link_wifi_connected = B_FALSE;
4806ba597c5SAnurag S. Maskey nwamd_set_selected_connected(ncu, B_FALSE,
4816ba597c5SAnurag S. Maskey B_FALSE);
4826ba597c5SAnurag S. Maskey }
4836ba597c5SAnurag S. Maskey nwamd_dlpi_delete_link(object);
4846ba597c5SAnurag S. Maskey } else {
4856ba597c5SAnurag S. Maskey /* Unplumb here. */
486f6da83d4SAnurag S. Maskey if (ncu->ncu_if.nwamd_if_ipv4) {
487f6da83d4SAnurag S. Maskey nwamd_unplumb_interface(ncu, AF_INET);
4886ba597c5SAnurag S. Maskey }
489f6da83d4SAnurag S. Maskey if (ncu->ncu_if.nwamd_if_ipv6) {
490f6da83d4SAnurag S. Maskey nwamd_unplumb_interface(ncu, AF_INET6);
4916ba597c5SAnurag S. Maskey }
4926ba597c5SAnurag S. Maskey /* trigger location condition checking */
4936ba597c5SAnurag S. Maskey nwamd_create_triggered_condition_check_event(0);
4946ba597c5SAnurag S. Maskey }
4956ba597c5SAnurag S. Maskey
4966ba597c5SAnurag S. Maskey switch (object->nwamd_object_aux_state) {
4976ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_MANUAL_DISABLE:
4986ba597c5SAnurag S. Maskey /* Change state to DISABLED if manually disabled */
4996ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
5006ba597c5SAnurag S. Maskey object_name, NWAM_STATE_DISABLED,
5016ba597c5SAnurag S. Maskey NWAM_AUX_STATE_MANUAL_DISABLE);
5026ba597c5SAnurag S. Maskey /* Note that NCU has been disabled */
5036ba597c5SAnurag S. Maskey ncu->ncu_enabled = B_FALSE;
5046ba597c5SAnurag S. Maskey break;
5056ba597c5SAnurag S. Maskey case NWAM_AUX_STATE_NOT_FOUND:
5066ba597c5SAnurag S. Maskey /* Change state to UNINITIALIZED for device removal */
5076ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
5086ba597c5SAnurag S. Maskey object_name, NWAM_STATE_UNINITIALIZED,
5096ba597c5SAnurag S. Maskey NWAM_AUX_STATE_NOT_FOUND);
5106ba597c5SAnurag S. Maskey break;
5116ba597c5SAnurag S. Maskey default:
5126ba597c5SAnurag S. Maskey break;
5136ba597c5SAnurag S. Maskey }
5146ba597c5SAnurag S. Maskey break;
5156ba597c5SAnurag S. Maskey default:
5166ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_state_machine: unexpected state");
5176ba597c5SAnurag S. Maskey break;
5186ba597c5SAnurag S. Maskey }
5196ba597c5SAnurag S. Maskey
5206ba597c5SAnurag S. Maskey nwamd_object_release(object);
5216ba597c5SAnurag S. Maskey }
5226ba597c5SAnurag S. Maskey
5236ba597c5SAnurag S. Maskey static int
ncu_create_init_fini_event(nwam_ncu_handle_t ncuh,void * data)5246ba597c5SAnurag S. Maskey ncu_create_init_fini_event(nwam_ncu_handle_t ncuh, void *data)
5256ba597c5SAnurag S. Maskey {
5266ba597c5SAnurag S. Maskey boolean_t *init = data;
5276ba597c5SAnurag S. Maskey char *name, *typedname;
5286ba597c5SAnurag S. Maskey nwam_error_t err;
5296ba597c5SAnurag S. Maskey nwam_value_t typeval = NULL;
5306ba597c5SAnurag S. Maskey uint64_t *type;
5316ba597c5SAnurag S. Maskey uint_t numvalues;
5326ba597c5SAnurag S. Maskey nwamd_event_t ncu_event;
5336ba597c5SAnurag S. Maskey
5346ba597c5SAnurag S. Maskey if (nwam_ncu_get_name(ncuh, &name) != NWAM_SUCCESS) {
5356ba597c5SAnurag S. Maskey nlog(LOG_ERR,
5366ba597c5SAnurag S. Maskey "ncu_create_init_fini_event: could not get NCU name");
5376ba597c5SAnurag S. Maskey return (0);
5386ba597c5SAnurag S. Maskey }
5396ba597c5SAnurag S. Maskey
5406ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "ncu_create_init_fini_event(%s, %p)", name, data);
5416ba597c5SAnurag S. Maskey
5426ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &typeval, &type, &numvalues,
5436ba597c5SAnurag S. Maskey NWAM_NCU_PROP_TYPE)) != NWAM_SUCCESS) {
5446ba597c5SAnurag S. Maskey nlog(LOG_ERR, "ncu_create_init_fini_event: "
5456ba597c5SAnurag S. Maskey "could not get NCU type: %s", nwam_strerror(err));
5466ba597c5SAnurag S. Maskey free(name);
5476ba597c5SAnurag S. Maskey nwam_value_free(typeval);
5486ba597c5SAnurag S. Maskey return (0);
5496ba597c5SAnurag S. Maskey }
5506ba597c5SAnurag S. Maskey
5516ba597c5SAnurag S. Maskey /* convert name to typedname for event */
5526ba597c5SAnurag S. Maskey if ((err = nwam_ncu_name_to_typed_name(name, *type, &typedname))
5536ba597c5SAnurag S. Maskey != NWAM_SUCCESS) {
5546ba597c5SAnurag S. Maskey nlog(LOG_ERR, "ncu_create_init_fini_event: "
5556ba597c5SAnurag S. Maskey "NCU name translation failed: %s", nwam_strerror(err));
5566ba597c5SAnurag S. Maskey free(name);
5576ba597c5SAnurag S. Maskey return (0);
5586ba597c5SAnurag S. Maskey }
5596ba597c5SAnurag S. Maskey free(name);
5606ba597c5SAnurag S. Maskey nwam_value_free(typeval);
5616ba597c5SAnurag S. Maskey
5626ba597c5SAnurag S. Maskey ncu_event = nwamd_event_init(*init ?
5636ba597c5SAnurag S. Maskey NWAM_EVENT_TYPE_OBJECT_INIT : NWAM_EVENT_TYPE_OBJECT_FINI,
5646ba597c5SAnurag S. Maskey NWAM_OBJECT_TYPE_NCU, 0, typedname);
5656ba597c5SAnurag S. Maskey if (ncu_event != NULL)
5666ba597c5SAnurag S. Maskey nwamd_event_enqueue(ncu_event);
5676ba597c5SAnurag S. Maskey free(typedname);
5686ba597c5SAnurag S. Maskey
5696ba597c5SAnurag S. Maskey return (0);
5706ba597c5SAnurag S. Maskey }
5716ba597c5SAnurag S. Maskey
5726ba597c5SAnurag S. Maskey /*
5736ba597c5SAnurag S. Maskey * Initialization - walk the NCUs, creating initialization events for each
5746ba597c5SAnurag S. Maskey * NCU. nwamd_ncu_handle_init_event() will check if the associated
5756ba597c5SAnurag S. Maskey * physical link exists or not.
5766ba597c5SAnurag S. Maskey */
5776ba597c5SAnurag S. Maskey void
nwamd_init_ncus(void)5786ba597c5SAnurag S. Maskey nwamd_init_ncus(void)
5796ba597c5SAnurag S. Maskey {
5806ba597c5SAnurag S. Maskey boolean_t init = B_TRUE;
5816ba597c5SAnurag S. Maskey
5826ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
5836ba597c5SAnurag S. Maskey if (active_ncph != NULL) {
5846ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_init_ncus: "
5856ba597c5SAnurag S. Maskey "(re)intializing NCUs for NCP %s", active_ncp);
5866ba597c5SAnurag S. Maskey (void) nwam_ncp_walk_ncus(active_ncph,
5876ba597c5SAnurag S. Maskey ncu_create_init_fini_event, &init, NWAM_FLAG_NCU_TYPE_ALL,
5886ba597c5SAnurag S. Maskey NULL);
5896ba597c5SAnurag S. Maskey }
5906ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
5916ba597c5SAnurag S. Maskey }
5926ba597c5SAnurag S. Maskey
5936ba597c5SAnurag S. Maskey void
nwamd_fini_ncus(void)5946ba597c5SAnurag S. Maskey nwamd_fini_ncus(void)
5956ba597c5SAnurag S. Maskey {
5966ba597c5SAnurag S. Maskey boolean_t init = B_FALSE;
5976ba597c5SAnurag S. Maskey
5986ba597c5SAnurag S. Maskey /* We may not have an active NCP on initialization, so skip fini */
5996ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
6006ba597c5SAnurag S. Maskey if (active_ncph != NULL) {
6016ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_fini_ncus: deinitializing NCUs for %s",
6026ba597c5SAnurag S. Maskey active_ncp);
6036ba597c5SAnurag S. Maskey (void) nwam_ncp_walk_ncus(active_ncph,
6046ba597c5SAnurag S. Maskey ncu_create_init_fini_event, &init, NWAM_FLAG_NCU_TYPE_ALL,
6056ba597c5SAnurag S. Maskey NULL);
6066ba597c5SAnurag S. Maskey }
6076ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
6086ba597c5SAnurag S. Maskey }
6096ba597c5SAnurag S. Maskey
6106ba597c5SAnurag S. Maskey /*
6116ba597c5SAnurag S. Maskey * Most properties of this type don't need to be cached locally. Only those
6126ba597c5SAnurag S. Maskey * interesting to the daemon are stored in an nwamd_ncu_t.
6136ba597c5SAnurag S. Maskey */
6146ba597c5SAnurag S. Maskey static void
populate_common_ncu_properties(nwam_ncu_handle_t ncuh,nwamd_ncu_t * ncu_data)6156ba597c5SAnurag S. Maskey populate_common_ncu_properties(nwam_ncu_handle_t ncuh, nwamd_ncu_t *ncu_data)
6166ba597c5SAnurag S. Maskey {
6176ba597c5SAnurag S. Maskey nwam_value_t ncu_prop;
6186ba597c5SAnurag S. Maskey nwam_error_t err;
6196ba597c5SAnurag S. Maskey boolean_t enablevalue;
6206ba597c5SAnurag S. Maskey uint_t numvalues;
6216ba597c5SAnurag S. Maskey char **parent;
6226ba597c5SAnurag S. Maskey
6236ba597c5SAnurag S. Maskey if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ENABLED,
6246ba597c5SAnurag S. Maskey &ncu_prop)) != NWAM_SUCCESS) {
6256ba597c5SAnurag S. Maskey char *name;
6266ba597c5SAnurag S. Maskey (void) nwam_ncu_name_to_typed_name(ncu_data->ncu_name,
6276ba597c5SAnurag S. Maskey ncu_data->ncu_type, &name);
6286ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwam_ncu_get_prop_value %s ENABLED failed: %s",
6296ba597c5SAnurag S. Maskey name, nwam_strerror(err));
6306ba597c5SAnurag S. Maskey free(name);
6316ba597c5SAnurag S. Maskey ncu_data->ncu_enabled = B_TRUE;
6326ba597c5SAnurag S. Maskey } else {
6336ba597c5SAnurag S. Maskey if ((err = nwam_value_get_boolean(ncu_prop, &enablevalue)) !=
6346ba597c5SAnurag S. Maskey NWAM_SUCCESS) {
6356ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwam_value_get_boolean ENABLED failed: "
6366ba597c5SAnurag S. Maskey "%s", nwam_strerror(err));
6376ba597c5SAnurag S. Maskey } else {
6386ba597c5SAnurag S. Maskey ncu_data->ncu_enabled = enablevalue;
6396ba597c5SAnurag S. Maskey }
6406ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
6416ba597c5SAnurag S. Maskey }
6426ba597c5SAnurag S. Maskey
6436ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &parent,
6446ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_PARENT_NCP)) != NWAM_SUCCESS) {
6456ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwam_ncu_get_prop_value %s PARENT failed: %s",
6466ba597c5SAnurag S. Maskey ncu_data->ncu_name, nwam_strerror(err));
6476ba597c5SAnurag S. Maskey } else {
6486ba597c5SAnurag S. Maskey (void) strlcpy(ncu_data->ncu_parent, parent[0],
6496ba597c5SAnurag S. Maskey sizeof (ncu_data->ncu_parent));
6506ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
6516ba597c5SAnurag S. Maskey }
6526ba597c5SAnurag S. Maskey }
6536ba597c5SAnurag S. Maskey
6546ba597c5SAnurag S. Maskey /*
6556ba597c5SAnurag S. Maskey * Read in link properties.
6566ba597c5SAnurag S. Maskey */
6576ba597c5SAnurag S. Maskey static void
populate_link_ncu_properties(nwam_ncu_handle_t ncuh,nwamd_ncu_t * ncu_data)6586ba597c5SAnurag S. Maskey populate_link_ncu_properties(nwam_ncu_handle_t ncuh, nwamd_ncu_t *ncu_data)
6596ba597c5SAnurag S. Maskey {
6606ba597c5SAnurag S. Maskey nwam_value_t ncu_prop;
6616ba597c5SAnurag S. Maskey nwam_error_t err;
6626ba597c5SAnurag S. Maskey char **mac_addr;
6636ba597c5SAnurag S. Maskey uint64_t *uintval;
6646ba597c5SAnurag S. Maskey uint_t numvalues;
6656ba597c5SAnurag S. Maskey
6666ba597c5SAnurag S. Maskey /* activation-mode */
6676ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval, &numvalues,
6686ba597c5SAnurag S. Maskey NWAM_NCU_PROP_ACTIVATION_MODE)) != NWAM_SUCCESS) {
6696ba597c5SAnurag S. Maskey nlog(LOG_ERR,
6706ba597c5SAnurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
6716ba597c5SAnurag S. Maskey NWAM_NCU_PROP_ACTIVATION_MODE, nwam_strerror(err));
6726ba597c5SAnurag S. Maskey } else {
673f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_activation_mode = uintval[0];
6746ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
6756ba597c5SAnurag S. Maskey }
6766ba597c5SAnurag S. Maskey
6776ba597c5SAnurag S. Maskey /* priority-group and priority-mode for prioritized activation */
678f6da83d4SAnurag S. Maskey if (ncu_data->ncu_link.nwamd_link_activation_mode ==
6796ba597c5SAnurag S. Maskey NWAM_ACTIVATION_MODE_PRIORITIZED) {
6806ba597c5SAnurag S. Maskey /* ncus with prioritized activation are always enabled */
6816ba597c5SAnurag S. Maskey ncu_data->ncu_enabled = B_TRUE;
6826ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval,
6836ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_PRIORITY_MODE))
6846ba597c5SAnurag S. Maskey != NWAM_SUCCESS) {
6856ba597c5SAnurag S. Maskey nlog(LOG_ERR, "populate_link_ncu_properties: "
6866ba597c5SAnurag S. Maskey "could not get %s value: %s",
6876ba597c5SAnurag S. Maskey NWAM_NCU_PROP_PRIORITY_MODE, nwam_strerror(err));
6886ba597c5SAnurag S. Maskey } else {
689f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_priority_mode =
6906ba597c5SAnurag S. Maskey uintval[0];
6916ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
6926ba597c5SAnurag S. Maskey }
6936ba597c5SAnurag S. Maskey
6946ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval,
6956ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_PRIORITY_GROUP))
6966ba597c5SAnurag S. Maskey != NWAM_SUCCESS) {
6976ba597c5SAnurag S. Maskey nlog(LOG_ERR, "populate_link_ncu_properties: "
6986ba597c5SAnurag S. Maskey "could not get %s value: %s",
6996ba597c5SAnurag S. Maskey NWAM_NCU_PROP_PRIORITY_GROUP, nwam_strerror(err));
7006ba597c5SAnurag S. Maskey } else {
701f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_priority_group =
7026ba597c5SAnurag S. Maskey uintval[0];
7036ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
7046ba597c5SAnurag S. Maskey }
7056ba597c5SAnurag S. Maskey }
7066ba597c5SAnurag S. Maskey
7076ba597c5SAnurag S. Maskey /* link-mac-addr */
7086ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &mac_addr, &numvalues,
7096ba597c5SAnurag S. Maskey NWAM_NCU_PROP_LINK_MAC_ADDR)) != NWAM_SUCCESS) {
7106ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
7116ba597c5SAnurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
7126ba597c5SAnurag S. Maskey NWAM_NCU_PROP_LINK_MAC_ADDR, nwam_strerror(err));
713f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_mac_addr = NULL;
7146ba597c5SAnurag S. Maskey } else {
715f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_mac_addr = strdup(*mac_addr);
716f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_mac_addr_len = strlen(*mac_addr);
7176ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
7186ba597c5SAnurag S. Maskey }
7196ba597c5SAnurag S. Maskey
7206ba597c5SAnurag S. Maskey /* link-mtu */
7216ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &uintval, &numvalues,
7226ba597c5SAnurag S. Maskey NWAM_NCU_PROP_LINK_MTU)) != NWAM_SUCCESS) {
7236ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
7246ba597c5SAnurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
7256ba597c5SAnurag S. Maskey NWAM_NCU_PROP_LINK_MTU, nwam_strerror(err));
726f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_mtu = 0;
7276ba597c5SAnurag S. Maskey } else {
728f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_mtu = uintval[0];
7296ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
7306ba597c5SAnurag S. Maskey }
7316ba597c5SAnurag S. Maskey
7326ba597c5SAnurag S. Maskey /* link-autopush */
7336ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop,
734f6da83d4SAnurag S. Maskey &ncu_data->ncu_link.nwamd_link_autopush,
735f6da83d4SAnurag S. Maskey &ncu_data->ncu_link.nwamd_link_num_autopush,
7366ba597c5SAnurag S. Maskey NWAM_NCU_PROP_LINK_AUTOPUSH)) != NWAM_SUCCESS) {
7376ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
7386ba597c5SAnurag S. Maskey "populate_link_ncu_properties: could not get %s value: %s",
7396ba597c5SAnurag S. Maskey NWAM_NCU_PROP_LINK_AUTOPUSH, nwam_strerror(err));
740f6da83d4SAnurag S. Maskey ncu_data->ncu_link.nwamd_link_num_autopush = 0;
7416ba597c5SAnurag S. Maskey }
7426ba597c5SAnurag S. Maskey }
7436ba597c5SAnurag S. Maskey
7446ba597c5SAnurag S. Maskey static void
populate_ip_ncu_properties(nwam_ncu_handle_t ncuh,nwamd_ncu_t * ncu_data)7456ba597c5SAnurag S. Maskey populate_ip_ncu_properties(nwam_ncu_handle_t ncuh, nwamd_ncu_t *ncu_data)
7466ba597c5SAnurag S. Maskey {
747f6da83d4SAnurag S. Maskey nwamd_if_t *nif = &ncu_data->ncu_if;
7486ba597c5SAnurag S. Maskey struct nwamd_if_address **nifa, *nifai, *nifait;
749*b31320a7SChris Fraire boolean_t static_addr = B_FALSE, *boolvalue, dhcp_primary = B_FALSE;
7506ba597c5SAnurag S. Maskey uint64_t *addrsrcvalue;
7516ba597c5SAnurag S. Maskey nwam_value_t ncu_prop;
7526ba597c5SAnurag S. Maskey nwam_error_t err;
753f6da83d4SAnurag S. Maskey ipadm_addrobj_t ipaddr;
754f6da83d4SAnurag S. Maskey ipadm_status_t ipstatus;
755*b31320a7SChris Fraire char **addrvalue, ipreqhost[MAXNAMELEN];
7566ba597c5SAnurag S. Maskey uint_t numvalues;
7576ba597c5SAnurag S. Maskey uint64_t *ipversion;
7586ba597c5SAnurag S. Maskey int i;
7596ba597c5SAnurag S. Maskey
7606ba597c5SAnurag S. Maskey nif->nwamd_if_ipv4 = B_FALSE;
7616ba597c5SAnurag S. Maskey nif->nwamd_if_ipv6 = B_FALSE;
7626ba597c5SAnurag S. Maskey nif->nwamd_if_dhcp_requested = B_FALSE;
7636ba597c5SAnurag S. Maskey nif->nwamd_if_stateful_requested = B_FALSE;
7646ba597c5SAnurag S. Maskey nif->nwamd_if_stateless_requested = B_FALSE;
7656ba597c5SAnurag S. Maskey nif->nwamd_if_ipv4_default_route_set = B_FALSE;
7666ba597c5SAnurag S. Maskey nif->nwamd_if_ipv6_default_route_set = B_FALSE;
7676ba597c5SAnurag S. Maskey
7686ba597c5SAnurag S. Maskey /* ip-version */
7696ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &ipversion, &numvalues,
7706ba597c5SAnurag S. Maskey NWAM_NCU_PROP_IP_VERSION)) != NWAM_SUCCESS) {
7716ba597c5SAnurag S. Maskey nlog(LOG_ERR,
7726ba597c5SAnurag S. Maskey "populate_ip_ncu_properties: could not get %s value: %s",
7736ba597c5SAnurag S. Maskey NWAM_NCU_PROP_IP_VERSION, nwam_strerror(err));
7746ba597c5SAnurag S. Maskey } else {
7756ba597c5SAnurag S. Maskey for (i = 0; i < numvalues; i++) {
7766ba597c5SAnurag S. Maskey switch (ipversion[i]) {
7776ba597c5SAnurag S. Maskey case IPV4_VERSION:
7786ba597c5SAnurag S. Maskey nif->nwamd_if_ipv4 = B_TRUE;
7796ba597c5SAnurag S. Maskey break;
7806ba597c5SAnurag S. Maskey case IPV6_VERSION:
7816ba597c5SAnurag S. Maskey nif->nwamd_if_ipv6 = B_TRUE;
7826ba597c5SAnurag S. Maskey break;
7836ba597c5SAnurag S. Maskey default:
7846ba597c5SAnurag S. Maskey nlog(LOG_ERR, "bogus ip version %lld",
7856ba597c5SAnurag S. Maskey ipversion[i]);
7866ba597c5SAnurag S. Maskey break;
7876ba597c5SAnurag S. Maskey }
7886ba597c5SAnurag S. Maskey }
7896ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
7906ba597c5SAnurag S. Maskey }
7916ba597c5SAnurag S. Maskey
792*b31320a7SChris Fraire /* ip-primary */
793*b31320a7SChris Fraire if ((err = nwamd_get_ncu_boolean(ncuh, &ncu_prop, &boolvalue,
794*b31320a7SChris Fraire &numvalues, NWAM_NCU_PROP_IP_PRIMARY)) != NWAM_SUCCESS) {
795*b31320a7SChris Fraire /* ip-primary is optional, so do not LOG_ERR */
796*b31320a7SChris Fraire nlog(LOG_DEBUG, "populate_ip_ncu_properties: "
797*b31320a7SChris Fraire "could not get %s value: %s",
798*b31320a7SChris Fraire NWAM_NCU_PROP_IP_PRIMARY, nwam_strerror(err));
799*b31320a7SChris Fraire } else {
800*b31320a7SChris Fraire if (numvalues > 0)
801*b31320a7SChris Fraire dhcp_primary = boolvalue[0];
802*b31320a7SChris Fraire nwam_value_free(ncu_prop);
803*b31320a7SChris Fraire }
804*b31320a7SChris Fraire
805*b31320a7SChris Fraire /* ip-reqhost */
806*b31320a7SChris Fraire *ipreqhost = '\0';
807*b31320a7SChris Fraire
808*b31320a7SChris Fraire if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
809*b31320a7SChris Fraire &numvalues, NWAM_NCU_PROP_IP_REQHOST)) != NWAM_SUCCESS) {
810*b31320a7SChris Fraire /* ip-reqhost is optional, so do not LOG_ERR */
811*b31320a7SChris Fraire nlog(LOG_DEBUG, "populate_ip_ncu_properties: "
812*b31320a7SChris Fraire "could not get %s value: %s",
813*b31320a7SChris Fraire NWAM_NCU_PROP_IP_REQHOST, nwam_strerror(err));
814*b31320a7SChris Fraire } else {
815*b31320a7SChris Fraire if (numvalues > 0 && strlcpy(ipreqhost, addrvalue[0],
816*b31320a7SChris Fraire sizeof (ipreqhost)) >= sizeof (ipreqhost)) {
817*b31320a7SChris Fraire nlog(LOG_WARNING, "populate_ip_ncu_properties: "
818*b31320a7SChris Fraire "too long %s value: %s",
819*b31320a7SChris Fraire NWAM_NCU_PROP_IP_REQHOST, addrvalue[0]);
820*b31320a7SChris Fraire *ipreqhost = '\0';
821*b31320a7SChris Fraire }
822*b31320a7SChris Fraire nwam_value_free(ncu_prop);
823*b31320a7SChris Fraire }
824*b31320a7SChris Fraire
8256ba597c5SAnurag S. Maskey /* Free the old list. */
8266ba597c5SAnurag S. Maskey for (nifai = nif->nwamd_if_list; nifai != NULL; nifai = nifait) {
8276ba597c5SAnurag S. Maskey nifait = nifai->next;
8286ba597c5SAnurag S. Maskey nifai->next = NULL;
829f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(nifai->ipaddr);
8306ba597c5SAnurag S. Maskey free(nifai);
8316ba597c5SAnurag S. Maskey }
8326ba597c5SAnurag S. Maskey nif->nwamd_if_list = NULL;
8336ba597c5SAnurag S. Maskey nifa = &(nif->nwamd_if_list);
8346ba597c5SAnurag S. Maskey
8356ba597c5SAnurag S. Maskey if (!nif->nwamd_if_ipv4)
8366ba597c5SAnurag S. Maskey goto skip_ipv4;
8376ba597c5SAnurag S. Maskey
8386ba597c5SAnurag S. Maskey /* ipv4-addrsrc */
8396ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &addrsrcvalue,
8406ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV4_ADDRSRC)) != NWAM_SUCCESS) {
8416ba597c5SAnurag S. Maskey nlog(nif->nwamd_if_ipv4 ? LOG_ERR : LOG_DEBUG,
8426ba597c5SAnurag S. Maskey "populate_ip_ncu_properties: could not get %s value: %s",
8436ba597c5SAnurag S. Maskey NWAM_NCU_PROP_IPV4_ADDRSRC, nwam_strerror(err));
8446ba597c5SAnurag S. Maskey } else {
8456ba597c5SAnurag S. Maskey for (i = 0; i < numvalues; i++) {
8466ba597c5SAnurag S. Maskey switch (addrsrcvalue[i]) {
8476ba597c5SAnurag S. Maskey case NWAM_ADDRSRC_DHCP:
8486ba597c5SAnurag S. Maskey nif->nwamd_if_dhcp_requested = B_TRUE;
8496ba597c5SAnurag S. Maskey break;
8506ba597c5SAnurag S. Maskey case NWAM_ADDRSRC_STATIC:
8516ba597c5SAnurag S. Maskey static_addr = B_TRUE;
8526ba597c5SAnurag S. Maskey break;
8536ba597c5SAnurag S. Maskey default:
8546ba597c5SAnurag S. Maskey break;
8556ba597c5SAnurag S. Maskey }
8566ba597c5SAnurag S. Maskey }
8576ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
8586ba597c5SAnurag S. Maskey }
8596ba597c5SAnurag S. Maskey if (nif->nwamd_if_dhcp_requested) {
860f6da83d4SAnurag S. Maskey ipstatus = ipadm_create_addrobj(IPADM_ADDR_DHCP,
861f6da83d4SAnurag S. Maskey ncu_data->ncu_name, &ipaddr);
862f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
863f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
864f6da83d4SAnurag S. Maskey "ipadm_create_addrobj failed for v4 dhcp: %s",
865f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
866f6da83d4SAnurag S. Maskey goto skip_ipv4_dhcp;
867f6da83d4SAnurag S. Maskey }
868f6da83d4SAnurag S. Maskey
869f6da83d4SAnurag S. Maskey ipstatus = ipadm_set_wait_time(ipaddr, ncu_wait_time);
870f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
871f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
872f6da83d4SAnurag S. Maskey "ipadm_set_wait_time failed for v4 dhcp: %s",
873f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
874f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
875f6da83d4SAnurag S. Maskey goto skip_ipv4_dhcp;
876f6da83d4SAnurag S. Maskey }
877*b31320a7SChris Fraire ipstatus = ipadm_set_primary(ipaddr, dhcp_primary);
878*b31320a7SChris Fraire if (ipstatus != IPADM_SUCCESS) {
879*b31320a7SChris Fraire nlog(LOG_ERR, "populate_ip_ncu_properties: "
880*b31320a7SChris Fraire "ipadm_set_primary failed for v4 dhcp: %s",
881*b31320a7SChris Fraire ipadm_status2str(ipstatus));
882*b31320a7SChris Fraire ipadm_destroy_addrobj(ipaddr);
883*b31320a7SChris Fraire goto skip_ipv4_dhcp;
884*b31320a7SChris Fraire }
885*b31320a7SChris Fraire ipstatus = ipadm_set_reqhost(ipaddr, ipreqhost);
886*b31320a7SChris Fraire if (ipstatus != IPADM_SUCCESS) {
887*b31320a7SChris Fraire nlog(LOG_ERR, "populate_ip_ncu_properties: "
888*b31320a7SChris Fraire "ipadm_set_reqhost failed for v4 dhcp: %s",
889*b31320a7SChris Fraire ipadm_status2str(ipstatus));
890*b31320a7SChris Fraire ipadm_destroy_addrobj(ipaddr);
891*b31320a7SChris Fraire goto skip_ipv4_dhcp;
892*b31320a7SChris Fraire }
8936ba597c5SAnurag S. Maskey if ((*nifa = calloc(sizeof (**nifa), 1)) != NULL) {
894f6da83d4SAnurag S. Maskey (*nifa)->family = AF_INET;
895f6da83d4SAnurag S. Maskey (*nifa)->ipaddr_atype = IPADM_ADDR_DHCP;
896f6da83d4SAnurag S. Maskey (*nifa)->ipaddr = ipaddr;
8976ba597c5SAnurag S. Maskey nifa = &((*nifa)->next);
8986ba597c5SAnurag S. Maskey *nifa = NULL;
899f6da83d4SAnurag S. Maskey } else {
900f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
901f6da83d4SAnurag S. Maskey "couldn't allocate nwamd address for v4 dhcp: %s",
902f6da83d4SAnurag S. Maskey strerror(errno));
903f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
9046ba597c5SAnurag S. Maskey }
9056ba597c5SAnurag S. Maskey }
9066ba597c5SAnurag S. Maskey
907f6da83d4SAnurag S. Maskey skip_ipv4_dhcp:
9086ba597c5SAnurag S. Maskey /* ipv4-addr */
9096ba597c5SAnurag S. Maskey if (static_addr) {
9106ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
9116ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV4_ADDR)) != NWAM_SUCCESS) {
9126ba597c5SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
913*b31320a7SChris Fraire "could not get %s value: %s",
9146ba597c5SAnurag S. Maskey NWAM_NCU_PROP_IPV4_ADDR, nwam_strerror(err));
9156ba597c5SAnurag S. Maskey } else {
9166ba597c5SAnurag S. Maskey for (i = 0; i < numvalues; i++) {
917f6da83d4SAnurag S. Maskey ipstatus = ipadm_create_addrobj(
918f6da83d4SAnurag S. Maskey IPADM_ADDR_STATIC, ncu_data->ncu_name,
919f6da83d4SAnurag S. Maskey &ipaddr);
920f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
921f6da83d4SAnurag S. Maskey nlog(LOG_ERR,
922f6da83d4SAnurag S. Maskey "populate_ip_ncu_properties: "
923f6da83d4SAnurag S. Maskey "ipadm_create_addrobj failed "
924f6da83d4SAnurag S. Maskey "for %s: %s", addrvalue[i],
925f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
9266ba597c5SAnurag S. Maskey continue;
9276ba597c5SAnurag S. Maskey }
928f6da83d4SAnurag S. Maskey /* ipadm_set_addr takes <addr>[/<mask>] */
929f6da83d4SAnurag S. Maskey ipstatus = ipadm_set_addr(ipaddr, addrvalue[i],
930f6da83d4SAnurag S. Maskey AF_INET);
931f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
932f6da83d4SAnurag S. Maskey nlog(LOG_ERR,
933f6da83d4SAnurag S. Maskey "populate_ip_ncu_properties: "
934f6da83d4SAnurag S. Maskey "ipadm_set_addr failed for %s: %s",
935f6da83d4SAnurag S. Maskey addrvalue[i],
936f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
937f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
938f6da83d4SAnurag S. Maskey continue;
939f6da83d4SAnurag S. Maskey }
940f6da83d4SAnurag S. Maskey
941f6da83d4SAnurag S. Maskey if ((*nifa = calloc(sizeof (**nifa), 1))
942f6da83d4SAnurag S. Maskey != NULL) {
943f6da83d4SAnurag S. Maskey (*nifa)->family = AF_INET;
944f6da83d4SAnurag S. Maskey (*nifa)->ipaddr_atype =
945f6da83d4SAnurag S. Maskey IPADM_ADDR_STATIC;
946f6da83d4SAnurag S. Maskey (*nifa)->ipaddr = ipaddr;
947f6da83d4SAnurag S. Maskey nifa = &((*nifa)->next);
948f6da83d4SAnurag S. Maskey } else {
949f6da83d4SAnurag S. Maskey nlog(LOG_ERR,
950f6da83d4SAnurag S. Maskey "populate_ip_ncu_properties: "
951f6da83d4SAnurag S. Maskey "couldn't allocate nwamd address "
952f6da83d4SAnurag S. Maskey "for %s: %s", addrvalue[i],
953f6da83d4SAnurag S. Maskey strerror(errno));
954f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
9556ba597c5SAnurag S. Maskey }
9566ba597c5SAnurag S. Maskey }
9576ba597c5SAnurag S. Maskey *nifa = NULL;
9586ba597c5SAnurag S. Maskey
9596ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
9606ba597c5SAnurag S. Maskey }
9616ba597c5SAnurag S. Maskey }
9626ba597c5SAnurag S. Maskey
9636ba597c5SAnurag S. Maskey /* get default route, if any */
9646ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
9656ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE)) == NWAM_SUCCESS) {
9666ba597c5SAnurag S. Maskey /* Only one default route is allowed. */
9676ba597c5SAnurag S. Maskey nif->nwamd_if_ipv4_default_route.sin_family = AF_INET;
9686ba597c5SAnurag S. Maskey (void) inet_pton(AF_INET, addrvalue[0],
9696ba597c5SAnurag S. Maskey &(nif->nwamd_if_ipv4_default_route.sin_addr));
9706ba597c5SAnurag S. Maskey nif->nwamd_if_ipv4_default_route_set = B_TRUE;
9716ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
9726ba597c5SAnurag S. Maskey }
9736ba597c5SAnurag S. Maskey
9746ba597c5SAnurag S. Maskey skip_ipv4:
9756ba597c5SAnurag S. Maskey if (!nif->nwamd_if_ipv6)
9766ba597c5SAnurag S. Maskey goto skip_ipv6;
9776ba597c5SAnurag S. Maskey
9786ba597c5SAnurag S. Maskey /* ipv6-addrsrc */
9796ba597c5SAnurag S. Maskey static_addr = B_FALSE;
9806ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_uint(ncuh, &ncu_prop, &addrsrcvalue,
9816ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV6_ADDRSRC)) != NWAM_SUCCESS) {
9826ba597c5SAnurag S. Maskey nlog(nif->nwamd_if_ipv6 ? LOG_ERR : LOG_DEBUG,
9836ba597c5SAnurag S. Maskey "populate_ip_ncu_properties: could not get %s value: %s",
9846ba597c5SAnurag S. Maskey NWAM_NCU_PROP_IPV6_ADDRSRC, nwam_strerror(err));
9856ba597c5SAnurag S. Maskey } else {
9866ba597c5SAnurag S. Maskey for (i = 0; i < numvalues; i++) {
9876ba597c5SAnurag S. Maskey switch (addrsrcvalue[i]) {
9886ba597c5SAnurag S. Maskey case NWAM_ADDRSRC_DHCP:
9896ba597c5SAnurag S. Maskey nif->nwamd_if_stateful_requested = B_TRUE;
9906ba597c5SAnurag S. Maskey break;
9916ba597c5SAnurag S. Maskey case NWAM_ADDRSRC_AUTOCONF:
9926ba597c5SAnurag S. Maskey nif->nwamd_if_stateless_requested = B_TRUE;
9936ba597c5SAnurag S. Maskey break;
9946ba597c5SAnurag S. Maskey case NWAM_ADDRSRC_STATIC:
9956ba597c5SAnurag S. Maskey static_addr = B_TRUE;
9966ba597c5SAnurag S. Maskey break;
9976ba597c5SAnurag S. Maskey default:
9986ba597c5SAnurag S. Maskey break;
9996ba597c5SAnurag S. Maskey }
10006ba597c5SAnurag S. Maskey }
10016ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
10026ba597c5SAnurag S. Maskey }
1003f6da83d4SAnurag S. Maskey /*
1004f6da83d4SAnurag S. Maskey * Both stateful and stateless share the same nwamd_if_address because
1005f6da83d4SAnurag S. Maskey * only one ipaddr for both of these addresses can be created.
1006f6da83d4SAnurag S. Maskey * ipadm_create_addr() adds both addresses from the same ipaddr.
1007f6da83d4SAnurag S. Maskey */
1008f6da83d4SAnurag S. Maskey if (nif->nwamd_if_stateful_requested ||
1009f6da83d4SAnurag S. Maskey nif->nwamd_if_stateless_requested) {
1010f6da83d4SAnurag S. Maskey ipstatus = ipadm_create_addrobj(IPADM_ADDR_IPV6_ADDRCONF,
1011f6da83d4SAnurag S. Maskey ncu_data->ncu_name, &ipaddr);
1012f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
1013f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
1014f6da83d4SAnurag S. Maskey "ipadm_create_addrobj failed for v6 "
1015f6da83d4SAnurag S. Maskey "stateless/stateful: %s",
1016f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
1017f6da83d4SAnurag S. Maskey goto skip_ipv6_addrconf;
1018f6da83d4SAnurag S. Maskey }
1019f6da83d4SAnurag S. Maskey /* create_addrobj sets both stateless and stateful to B_TRUE */
1020f6da83d4SAnurag S. Maskey if (!nif->nwamd_if_stateful_requested) {
1021f6da83d4SAnurag S. Maskey ipstatus = ipadm_set_stateful(ipaddr, B_FALSE);
1022f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
1023f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
1024f6da83d4SAnurag S. Maskey "ipadm_set_stateful failed for v6: %s",
1025f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
1026f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
1027f6da83d4SAnurag S. Maskey goto skip_ipv6_addrconf;
1028f6da83d4SAnurag S. Maskey }
1029f6da83d4SAnurag S. Maskey }
1030f6da83d4SAnurag S. Maskey if (!nif->nwamd_if_stateless_requested) {
1031f6da83d4SAnurag S. Maskey ipstatus = ipadm_set_stateless(ipaddr, B_FALSE);
1032f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
1033f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
1034f6da83d4SAnurag S. Maskey "ipadm_set_stateless failed for v6: %s",
1035f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
1036f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
1037f6da83d4SAnurag S. Maskey goto skip_ipv6_addrconf;
1038f6da83d4SAnurag S. Maskey }
10396ba597c5SAnurag S. Maskey }
10406ba597c5SAnurag S. Maskey if ((*nifa = calloc(sizeof (**nifa), 1)) != NULL) {
1041f6da83d4SAnurag S. Maskey (*nifa)->family = AF_INET6;
1042f6da83d4SAnurag S. Maskey (*nifa)->ipaddr_atype = IPADM_ADDR_IPV6_ADDRCONF;
1043f6da83d4SAnurag S. Maskey (*nifa)->ipaddr = ipaddr;
10446ba597c5SAnurag S. Maskey nifa = &((*nifa)->next);
10456ba597c5SAnurag S. Maskey *nifa = NULL;
1046f6da83d4SAnurag S. Maskey } else {
1047f6da83d4SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
1048f6da83d4SAnurag S. Maskey "couldn't allocate nwamd address for "
1049f6da83d4SAnurag S. Maskey "v6 stateless/stateful: %s", strerror(errno));
1050f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
10516ba597c5SAnurag S. Maskey }
10526ba597c5SAnurag S. Maskey }
10536ba597c5SAnurag S. Maskey
1054f6da83d4SAnurag S. Maskey skip_ipv6_addrconf:
10556ba597c5SAnurag S. Maskey /* ipv6-addr */
10566ba597c5SAnurag S. Maskey if (static_addr) {
10576ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
10586ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV6_ADDR)) != NWAM_SUCCESS) {
10596ba597c5SAnurag S. Maskey nlog(LOG_ERR, "populate_ip_ncu_properties: "
1060*b31320a7SChris Fraire "could not get %s value: %s",
10616ba597c5SAnurag S. Maskey NWAM_NCU_PROP_IPV6_ADDR, nwam_strerror(err));
10626ba597c5SAnurag S. Maskey } else {
10636ba597c5SAnurag S. Maskey for (i = 0; i < numvalues; i++) {
1064f6da83d4SAnurag S. Maskey ipstatus = ipadm_create_addrobj(
1065f6da83d4SAnurag S. Maskey IPADM_ADDR_STATIC, ncu_data->ncu_name,
1066f6da83d4SAnurag S. Maskey &ipaddr);
1067f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
1068f6da83d4SAnurag S. Maskey nlog(LOG_ERR,
1069f6da83d4SAnurag S. Maskey "populate_ip_ncu_properties: "
1070f6da83d4SAnurag S. Maskey "ipadm_create_addrobj failed "
1071f6da83d4SAnurag S. Maskey "for %s: %s", addrvalue[i],
1072f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
10736ba597c5SAnurag S. Maskey continue;
10746ba597c5SAnurag S. Maskey }
1075f6da83d4SAnurag S. Maskey /* ipadm_set_addr takes <addr>[/<mask>] */
1076f6da83d4SAnurag S. Maskey ipstatus = ipadm_set_addr(ipaddr, addrvalue[i],
1077f6da83d4SAnurag S. Maskey AF_INET6);
1078f6da83d4SAnurag S. Maskey if (ipstatus != IPADM_SUCCESS) {
1079f6da83d4SAnurag S. Maskey nlog(LOG_ERR,
1080f6da83d4SAnurag S. Maskey "populate_ip_ncu_properties: "
1081f6da83d4SAnurag S. Maskey "ipadm_set_addr failed for %s: %s",
1082f6da83d4SAnurag S. Maskey addrvalue[i],
1083f6da83d4SAnurag S. Maskey ipadm_status2str(ipstatus));
1084f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
1085f6da83d4SAnurag S. Maskey continue;
1086f6da83d4SAnurag S. Maskey }
1087f6da83d4SAnurag S. Maskey
1088f6da83d4SAnurag S. Maskey if ((*nifa = calloc(sizeof (**nifa), 1))
1089f6da83d4SAnurag S. Maskey != NULL) {
1090f6da83d4SAnurag S. Maskey (*nifa)->family = AF_INET6;
1091f6da83d4SAnurag S. Maskey (*nifa)->ipaddr_atype =
1092f6da83d4SAnurag S. Maskey IPADM_ADDR_STATIC;
1093f6da83d4SAnurag S. Maskey (*nifa)->ipaddr = ipaddr;
1094f6da83d4SAnurag S. Maskey nifa = &((*nifa)->next);
1095f6da83d4SAnurag S. Maskey } else {
1096f6da83d4SAnurag S. Maskey nlog(LOG_ERR,
1097f6da83d4SAnurag S. Maskey "populate_ip_ncu_properties: "
1098f6da83d4SAnurag S. Maskey "couldn't allocate nwamd address "
1099f6da83d4SAnurag S. Maskey "for %s: %s", addrvalue[i],
1100f6da83d4SAnurag S. Maskey strerror(errno));
1101f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(ipaddr);
11026ba597c5SAnurag S. Maskey }
11036ba597c5SAnurag S. Maskey }
11046ba597c5SAnurag S. Maskey *nifa = NULL;
11056ba597c5SAnurag S. Maskey
11066ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
11076ba597c5SAnurag S. Maskey }
11086ba597c5SAnurag S. Maskey }
11096ba597c5SAnurag S. Maskey
11106ba597c5SAnurag S. Maskey /* get default route, if any */
11116ba597c5SAnurag S. Maskey if ((err = nwamd_get_ncu_string(ncuh, &ncu_prop, &addrvalue,
11126ba597c5SAnurag S. Maskey &numvalues, NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE)) == NWAM_SUCCESS) {
11136ba597c5SAnurag S. Maskey /* Only one default route is allowed. */
11146ba597c5SAnurag S. Maskey nif->nwamd_if_ipv6_default_route.sin6_family = AF_INET6;
11156ba597c5SAnurag S. Maskey (void) inet_pton(AF_INET6, addrvalue[0],
11166ba597c5SAnurag S. Maskey &(nif->nwamd_if_ipv6_default_route.sin6_addr));
11176ba597c5SAnurag S. Maskey nif->nwamd_if_ipv6_default_route_set = B_TRUE;
11186ba597c5SAnurag S. Maskey nwam_value_free(ncu_prop);
11196ba597c5SAnurag S. Maskey }
11206ba597c5SAnurag S. Maskey
11216ba597c5SAnurag S. Maskey skip_ipv6:
11226ba597c5SAnurag S. Maskey ;
11236ba597c5SAnurag S. Maskey }
11246ba597c5SAnurag S. Maskey
11256ba597c5SAnurag S. Maskey static nwamd_ncu_t *
nwamd_ncu_init(nwam_ncu_type_t ncu_type,const char * name)11266ba597c5SAnurag S. Maskey nwamd_ncu_init(nwam_ncu_type_t ncu_type, const char *name)
11276ba597c5SAnurag S. Maskey {
11286ba597c5SAnurag S. Maskey nwamd_ncu_t *rv;
11296ba597c5SAnurag S. Maskey
11306ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_init(%d, %s)", ncu_type, name);
11316ba597c5SAnurag S. Maskey
11326ba597c5SAnurag S. Maskey if ((rv = calloc(1, sizeof (*rv))) == NULL)
11336ba597c5SAnurag S. Maskey return (NULL);
11346ba597c5SAnurag S. Maskey
11356ba597c5SAnurag S. Maskey rv->ncu_type = ncu_type;
11366ba597c5SAnurag S. Maskey rv->ncu_name = strdup(name);
11376ba597c5SAnurag S. Maskey rv->ncu_enabled = B_FALSE;
11386ba597c5SAnurag S. Maskey
11396ba597c5SAnurag S. Maskey /* Initialize link/interface-specific data */
11406ba597c5SAnurag S. Maskey if (rv->ncu_type == NWAM_NCU_TYPE_LINK) {
1141f6da83d4SAnurag S. Maskey (void) bzero(&rv->ncu_link, sizeof (nwamd_link_t));
11426ba597c5SAnurag S. Maskey (void) dladm_name2info(dld_handle, name,
1143f6da83d4SAnurag S. Maskey &rv->ncu_link.nwamd_link_id, NULL, NULL,
1144f6da83d4SAnurag S. Maskey &rv->ncu_link.nwamd_link_media);
11456ba597c5SAnurag S. Maskey (void) pthread_mutex_init(
1146f6da83d4SAnurag S. Maskey &rv->ncu_link.nwamd_link_wifi_mutex, NULL);
1147f6da83d4SAnurag S. Maskey rv->ncu_link.nwamd_link_wifi_priority = MAXINT;
11486ba597c5SAnurag S. Maskey } else {
1149f6da83d4SAnurag S. Maskey (void) bzero(&rv->ncu_if, sizeof (nwamd_if_t));
11506ba597c5SAnurag S. Maskey }
11516ba597c5SAnurag S. Maskey
11526ba597c5SAnurag S. Maskey return (rv);
11536ba597c5SAnurag S. Maskey }
11546ba597c5SAnurag S. Maskey
11556ba597c5SAnurag S. Maskey void
nwamd_ncu_free(nwamd_ncu_t * ncu)11566ba597c5SAnurag S. Maskey nwamd_ncu_free(nwamd_ncu_t *ncu)
11576ba597c5SAnurag S. Maskey {
11586ba597c5SAnurag S. Maskey if (ncu != NULL) {
11596ba597c5SAnurag S. Maskey assert(ncu->ncu_type == NWAM_NCU_TYPE_LINK ||
11606ba597c5SAnurag S. Maskey ncu->ncu_type == NWAM_NCU_TYPE_INTERFACE);
11616ba597c5SAnurag S. Maskey if (ncu->ncu_type == NWAM_NCU_TYPE_LINK) {
1162f6da83d4SAnurag S. Maskey struct nwamd_link *l = &ncu->ncu_link;
11636ba597c5SAnurag S. Maskey int i;
11646ba597c5SAnurag S. Maskey
11656ba597c5SAnurag S. Maskey free(l->nwamd_link_wifi_key);
11666ba597c5SAnurag S. Maskey free(l->nwamd_link_mac_addr);
11676ba597c5SAnurag S. Maskey for (i = 0; i < l->nwamd_link_num_autopush; i++)
11686ba597c5SAnurag S. Maskey free(l->nwamd_link_autopush[i]);
11696ba597c5SAnurag S. Maskey } else if (ncu->ncu_type == NWAM_NCU_TYPE_INTERFACE) {
11706ba597c5SAnurag S. Maskey struct nwamd_if_address *nifa;
11716ba597c5SAnurag S. Maskey
1172f6da83d4SAnurag S. Maskey nifa = ncu->ncu_if.nwamd_if_list;
11736ba597c5SAnurag S. Maskey while (nifa != NULL) {
11746ba597c5SAnurag S. Maskey struct nwamd_if_address *n;
11756ba597c5SAnurag S. Maskey
11766ba597c5SAnurag S. Maskey n = nifa;
11776ba597c5SAnurag S. Maskey nifa = nifa->next;
1178f6da83d4SAnurag S. Maskey ipadm_destroy_addrobj(n->ipaddr);
11796ba597c5SAnurag S. Maskey free(n);
11806ba597c5SAnurag S. Maskey }
11816ba597c5SAnurag S. Maskey }
11826ba597c5SAnurag S. Maskey free(ncu->ncu_name);
11836ba597c5SAnurag S. Maskey free(ncu);
11846ba597c5SAnurag S. Maskey }
11856ba597c5SAnurag S. Maskey }
11866ba597c5SAnurag S. Maskey
11876ba597c5SAnurag S. Maskey static int
nwamd_ncu_display(nwamd_object_t ncu_obj,void * data)11886ba597c5SAnurag S. Maskey nwamd_ncu_display(nwamd_object_t ncu_obj, void *data)
11896ba597c5SAnurag S. Maskey {
11906ba597c5SAnurag S. Maskey nwamd_ncu_t *ncu = (nwamd_ncu_t *)ncu_obj->nwamd_object_data;
11916ba597c5SAnurag S. Maskey data = data;
11926ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "NCU (%p) %s state %s, %s",
11936ba597c5SAnurag S. Maskey (void *)ncu, ncu_obj->nwamd_object_name,
11946ba597c5SAnurag S. Maskey nwam_state_to_string(ncu_obj->nwamd_object_state),
11956ba597c5SAnurag S. Maskey nwam_aux_state_to_string(ncu_obj->nwamd_object_aux_state));
11966ba597c5SAnurag S. Maskey return (0);
11976ba597c5SAnurag S. Maskey }
11986ba597c5SAnurag S. Maskey
11996ba597c5SAnurag S. Maskey void
nwamd_log_ncus(void)12006ba597c5SAnurag S. Maskey nwamd_log_ncus(void)
12016ba597c5SAnurag S. Maskey {
12026ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "NCP %s", active_ncp);
12036ba597c5SAnurag S. Maskey (void) nwamd_walk_objects(NWAM_OBJECT_TYPE_NCU, nwamd_ncu_display,
12046ba597c5SAnurag S. Maskey NULL);
12056ba597c5SAnurag S. Maskey }
12066ba597c5SAnurag S. Maskey
12076ba597c5SAnurag S. Maskey int
nwamd_ncu_action(const char * ncu,const char * parent,nwam_action_t action)12086ba597c5SAnurag S. Maskey nwamd_ncu_action(const char *ncu, const char *parent, nwam_action_t action)
12096ba597c5SAnurag S. Maskey {
12106ba597c5SAnurag S. Maskey nwamd_event_t ncu_event = nwamd_event_init_object_action
12116ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU, ncu, parent, action);
12126ba597c5SAnurag S. Maskey if (ncu_event == NULL)
12136ba597c5SAnurag S. Maskey return (1);
12146ba597c5SAnurag S. Maskey nwamd_event_enqueue(ncu_event);
12156ba597c5SAnurag S. Maskey return (0);
12166ba597c5SAnurag S. Maskey }
12176ba597c5SAnurag S. Maskey
12186ba597c5SAnurag S. Maskey static void
add_phys_ncu_to_ncp(nwam_ncp_handle_t ncph,const char * name)12196ba597c5SAnurag S. Maskey add_phys_ncu_to_ncp(nwam_ncp_handle_t ncph, const char *name)
12206ba597c5SAnurag S. Maskey {
12216ba597c5SAnurag S. Maskey dladm_status_t dlrtn;
12226ba597c5SAnurag S. Maskey uint32_t media;
12236ba597c5SAnurag S. Maskey boolean_t is_wireless;
12246ba597c5SAnurag S. Maskey nwam_error_t err;
12256ba597c5SAnurag S. Maskey nwam_ncu_handle_t ncuh;
12266ba597c5SAnurag S. Maskey uint64_t uintval;
12276ba597c5SAnurag S. Maskey
12286ba597c5SAnurag S. Maskey if ((dlrtn = dladm_name2info(dld_handle, name, NULL, NULL, NULL,
12296ba597c5SAnurag S. Maskey &media)) != DLADM_STATUS_OK) {
12306ba597c5SAnurag S. Maskey char errmsg[DLADM_STRSIZE];
12316ba597c5SAnurag S. Maskey nlog(LOG_ERR, "failed to get media type for %s: %s", name,
12326ba597c5SAnurag S. Maskey dladm_status2str(dlrtn, errmsg));
12336ba597c5SAnurag S. Maskey return;
12346ba597c5SAnurag S. Maskey }
12356ba597c5SAnurag S. Maskey is_wireless = (media == DL_WIFI);
12366ba597c5SAnurag S. Maskey
12376ba597c5SAnurag S. Maskey if ((err = nwam_ncu_create(ncph, name, NWAM_NCU_TYPE_LINK,
12386ba597c5SAnurag S. Maskey NWAM_NCU_CLASS_PHYS, &ncuh)) != NWAM_SUCCESS) {
12396ba597c5SAnurag S. Maskey nlog(LOG_ERR, "failed to create link ncu for %s: %s", name,
12406ba597c5SAnurag S. Maskey nwam_strerror(err));
12416ba597c5SAnurag S. Maskey if (err == NWAM_ENTITY_READ_ONLY) {
12426ba597c5SAnurag S. Maskey nwamd_event_t retry_event;
12436ba597c5SAnurag S. Maskey
12446ba597c5SAnurag S. Maskey /*
12456ba597c5SAnurag S. Maskey * Root filesystem may be read-only, retry in
12466ba597c5SAnurag S. Maskey * a few seconds.
12476ba597c5SAnurag S. Maskey */
12486ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "Retrying addition of phys ncu for %s",
12496ba597c5SAnurag S. Maskey name);
12506ba597c5SAnurag S. Maskey retry_event = nwamd_event_init_link_action(name,
12516ba597c5SAnurag S. Maskey NWAM_ACTION_ADD);
12526ba597c5SAnurag S. Maskey if (retry_event != NULL) {
12536ba597c5SAnurag S. Maskey nwamd_event_enqueue_timed(retry_event,
12546ba597c5SAnurag S. Maskey NWAMD_READONLY_RETRY_INTERVAL);
12556ba597c5SAnurag S. Maskey }
12566ba597c5SAnurag S. Maskey }
12576ba597c5SAnurag S. Maskey return;
12586ba597c5SAnurag S. Maskey }
12596ba597c5SAnurag S. Maskey
12606ba597c5SAnurag S. Maskey uintval = NWAM_ACTIVATION_MODE_PRIORITIZED;
12616ba597c5SAnurag S. Maskey if ((err = nwamd_set_ncu_uint(ncuh, &uintval, 1,
12626ba597c5SAnurag S. Maskey NWAM_NCU_PROP_ACTIVATION_MODE)) != NWAM_SUCCESS) {
12636ba597c5SAnurag S. Maskey goto finish;
12646ba597c5SAnurag S. Maskey }
12656ba597c5SAnurag S. Maskey
12666ba597c5SAnurag S. Maskey uintval = is_wireless ? 1 : 0;
12676ba597c5SAnurag S. Maskey if ((err = nwamd_set_ncu_uint(ncuh, &uintval, 1,
12686ba597c5SAnurag S. Maskey NWAM_NCU_PROP_PRIORITY_GROUP)) != NWAM_SUCCESS) {
12696ba597c5SAnurag S. Maskey goto finish;
12706ba597c5SAnurag S. Maskey }
12716ba597c5SAnurag S. Maskey
12726ba597c5SAnurag S. Maskey uintval = is_wireless ? NWAM_PRIORITY_MODE_EXCLUSIVE :
12736ba597c5SAnurag S. Maskey NWAM_PRIORITY_MODE_SHARED;
12746ba597c5SAnurag S. Maskey if ((err = nwamd_set_ncu_uint(ncuh, &uintval, 1,
12756ba597c5SAnurag S. Maskey NWAM_NCU_PROP_PRIORITY_MODE)) != NWAM_SUCCESS) {
12766ba597c5SAnurag S. Maskey goto finish;
12776ba597c5SAnurag S. Maskey }
12786ba597c5SAnurag S. Maskey
12796ba597c5SAnurag S. Maskey err = nwam_ncu_commit(ncuh, 0);
12806ba597c5SAnurag S. Maskey
12816ba597c5SAnurag S. Maskey finish:
12826ba597c5SAnurag S. Maskey nwam_ncu_free(ncuh);
12836ba597c5SAnurag S. Maskey if (err != NWAM_SUCCESS) {
12846ba597c5SAnurag S. Maskey nlog(LOG_ERR,
12856ba597c5SAnurag S. Maskey "failed to create automatic link ncu for %s: %s",
12866ba597c5SAnurag S. Maskey name, nwam_strerror(err));
12876ba597c5SAnurag S. Maskey }
12886ba597c5SAnurag S. Maskey }
12896ba597c5SAnurag S. Maskey
12906ba597c5SAnurag S. Maskey static void
add_ip_ncu_to_ncp(nwam_ncp_handle_t ncph,const char * name)12916ba597c5SAnurag S. Maskey add_ip_ncu_to_ncp(nwam_ncp_handle_t ncph, const char *name)
12926ba597c5SAnurag S. Maskey {
12936ba597c5SAnurag S. Maskey nwam_error_t err;
12946ba597c5SAnurag S. Maskey nwam_ncu_handle_t ncuh;
12956ba597c5SAnurag S. Maskey
12966ba597c5SAnurag S. Maskey if ((err = nwam_ncu_create(ncph, name, NWAM_NCU_TYPE_INTERFACE,
12976ba597c5SAnurag S. Maskey NWAM_NCU_CLASS_IP, &ncuh)) != NWAM_SUCCESS) {
12986ba597c5SAnurag S. Maskey nlog(LOG_ERR, "failed to create ip ncu for %s: %s", name,
12996ba597c5SAnurag S. Maskey nwam_strerror(err));
13006ba597c5SAnurag S. Maskey /*
13016ba597c5SAnurag S. Maskey * Root filesystem may be read-only, but no need to
13026ba597c5SAnurag S. Maskey * retry here since add_phys_ncu_to_ncp() enqueues
13036ba597c5SAnurag S. Maskey * a retry event which will lead to add_ip_ncu_to_ncp()
13046ba597c5SAnurag S. Maskey * being called.
13056ba597c5SAnurag S. Maskey */
13066ba597c5SAnurag S. Maskey return;
13076ba597c5SAnurag S. Maskey }
13086ba597c5SAnurag S. Maskey
13096ba597c5SAnurag S. Maskey /* IP NCU has the default values, so nothing else to do */
13106ba597c5SAnurag S. Maskey err = nwam_ncu_commit(ncuh, 0);
13116ba597c5SAnurag S. Maskey
13126ba597c5SAnurag S. Maskey finish:
13136ba597c5SAnurag S. Maskey nwam_ncu_free(ncuh);
13146ba597c5SAnurag S. Maskey if (err != NWAM_SUCCESS) {
13156ba597c5SAnurag S. Maskey nlog(LOG_ERR,
13166ba597c5SAnurag S. Maskey "failed to create ip ncu for %s: %s", name,
13176ba597c5SAnurag S. Maskey nwam_strerror(err));
13186ba597c5SAnurag S. Maskey }
13196ba597c5SAnurag S. Maskey }
13206ba597c5SAnurag S. Maskey
13216ba597c5SAnurag S. Maskey static void
remove_ncu_from_ncp(nwam_ncp_handle_t ncph,const char * name,nwam_ncu_type_t type)13226ba597c5SAnurag S. Maskey remove_ncu_from_ncp(nwam_ncp_handle_t ncph, const char *name,
13236ba597c5SAnurag S. Maskey nwam_ncu_type_t type)
13246ba597c5SAnurag S. Maskey {
13256ba597c5SAnurag S. Maskey nwam_error_t err;
13266ba597c5SAnurag S. Maskey nwam_ncu_handle_t ncuh;
13276ba597c5SAnurag S. Maskey
13286ba597c5SAnurag S. Maskey if ((err = nwam_ncu_read(ncph, name, type, 0, &ncuh)) != NWAM_SUCCESS) {
13296ba597c5SAnurag S. Maskey nlog(LOG_ERR, "failed to read automatic ncu %s: %s", name,
13306ba597c5SAnurag S. Maskey nwam_strerror(err));
13316ba597c5SAnurag S. Maskey return;
13326ba597c5SAnurag S. Maskey }
13336ba597c5SAnurag S. Maskey
13346ba597c5SAnurag S. Maskey err = nwam_ncu_destroy(ncuh, 0);
13356ba597c5SAnurag S. Maskey if (err != NWAM_SUCCESS) {
13366ba597c5SAnurag S. Maskey nlog(LOG_ERR, "failed to delete automatic ncu %s: %s", name,
13376ba597c5SAnurag S. Maskey nwam_strerror(err));
13386ba597c5SAnurag S. Maskey }
13396ba597c5SAnurag S. Maskey }
13406ba597c5SAnurag S. Maskey
13416ba597c5SAnurag S. Maskey /*
13426ba597c5SAnurag S. Maskey * Device represented by NCU has been added or removed for the active
13436ba597c5SAnurag S. Maskey * User NCP. If an associated NCU of the given type is found, transition it
13446ba597c5SAnurag S. Maskey * to the appropriate state.
13456ba597c5SAnurag S. Maskey */
13466ba597c5SAnurag S. Maskey void
ncu_action_change_state(nwam_action_t action,nwam_ncu_type_t type,const char * name)13476ba597c5SAnurag S. Maskey ncu_action_change_state(nwam_action_t action, nwam_ncu_type_t type,
13486ba597c5SAnurag S. Maskey const char *name)
13496ba597c5SAnurag S. Maskey {
13506ba597c5SAnurag S. Maskey nwamd_object_t ncu_obj = NULL;
13516ba597c5SAnurag S. Maskey nwamd_ncu_t *ncu;
13526ba597c5SAnurag S. Maskey
13536ba597c5SAnurag S. Maskey if ((ncu_obj = nwamd_ncu_object_find(type, name)) == NULL)
13546ba597c5SAnurag S. Maskey return;
13556ba597c5SAnurag S. Maskey
13566ba597c5SAnurag S. Maskey ncu = ncu_obj->nwamd_object_data;
13576ba597c5SAnurag S. Maskey
13586ba597c5SAnurag S. Maskey /*
13596ba597c5SAnurag S. Maskey * If device has been added, transition from uninitialized to offline.
13606ba597c5SAnurag S. Maskey * If device has been removed, transition to uninitialized (via online*
13616ba597c5SAnurag S. Maskey * if the NCU is currently enabled in order to tear down config).
13626ba597c5SAnurag S. Maskey */
13636ba597c5SAnurag S. Maskey if (action == NWAM_ACTION_ADD) {
13646ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
13656ba597c5SAnurag S. Maskey ncu_obj->nwamd_object_name,
13666ba597c5SAnurag S. Maskey NWAM_STATE_OFFLINE, NWAM_AUX_STATE_CONDITIONS_NOT_MET);
13676ba597c5SAnurag S. Maskey } else {
13686ba597c5SAnurag S. Maskey if (ncu->ncu_enabled) {
13696ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
13706ba597c5SAnurag S. Maskey ncu_obj->nwamd_object_name,
13716ba597c5SAnurag S. Maskey NWAM_STATE_ONLINE_TO_OFFLINE,
13726ba597c5SAnurag S. Maskey NWAM_AUX_STATE_NOT_FOUND);
13736ba597c5SAnurag S. Maskey } else {
13746ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
13756ba597c5SAnurag S. Maskey ncu_obj->nwamd_object_name,
13766ba597c5SAnurag S. Maskey NWAM_STATE_UNINITIALIZED,
13776ba597c5SAnurag S. Maskey NWAM_AUX_STATE_NOT_FOUND);
13786ba597c5SAnurag S. Maskey }
13796ba597c5SAnurag S. Maskey }
13806ba597c5SAnurag S. Maskey nwamd_object_release(ncu_obj);
13816ba597c5SAnurag S. Maskey }
13826ba597c5SAnurag S. Maskey
13836ba597c5SAnurag S. Maskey /*
13846ba597c5SAnurag S. Maskey * Called with hotplug sysevent or when nwam is started and walking the
13856ba597c5SAnurag S. Maskey * physical interfaces. Add/remove both link and interface NCUs from the
13866ba597c5SAnurag S. Maskey * Automatic NCP. Assumes that both link and interface NCUs don't exist.
13876ba597c5SAnurag S. Maskey */
13886ba597c5SAnurag S. Maskey void
nwamd_ncu_handle_link_action_event(nwamd_event_t event)13896ba597c5SAnurag S. Maskey nwamd_ncu_handle_link_action_event(nwamd_event_t event)
13906ba597c5SAnurag S. Maskey {
13916ba597c5SAnurag S. Maskey nwam_ncp_handle_t ncph;
13926ba597c5SAnurag S. Maskey nwam_ncu_type_t type;
13936ba597c5SAnurag S. Maskey nwam_action_t action =
13946ba597c5SAnurag S. Maskey event->event_msg->nwe_data.nwe_link_action.nwe_action;
13956ba597c5SAnurag S. Maskey nwam_error_t err;
13966ba597c5SAnurag S. Maskey char *name;
13976ba597c5SAnurag S. Maskey boolean_t automatic_ncp_active = B_FALSE;
13986ba597c5SAnurag S. Maskey
13996ba597c5SAnurag S. Maskey if (action != NWAM_ACTION_ADD && action != NWAM_ACTION_REMOVE) {
14006ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
14016ba597c5SAnurag S. Maskey "invalid link action %s", nwam_action_to_string(action));
14026ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
14036ba597c5SAnurag S. Maskey return;
14046ba597c5SAnurag S. Maskey }
14056ba597c5SAnurag S. Maskey
14066ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_link_action_event: "
14076ba597c5SAnurag S. Maskey "link action '%s' event on %s", nwam_action_to_string(action),
14086ba597c5SAnurag S. Maskey event->event_object[0] == 0 ? "n/a" : event->event_object);
14096ba597c5SAnurag S. Maskey
14106ba597c5SAnurag S. Maskey if ((err = nwam_ncu_typed_name_to_name(event->event_object, &type,
14116ba597c5SAnurag S. Maskey &name)) != NWAM_SUCCESS) {
14126ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
14136ba597c5SAnurag S. Maskey "translation from typedname error: %s", nwam_strerror(err));
14146ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
14156ba597c5SAnurag S. Maskey return;
14166ba597c5SAnurag S. Maskey }
14176ba597c5SAnurag S. Maskey
14186ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
14196ba597c5SAnurag S. Maskey if (strcmp(active_ncp, NWAM_NCP_NAME_AUTOMATIC) == 0 &&
14206ba597c5SAnurag S. Maskey active_ncph != NULL) {
14216ba597c5SAnurag S. Maskey automatic_ncp_active = B_TRUE;
14226ba597c5SAnurag S. Maskey }
14236ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
14246ba597c5SAnurag S. Maskey
14256ba597c5SAnurag S. Maskey /*
14266ba597c5SAnurag S. Maskey * We could use active_ncph for cases where the Automatic NCP is active,
14276ba597c5SAnurag S. Maskey * but that would involve holding the active_ncp_mutex for too long.
14286ba597c5SAnurag S. Maskey */
14296ba597c5SAnurag S. Maskey if ((err = nwam_ncp_read(NWAM_NCP_NAME_AUTOMATIC, 0, &ncph))
14306ba597c5SAnurag S. Maskey == NWAM_ENTITY_NOT_FOUND) {
14316ba597c5SAnurag S. Maskey /* Automatic NCP doesn't exist, create it */
143271ed50cfSAnurag S. Maskey err = nwam_ncp_create(NWAM_NCP_NAME_AUTOMATIC, 0, &ncph);
14336ba597c5SAnurag S. Maskey }
143471ed50cfSAnurag S. Maskey if (err != NWAM_SUCCESS)
143571ed50cfSAnurag S. Maskey goto fail;
14366ba597c5SAnurag S. Maskey
14376ba597c5SAnurag S. Maskey /* add or remove NCUs from Automatic NCP */
14386ba597c5SAnurag S. Maskey if (action == NWAM_ACTION_ADD) {
14396ba597c5SAnurag S. Maskey add_phys_ncu_to_ncp(ncph, name);
14406ba597c5SAnurag S. Maskey add_ip_ncu_to_ncp(ncph, name);
14416ba597c5SAnurag S. Maskey } else {
14426ba597c5SAnurag S. Maskey /*
14436ba597c5SAnurag S. Maskey * Order is important here, remove IP NCU first to prevent
14446ba597c5SAnurag S. Maskey * propogation of down event from link to IP. No need to
14456ba597c5SAnurag S. Maskey * create REFRESH or DESTROY events. They are generated by
14466ba597c5SAnurag S. Maskey * nwam_ncu_commit() and nwam_ncu_destroy().
14476ba597c5SAnurag S. Maskey */
14486ba597c5SAnurag S. Maskey remove_ncu_from_ncp(ncph, name, NWAM_NCU_TYPE_INTERFACE);
14496ba597c5SAnurag S. Maskey remove_ncu_from_ncp(ncph, name, NWAM_NCU_TYPE_LINK);
14506ba597c5SAnurag S. Maskey }
14516ba597c5SAnurag S. Maskey nwam_ncp_free(ncph);
14526ba597c5SAnurag S. Maskey
14536ba597c5SAnurag S. Maskey /*
14546ba597c5SAnurag S. Maskey * If the Automatic NCP is not active, and the associated NCUs
14556ba597c5SAnurag S. Maskey * exist, they must be moved into the appropriate states given the
14566ba597c5SAnurag S. Maskey * action that has occurred.
14576ba597c5SAnurag S. Maskey */
14586ba597c5SAnurag S. Maskey if (!automatic_ncp_active) {
14596ba597c5SAnurag S. Maskey ncu_action_change_state(action, NWAM_NCU_TYPE_INTERFACE, name);
14606ba597c5SAnurag S. Maskey ncu_action_change_state(action, NWAM_NCU_TYPE_LINK, name);
14616ba597c5SAnurag S. Maskey }
14626ba597c5SAnurag S. Maskey
14636ba597c5SAnurag S. Maskey /* Need NCU check to evaluate state in light of added/removed NCUs */
14646ba597c5SAnurag S. Maskey if (!nwamd_event_enqueued(NWAM_EVENT_TYPE_NCU_CHECK,
14656ba597c5SAnurag S. Maskey NWAM_OBJECT_TYPE_NCP, NULL)) {
14666ba597c5SAnurag S. Maskey nwamd_create_ncu_check_event(NEXT_FEW_SECONDS);
14676ba597c5SAnurag S. Maskey }
14686ba597c5SAnurag S. Maskey
146971ed50cfSAnurag S. Maskey fail:
14706ba597c5SAnurag S. Maskey free(name);
147171ed50cfSAnurag S. Maskey if (err != NWAM_SUCCESS) {
147271ed50cfSAnurag S. Maskey nwamd_event_t retry_event = nwamd_event_init_link_action(name,
147371ed50cfSAnurag S. Maskey action);
147471ed50cfSAnurag S. Maskey if (retry_event == NULL) {
147571ed50cfSAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
147671ed50cfSAnurag S. Maskey "could not create retry event to read/create "
147771ed50cfSAnurag S. Maskey "%s NCP", NWAM_NCP_NAME_AUTOMATIC);
147871ed50cfSAnurag S. Maskey return;
147971ed50cfSAnurag S. Maskey }
148071ed50cfSAnurag S. Maskey
148171ed50cfSAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_link_action_event: "
148271ed50cfSAnurag S. Maskey "could not read/create %s NCP, retrying in %d seconds",
148371ed50cfSAnurag S. Maskey NWAM_NCP_NAME_AUTOMATIC, NWAMD_READONLY_RETRY_INTERVAL);
148471ed50cfSAnurag S. Maskey nwamd_event_enqueue_timed(retry_event,
148571ed50cfSAnurag S. Maskey NWAMD_READONLY_RETRY_INTERVAL);
148671ed50cfSAnurag S. Maskey }
14876ba597c5SAnurag S. Maskey }
14886ba597c5SAnurag S. Maskey
14896ba597c5SAnurag S. Maskey /*
14906ba597c5SAnurag S. Maskey * Figure out if this link is part of an aggregation. This is fairly
14916ba597c5SAnurag S. Maskey * inefficient since we generate this list for every query and search
14926ba597c5SAnurag S. Maskey * linearly. A better way would be to generate the list of links in an
14936ba597c5SAnurag S. Maskey * aggregation once and then check each link against it.
14946ba597c5SAnurag S. Maskey */
14956ba597c5SAnurag S. Maskey struct link_aggr_search_data {
14966ba597c5SAnurag S. Maskey datalink_id_t linkid;
14976ba597c5SAnurag S. Maskey boolean_t under;
14986ba597c5SAnurag S. Maskey };
14996ba597c5SAnurag S. Maskey
15006ba597c5SAnurag S. Maskey static int
ncu_aggr_search(const char * name,void * data)15016ba597c5SAnurag S. Maskey ncu_aggr_search(const char *name, void *data)
15026ba597c5SAnurag S. Maskey {
15036ba597c5SAnurag S. Maskey struct link_aggr_search_data *lasd = data;
15046ba597c5SAnurag S. Maskey dladm_aggr_grp_attr_t ginfo;
15056ba597c5SAnurag S. Maskey datalink_id_t linkid;
15066ba597c5SAnurag S. Maskey int i;
15076ba597c5SAnurag S. Maskey
15086ba597c5SAnurag S. Maskey if (dladm_name2info(dld_handle, name, &linkid, NULL, NULL, NULL) !=
15096ba597c5SAnurag S. Maskey DLADM_STATUS_OK)
15106ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15116ba597c5SAnurag S. Maskey if (dladm_aggr_info(dld_handle, linkid, &ginfo, DLADM_OPT_ACTIVE)
15126ba597c5SAnurag S. Maskey != DLADM_STATUS_OK || ginfo.lg_nports == 0)
15136ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15146ba597c5SAnurag S. Maskey
15156ba597c5SAnurag S. Maskey for (i = 0; i < ginfo.lg_nports; i++) {
15166ba597c5SAnurag S. Maskey if (lasd->linkid == ginfo.lg_ports[i].lp_linkid) {
15176ba597c5SAnurag S. Maskey lasd->under = B_TRUE;
15186ba597c5SAnurag S. Maskey return (DLADM_WALK_TERMINATE);
15196ba597c5SAnurag S. Maskey }
15206ba597c5SAnurag S. Maskey }
15216ba597c5SAnurag S. Maskey free(ginfo.lg_ports);
15226ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15236ba597c5SAnurag S. Maskey }
15246ba597c5SAnurag S. Maskey
15256ba597c5SAnurag S. Maskey static boolean_t
nwamd_link_belongs_to_an_aggr(const char * name)15266ba597c5SAnurag S. Maskey nwamd_link_belongs_to_an_aggr(const char *name)
15276ba597c5SAnurag S. Maskey {
15286ba597c5SAnurag S. Maskey struct link_aggr_search_data lasd;
15296ba597c5SAnurag S. Maskey
15306ba597c5SAnurag S. Maskey if (dladm_name2info(dld_handle, name, &lasd.linkid, NULL, NULL, NULL)
15316ba597c5SAnurag S. Maskey != DLADM_STATUS_OK)
15326ba597c5SAnurag S. Maskey return (B_FALSE);
15336ba597c5SAnurag S. Maskey lasd.under = B_FALSE;
15346ba597c5SAnurag S. Maskey (void) dladm_walk(ncu_aggr_search, dld_handle, &lasd,
15356ba597c5SAnurag S. Maskey DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
15366ba597c5SAnurag S. Maskey return (lasd.under);
15376ba597c5SAnurag S. Maskey }
15386ba597c5SAnurag S. Maskey
15396ba597c5SAnurag S. Maskey /*
15406ba597c5SAnurag S. Maskey * If NCU doesn't exist for interface with given name, enqueue a ADD
15416ba597c5SAnurag S. Maskey * LINK_ACTION event.
15426ba597c5SAnurag S. Maskey */
15436ba597c5SAnurag S. Maskey static int
ncu_create_link_action_event(const char * name,void * data)15446ba597c5SAnurag S. Maskey ncu_create_link_action_event(const char *name, void *data)
15456ba597c5SAnurag S. Maskey {
15466ba597c5SAnurag S. Maskey nwam_ncp_handle_t ncph = data;
15476ba597c5SAnurag S. Maskey nwam_ncu_handle_t ncuh;
15486ba597c5SAnurag S. Maskey nwamd_event_t link_event;
15496ba597c5SAnurag S. Maskey
15506ba597c5SAnurag S. Maskey /* Do not generate an event if this is a VirtualBox interface. */
15516ba597c5SAnurag S. Maskey if (strncmp(name, VBOX_IFACE_PREFIX, strlen(VBOX_IFACE_PREFIX)) == 0)
15526ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15536ba597c5SAnurag S. Maskey
15546ba597c5SAnurag S. Maskey /* Do not generate an event if this link belongs to another zone. */
15556ba597c5SAnurag S. Maskey if (!nwamd_link_belongs_to_this_zone(name))
15566ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15576ba597c5SAnurag S. Maskey
15586ba597c5SAnurag S. Maskey /* Do not generate an event if this link belongs to an aggregation. */
15596ba597c5SAnurag S. Maskey if (nwamd_link_belongs_to_an_aggr(name)) {
15606ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15616ba597c5SAnurag S. Maskey }
15626ba597c5SAnurag S. Maskey
15636ba597c5SAnurag S. Maskey /* Don't create an event if the NCU already exists. */
15646ba597c5SAnurag S. Maskey if (ncph != NULL && nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK, 0,
15656ba597c5SAnurag S. Maskey &ncuh) == NWAM_SUCCESS) {
15666ba597c5SAnurag S. Maskey nwam_ncu_free(ncuh);
15676ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15686ba597c5SAnurag S. Maskey }
15696ba597c5SAnurag S. Maskey
15706ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "ncu_create_link_action_event: adding ncus for %s",
15716ba597c5SAnurag S. Maskey name);
15726ba597c5SAnurag S. Maskey
15736ba597c5SAnurag S. Maskey link_event = nwamd_event_init_link_action(name, NWAM_ACTION_ADD);
15746ba597c5SAnurag S. Maskey if (link_event != NULL)
15756ba597c5SAnurag S. Maskey nwamd_event_enqueue(link_event);
15766ba597c5SAnurag S. Maskey
15776ba597c5SAnurag S. Maskey return (DLADM_WALK_CONTINUE);
15786ba597c5SAnurag S. Maskey }
15796ba597c5SAnurag S. Maskey
15806ba597c5SAnurag S. Maskey /*
15816ba597c5SAnurag S. Maskey * Check if interface exists for this NCU. If not, enqueue a REMOVE
15826ba597c5SAnurag S. Maskey * LINK_ACTION event.
15836ba597c5SAnurag S. Maskey */
15846ba597c5SAnurag S. Maskey /* ARGSUSED */
15856ba597c5SAnurag S. Maskey static int
nwamd_destroy_ncu(nwam_ncu_handle_t ncuh,void * data)15866ba597c5SAnurag S. Maskey nwamd_destroy_ncu(nwam_ncu_handle_t ncuh, void *data)
15876ba597c5SAnurag S. Maskey {
15886ba597c5SAnurag S. Maskey char *name;
15896ba597c5SAnurag S. Maskey uint32_t flags;
15906ba597c5SAnurag S. Maskey nwamd_event_t link_event;
15916ba597c5SAnurag S. Maskey
15926ba597c5SAnurag S. Maskey if (nwam_ncu_get_name(ncuh, &name) != NWAM_SUCCESS) {
15936ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_destroy_ncu: could not get NCU name");
15946ba597c5SAnurag S. Maskey return (0);
15956ba597c5SAnurag S. Maskey }
15966ba597c5SAnurag S. Maskey
15976ba597c5SAnurag S. Maskey /* Interfaces that exist return DLADM_OPT_ACTIVE flag */
15986ba597c5SAnurag S. Maskey if ((dladm_name2info(dld_handle, name, NULL, &flags, NULL, NULL)
15996ba597c5SAnurag S. Maskey == DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) &&
16006ba597c5SAnurag S. Maskey !nwamd_link_belongs_to_an_aggr(name)) {
16016ba597c5SAnurag S. Maskey free(name);
16026ba597c5SAnurag S. Maskey return (0);
16036ba597c5SAnurag S. Maskey }
16046ba597c5SAnurag S. Maskey
16056ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_destroy_ncu: destroying ncus for %s", name);
16066ba597c5SAnurag S. Maskey
16076ba597c5SAnurag S. Maskey link_event = nwamd_event_init_link_action(name, NWAM_ACTION_REMOVE);
16086ba597c5SAnurag S. Maskey if (link_event != NULL)
16096ba597c5SAnurag S. Maskey nwamd_event_enqueue(link_event);
16106ba597c5SAnurag S. Maskey free(name);
16116ba597c5SAnurag S. Maskey return (0);
16126ba597c5SAnurag S. Maskey }
16136ba597c5SAnurag S. Maskey
16146ba597c5SAnurag S. Maskey /*
16156ba597c5SAnurag S. Maskey * Called when nwamd is starting up.
16166ba597c5SAnurag S. Maskey *
16176ba597c5SAnurag S. Maskey * Walk all NCUs and destroy any NCU from the Automatic NCP without an
16186ba597c5SAnurag S. Maskey * underlying interface (assumption here is that the interface was removed
16196ba597c5SAnurag S. Maskey * when nwam was disabled).
16206ba597c5SAnurag S. Maskey *
16216ba597c5SAnurag S. Maskey * Walk the physical interfaces and create ADD LINK_ACTION event, which
16226ba597c5SAnurag S. Maskey * will create appropriate interface and link NCUs in the Automatic NCP.
16236ba597c5SAnurag S. Maskey */
16246ba597c5SAnurag S. Maskey void
nwamd_walk_physical_configuration(void)16256ba597c5SAnurag S. Maskey nwamd_walk_physical_configuration(void)
16266ba597c5SAnurag S. Maskey {
16276ba597c5SAnurag S. Maskey nwam_ncp_handle_t ncph;
1628f689bed1SRishi Srivatsavai datalink_class_t dlclass = DATALINK_CLASS_PHYS;
1629f689bed1SRishi Srivatsavai zoneid_t zoneid = getzoneid();
16306ba597c5SAnurag S. Maskey
16316ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
16326ba597c5SAnurag S. Maskey if (strcmp(active_ncp, NWAM_NCP_NAME_AUTOMATIC) == 0 &&
16336ba597c5SAnurag S. Maskey active_ncph != NULL) {
16346ba597c5SAnurag S. Maskey ncph = active_ncph;
16356ba597c5SAnurag S. Maskey } else {
16366ba597c5SAnurag S. Maskey if (nwam_ncp_read(NWAM_NCP_NAME_AUTOMATIC, 0, &ncph)
16376ba597c5SAnurag S. Maskey != NWAM_SUCCESS) {
16386ba597c5SAnurag S. Maskey ncph = NULL;
16396ba597c5SAnurag S. Maskey }
16406ba597c5SAnurag S. Maskey }
16416ba597c5SAnurag S. Maskey
16426ba597c5SAnurag S. Maskey /* destroy NCUs for interfaces that don't exist */
16436ba597c5SAnurag S. Maskey if (ncph != NULL) {
16446ba597c5SAnurag S. Maskey (void) nwam_ncp_walk_ncus(ncph, nwamd_destroy_ncu, NULL,
16456ba597c5SAnurag S. Maskey NWAM_FLAG_NCU_TYPE_LINK, NULL);
16466ba597c5SAnurag S. Maskey }
16476ba597c5SAnurag S. Maskey
1648f689bed1SRishi Srivatsavai /* In non-global zones NWAM can support VNICs */
1649f689bed1SRishi Srivatsavai if (zoneid != GLOBAL_ZONEID)
1650f689bed1SRishi Srivatsavai dlclass |= DATALINK_CLASS_VNIC;
1651f689bed1SRishi Srivatsavai
16526ba597c5SAnurag S. Maskey /* create NCUs for interfaces without NCUs */
16536ba597c5SAnurag S. Maskey (void) dladm_walk(ncu_create_link_action_event, dld_handle, ncph,
1654f689bed1SRishi Srivatsavai dlclass, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
16556ba597c5SAnurag S. Maskey
16566ba597c5SAnurag S. Maskey if (strcmp(active_ncp, NWAM_NCP_NAME_AUTOMATIC) != 0 ||
16576ba597c5SAnurag S. Maskey active_ncph == NULL) {
16586ba597c5SAnurag S. Maskey nwam_ncp_free(ncph);
16596ba597c5SAnurag S. Maskey }
16606ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
16616ba597c5SAnurag S. Maskey }
16626ba597c5SAnurag S. Maskey
16636ba597c5SAnurag S. Maskey /*
16646ba597c5SAnurag S. Maskey * Handle NCU initialization/refresh event.
16656ba597c5SAnurag S. Maskey */
16666ba597c5SAnurag S. Maskey void
nwamd_ncu_handle_init_event(nwamd_event_t event)16676ba597c5SAnurag S. Maskey nwamd_ncu_handle_init_event(nwamd_event_t event)
16686ba597c5SAnurag S. Maskey {
16696ba597c5SAnurag S. Maskey nwamd_object_t object = NULL;
16706ba597c5SAnurag S. Maskey nwam_ncu_handle_t ncuh;
16716ba597c5SAnurag S. Maskey nwamd_ncu_t *ncu = NULL;
16726ba597c5SAnurag S. Maskey nwam_error_t err;
16736ba597c5SAnurag S. Maskey nwam_ncu_type_t type;
16746ba597c5SAnurag S. Maskey char *name;
16756ba597c5SAnurag S. Maskey uint32_t flags;
16766ba597c5SAnurag S. Maskey boolean_t new = B_TRUE;
16776ba597c5SAnurag S. Maskey
16786ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_init_event(%s)",
16796ba597c5SAnurag S. Maskey event->event_object);
16806ba597c5SAnurag S. Maskey
16816ba597c5SAnurag S. Maskey /* Get base linkname rather than interface:linkname or link:linkname */
16826ba597c5SAnurag S. Maskey err = nwam_ncu_typed_name_to_name(event->event_object,
16836ba597c5SAnurag S. Maskey &type, &name);
16846ba597c5SAnurag S. Maskey if (err != NWAM_SUCCESS) {
16856ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_init_event: "
16866ba597c5SAnurag S. Maskey "nwam_ncu_typed_name_to_name returned %s",
16876ba597c5SAnurag S. Maskey nwam_strerror(err));
16886ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
16896ba597c5SAnurag S. Maskey return;
16906ba597c5SAnurag S. Maskey }
16916ba597c5SAnurag S. Maskey
16926ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
16936ba597c5SAnurag S. Maskey if (active_ncph == NULL) {
16946ba597c5SAnurag S. Maskey nlog(LOG_DEBUG,
16956ba597c5SAnurag S. Maskey "nwamd_ncu_handle_init_event: active NCP handle NULL");
16966ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
169771ed50cfSAnurag S. Maskey free(name);
16986ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
16996ba597c5SAnurag S. Maskey return;
17006ba597c5SAnurag S. Maskey }
17016ba597c5SAnurag S. Maskey err = nwam_ncu_read(active_ncph, event->event_object,
17026ba597c5SAnurag S. Maskey type, 0, &ncuh);
17036ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
17046ba597c5SAnurag S. Maskey if (err != NWAM_SUCCESS) {
17056ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_init_event: "
17066ba597c5SAnurag S. Maskey "could not read object '%s': %s",
17076ba597c5SAnurag S. Maskey event->event_object, nwam_strerror(err));
17086ba597c5SAnurag S. Maskey free(name);
17096ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
17106ba597c5SAnurag S. Maskey return;
17116ba597c5SAnurag S. Maskey }
17126ba597c5SAnurag S. Maskey
17136ba597c5SAnurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
17146ba597c5SAnurag S. Maskey event->event_object)) != NULL)
17156ba597c5SAnurag S. Maskey new = B_FALSE;
17166ba597c5SAnurag S. Maskey
17176ba597c5SAnurag S. Maskey /*
17186ba597c5SAnurag S. Maskey * For new NCUs, or interface NCUs, we (re)initialize data from scratch.
17196ba597c5SAnurag S. Maskey * For link NCUs, we want to retain object data.
17206ba597c5SAnurag S. Maskey */
17216ba597c5SAnurag S. Maskey switch (type) {
17226ba597c5SAnurag S. Maskey case NWAM_NCU_TYPE_LINK:
17236ba597c5SAnurag S. Maskey if (new) {
17246ba597c5SAnurag S. Maskey ncu = nwamd_ncu_init(type, name);
17256ba597c5SAnurag S. Maskey } else {
17266ba597c5SAnurag S. Maskey ncu = object->nwamd_object_data;
17276ba597c5SAnurag S. Maskey nwam_ncu_free(object->nwamd_object_handle);
17286ba597c5SAnurag S. Maskey }
17296ba597c5SAnurag S. Maskey populate_common_ncu_properties(ncuh, ncu);
17306ba597c5SAnurag S. Maskey populate_link_ncu_properties(ncuh, ncu);
17316ba597c5SAnurag S. Maskey break;
17326ba597c5SAnurag S. Maskey case NWAM_NCU_TYPE_INTERFACE:
17336ba597c5SAnurag S. Maskey if (!new) {
17346ba597c5SAnurag S. Maskey nwam_ncu_free(object->nwamd_object_handle);
17356ba597c5SAnurag S. Maskey nwamd_ncu_free(object->nwamd_object_data);
17366ba597c5SAnurag S. Maskey }
17376ba597c5SAnurag S. Maskey ncu = nwamd_ncu_init(type, name);
17386ba597c5SAnurag S. Maskey populate_common_ncu_properties(ncuh, ncu);
17396ba597c5SAnurag S. Maskey populate_ip_ncu_properties(ncuh, ncu);
17406ba597c5SAnurag S. Maskey break;
17416ba597c5SAnurag S. Maskey default:
17426ba597c5SAnurag S. Maskey nlog(LOG_ERR, "unknown ncu type %d", type);
17436ba597c5SAnurag S. Maskey free(name);
17446ba597c5SAnurag S. Maskey nwam_ncu_free(ncuh);
17456ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
17466ba597c5SAnurag S. Maskey nwamd_object_release(object);
17476ba597c5SAnurag S. Maskey return;
17486ba597c5SAnurag S. Maskey }
17496ba597c5SAnurag S. Maskey
17506ba597c5SAnurag S. Maskey if (new) {
17516ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_init_event: didn't find "
17526ba597c5SAnurag S. Maskey "ncu so create it %s", name);
17536ba597c5SAnurag S. Maskey object = nwamd_object_init(NWAM_OBJECT_TYPE_NCU,
17546ba597c5SAnurag S. Maskey event->event_object, ncuh, ncu);
17556ba597c5SAnurag S. Maskey } else {
17566ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_init_event: refreshing "
17576ba597c5SAnurag S. Maskey "ncu %s", name);
17586ba597c5SAnurag S. Maskey object->nwamd_object_data = ncu;
17596ba597c5SAnurag S. Maskey object->nwamd_object_handle = ncuh;
17606ba597c5SAnurag S. Maskey }
17616ba597c5SAnurag S. Maskey
17626ba597c5SAnurag S. Maskey /*
17636ba597c5SAnurag S. Maskey * If the physical link for this NCU doesn't exist in the system,
17646ba597c5SAnurag S. Maskey * the state should be UNINITIALIZED/NOT_FOUND. Interfaces that
17656ba597c5SAnurag S. Maskey * exist return DLADM_OPT_ACTIVE flag.
17666ba597c5SAnurag S. Maskey */
17676ba597c5SAnurag S. Maskey if (dladm_name2info(dld_handle, name, NULL, &flags, NULL, NULL)
17686ba597c5SAnurag S. Maskey != DLADM_STATUS_OK || !(flags & DLADM_OPT_ACTIVE)) {
17696ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwam_ncu_handle_init_event: "
17706ba597c5SAnurag S. Maskey "interface for NCU %s doesn't exist",
17716ba597c5SAnurag S. Maskey event->event_object);
17726ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
17736ba597c5SAnurag S. Maskey object->nwamd_object_name, NWAM_STATE_UNINITIALIZED,
17746ba597c5SAnurag S. Maskey NWAM_AUX_STATE_NOT_FOUND);
17756ba597c5SAnurag S. Maskey free(name);
17766ba597c5SAnurag S. Maskey nwamd_object_release(object);
17776ba597c5SAnurag S. Maskey return;
17786ba597c5SAnurag S. Maskey }
17796ba597c5SAnurag S. Maskey
17806ba597c5SAnurag S. Maskey /*
17816ba597c5SAnurag S. Maskey * If NCU is being initialized (rather than refreshed), the
17826ba597c5SAnurag S. Maskey * object_state is INITIALIZED (from nwamd_object_init()).
17836ba597c5SAnurag S. Maskey */
17846ba597c5SAnurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_INITIALIZED) {
17856ba597c5SAnurag S. Maskey /*
17866ba597c5SAnurag S. Maskey * If the NCU is disabled, initial state should be DISABLED.
17876ba597c5SAnurag S. Maskey *
17886ba597c5SAnurag S. Maskey * Otherwise, the initial state will be
17896ba597c5SAnurag S. Maskey * OFFLINE/CONDITIONS_NOT_MET, and the link selection
17906ba597c5SAnurag S. Maskey * algorithm will do the rest.
17916ba597c5SAnurag S. Maskey */
17926ba597c5SAnurag S. Maskey if (!ncu->ncu_enabled) {
17936ba597c5SAnurag S. Maskey object->nwamd_object_state = NWAM_STATE_DISABLED;
17946ba597c5SAnurag S. Maskey object->nwamd_object_aux_state =
17956ba597c5SAnurag S. Maskey NWAM_AUX_STATE_MANUAL_DISABLE;
17966ba597c5SAnurag S. Maskey } else {
17976ba597c5SAnurag S. Maskey object->nwamd_object_state = NWAM_STATE_OFFLINE;
17986ba597c5SAnurag S. Maskey object->nwamd_object_aux_state =
17996ba597c5SAnurag S. Maskey NWAM_AUX_STATE_CONDITIONS_NOT_MET;
18006ba597c5SAnurag S. Maskey }
18016ba597c5SAnurag S. Maskey } else {
1802f6da83d4SAnurag S. Maskey nwamd_link_t *link = &ncu->ncu_link;
18036ba597c5SAnurag S. Maskey
18046ba597c5SAnurag S. Maskey /*
18056ba597c5SAnurag S. Maskey * Refresh NCU. Deal with disabled cases first, moving NCUs
18066ba597c5SAnurag S. Maskey * that are not disabled - but have the enabled value set - to
18076ba597c5SAnurag S. Maskey * the disabled state. Then handle cases where the NCU was
18086ba597c5SAnurag S. Maskey * disabled but is no longer. Finally, deal with refresh of
18096ba597c5SAnurag S. Maskey * link and interface NCUs, as these are handled differently.
18106ba597c5SAnurag S. Maskey */
18116ba597c5SAnurag S. Maskey if (!ncu->ncu_enabled) {
18126ba597c5SAnurag S. Maskey if (object->nwamd_object_state != NWAM_STATE_DISABLED) {
18136ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
18146ba597c5SAnurag S. Maskey object->nwamd_object_name,
18156ba597c5SAnurag S. Maskey NWAM_STATE_ONLINE_TO_OFFLINE,
18166ba597c5SAnurag S. Maskey NWAM_AUX_STATE_MANUAL_DISABLE);
18176ba597c5SAnurag S. Maskey }
18186ba597c5SAnurag S. Maskey goto done;
18196ba597c5SAnurag S. Maskey } else {
18206ba597c5SAnurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_DISABLED) {
18216ba597c5SAnurag S. Maskey int64_t c;
18226ba597c5SAnurag S. Maskey
18236ba597c5SAnurag S. Maskey /*
18246ba597c5SAnurag S. Maskey * Try to activate the NCU if manual or
18256ba597c5SAnurag S. Maskey * prioritized (when priority <= current).
18266ba597c5SAnurag S. Maskey */
18276ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
18286ba597c5SAnurag S. Maskey c = current_ncu_priority_group;
18296ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
18306ba597c5SAnurag S. Maskey if (link->nwamd_link_activation_mode ==
18316ba597c5SAnurag S. Maskey NWAM_ACTIVATION_MODE_MANUAL ||
18326ba597c5SAnurag S. Maskey (link->nwamd_link_activation_mode ==
18336ba597c5SAnurag S. Maskey NWAM_ACTIVATION_MODE_PRIORITIZED &&
18346ba597c5SAnurag S. Maskey link->nwamd_link_priority_mode <= c)) {
18356ba597c5SAnurag S. Maskey nwamd_object_set_state
18366ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU,
18376ba597c5SAnurag S. Maskey object->nwamd_object_name,
18386ba597c5SAnurag S. Maskey NWAM_STATE_OFFLINE_TO_ONLINE,
18396ba597c5SAnurag S. Maskey NWAM_AUX_STATE_INITIALIZED);
18406ba597c5SAnurag S. Maskey } else {
18416ba597c5SAnurag S. Maskey nwamd_object_set_state
18426ba597c5SAnurag S. Maskey (NWAM_OBJECT_TYPE_NCU,
18436ba597c5SAnurag S. Maskey object->nwamd_object_name,
18446ba597c5SAnurag S. Maskey NWAM_STATE_OFFLINE_TO_ONLINE,
18456ba597c5SAnurag S. Maskey NWAM_AUX_STATE_INITIALIZED);
18466ba597c5SAnurag S. Maskey }
18476ba597c5SAnurag S. Maskey goto done;
18486ba597c5SAnurag S. Maskey }
18496ba597c5SAnurag S. Maskey }
18506ba597c5SAnurag S. Maskey
18516ba597c5SAnurag S. Maskey switch (type) {
18526ba597c5SAnurag S. Maskey case NWAM_NCU_TYPE_LINK:
1853f6da83d4SAnurag S. Maskey if (ncu->ncu_link.nwamd_link_media == DL_WIFI) {
18546ba597c5SAnurag S. Maskey /*
18556ba597c5SAnurag S. Maskey * Do rescan. If the current state and the
18566ba597c5SAnurag S. Maskey * active priority-group do not allow wireless
18576ba597c5SAnurag S. Maskey * network selection, then it won't happen.
18586ba597c5SAnurag S. Maskey */
18596ba597c5SAnurag S. Maskey (void) nwamd_wlan_scan(ncu->ncu_name);
18606ba597c5SAnurag S. Maskey }
18616ba597c5SAnurag S. Maskey break;
18626ba597c5SAnurag S. Maskey case NWAM_NCU_TYPE_INTERFACE:
18636ba597c5SAnurag S. Maskey /*
18646ba597c5SAnurag S. Maskey * If interface NCU is offline*, online or in
18656ba597c5SAnurag S. Maskey * maintenance, mark it down (from there, it will be
18666ba597c5SAnurag S. Maskey * reinitialized to reapply addresses).
18676ba597c5SAnurag S. Maskey */
18686ba597c5SAnurag S. Maskey if (object->nwamd_object_state != NWAM_STATE_OFFLINE) {
18696ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
18706ba597c5SAnurag S. Maskey object->nwamd_object_name,
18716ba597c5SAnurag S. Maskey NWAM_STATE_ONLINE_TO_OFFLINE,
18726ba597c5SAnurag S. Maskey NWAM_AUX_STATE_DOWN);
18736ba597c5SAnurag S. Maskey } else {
18746ba597c5SAnurag S. Maskey object->nwamd_object_state = NWAM_STATE_OFFLINE;
18756ba597c5SAnurag S. Maskey object->nwamd_object_aux_state =
18766ba597c5SAnurag S. Maskey NWAM_AUX_STATE_CONDITIONS_NOT_MET;
18776ba597c5SAnurag S. Maskey }
18786ba597c5SAnurag S. Maskey break;
18796ba597c5SAnurag S. Maskey }
18806ba597c5SAnurag S. Maskey }
18816ba597c5SAnurag S. Maskey
18826ba597c5SAnurag S. Maskey done:
18836ba597c5SAnurag S. Maskey if (type == NWAM_NCU_TYPE_LINK &&
18846ba597c5SAnurag S. Maskey !nwamd_event_enqueued(NWAM_EVENT_TYPE_NCU_CHECK,
18856ba597c5SAnurag S. Maskey NWAM_OBJECT_TYPE_NCP, NULL)) {
18866ba597c5SAnurag S. Maskey nwamd_create_ncu_check_event(NEXT_FEW_SECONDS);
18876ba597c5SAnurag S. Maskey }
18886ba597c5SAnurag S. Maskey free(name);
18896ba597c5SAnurag S. Maskey nwamd_object_release(object);
18906ba597c5SAnurag S. Maskey }
18916ba597c5SAnurag S. Maskey
18926ba597c5SAnurag S. Maskey void
nwamd_ncu_handle_fini_event(nwamd_event_t event)18936ba597c5SAnurag S. Maskey nwamd_ncu_handle_fini_event(nwamd_event_t event)
18946ba597c5SAnurag S. Maskey {
18956ba597c5SAnurag S. Maskey nwamd_object_t object;
18966ba597c5SAnurag S. Maskey nwamd_event_t state_event;
18976ba597c5SAnurag S. Maskey
18986ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_fini_event(%s)",
18996ba597c5SAnurag S. Maskey event->event_object);
19006ba597c5SAnurag S. Maskey
19016ba597c5SAnurag S. Maskey /*
19026ba597c5SAnurag S. Maskey * Simulate a state event so that the state machine can correctly
19036ba597c5SAnurag S. Maskey * disable the NCU. Then free up allocated objects.
19046ba597c5SAnurag S. Maskey */
19056ba597c5SAnurag S. Maskey state_event = nwamd_event_init_object_state(NWAM_OBJECT_TYPE_NCU,
19066ba597c5SAnurag S. Maskey event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
19076ba597c5SAnurag S. Maskey NWAM_AUX_STATE_UNINITIALIZED);
19086ba597c5SAnurag S. Maskey if (state_event == NULL) {
19096ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
19106ba597c5SAnurag S. Maskey return;
19116ba597c5SAnurag S. Maskey }
19126ba597c5SAnurag S. Maskey nwamd_ncu_handle_state_event(state_event);
19136ba597c5SAnurag S. Maskey nwamd_event_fini(state_event);
19146ba597c5SAnurag S. Maskey
19156ba597c5SAnurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
19166ba597c5SAnurag S. Maskey event->event_object)) == NULL) {
1917f6904bc3SRenee Danson Sommerfeld nlog(LOG_INFO, "nwamd_ncu_handle_fini_event: "
19186ba597c5SAnurag S. Maskey "ncu %s not found", event->event_object);
19196ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
19206ba597c5SAnurag S. Maskey return;
19216ba597c5SAnurag S. Maskey }
19226ba597c5SAnurag S. Maskey nwamd_object_release_and_destroy(object);
19236ba597c5SAnurag S. Maskey }
19246ba597c5SAnurag S. Maskey
19256ba597c5SAnurag S. Maskey void
nwamd_ncu_handle_action_event(nwamd_event_t event)19266ba597c5SAnurag S. Maskey nwamd_ncu_handle_action_event(nwamd_event_t event)
19276ba597c5SAnurag S. Maskey {
19286ba597c5SAnurag S. Maskey nwamd_object_t object;
19296ba597c5SAnurag S. Maskey
19306ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&active_ncp_mutex);
19316ba597c5SAnurag S. Maskey if (strcmp(event->event_msg->nwe_data.nwe_object_action.nwe_parent,
19326ba597c5SAnurag S. Maskey active_ncp) != 0) {
19336ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_action_event: action for "
19346ba597c5SAnurag S. Maskey "inactive NCP %s, nothing to do",
19356ba597c5SAnurag S. Maskey event->event_msg->nwe_data.nwe_object_action.nwe_parent);
19366ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
19376ba597c5SAnurag S. Maskey return;
19386ba597c5SAnurag S. Maskey }
19396ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&active_ncp_mutex);
19406ba597c5SAnurag S. Maskey
19416ba597c5SAnurag S. Maskey switch (event->event_msg->nwe_data.nwe_object_action.nwe_action) {
19426ba597c5SAnurag S. Maskey case NWAM_ACTION_ENABLE:
19436ba597c5SAnurag S. Maskey object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
19446ba597c5SAnurag S. Maskey event->event_object);
19456ba597c5SAnurag S. Maskey if (object == NULL) {
19466ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_action_event: "
19476ba597c5SAnurag S. Maskey "could not find ncu %s", event->event_object);
19486ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
19496ba597c5SAnurag S. Maskey return;
19506ba597c5SAnurag S. Maskey }
19516ba597c5SAnurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_ONLINE) {
19526ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_action_event: "
19536ba597c5SAnurag S. Maskey "ncu %s already online, nothing to do",
19546ba597c5SAnurag S. Maskey event->event_object);
19556ba597c5SAnurag S. Maskey nwamd_object_release(object);
19566ba597c5SAnurag S. Maskey return;
19576ba597c5SAnurag S. Maskey }
19586ba597c5SAnurag S. Maskey nwamd_object_release(object);
19596ba597c5SAnurag S. Maskey
19606ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
19616ba597c5SAnurag S. Maskey event->event_object, NWAM_STATE_OFFLINE_TO_ONLINE,
19626ba597c5SAnurag S. Maskey NWAM_AUX_STATE_INITIALIZED);
19636ba597c5SAnurag S. Maskey break;
19646ba597c5SAnurag S. Maskey case NWAM_ACTION_DISABLE:
19656ba597c5SAnurag S. Maskey object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
19666ba597c5SAnurag S. Maskey event->event_object);
19676ba597c5SAnurag S. Maskey if (object == NULL) {
19686ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_ncu_handle_action_event: "
19696ba597c5SAnurag S. Maskey "could not find ncu %s", event->event_object);
19706ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
19716ba597c5SAnurag S. Maskey return;
19726ba597c5SAnurag S. Maskey }
19736ba597c5SAnurag S. Maskey if (object->nwamd_object_state == NWAM_STATE_DISABLED) {
19746ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_action_event: "
19756ba597c5SAnurag S. Maskey "ncu %s already disabled, nothing to do",
19766ba597c5SAnurag S. Maskey event->event_object);
19776ba597c5SAnurag S. Maskey nwamd_object_release(object);
19786ba597c5SAnurag S. Maskey return;
19796ba597c5SAnurag S. Maskey }
19806ba597c5SAnurag S. Maskey nwamd_object_release(object);
19816ba597c5SAnurag S. Maskey
19826ba597c5SAnurag S. Maskey nwamd_object_set_state(NWAM_OBJECT_TYPE_NCU,
19836ba597c5SAnurag S. Maskey event->event_object, NWAM_STATE_ONLINE_TO_OFFLINE,
19846ba597c5SAnurag S. Maskey NWAM_AUX_STATE_MANUAL_DISABLE);
19856ba597c5SAnurag S. Maskey break;
19866ba597c5SAnurag S. Maskey case NWAM_ACTION_ADD:
19876ba597c5SAnurag S. Maskey case NWAM_ACTION_REFRESH:
19886ba597c5SAnurag S. Maskey nwamd_ncu_handle_init_event(event);
19896ba597c5SAnurag S. Maskey break;
19906ba597c5SAnurag S. Maskey case NWAM_ACTION_DESTROY:
19916ba597c5SAnurag S. Maskey nwamd_ncu_handle_fini_event(event);
19926ba597c5SAnurag S. Maskey break;
19936ba597c5SAnurag S. Maskey default:
19946ba597c5SAnurag S. Maskey nlog(LOG_INFO, "nwam_ncu_handle_action_event: "
19956ba597c5SAnurag S. Maskey "unexpected action");
19966ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
19976ba597c5SAnurag S. Maskey break;
19986ba597c5SAnurag S. Maskey }
19996ba597c5SAnurag S. Maskey }
20006ba597c5SAnurag S. Maskey
20016ba597c5SAnurag S. Maskey void
nwamd_ncu_handle_state_event(nwamd_event_t event)20026ba597c5SAnurag S. Maskey nwamd_ncu_handle_state_event(nwamd_event_t event)
20036ba597c5SAnurag S. Maskey {
20046ba597c5SAnurag S. Maskey nwamd_object_t object;
20056ba597c5SAnurag S. Maskey nwam_state_t old_state, new_state;
20066ba597c5SAnurag S. Maskey nwam_aux_state_t new_aux_state;
20076ba597c5SAnurag S. Maskey nwamd_ncu_t *ncu;
20086ba597c5SAnurag S. Maskey boolean_t is_link, enabled, prioritized = B_FALSE;
20096ba597c5SAnurag S. Maskey char linkname[NWAM_MAX_NAME_LEN];
20106ba597c5SAnurag S. Maskey nwam_event_t m = event->event_msg;
20116ba597c5SAnurag S. Maskey
20126ba597c5SAnurag S. Maskey if ((object = nwamd_object_find(NWAM_OBJECT_TYPE_NCU,
20136ba597c5SAnurag S. Maskey event->event_object)) == NULL) {
2014f6904bc3SRenee Danson Sommerfeld nlog(LOG_INFO, "nwamd_ncu_handle_state_event %lld: "
20156ba597c5SAnurag S. Maskey "state event for nonexistent NCU %s", event->event_id,
20166ba597c5SAnurag S. Maskey event->event_object);
20176ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
20186ba597c5SAnurag S. Maskey return;
20196ba597c5SAnurag S. Maskey }
20206ba597c5SAnurag S. Maskey ncu = object->nwamd_object_data;
20216ba597c5SAnurag S. Maskey old_state = object->nwamd_object_state;
20226ba597c5SAnurag S. Maskey new_state = event->event_msg->nwe_data.nwe_object_state.nwe_state;
20236ba597c5SAnurag S. Maskey new_aux_state =
20246ba597c5SAnurag S. Maskey event->event_msg->nwe_data.nwe_object_state.nwe_aux_state;
20256ba597c5SAnurag S. Maskey
20266ba597c5SAnurag S. Maskey /*
20276ba597c5SAnurag S. Maskey * For NCU state changes, we need to supply the parent NCP name also,
20286ba597c5SAnurag S. Maskey * regardless of whether the event is handled or not. It is best to
20296ba597c5SAnurag S. Maskey * fill this in here as we have the object lock - when we create
20306ba597c5SAnurag S. Maskey * object state events we sometimes do not have the object lock, but
20316ba597c5SAnurag S. Maskey * at this point in consuming the events (and prior to the associated
20326ba597c5SAnurag S. Maskey * event message being sent out) we do.
20336ba597c5SAnurag S. Maskey */
20346ba597c5SAnurag S. Maskey (void) strlcpy(m->nwe_data.nwe_object_state.nwe_parent, ncu->ncu_parent,
20356ba597c5SAnurag S. Maskey sizeof (m->nwe_data.nwe_object_state.nwe_parent));
20366ba597c5SAnurag S. Maskey
20376ba597c5SAnurag S. Maskey /*
20386ba597c5SAnurag S. Maskey * If we receive a state change event moving this NCU to
20396ba597c5SAnurag S. Maskey * DHCP_TIMED_OUT or UP state but this NCU is already ONLINE, then
20406ba597c5SAnurag S. Maskey * ignore this state change event.
20416ba597c5SAnurag S. Maskey */
20426ba597c5SAnurag S. Maskey if ((new_aux_state == NWAM_AUX_STATE_IF_DHCP_TIMED_OUT ||
20436ba597c5SAnurag S. Maskey new_aux_state == NWAM_AUX_STATE_UP) &&
20446ba597c5SAnurag S. Maskey object->nwamd_object_state == NWAM_STATE_ONLINE) {
20456ba597c5SAnurag S. Maskey nlog(LOG_INFO, "nwamd_ncu_handle_state_event: "
20466ba597c5SAnurag S. Maskey "NCU %s already online, not going to '%s' state",
20476ba597c5SAnurag S. Maskey object->nwamd_object_name,
20486ba597c5SAnurag S. Maskey nwam_aux_state_to_string(new_aux_state));
20496ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
20506ba597c5SAnurag S. Maskey nwamd_object_release(object);
20516ba597c5SAnurag S. Maskey return;
20526ba597c5SAnurag S. Maskey }
20536ba597c5SAnurag S. Maskey
20546ba597c5SAnurag S. Maskey if (new_state == object->nwamd_object_state &&
20556ba597c5SAnurag S. Maskey new_aux_state == object->nwamd_object_aux_state) {
20566ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: "
20576ba597c5SAnurag S. Maskey "NCU %s already in state (%s, %s)",
20586ba597c5SAnurag S. Maskey object->nwamd_object_name, nwam_state_to_string(new_state),
20596ba597c5SAnurag S. Maskey nwam_aux_state_to_string(new_aux_state));
20606ba597c5SAnurag S. Maskey nwamd_object_release(object);
20616ba597c5SAnurag S. Maskey return;
20626ba597c5SAnurag S. Maskey }
20636ba597c5SAnurag S. Maskey
20646ba597c5SAnurag S. Maskey if (old_state == NWAM_STATE_MAINTENANCE &&
20656ba597c5SAnurag S. Maskey (new_state == NWAM_STATE_ONLINE ||
20666ba597c5SAnurag S. Maskey (new_state == NWAM_STATE_OFFLINE_TO_ONLINE &&
20676ba597c5SAnurag S. Maskey new_aux_state != NWAM_AUX_STATE_INITIALIZED))) {
20686ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: "
20696ba597c5SAnurag S. Maskey "NCU %s cannot transition from state %s to state (%s, %s)",
20706ba597c5SAnurag S. Maskey object->nwamd_object_name, nwam_state_to_string(old_state),
20716ba597c5SAnurag S. Maskey nwam_state_to_string(new_state),
20726ba597c5SAnurag S. Maskey nwam_aux_state_to_string(new_aux_state));
20736ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
20746ba597c5SAnurag S. Maskey nwamd_object_release(object);
20756ba597c5SAnurag S. Maskey return;
20766ba597c5SAnurag S. Maskey }
20776ba597c5SAnurag S. Maskey
20786ba597c5SAnurag S. Maskey object->nwamd_object_state = new_state;
20796ba597c5SAnurag S. Maskey object->nwamd_object_aux_state = new_aux_state;
20806ba597c5SAnurag S. Maskey
20816ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: changing state for NCU "
20826ba597c5SAnurag S. Maskey "%s to (%s, %s)", object->nwamd_object_name,
20836ba597c5SAnurag S. Maskey nwam_state_to_string(object->nwamd_object_state),
20846ba597c5SAnurag S. Maskey nwam_aux_state_to_string(object->nwamd_object_aux_state));
20856ba597c5SAnurag S. Maskey
20866ba597c5SAnurag S. Maskey is_link = (ncu->ncu_type == NWAM_NCU_TYPE_LINK);
20876ba597c5SAnurag S. Maskey if (is_link)
20886ba597c5SAnurag S. Maskey (void) strlcpy(linkname, ncu->ncu_name, sizeof (linkname));
20896ba597c5SAnurag S. Maskey prioritized = (ncu->ncu_type == NWAM_NCU_TYPE_LINK &&
2090f6da83d4SAnurag S. Maskey ncu->ncu_link.nwamd_link_activation_mode ==
20916ba597c5SAnurag S. Maskey NWAM_ACTIVATION_MODE_PRIORITIZED);
20926ba597c5SAnurag S. Maskey enabled = ncu->ncu_enabled;
20936ba597c5SAnurag S. Maskey
20946ba597c5SAnurag S. Maskey nwamd_object_release(object);
20956ba597c5SAnurag S. Maskey
20966ba597c5SAnurag S. Maskey /*
20976ba597c5SAnurag S. Maskey * State machine for NCUs
20986ba597c5SAnurag S. Maskey */
20996ba597c5SAnurag S. Maskey switch (new_state) {
21006ba597c5SAnurag S. Maskey case NWAM_STATE_OFFLINE_TO_ONLINE:
21016ba597c5SAnurag S. Maskey if (enabled) {
21026ba597c5SAnurag S. Maskey nwamd_ncu_state_machine(event->event_object);
21036ba597c5SAnurag S. Maskey } else {
21046ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "nwamd_ncu_handle_state_event: "
21056ba597c5SAnurag S. Maskey "cannot move disabled NCU %s online",
21066ba597c5SAnurag S. Maskey event->event_object);
21076ba597c5SAnurag S. Maskey nwamd_event_do_not_send(event);
21086ba597c5SAnurag S. Maskey }
21096ba597c5SAnurag S. Maskey break;
21106ba597c5SAnurag S. Maskey
21116ba597c5SAnurag S. Maskey case NWAM_STATE_ONLINE_TO_OFFLINE:
21126ba597c5SAnurag S. Maskey nwamd_ncu_state_machine(event->event_object);
21136ba597c5SAnurag S. Maskey break;
21146ba597c5SAnurag S. Maskey
21156ba597c5SAnurag S. Maskey case NWAM_STATE_ONLINE:
21166ba597c5SAnurag S. Maskey /*
21176ba597c5SAnurag S. Maskey * We usually don't need to do anything when we're in the
21186ba597c5SAnurag S. Maskey * ONLINE state. However, for WiFi we can be in INIT or
21196ba597c5SAnurag S. Maskey * SCAN aux states while being ONLINE.
21206ba597c5SAnurag S. Maskey */
21216ba597c5SAnurag S. Maskey nwamd_ncu_state_machine(event->event_object);
21226ba597c5SAnurag S. Maskey break;
21236ba597c5SAnurag S. Maskey
21246ba597c5SAnurag S. Maskey case NWAM_STATE_OFFLINE:
21256ba597c5SAnurag S. Maskey /* Reassess priority group now member is offline */
21266ba597c5SAnurag S. Maskey if (prioritized) {
21276ba597c5SAnurag S. Maskey nwamd_create_ncu_check_event(0);
21286ba597c5SAnurag S. Maskey }
21296ba597c5SAnurag S. Maskey break;
21306ba597c5SAnurag S. Maskey
21316ba597c5SAnurag S. Maskey case NWAM_STATE_DISABLED:
21326ba597c5SAnurag S. Maskey case NWAM_STATE_UNINITIALIZED:
21336ba597c5SAnurag S. Maskey case NWAM_STATE_MAINTENANCE:
21346ba597c5SAnurag S. Maskey case NWAM_STATE_DEGRADED:
21356ba597c5SAnurag S. Maskey default:
21366ba597c5SAnurag S. Maskey /* do nothing */
21376ba597c5SAnurag S. Maskey break;
21386ba597c5SAnurag S. Maskey }
21396ba597c5SAnurag S. Maskey
21406ba597c5SAnurag S. Maskey if (is_link) {
21416ba597c5SAnurag S. Maskey if ((new_state == NWAM_STATE_ONLINE_TO_OFFLINE &&
21426ba597c5SAnurag S. Maskey new_aux_state != NWAM_AUX_STATE_UNINITIALIZED &&
21436ba597c5SAnurag S. Maskey new_aux_state != NWAM_AUX_STATE_NOT_FOUND) ||
21446ba597c5SAnurag S. Maskey new_state == NWAM_STATE_DISABLED) {
21456ba597c5SAnurag S. Maskey /*
21466ba597c5SAnurag S. Maskey * Going offline, propogate down event to IP NCU. Do
21476ba597c5SAnurag S. Maskey * not propogate event if new aux state is uninitialized
21486ba597c5SAnurag S. Maskey * or not found as these auxiliary states signify
21496ba597c5SAnurag S. Maskey * that an NCP switch/device removal is in progress.
21506ba597c5SAnurag S. Maskey */
21516ba597c5SAnurag S. Maskey nwamd_propogate_link_up_down_to_ip(linkname, B_FALSE);
21526ba597c5SAnurag S. Maskey }
21536ba597c5SAnurag S. Maskey if (new_state == NWAM_STATE_ONLINE) {
21546ba597c5SAnurag S. Maskey /* gone online, propogate up event to IP NCU */
21556ba597c5SAnurag S. Maskey nwamd_propogate_link_up_down_to_ip(linkname, B_TRUE);
21566ba597c5SAnurag S. Maskey }
21576ba597c5SAnurag S. Maskey } else {
21586ba597c5SAnurag S. Maskey /* If IP NCU is online, reasses priority group */
21596ba597c5SAnurag S. Maskey if (new_state == NWAM_STATE_ONLINE)
21606ba597c5SAnurag S. Maskey nwamd_create_ncu_check_event(0);
21616ba597c5SAnurag S. Maskey }
21626ba597c5SAnurag S. Maskey }
2163