1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
  25  */
  26 
  27 #ifndef _NCU_H
  28 #define _NCU_H
  29 
  30 #include <dhcpagent_ipc.h>
  31 #include <dhcpagent_util.h>
  32 #include <libdladm.h>
  33 #include <libdlpi.h>
  34 #include <libdlwlan.h>
  35 #include <libinetutil.h>
  36 #include <libipadm.h>
  37 #include <libnwam.h>
  38 #include <libnwam_priv.h>
  39 #include <libuutil.h>
  40 #include <pthread.h>
  41 #include <sys/mac.h>
  42 
  43 #include "events.h"
  44 
  45 extern pthread_mutex_t active_ncp_mutex;
  46 extern pthread_mutex_t active_loc_mutex;
  47 extern char active_loc[];
  48 extern uint64_t wireless_scan_interval;
  49 extern dladm_wlan_strength_t wireless_scan_level;
  50 extern boolean_t wireless_autoconf;
  51 extern boolean_t wireless_strict_bssid;
  52 
  53 /*
  54  * NCPs are collections of NCUs.  At the moment there is one NCP in the system
  55  * and its expected there will never be many.  There is a lock on the NCP which
  56  * must be obtained to add or remove anything from the NCP.
  57  *
  58  * NCUs are also kept in a uu list for easy walking.  Each NCU has a lock which
  59  * is used to protect manipulation of its contents.  One of its members is a
  60  * reference count which is initialized to 1 when its placed on the NCP.  As
  61  * references are passed around that should be manipulated as necessary
  62  * (helper functions YYY provided).  It is removed from the NCP by
  63  * ncu_destroy() but the memory containing it is not returned to the free pool
  64  * until the reference count falls to 0.
  65  *
  66  * As we add
  67  * more complex system objects their relationship becomes more complex.  That
  68  * is represented by the links within the NCUs.  Reference counts should be
  69  * used to maintain the consistency of these links.  Care should be used when
  70  * walking more complex structures that might contain cycles.
  71  */
  72 
  73 /* Stores details of last/current WiFi scans */
  74 typedef struct nwamd_wifi_scan {
  75         char nwamd_wifi_scan_link[NWAM_MAX_NAME_LEN];
  76         nwam_wlan_t nwamd_wifi_scan_last[NWAMD_MAX_NUM_WLANS];
  77         uint_t nwamd_wifi_scan_last_num;
  78         nwam_wlan_t nwamd_wifi_scan_curr[NWAMD_MAX_NUM_WLANS];
  79         uint_t nwamd_wifi_scan_curr_num;
  80         boolean_t nwamd_wifi_scan_changed;
  81         uint32_t nwamd_wifi_scan_last_time;
  82 } nwamd_wifi_scan_t;
  83 
  84 typedef struct nwamd_link {
  85         pthread_mutex_t nwamd_link_wifi_mutex;
  86         pthread_t nwamd_link_wifi_scan_thread;
  87         pthread_t nwamd_link_wifi_monitor_thread;
  88         char nwamd_link_wifi_essid[DLADM_STRSIZE];
  89         char nwamd_link_wifi_bssid[DLADM_STRSIZE];
  90         char nwamd_link_wifi_keyname[DLADM_STRSIZE];
  91         char nwamd_link_wifi_signal_strength[DLADM_STRSIZE];
  92         boolean_t nwamd_link_wifi_add_to_known_wlans;
  93         boolean_t nwamd_link_wifi_connected;
  94         uint32_t nwamd_link_wifi_security_mode;
  95         dladm_wlan_key_t *nwamd_link_wifi_key;
  96         nwamd_wifi_scan_t nwamd_link_wifi_scan;
  97         uint64_t nwamd_link_wifi_priority;
  98         boolean_t nwamd_link_wifi_autoconf;
  99         uint32_t nwamd_link_id;
 100         uint32_t nwamd_link_media;
 101         uint64_t nwamd_link_flags;
 102         dlpi_handle_t nwamd_link_dhp;
 103         pthread_t nwamd_link_dlpi_thread;
 104         uint64_t nwamd_link_activation_mode;
 105         uint64_t nwamd_link_priority_mode;
 106         uint64_t nwamd_link_priority_group;
 107         char *nwamd_link_mac_addr;
 108         size_t nwamd_link_mac_addr_len;
 109         uint64_t nwamd_link_mtu;
 110         char **nwamd_link_autopush;
 111         uint_t nwamd_link_num_autopush;
 112 } nwamd_link_t;
 113 
 114 struct nwamd_if_address {
 115         sa_family_t family;
 116         ipadm_addr_type_t ipaddr_atype;
 117         ipadm_addrobj_t ipaddr;
 118         boolean_t configured;
 119         struct sockaddr_storage conf_addr;      /* address configured for */
 120         struct sockaddr_storage conf_stateless_addr; /* this nwamd_if_address */
 121         struct nwamd_if_address *next;
 122 };
 123 
 124 typedef struct nwamd_if {
 125         boolean_t nwamd_if_dhcp_requested;
 126         boolean_t nwamd_if_dhcp_configured;
 127         boolean_t nwamd_if_stateful_requested;
 128         boolean_t nwamd_if_stateful_configured;
 129         boolean_t nwamd_if_stateless_requested;
 130         boolean_t nwamd_if_stateless_configured;
 131         struct nwamd_if_address *nwamd_if_list;
 132         struct sockaddr_in nwamd_if_ipv4_default_route;
 133         boolean_t nwamd_if_ipv4_default_route_set;
 134         struct sockaddr_in6 nwamd_if_ipv6_default_route;
 135         boolean_t nwamd_if_ipv6_default_route_set;
 136         boolean_t nwamd_if_ipv4;
 137         boolean_t nwamd_if_ipv6;
 138 } nwamd_if_t;
 139 
 140 typedef struct nwamd_ncu {
 141         nwam_ncu_type_t ncu_type;
 142         char *ncu_name;
 143         char ncu_parent[NWAM_MAX_NAME_LEN];
 144         boolean_t ncu_enabled; /* whether NCU has been enabled or not */
 145         union {
 146                 nwamd_link_t u_link;
 147                 nwamd_if_t u_if;
 148         } ncu_node;
 149 } nwamd_ncu_t;
 150 
 151 #define ncu_link        ncu_node.u_link
 152 #define ncu_if          ncu_node.u_if
 153 
 154 #define LOOPBACK_IF                             "lo0"
 155 
 156 struct nwamd_dhcp_thread_arg {
 157         char *name;
 158         dhcp_ipc_type_t type;
 159         ipadm_addrobj_t ipaddr;
 160         volatile uint32_t *guard;
 161 };
 162 
 163 #define WIRELESS_SCAN_INTERVAL_DEFAULT          120
 164 #define WIRELESS_SCAN_INTERVAL_MIN              30
 165 #define WIRELESS_SCAN_REQUESTED_INTERVAL_MIN    10
 166 #define WIRELESS_MONITOR_SIGNAL_INTERVAL        10
 167 #define WIRELESS_RETRY_INTERVAL                 30
 168 #define WIRELESS_SCAN_LEVEL_DEFAULT             DLADM_WLAN_STRENGTH_WEAK
 169 #define NWAMD_DHCP_RETRIES                      5
 170 #define NWAMD_DHCP_RETRY_WAIT_TIME              10
 171 #define NWAMD_READONLY_RETRY_INTERVAL           5
 172 
 173 /*
 174  * This dladm and ipadm handles are opened before interfaces are initialized
 175  * and closed only when nwamd shuts down.
 176  */
 177 extern dladm_handle_t dld_handle;
 178 extern ipadm_handle_t ipadm_handle;
 179 
 180 extern nwamd_object_t nwamd_ncu_object_find(nwam_ncu_type_t, const char *);
 181 extern void nwamd_log_ncus(void);
 182 extern void nwamd_ncu_free(nwamd_ncu_t *);
 183 
 184 /* WLAN functions */
 185 extern void nwamd_set_selected_connected(nwamd_ncu_t *, boolean_t, boolean_t);
 186 extern nwam_error_t nwamd_wlan_select(const char *, const char *, const char *,
 187     uint32_t, boolean_t);
 188 extern nwam_error_t nwamd_wlan_set_key(const char *, const char *, const char *,
 189     uint32_t, uint_t, char *);
 190 extern nwam_error_t nwamd_wlan_scan(const char *);
 191 extern void nwamd_wlan_connect(const char *);
 192 extern boolean_t nwamd_wlan_connected(nwamd_object_t);
 193 extern void nwamd_wlan_monitor_signal(const char *);
 194 extern void nwamd_ncu_create_periodic_scan_event(nwamd_object_t);
 195 extern dladm_wlan_key_t *nwamd_wlan_get_key_named(const char *, uint32_t);
 196 extern void nwamd_set_key_name(const char *, const char *, char *, size_t);
 197 
 198 /* Link functions */
 199 extern link_state_t nwamd_get_link_state(const char *);
 200 extern const char *nwamd_sockaddr_to_str(const struct sockaddr *, char *,
 201     size_t);
 202 extern void nwamd_propogate_link_up_down_to_ip(const char *, boolean_t);
 203 extern void nwamd_set_unset_link_properties(nwamd_ncu_t *, boolean_t);
 204 /* DLPI event hooking */
 205 extern void nwamd_dlpi_add_link(nwamd_object_t);
 206 extern void nwamd_dlpi_delete_link(nwamd_object_t);
 207 
 208 /* IP functions */
 209 extern boolean_t nwamd_static_addresses_configured(nwamd_ncu_t *, sa_family_t);
 210 extern void nwamd_plumb_interface(nwamd_ncu_t *, sa_family_t);
 211 extern void nwamd_unplumb_interface(nwamd_ncu_t *, sa_family_t);
 212 extern boolean_t nwamd_dhcp_managing(int, nwamd_ncu_t *);
 213 extern void nwamd_configure_interface_addresses(nwamd_ncu_t *);
 214 extern char *nwamd_get_dhcpinfo_data(const char *, char *);
 215 extern void nwamd_dhcp_release(const char *);
 216 extern void nwamd_add_default_routes(nwamd_ncu_t *);
 217 extern void nwamd_add_route(struct sockaddr *, struct sockaddr *,
 218     struct sockaddr *, const char *);
 219 
 220 /* NCU value set/get functions */
 221 extern nwam_error_t nwamd_set_ncu_uint(nwam_ncu_handle_t, uint64_t *, uint_t,
 222     const char *);
 223 extern nwam_error_t nwamd_set_ncu_string(nwam_ncu_handle_t, char **, uint_t,
 224     const char *);
 225 extern nwam_error_t nwamd_get_ncu_uint(nwam_ncu_handle_t, nwam_value_t *,
 226     uint64_t **, uint_t *, const char *);
 227 extern nwam_error_t nwamd_get_ncu_string(nwam_ncu_handle_t, nwam_value_t *,
 228     char ***, uint_t *, const char *);
 229 extern nwam_error_t nwamd_get_ncu_boolean(nwam_ncu_handle_t, nwam_value_t *,
 230     boolean_t **, uint_t *, const char *);
 231 
 232 extern void nwamd_walk_physical_configuration(void);
 233 
 234 #endif /* _NCU_H */