LCOV - code coverage report
Current view: top level - src/drivers - driver_nl80211.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 3391 4479 75.7 %
Date: 2015-09-27 Functions: 237 249 95.2 %

          Line data    Source code
       1             : /*
       2             :  * Driver interaction with Linux nl80211/cfg80211
       3             :  * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
       4             :  * Copyright (c) 2003-2004, Instant802 Networks, Inc.
       5             :  * Copyright (c) 2005-2006, Devicescape Software, Inc.
       6             :  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
       7             :  * Copyright (c) 2009-2010, Atheros Communications
       8             :  *
       9             :  * This software may be distributed under the terms of the BSD license.
      10             :  * See README for more details.
      11             :  */
      12             : 
      13             : #include "includes.h"
      14             : #include <sys/types.h>
      15             : #include <fcntl.h>
      16             : #include <net/if.h>
      17             : #include <netlink/genl/genl.h>
      18             : #include <netlink/genl/ctrl.h>
      19             : #ifdef CONFIG_LIBNL3_ROUTE
      20             : #include <netlink/route/neighbour.h>
      21             : #endif /* CONFIG_LIBNL3_ROUTE */
      22             : #include <linux/rtnetlink.h>
      23             : #include <netpacket/packet.h>
      24             : #include <linux/errqueue.h>
      25             : 
      26             : #include "common.h"
      27             : #include "eloop.h"
      28             : #include "common/qca-vendor.h"
      29             : #include "common/qca-vendor-attr.h"
      30             : #include "common/ieee802_11_defs.h"
      31             : #include "common/ieee802_11_common.h"
      32             : #include "l2_packet/l2_packet.h"
      33             : #include "netlink.h"
      34             : #include "linux_defines.h"
      35             : #include "linux_ioctl.h"
      36             : #include "radiotap.h"
      37             : #include "radiotap_iter.h"
      38             : #include "rfkill.h"
      39             : #include "driver_nl80211.h"
      40             : 
      41             : 
      42             : #ifndef CONFIG_LIBNL20
      43             : /*
      44             :  * libnl 1.1 has a bug, it tries to allocate socket numbers densely
      45             :  * but when you free a socket again it will mess up its bitmap and
      46             :  * and use the wrong number the next time it needs a socket ID.
      47             :  * Therefore, we wrap the handle alloc/destroy and add our own pid
      48             :  * accounting.
      49             :  */
      50             : static uint32_t port_bitmap[32] = { 0 };
      51             : 
      52             : static struct nl_handle *nl80211_handle_alloc(void *cb)
      53             : {
      54             :         struct nl_handle *handle;
      55             :         uint32_t pid = getpid() & 0x3FFFFF;
      56             :         int i;
      57             : 
      58             :         handle = nl_handle_alloc_cb(cb);
      59             : 
      60             :         for (i = 0; i < 1024; i++) {
      61             :                 if (port_bitmap[i / 32] & (1 << (i % 32)))
      62             :                         continue;
      63             :                 port_bitmap[i / 32] |= 1 << (i % 32);
      64             :                 pid += i << 22;
      65             :                 break;
      66             :         }
      67             : 
      68             :         nl_socket_set_local_port(handle, pid);
      69             : 
      70             :         return handle;
      71             : }
      72             : 
      73             : static void nl80211_handle_destroy(struct nl_handle *handle)
      74             : {
      75             :         uint32_t port = nl_socket_get_local_port(handle);
      76             : 
      77             :         port >>= 22;
      78             :         port_bitmap[port / 32] &= ~(1 << (port % 32));
      79             : 
      80             :         nl_handle_destroy(handle);
      81             : }
      82             : #endif /* CONFIG_LIBNL20 */
      83             : 
      84             : 
      85             : #ifdef ANDROID
      86             : /* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
      87             : #undef nl_socket_set_nonblocking
      88             : #define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
      89             : 
      90             : #endif /* ANDROID */
      91             : 
      92             : 
      93        6963 : static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
      94             : {
      95             :         struct nl_handle *handle;
      96             : 
      97        6963 :         handle = nl80211_handle_alloc(cb);
      98        6963 :         if (handle == NULL) {
      99           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
     100             :                            "callbacks (%s)", dbg);
     101           0 :                 return NULL;
     102             :         }
     103             : 
     104        6963 :         if (genl_connect(handle)) {
     105           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
     106             :                            "netlink (%s)", dbg);
     107           0 :                 nl80211_handle_destroy(handle);
     108           0 :                 return NULL;
     109             :         }
     110             : 
     111        6963 :         return handle;
     112             : }
     113             : 
     114             : 
     115        6963 : static void nl_destroy_handles(struct nl_handle **handle)
     116             : {
     117        6963 :         if (*handle == NULL)
     118        6963 :                 return;
     119        6963 :         nl80211_handle_destroy(*handle);
     120        6963 :         *handle = NULL;
     121             : }
     122             : 
     123             : 
     124             : #if __WORDSIZE == 64
     125             : #define ELOOP_SOCKET_INVALID    (intptr_t) 0x8888888888888889ULL
     126             : #else
     127             : #define ELOOP_SOCKET_INVALID    (intptr_t) 0x88888889ULL
     128             : #endif
     129             : 
     130        6912 : static void nl80211_register_eloop_read(struct nl_handle **handle,
     131             :                                         eloop_sock_handler handler,
     132             :                                         void *eloop_data)
     133             : {
     134             : #ifdef CONFIG_LIBNL20
     135             :         /*
     136             :          * libnl uses a pretty small buffer (32 kB that gets converted to 64 kB)
     137             :          * by default. It is possible to hit that limit in some cases where
     138             :          * operations are blocked, e.g., with a burst of Deauthentication frames
     139             :          * to hostapd and STA entry deletion. Try to increase the buffer to make
     140             :          * this less likely to occur.
     141             :          */
     142        6912 :         if (nl_socket_set_buffer_size(*handle, 262144, 0) < 0) {
     143           0 :                 wpa_printf(MSG_DEBUG,
     144             :                            "nl80211: Could not set nl_socket RX buffer size: %s",
     145           0 :                            strerror(errno));
     146             :                 /* continue anyway with the default (smaller) buffer */
     147             :         }
     148             : #endif /* CONFIG_LIBNL20 */
     149             : 
     150        6912 :         nl_socket_set_nonblocking(*handle);
     151        6912 :         eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
     152             :                                  eloop_data, *handle);
     153        6912 :         *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
     154        6912 : }
     155             : 
     156             : 
     157        6912 : static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
     158             : {
     159        6912 :         *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
     160        6912 :         eloop_unregister_read_sock(nl_socket_get_fd(*handle));
     161        6912 :         nl_destroy_handles(handle);
     162        6912 : }
     163             : 
     164             : 
     165             : static void nl80211_global_deinit(void *priv);
     166             : static void nl80211_check_global(struct nl80211_global *global);
     167             : 
     168             : static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
     169             : static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
     170             :                                             struct hostapd_freq_params *freq);
     171             : 
     172             : static int
     173             : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
     174             :                                    const u8 *set_addr, int first,
     175             :                                    const char *driver_params);
     176             : static int nl80211_send_frame_cmd(struct i802_bss *bss,
     177             :                                   unsigned int freq, unsigned int wait,
     178             :                                   const u8 *buf, size_t buf_len, u64 *cookie,
     179             :                                   int no_cck, int no_ack, int offchanok);
     180             : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
     181             :                                                int report);
     182             : 
     183             : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
     184             : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
     185             : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
     186             : 
     187             : static int nl80211_set_channel(struct i802_bss *bss,
     188             :                                struct hostapd_freq_params *freq, int set_chan);
     189             : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
     190             :                                      int ifindex, int disabled);
     191             : 
     192             : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
     193             :                               int reset_mode);
     194             : 
     195             : static int i802_set_iface_flags(struct i802_bss *bss, int up);
     196             : static int nl80211_set_param(void *priv, const char *param);
     197             : 
     198             : 
     199             : /* Converts nl80211_chan_width to a common format */
     200         121 : enum chan_width convert2width(int width)
     201             : {
     202         121 :         switch (width) {
     203             :         case NL80211_CHAN_WIDTH_20_NOHT:
     204          17 :                 return CHAN_WIDTH_20_NOHT;
     205             :         case NL80211_CHAN_WIDTH_20:
     206          68 :                 return CHAN_WIDTH_20;
     207             :         case NL80211_CHAN_WIDTH_40:
     208          24 :                 return CHAN_WIDTH_40;
     209             :         case NL80211_CHAN_WIDTH_80:
     210           7 :                 return CHAN_WIDTH_80;
     211             :         case NL80211_CHAN_WIDTH_80P80:
     212           1 :                 return CHAN_WIDTH_80P80;
     213             :         case NL80211_CHAN_WIDTH_160:
     214           4 :                 return CHAN_WIDTH_160;
     215             :         }
     216           0 :         return CHAN_WIDTH_UNKNOWN;
     217             : }
     218             : 
     219             : 
     220       52747 : int is_ap_interface(enum nl80211_iftype nlmode)
     221             : {
     222       52747 :         return nlmode == NL80211_IFTYPE_AP ||
     223             :                 nlmode == NL80211_IFTYPE_P2P_GO;
     224             : }
     225             : 
     226             : 
     227       17624 : int is_sta_interface(enum nl80211_iftype nlmode)
     228             : {
     229       17624 :         return nlmode == NL80211_IFTYPE_STATION ||
     230             :                 nlmode == NL80211_IFTYPE_P2P_CLIENT;
     231             : }
     232             : 
     233             : 
     234       12893 : static int is_p2p_net_interface(enum nl80211_iftype nlmode)
     235             : {
     236       12893 :         return nlmode == NL80211_IFTYPE_P2P_CLIENT ||
     237             :                 nlmode == NL80211_IFTYPE_P2P_GO;
     238             : }
     239             : 
     240             : 
     241          46 : struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
     242             :                                   int ifindex)
     243             : {
     244             :         struct i802_bss *bss;
     245             : 
     246          46 :         for (bss = drv->first_bss; bss; bss = bss->next) {
     247          46 :                 if (bss->ifindex == ifindex)
     248          46 :                         return bss;
     249             :         }
     250             : 
     251           0 :         return NULL;
     252             : }
     253             : 
     254             : 
     255       11456 : static int is_mesh_interface(enum nl80211_iftype nlmode)
     256             : {
     257       11456 :         return nlmode == NL80211_IFTYPE_MESH_POINT;
     258             : }
     259             : 
     260             : 
     261       12323 : void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
     262             : {
     263       12323 :         if (drv->associated)
     264        3313 :                 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
     265       12323 :         drv->associated = 0;
     266       12323 :         os_memset(drv->bssid, 0, ETH_ALEN);
     267       12323 : }
     268             : 
     269             : 
     270             : /* nl80211 code */
     271      205998 : static int ack_handler(struct nl_msg *msg, void *arg)
     272             : {
     273      205998 :         int *err = arg;
     274      205998 :         *err = 0;
     275      205998 :         return NL_STOP;
     276             : }
     277             : 
     278       25397 : static int finish_handler(struct nl_msg *msg, void *arg)
     279             : {
     280       25397 :         int *ret = arg;
     281       25397 :         *ret = 0;
     282       25397 :         return NL_SKIP;
     283             : }
     284             : 
     285       35736 : static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
     286             :                          void *arg)
     287             : {
     288       35736 :         int *ret = arg;
     289       35736 :         *ret = err->error;
     290       35736 :         return NL_SKIP;
     291             : }
     292             : 
     293             : 
     294     1529923 : static int no_seq_check(struct nl_msg *msg, void *arg)
     295             : {
     296     1529923 :         return NL_OK;
     297             : }
     298             : 
     299             : 
     300        8583 : static void nl80211_nlmsg_clear(struct nl_msg *msg)
     301             : {
     302             :         /*
     303             :          * Clear nlmsg data, e.g., to make sure key material is not left in
     304             :          * heap memory for unnecessarily long time.
     305             :          */
     306        8583 :         if (msg) {
     307        8581 :                 struct nlmsghdr *hdr = nlmsg_hdr(msg);
     308        8581 :                 void *data = nlmsg_data(hdr);
     309             :                 /*
     310             :                  * This would use nlmsg_datalen() or the older nlmsg_len() if
     311             :                  * only libnl were to maintain a stable API.. Neither will work
     312             :                  * with all released versions, so just calculate the length
     313             :                  * here.
     314             :                  */
     315        8581 :                 int len = hdr->nlmsg_len - NLMSG_HDRLEN;
     316             : 
     317        8581 :                 os_memset(data, 0, len);
     318             :         }
     319        8583 : }
     320             : 
     321             : 
     322      267131 : static int send_and_recv(struct nl80211_global *global,
     323             :                          struct nl_handle *nl_handle, struct nl_msg *msg,
     324             :                          int (*valid_handler)(struct nl_msg *, void *),
     325             :                          void *valid_data)
     326             : {
     327             :         struct nl_cb *cb;
     328      267131 :         int err = -ENOMEM;
     329             : 
     330      267131 :         if (!msg)
     331           0 :                 return -ENOMEM;
     332             : 
     333      267131 :         cb = nl_cb_clone(global->nl_cb);
     334      267131 :         if (!cb)
     335           0 :                 goto out;
     336             : 
     337      267131 :         err = nl_send_auto_complete(nl_handle, msg);
     338      267131 :         if (err < 0)
     339           0 :                 goto out;
     340             : 
     341      267131 :         err = 1;
     342             : 
     343      267131 :         nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
     344      267131 :         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
     345      267131 :         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
     346             : 
     347      267131 :         if (valid_handler)
     348      102732 :                 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
     349             :                           valid_handler, valid_data);
     350             : 
     351      872817 :         while (err > 0) {
     352      338555 :                 int res = nl_recvmsgs(nl_handle, cb);
     353      338555 :                 if (res < 0) {
     354           0 :                         wpa_printf(MSG_INFO,
     355             :                                    "nl80211: %s->nl_recvmsgs failed: %d",
     356             :                                    __func__, res);
     357             :                 }
     358             :         }
     359             :  out:
     360      267131 :         nl_cb_put(cb);
     361      267131 :         if (!valid_handler && valid_data == (void *) -1)
     362        8581 :                 nl80211_nlmsg_clear(msg);
     363      267131 :         nlmsg_free(msg);
     364      267131 :         return err;
     365             : }
     366             : 
     367             : 
     368      208823 : int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
     369             :                        struct nl_msg *msg,
     370             :                        int (*valid_handler)(struct nl_msg *, void *),
     371             :                        void *valid_data)
     372             : {
     373      208823 :         return send_and_recv(drv->global, drv->global->nl, msg,
     374             :                              valid_handler, valid_data);
     375             : }
     376             : 
     377             : 
     378             : struct family_data {
     379             :         const char *group;
     380             :         int id;
     381             : };
     382             : 
     383             : 
     384        8868 : static int family_handler(struct nl_msg *msg, void *arg)
     385             : {
     386        8868 :         struct family_data *res = arg;
     387             :         struct nlattr *tb[CTRL_ATTR_MAX + 1];
     388        8868 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
     389             :         struct nlattr *mcgrp;
     390             :         int i;
     391             : 
     392        8868 :         nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
     393             :                   genlmsg_attrlen(gnlh, 0), NULL);
     394        8868 :         if (!tb[CTRL_ATTR_MCAST_GROUPS])
     395           0 :                 return NL_SKIP;
     396             : 
     397       62076 :         nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
     398             :                 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
     399       31038 :                 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
     400             :                           nla_len(mcgrp), NULL);
     401       62076 :                 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
     402       62076 :                     !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
     403       31038 :                     os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
     404             :                                res->group,
     405             :                                nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
     406       22170 :                         continue;
     407        8868 :                 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
     408        8868 :                 break;
     409             :         };
     410             : 
     411        8868 :         return NL_SKIP;
     412             : }
     413             : 
     414             : 
     415        8868 : static int nl_get_multicast_id(struct nl80211_global *global,
     416             :                                const char *family, const char *group)
     417             : {
     418             :         struct nl_msg *msg;
     419             :         int ret;
     420        8868 :         struct family_data res = { group, -ENOENT };
     421             : 
     422        8868 :         msg = nlmsg_alloc();
     423        8868 :         if (!msg)
     424           0 :                 return -ENOMEM;
     425        8868 :         if (!genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
     426        8868 :                          0, 0, CTRL_CMD_GETFAMILY, 0) ||
     427        8868 :             nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
     428           0 :                 nlmsg_free(msg);
     429           0 :                 return -1;
     430             :         }
     431             : 
     432        8868 :         ret = send_and_recv(global, global->nl, msg, family_handler, &res);
     433        8868 :         if (ret == 0)
     434        8868 :                 ret = res.id;
     435        8868 :         return ret;
     436             : }
     437             : 
     438             : 
     439      258264 : void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
     440             :                    struct nl_msg *msg, int flags, uint8_t cmd)
     441             : {
     442      258264 :         return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
     443             :                            0, flags, cmd, 0);
     444             : }
     445             : 
     446             : 
     447      113266 : static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
     448             : {
     449      113266 :         if (bss->wdev_id_set)
     450         350 :                 return nla_put_u64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
     451      112916 :         return nla_put_u32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
     452             : }
     453             : 
     454             : 
     455      113266 : struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd)
     456             : {
     457             :         struct nl_msg *msg;
     458             : 
     459      113266 :         msg = nlmsg_alloc();
     460      113266 :         if (!msg)
     461           0 :                 return NULL;
     462             : 
     463      226532 :         if (!nl80211_cmd(bss->drv, msg, flags, cmd) ||
     464      113266 :             nl80211_set_iface_id(msg, bss) < 0) {
     465           0 :                 nlmsg_free(msg);
     466           0 :                 return NULL;
     467             :         }
     468             : 
     469      113266 :         return msg;
     470             : }
     471             : 
     472             : 
     473             : static struct nl_msg *
     474      113711 : nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
     475             :                     int flags, uint8_t cmd)
     476             : {
     477             :         struct nl_msg *msg;
     478             : 
     479      113711 :         msg = nlmsg_alloc();
     480      113711 :         if (!msg)
     481           0 :                 return NULL;
     482             : 
     483      227422 :         if (!nl80211_cmd(drv, msg, flags, cmd) ||
     484      113711 :             nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex)) {
     485           0 :                 nlmsg_free(msg);
     486           0 :                 return NULL;
     487             :         }
     488             : 
     489      113711 :         return msg;
     490             : }
     491             : 
     492             : 
     493       21884 : struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
     494             :                                 uint8_t cmd)
     495             : {
     496       21884 :         return nl80211_ifindex_msg(drv, drv->ifindex, flags, cmd);
     497             : }
     498             : 
     499             : 
     500       47118 : struct nl_msg * nl80211_bss_msg(struct i802_bss *bss, int flags, uint8_t cmd)
     501             : {
     502       47118 :         return nl80211_ifindex_msg(bss->drv, bss->ifindex, flags, cmd);
     503             : }
     504             : 
     505             : 
     506             : struct wiphy_idx_data {
     507             :         int wiphy_idx;
     508             :         enum nl80211_iftype nlmode;
     509             :         u8 *macaddr;
     510             : };
     511             : 
     512             : 
     513       13078 : static int netdev_info_handler(struct nl_msg *msg, void *arg)
     514             : {
     515             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
     516       13078 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
     517       13078 :         struct wiphy_idx_data *info = arg;
     518             : 
     519       13078 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
     520             :                   genlmsg_attrlen(gnlh, 0), NULL);
     521             : 
     522       13078 :         if (tb[NL80211_ATTR_WIPHY])
     523       13078 :                 info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
     524             : 
     525       13078 :         if (tb[NL80211_ATTR_IFTYPE])
     526       13078 :                 info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
     527             : 
     528       13078 :         if (tb[NL80211_ATTR_MAC] && info->macaddr)
     529           8 :                 os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
     530             :                           ETH_ALEN);
     531             : 
     532       13078 :         return NL_SKIP;
     533             : }
     534             : 
     535             : 
     536        4246 : int nl80211_get_wiphy_index(struct i802_bss *bss)
     537             : {
     538             :         struct nl_msg *msg;
     539        4246 :         struct wiphy_idx_data data = {
     540             :                 .wiphy_idx = -1,
     541             :                 .macaddr = NULL,
     542             :         };
     543             : 
     544        4246 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
     545           0 :                 return -1;
     546             : 
     547        4246 :         if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
     548        4246 :                 return data.wiphy_idx;
     549           0 :         return -1;
     550             : }
     551             : 
     552             : 
     553        8887 : static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
     554             : {
     555             :         struct nl_msg *msg;
     556        8887 :         struct wiphy_idx_data data = {
     557             :                 .nlmode = NL80211_IFTYPE_UNSPECIFIED,
     558             :                 .macaddr = NULL,
     559             :         };
     560             : 
     561        8887 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
     562           0 :                 return NL80211_IFTYPE_UNSPECIFIED;
     563             : 
     564        8887 :         if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
     565        8824 :                 return data.nlmode;
     566          63 :         return NL80211_IFTYPE_UNSPECIFIED;
     567             : }
     568             : 
     569             : 
     570           8 : static int nl80211_get_macaddr(struct i802_bss *bss)
     571             : {
     572             :         struct nl_msg *msg;
     573          16 :         struct wiphy_idx_data data = {
     574           8 :                 .macaddr = bss->addr,
     575             :         };
     576             : 
     577           8 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
     578           0 :                 return -1;
     579             : 
     580           8 :         return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
     581             : }
     582             : 
     583             : 
     584        1947 : static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
     585             :                                     struct nl80211_wiphy_data *w)
     586             : {
     587             :         struct nl_msg *msg;
     588             :         int ret;
     589             : 
     590        1947 :         msg = nlmsg_alloc();
     591        1947 :         if (!msg)
     592           0 :                 return -1;
     593             : 
     594        3894 :         if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS) ||
     595        1947 :             nla_put_u32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx)) {
     596           0 :                 nlmsg_free(msg);
     597           0 :                 return -1;
     598             :         }
     599             : 
     600        1947 :         ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
     601        1947 :         if (ret) {
     602           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
     603             :                            "failed: ret=%d (%s)",
     604             :                            ret, strerror(-ret));
     605             :         }
     606        1947 :         return ret;
     607             : }
     608             : 
     609             : 
     610        8630 : static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
     611             : {
     612        8630 :         struct nl80211_wiphy_data *w = eloop_ctx;
     613             :         int res;
     614             : 
     615        8630 :         wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
     616             : 
     617        8630 :         res = nl_recvmsgs(handle, w->nl_cb);
     618        8630 :         if (res < 0) {
     619           0 :                 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
     620             :                            __func__, res);
     621             :         }
     622        8630 : }
     623             : 
     624             : 
     625        8630 : static int process_beacon_event(struct nl_msg *msg, void *arg)
     626             : {
     627        8630 :         struct nl80211_wiphy_data *w = arg;
     628             :         struct wpa_driver_nl80211_data *drv;
     629        8630 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
     630             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
     631             :         union wpa_event_data event;
     632             : 
     633        8630 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
     634             :                   genlmsg_attrlen(gnlh, 0), NULL);
     635             : 
     636        8630 :         if (gnlh->cmd != NL80211_CMD_FRAME) {
     637           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
     638           0 :                            gnlh->cmd);
     639           0 :                 return NL_SKIP;
     640             :         }
     641             : 
     642        8630 :         if (!tb[NL80211_ATTR_FRAME])
     643           0 :                 return NL_SKIP;
     644             : 
     645       17260 :         dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
     646             :                          wiphy_list) {
     647        8630 :                 os_memset(&event, 0, sizeof(event));
     648        8630 :                 event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
     649        8630 :                 event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
     650        8630 :                 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
     651             :         }
     652             : 
     653        8630 :         return NL_SKIP;
     654             : }
     655             : 
     656             : 
     657             : static struct nl80211_wiphy_data *
     658        2113 : nl80211_get_wiphy_data_ap(struct i802_bss *bss)
     659             : {
     660             :         static DEFINE_DL_LIST(nl80211_wiphys);
     661             :         struct nl80211_wiphy_data *w;
     662        2113 :         int wiphy_idx, found = 0;
     663             :         struct i802_bss *tmp_bss;
     664             : 
     665        2113 :         if (bss->wiphy_data != NULL)
     666           0 :                 return bss->wiphy_data;
     667             : 
     668        2113 :         wiphy_idx = nl80211_get_wiphy_index(bss);
     669             : 
     670        2477 :         dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
     671         530 :                 if (w->wiphy_idx == wiphy_idx)
     672         166 :                         goto add;
     673             :         }
     674             : 
     675             :         /* alloc new one */
     676        1947 :         w = os_zalloc(sizeof(*w));
     677        1947 :         if (w == NULL)
     678           0 :                 return NULL;
     679        1947 :         w->wiphy_idx = wiphy_idx;
     680        1947 :         dl_list_init(&w->bsss);
     681        1947 :         dl_list_init(&w->drvs);
     682             : 
     683        1947 :         w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
     684        1947 :         if (!w->nl_cb) {
     685           0 :                 os_free(w);
     686           0 :                 return NULL;
     687             :         }
     688        1947 :         nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
     689        1947 :         nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
     690             :                   w);
     691             : 
     692        1947 :         w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
     693             :                                          "wiphy beacons");
     694        1947 :         if (w->nl_beacons == NULL) {
     695           0 :                 os_free(w);
     696           0 :                 return NULL;
     697             :         }
     698             : 
     699        1947 :         if (nl80211_register_beacons(bss->drv, w)) {
     700           0 :                 nl_destroy_handles(&w->nl_beacons);
     701           0 :                 os_free(w);
     702           0 :                 return NULL;
     703             :         }
     704             : 
     705        1947 :         nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
     706             : 
     707        1947 :         dl_list_add(&nl80211_wiphys, &w->list);
     708             : 
     709             : add:
     710             :         /* drv entry for this bss already there? */
     711        6019 :         dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
     712        3948 :                 if (tmp_bss->drv == bss->drv) {
     713          42 :                         found = 1;
     714          42 :                         break;
     715             :                 }
     716             :         }
     717             :         /* if not add it */
     718        2113 :         if (!found)
     719        2071 :                 dl_list_add(&w->drvs, &bss->drv->wiphy_list);
     720             : 
     721        2113 :         dl_list_add(&w->bsss, &bss->wiphy_list);
     722        2113 :         bss->wiphy_data = w;
     723        2113 :         return w;
     724             : }
     725             : 
     726             : 
     727        3534 : static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
     728             : {
     729        3534 :         struct nl80211_wiphy_data *w = bss->wiphy_data;
     730             :         struct i802_bss *tmp_bss;
     731        3534 :         int found = 0;
     732             : 
     733        3534 :         if (w == NULL)
     734        1421 :                 return;
     735        2113 :         bss->wiphy_data = NULL;
     736        2113 :         dl_list_del(&bss->wiphy_list);
     737             : 
     738             :         /* still any for this drv present? */
     739        6019 :         dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
     740        3948 :                 if (tmp_bss->drv == bss->drv) {
     741          42 :                         found = 1;
     742          42 :                         break;
     743             :                 }
     744             :         }
     745             :         /* if not remove it */
     746        2113 :         if (!found)
     747        2071 :                 dl_list_del(&bss->drv->wiphy_list);
     748             : 
     749        2113 :         if (!dl_list_empty(&w->bsss))
     750         166 :                 return;
     751             : 
     752        1947 :         nl80211_destroy_eloop_handle(&w->nl_beacons);
     753             : 
     754        1947 :         nl_cb_put(w->nl_cb);
     755        1947 :         dl_list_del(&w->list);
     756        1947 :         os_free(w);
     757             : }
     758             : 
     759             : 
     760       18471 : static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
     761             : {
     762       18471 :         struct i802_bss *bss = priv;
     763       18471 :         struct wpa_driver_nl80211_data *drv = bss->drv;
     764       18471 :         if (!drv->associated)
     765        3516 :                 return -1;
     766       14955 :         os_memcpy(bssid, drv->bssid, ETH_ALEN);
     767       14955 :         return 0;
     768             : }
     769             : 
     770             : 
     771        4734 : static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
     772             : {
     773        4734 :         struct i802_bss *bss = priv;
     774        4734 :         struct wpa_driver_nl80211_data *drv = bss->drv;
     775        4734 :         if (!drv->associated)
     776           1 :                 return -1;
     777        4733 :         os_memcpy(ssid, drv->ssid, drv->ssid_len);
     778        4733 :         return drv->ssid_len;
     779             : }
     780             : 
     781             : 
     782       28881 : static void wpa_driver_nl80211_event_newlink(
     783             :         struct wpa_driver_nl80211_data *drv, const char *ifname)
     784             : {
     785             :         union wpa_event_data event;
     786             : 
     787       28881 :         if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
     788       28457 :                 if (if_nametoindex(drv->first_bss->ifname) == 0) {
     789          20 :                         wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
     790          20 :                                    drv->first_bss->ifname);
     791          20 :                         return;
     792             :                 }
     793       28437 :                 if (!drv->if_removed)
     794       28437 :                         return;
     795           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
     796           0 :                            drv->first_bss->ifname);
     797           0 :                 drv->if_removed = 0;
     798             :         }
     799             : 
     800         424 :         os_memset(&event, 0, sizeof(event));
     801         424 :         os_strlcpy(event.interface_status.ifname, ifname,
     802             :                    sizeof(event.interface_status.ifname));
     803         424 :         event.interface_status.ievent = EVENT_INTERFACE_ADDED;
     804         424 :         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
     805             : }
     806             : 
     807             : 
     808          30 : static void wpa_driver_nl80211_event_dellink(
     809             :         struct wpa_driver_nl80211_data *drv, const char *ifname)
     810             : {
     811             :         union wpa_event_data event;
     812             : 
     813          30 :         if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
     814          14 :                 if (drv->if_removed) {
     815           0 :                         wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
     816             :                                    ifname);
     817          30 :                         return;
     818             :                 }
     819          14 :                 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
     820             :                            ifname);
     821          14 :                 drv->if_removed = 1;
     822             :         } else {
     823          16 :                 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
     824             :                            ifname);
     825             :         }
     826             : 
     827          30 :         os_memset(&event, 0, sizeof(event));
     828          30 :         os_strlcpy(event.interface_status.ifname, ifname,
     829             :                    sizeof(event.interface_status.ifname));
     830          30 :         event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
     831          30 :         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
     832             : }
     833             : 
     834             : 
     835          11 : static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
     836             :                                          u8 *buf, size_t len)
     837             : {
     838             :         int attrlen, rta_len;
     839             :         struct rtattr *attr;
     840             : 
     841          11 :         attrlen = len;
     842          11 :         attr = (struct rtattr *) buf;
     843             : 
     844          11 :         rta_len = RTA_ALIGN(sizeof(struct rtattr));
     845          22 :         while (RTA_OK(attr, attrlen)) {
     846          11 :                 if (attr->rta_type == IFLA_IFNAME) {
     847          11 :                         if (os_strcmp(((char *) attr) + rta_len,
     848             :                                       drv->first_bss->ifname) == 0)
     849           0 :                                 return 1;
     850             :                         else
     851          11 :                                 break;
     852             :                 }
     853           0 :                 attr = RTA_NEXT(attr, attrlen);
     854             :         }
     855             : 
     856          11 :         return 0;
     857             : }
     858             : 
     859             : 
     860      148996 : static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
     861             :                                           int ifindex, u8 *buf, size_t len)
     862             : {
     863      148996 :         if (drv->ifindex == ifindex)
     864       28841 :                 return 1;
     865             : 
     866      120155 :         if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
     867           0 :                 nl80211_check_global(drv->global);
     868           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
     869             :                            "interface");
     870           0 :                 wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL);
     871           0 :                 return 1;
     872             :         }
     873             : 
     874      120155 :         return 0;
     875             : }
     876             : 
     877             : 
     878             : static struct wpa_driver_nl80211_data *
     879      162333 : nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
     880             : {
     881             :         struct wpa_driver_nl80211_data *drv;
     882      281909 :         dl_list_for_each(drv, &global->interfaces,
     883             :                          struct wpa_driver_nl80211_data, list) {
     884      269151 :                 if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
     885      120155 :                     have_ifidx(drv, idx))
     886       29420 :                         return drv;
     887             :         }
     888      132913 :         return NULL;
     889             : }
     890             : 
     891             : 
     892      160673 : static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
     893             :                                                  struct ifinfomsg *ifi,
     894             :                                                  u8 *buf, size_t len)
     895             : {
     896      160673 :         struct nl80211_global *global = ctx;
     897             :         struct wpa_driver_nl80211_data *drv;
     898             :         int attrlen;
     899             :         struct rtattr *attr;
     900      160673 :         u32 brid = 0;
     901             :         char namebuf[IFNAMSIZ];
     902             :         char ifname[IFNAMSIZ + 1];
     903             :         char extra[100], *pos, *end;
     904             : 
     905      160673 :         drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
     906      160673 :         if (!drv) {
     907      131336 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
     908             :                            ifi->ifi_index);
     909      131336 :                 return;
     910             :         }
     911             : 
     912       29337 :         extra[0] = '\0';
     913       29337 :         pos = extra;
     914       29337 :         end = pos + sizeof(extra);
     915       29337 :         ifname[0] = '\0';
     916             : 
     917       29337 :         attrlen = len;
     918       29337 :         attr = (struct rtattr *) buf;
     919      364725 :         while (RTA_OK(attr, attrlen)) {
     920      306051 :                 switch (attr->rta_type) {
     921             :                 case IFLA_IFNAME:
     922       29337 :                         if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
     923           0 :                                 break;
     924       29337 :                         os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
     925       29337 :                         ifname[RTA_PAYLOAD(attr)] = '\0';
     926       29337 :                         break;
     927             :                 case IFLA_MASTER:
     928         414 :                         brid = nla_get_u32((struct nlattr *) attr);
     929         414 :                         pos += os_snprintf(pos, end - pos, " master=%u", brid);
     930         414 :                         break;
     931             :                 case IFLA_WIRELESS:
     932       14613 :                         pos += os_snprintf(pos, end - pos, " wext");
     933       14613 :                         break;
     934             :                 case IFLA_OPERSTATE:
     935       14724 :                         pos += os_snprintf(pos, end - pos, " operstate=%u",
     936             :                                            nla_get_u32((struct nlattr *) attr));
     937       14724 :                         break;
     938             :                 case IFLA_LINKMODE:
     939       14462 :                         pos += os_snprintf(pos, end - pos, " linkmode=%u",
     940             :                                            nla_get_u32((struct nlattr *) attr));
     941       14462 :                         break;
     942             :                 }
     943      306051 :                 attr = RTA_NEXT(attr, attrlen);
     944             :         }
     945       29337 :         extra[sizeof(extra) - 1] = '\0';
     946             : 
     947      146685 :         wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
     948       29337 :                    ifi->ifi_index, ifname, extra, ifi->ifi_family,
     949             :                    ifi->ifi_flags,
     950       29337 :                    (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
     951       29337 :                    (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
     952       29337 :                    (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
     953       29337 :                    (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
     954             : 
     955       29337 :         if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
     956         559 :                 namebuf[0] = '\0';
     957        1087 :                 if (if_indextoname(ifi->ifi_index, namebuf) &&
     958         528 :                     linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) {
     959         456 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
     960             :                                    "event since interface %s is up", namebuf);
     961         456 :                         drv->ignore_if_down_event = 0;
     962         456 :                         return;
     963             :                 }
     964         103 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
     965             :                            namebuf, ifname);
     966         103 :                 if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
     967          76 :                         wpa_printf(MSG_DEBUG,
     968             :                                    "nl80211: Not the main interface (%s) - do not indicate interface down",
     969          76 :                                    drv->first_bss->ifname);
     970          27 :                 } else if (drv->ignore_if_down_event) {
     971           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
     972             :                                    "event generated by mode change");
     973           0 :                         drv->ignore_if_down_event = 0;
     974             :                 } else {
     975          27 :                         drv->if_disabled = 1;
     976          27 :                         wpa_supplicant_event(drv->ctx,
     977             :                                              EVENT_INTERFACE_DISABLED, NULL);
     978             : 
     979             :                         /*
     980             :                          * Try to get drv again, since it may be removed as
     981             :                          * part of the EVENT_INTERFACE_DISABLED handling for
     982             :                          * dynamic interfaces
     983             :                          */
     984          27 :                         drv = nl80211_find_drv(global, ifi->ifi_index,
     985             :                                                buf, len);
     986          27 :                         if (!drv)
     987           0 :                                 return;
     988             :                 }
     989             :         }
     990             : 
     991       28881 :         if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
     992          36 :                 if (if_indextoname(ifi->ifi_index, namebuf) &&
     993          16 :                     linux_iface_up(drv->global->ioctl_sock, namebuf) == 0) {
     994           5 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
     995             :                                    "event since interface %s is down",
     996             :                                    namebuf);
     997          15 :                 } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
     998           4 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
     999             :                                    "event since interface %s does not exist",
    1000           4 :                                    drv->first_bss->ifname);
    1001          11 :                 } else if (drv->if_removed) {
    1002           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
    1003             :                                    "event since interface %s is marked "
    1004           0 :                                    "removed", drv->first_bss->ifname);
    1005             :                 } else {
    1006             :                         struct i802_bss *bss;
    1007             :                         u8 addr[ETH_ALEN];
    1008             : 
    1009             :                         /* Re-read MAC address as it may have changed */
    1010          11 :                         bss = get_bss_ifindex(drv, ifi->ifi_index);
    1011          22 :                         if (bss &&
    1012          11 :                             linux_get_ifhwaddr(drv->global->ioctl_sock,
    1013          11 :                                                bss->ifname, addr) < 0) {
    1014           0 :                                 wpa_printf(MSG_DEBUG,
    1015             :                                            "nl80211: %s: failed to re-read MAC address",
    1016           0 :                                            bss->ifname);
    1017          22 :                         } else if (bss &&
    1018          11 :                                    os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
    1019          26 :                                 wpa_printf(MSG_DEBUG,
    1020             :                                            "nl80211: Own MAC address on ifindex %d (%s) changed from "
    1021             :                                            MACSTR " to " MACSTR,
    1022           2 :                                            ifi->ifi_index, bss->ifname,
    1023          12 :                                            MAC2STR(bss->addr),
    1024          12 :                                            MAC2STR(addr));
    1025           2 :                                 os_memcpy(bss->addr, addr, ETH_ALEN);
    1026             :                         }
    1027             : 
    1028          11 :                         wpa_printf(MSG_DEBUG, "nl80211: Interface up");
    1029          11 :                         drv->if_disabled = 0;
    1030          11 :                         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
    1031             :                                              NULL);
    1032             :                 }
    1033             :         }
    1034             : 
    1035             :         /*
    1036             :          * Some drivers send the association event before the operup event--in
    1037             :          * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
    1038             :          * fails. This will hit us when wpa_supplicant does not need to do
    1039             :          * IEEE 802.1X authentication
    1040             :          */
    1041       36697 :         if (drv->operstate == 1 &&
    1042       13541 :             (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
    1043        5725 :             !(ifi->ifi_flags & IFF_RUNNING)) {
    1044         652 :                 wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
    1045         652 :                 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
    1046             :                                        -1, IF_OPER_UP);
    1047             :         }
    1048             : 
    1049       28881 :         if (ifname[0])
    1050       28881 :                 wpa_driver_nl80211_event_newlink(drv, ifname);
    1051             : 
    1052       28881 :         if (ifi->ifi_family == AF_BRIDGE && brid) {
    1053             :                 struct i802_bss *bss;
    1054             : 
    1055             :                 /* device has been added to bridge */
    1056         261 :                 if (!if_indextoname(brid, namebuf)) {
    1057          15 :                         wpa_printf(MSG_DEBUG,
    1058             :                                    "nl80211: Could not find bridge ifname for ifindex %u",
    1059             :                                    brid);
    1060          15 :                         return;
    1061             :                 }
    1062         246 :                 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
    1063             :                            brid, namebuf);
    1064         246 :                 add_ifidx(drv, brid);
    1065             : 
    1066         351 :                 for (bss = drv->first_bss; bss; bss = bss->next) {
    1067         262 :                         if (os_strcmp(ifname, bss->ifname) == 0) {
    1068         157 :                                 os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
    1069         157 :                                 break;
    1070             :                         }
    1071             :                 }
    1072             :         }
    1073             : }
    1074             : 
    1075             : 
    1076        1633 : static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
    1077             :                                                  struct ifinfomsg *ifi,
    1078             :                                                  u8 *buf, size_t len)
    1079             : {
    1080        1633 :         struct nl80211_global *global = ctx;
    1081             :         struct wpa_driver_nl80211_data *drv;
    1082             :         int attrlen;
    1083             :         struct rtattr *attr;
    1084        1633 :         u32 brid = 0;
    1085             :         char ifname[IFNAMSIZ + 1];
    1086             :         char extra[100], *pos, *end;
    1087             : 
    1088        1633 :         drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
    1089        1633 :         if (!drv) {
    1090        1577 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
    1091             :                            ifi->ifi_index);
    1092        3210 :                 return;
    1093             :         }
    1094             : 
    1095          56 :         extra[0] = '\0';
    1096          56 :         pos = extra;
    1097          56 :         end = pos + sizeof(extra);
    1098          56 :         ifname[0] = '\0';
    1099             : 
    1100          56 :         attrlen = len;
    1101          56 :         attr = (struct rtattr *) buf;
    1102         828 :         while (RTA_OK(attr, attrlen)) {
    1103         716 :                 switch (attr->rta_type) {
    1104             :                 case IFLA_IFNAME:
    1105          56 :                         if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
    1106           0 :                                 break;
    1107          56 :                         os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
    1108          56 :                         ifname[RTA_PAYLOAD(attr)] = '\0';
    1109          56 :                         break;
    1110             :                 case IFLA_MASTER:
    1111          26 :                         brid = nla_get_u32((struct nlattr *) attr);
    1112          26 :                         pos += os_snprintf(pos, end - pos, " master=%u", brid);
    1113          26 :                         break;
    1114             :                 case IFLA_OPERSTATE:
    1115          56 :                         pos += os_snprintf(pos, end - pos, " operstate=%u",
    1116             :                                            nla_get_u32((struct nlattr *) attr));
    1117          56 :                         break;
    1118             :                 case IFLA_LINKMODE:
    1119          30 :                         pos += os_snprintf(pos, end - pos, " linkmode=%u",
    1120             :                                            nla_get_u32((struct nlattr *) attr));
    1121          30 :                         break;
    1122             :                 }
    1123         716 :                 attr = RTA_NEXT(attr, attrlen);
    1124             :         }
    1125          56 :         extra[sizeof(extra) - 1] = '\0';
    1126             : 
    1127         280 :         wpa_printf(MSG_DEBUG, "RTM_DELLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
    1128          56 :                    ifi->ifi_index, ifname, extra, ifi->ifi_family,
    1129             :                    ifi->ifi_flags,
    1130          56 :                    (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
    1131          56 :                    (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
    1132          56 :                    (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
    1133          56 :                    (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
    1134             : 
    1135          56 :         if (ifname[0] && (ifi->ifi_family != AF_BRIDGE || !brid))
    1136          30 :                 wpa_driver_nl80211_event_dellink(drv, ifname);
    1137             : 
    1138          56 :         if (ifi->ifi_family == AF_BRIDGE && brid) {
    1139             :                 /* device has been removed from bridge */
    1140             :                 char namebuf[IFNAMSIZ];
    1141             : 
    1142          26 :                 if (!if_indextoname(brid, namebuf)) {
    1143          16 :                         wpa_printf(MSG_DEBUG,
    1144             :                                    "nl80211: Could not find bridge ifname for ifindex %u",
    1145             :                                    brid);
    1146             :                 } else {
    1147          10 :                         wpa_printf(MSG_DEBUG,
    1148             :                                    "nl80211: Remove ifindex %u for bridge %s",
    1149             :                                    brid, namebuf);
    1150             :                 }
    1151          26 :                 del_ifidx(drv, brid);
    1152             :         }
    1153             : }
    1154             : 
    1155             : 
    1156         313 : unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
    1157             : {
    1158             :         struct nl_msg *msg;
    1159             :         int ret;
    1160             :         struct nl80211_bss_info_arg arg;
    1161             : 
    1162         313 :         msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
    1163         313 :         os_memset(&arg, 0, sizeof(arg));
    1164         313 :         arg.drv = drv;
    1165         313 :         ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
    1166         313 :         if (ret == 0) {
    1167         626 :                 unsigned int freq = drv->nlmode == NL80211_IFTYPE_ADHOC ?
    1168         313 :                         arg.ibss_freq : arg.assoc_freq;
    1169         313 :                 wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
    1170             :                            "associated BSS from scan results: %u MHz", freq);
    1171         313 :                 if (freq)
    1172         312 :                         drv->assoc_freq = freq;
    1173         313 :                 return drv->assoc_freq;
    1174             :         }
    1175           0 :         wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
    1176             :                    "(%s)", ret, strerror(-ret));
    1177           0 :         return drv->assoc_freq;
    1178             : }
    1179             : 
    1180             : 
    1181          50 : static int get_link_signal(struct nl_msg *msg, void *arg)
    1182             : {
    1183             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    1184          50 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    1185             :         struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
    1186             :         static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
    1187             :                 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
    1188             :                 [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
    1189             :                 [NL80211_STA_INFO_BEACON_SIGNAL_AVG] = { .type = NLA_U8 },
    1190             :         };
    1191             :         struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
    1192             :         static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
    1193             :                 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
    1194             :                 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
    1195             :                 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
    1196             :                 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
    1197             :         };
    1198          50 :         struct wpa_signal_info *sig_change = arg;
    1199             : 
    1200          50 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    1201             :                   genlmsg_attrlen(gnlh, 0), NULL);
    1202         100 :         if (!tb[NL80211_ATTR_STA_INFO] ||
    1203          50 :             nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
    1204             :                              tb[NL80211_ATTR_STA_INFO], policy))
    1205           0 :                 return NL_SKIP;
    1206          50 :         if (!sinfo[NL80211_STA_INFO_SIGNAL])
    1207           0 :                 return NL_SKIP;
    1208             : 
    1209          50 :         sig_change->current_signal =
    1210          50 :                 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
    1211             : 
    1212          50 :         if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
    1213          50 :                 sig_change->avg_signal =
    1214          50 :                         (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
    1215             :         else
    1216           0 :                 sig_change->avg_signal = 0;
    1217             : 
    1218          50 :         if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG])
    1219          50 :                 sig_change->avg_beacon_signal =
    1220          50 :                         (s8)
    1221          50 :                         nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]);
    1222             :         else
    1223           0 :                 sig_change->avg_beacon_signal = 0;
    1224             : 
    1225          50 :         if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
    1226          50 :                 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
    1227             :                                      sinfo[NL80211_STA_INFO_TX_BITRATE],
    1228             :                                      rate_policy)) {
    1229           0 :                         sig_change->current_txrate = 0;
    1230             :                 } else {
    1231          50 :                         if (rinfo[NL80211_RATE_INFO_BITRATE]) {
    1232          50 :                                 sig_change->current_txrate =
    1233          50 :                                         nla_get_u16(rinfo[
    1234          50 :                                              NL80211_RATE_INFO_BITRATE]) * 100;
    1235             :                         }
    1236             :                 }
    1237             :         }
    1238             : 
    1239          50 :         return NL_SKIP;
    1240             : }
    1241             : 
    1242             : 
    1243          50 : int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
    1244             :                             struct wpa_signal_info *sig)
    1245             : {
    1246             :         struct nl_msg *msg;
    1247             : 
    1248          50 :         sig->current_signal = -9999;
    1249          50 :         sig->current_txrate = 0;
    1250             : 
    1251         100 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_STATION)) ||
    1252          50 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid)) {
    1253           0 :                 nlmsg_free(msg);
    1254           0 :                 return -ENOBUFS;
    1255             :         }
    1256             : 
    1257          50 :         return send_and_recv_msgs(drv, msg, get_link_signal, sig);
    1258             : }
    1259             : 
    1260             : 
    1261          50 : static int get_link_noise(struct nl_msg *msg, void *arg)
    1262             : {
    1263             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    1264          50 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    1265             :         struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
    1266             :         static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
    1267             :                 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
    1268             :                 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
    1269             :         };
    1270          50 :         struct wpa_signal_info *sig_change = arg;
    1271             : 
    1272          50 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    1273             :                   genlmsg_attrlen(gnlh, 0), NULL);
    1274             : 
    1275          50 :         if (!tb[NL80211_ATTR_SURVEY_INFO]) {
    1276           0 :                 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
    1277           0 :                 return NL_SKIP;
    1278             :         }
    1279             : 
    1280          50 :         if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
    1281             :                              tb[NL80211_ATTR_SURVEY_INFO],
    1282             :                              survey_policy)) {
    1283           0 :                 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
    1284             :                            "attributes!");
    1285           0 :                 return NL_SKIP;
    1286             :         }
    1287             : 
    1288          50 :         if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
    1289           0 :                 return NL_SKIP;
    1290             : 
    1291         100 :         if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
    1292          50 :             sig_change->frequency)
    1293           0 :                 return NL_SKIP;
    1294             : 
    1295          50 :         if (!sinfo[NL80211_SURVEY_INFO_NOISE])
    1296           0 :                 return NL_SKIP;
    1297             : 
    1298          50 :         sig_change->current_noise =
    1299          50 :                 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
    1300             : 
    1301          50 :         return NL_SKIP;
    1302             : }
    1303             : 
    1304             : 
    1305          50 : int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
    1306             :                            struct wpa_signal_info *sig_change)
    1307             : {
    1308             :         struct nl_msg *msg;
    1309             : 
    1310          50 :         sig_change->current_noise = 9999;
    1311          50 :         sig_change->frequency = drv->assoc_freq;
    1312             : 
    1313          50 :         msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
    1314          50 :         return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
    1315             : }
    1316             : 
    1317             : 
    1318      322760 : static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
    1319             :                                              void *handle)
    1320             : {
    1321      322760 :         struct nl_cb *cb = eloop_ctx;
    1322             :         int res;
    1323             : 
    1324      322760 :         wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
    1325             : 
    1326      322760 :         res = nl_recvmsgs(handle, cb);
    1327      322760 :         if (res < 0) {
    1328           0 :                 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
    1329             :                            __func__, res);
    1330             :         }
    1331      322760 : }
    1332             : 
    1333             : 
    1334             : /**
    1335             :  * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
    1336             :  * @priv: driver_nl80211 private data
    1337             :  * @alpha2_arg: country to which to switch to
    1338             :  * Returns: 0 on success, -1 on failure
    1339             :  *
    1340             :  * This asks nl80211 to set the regulatory domain for given
    1341             :  * country ISO / IEC alpha2.
    1342             :  */
    1343         346 : static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
    1344             : {
    1345         346 :         struct i802_bss *bss = priv;
    1346         346 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1347             :         char alpha2[3];
    1348             :         struct nl_msg *msg;
    1349             : 
    1350         346 :         msg = nlmsg_alloc();
    1351         346 :         if (!msg)
    1352           0 :                 return -ENOMEM;
    1353             : 
    1354         346 :         alpha2[0] = alpha2_arg[0];
    1355         346 :         alpha2[1] = alpha2_arg[1];
    1356         346 :         alpha2[2] = '\0';
    1357             : 
    1358         692 :         if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG) ||
    1359         346 :             nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, alpha2)) {
    1360           0 :                 nlmsg_free(msg);
    1361           0 :                 return -EINVAL;
    1362             :         }
    1363         346 :         if (send_and_recv_msgs(drv, msg, NULL, NULL))
    1364           0 :                 return -EINVAL;
    1365         346 :         return 0;
    1366             : }
    1367             : 
    1368             : 
    1369         339 : static int nl80211_get_country(struct nl_msg *msg, void *arg)
    1370             : {
    1371         339 :         char *alpha2 = arg;
    1372             :         struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
    1373         339 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    1374             : 
    1375         339 :         nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    1376             :                   genlmsg_attrlen(gnlh, 0), NULL);
    1377         339 :         if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
    1378           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No country information available");
    1379           0 :                 return NL_SKIP;
    1380             :         }
    1381         339 :         os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
    1382         339 :         return NL_SKIP;
    1383             : }
    1384             : 
    1385             : 
    1386         339 : static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
    1387             : {
    1388         339 :         struct i802_bss *bss = priv;
    1389         339 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1390             :         struct nl_msg *msg;
    1391             :         int ret;
    1392             : 
    1393         339 :         msg = nlmsg_alloc();
    1394         339 :         if (!msg)
    1395           0 :                 return -ENOMEM;
    1396             : 
    1397         339 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
    1398         339 :         alpha2[0] = '\0';
    1399         339 :         ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
    1400         339 :         if (!alpha2[0])
    1401           0 :                 ret = -1;
    1402             : 
    1403         339 :         return ret;
    1404             : }
    1405             : 
    1406             : 
    1407          46 : static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
    1408             : {
    1409             :         int ret;
    1410             : 
    1411          46 :         global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
    1412          46 :         if (global->nl_cb == NULL) {
    1413           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
    1414             :                            "callbacks");
    1415           0 :                 return -1;
    1416             :         }
    1417             : 
    1418          46 :         global->nl = nl_create_handle(global->nl_cb, "nl");
    1419          46 :         if (global->nl == NULL)
    1420           0 :                 goto err;
    1421             : 
    1422          46 :         global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");
    1423          46 :         if (global->nl80211_id < 0) {
    1424           0 :                 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
    1425             :                            "found");
    1426           0 :                 goto err;
    1427             :         }
    1428             : 
    1429          46 :         global->nl_event = nl_create_handle(global->nl_cb, "event");
    1430          46 :         if (global->nl_event == NULL)
    1431           0 :                 goto err;
    1432             : 
    1433          46 :         ret = nl_get_multicast_id(global, "nl80211", "scan");
    1434          46 :         if (ret >= 0)
    1435          46 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    1436          46 :         if (ret < 0) {
    1437           0 :                 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
    1438             :                            "membership for scan events: %d (%s)",
    1439             :                            ret, strerror(-ret));
    1440           0 :                 goto err;
    1441             :         }
    1442             : 
    1443          46 :         ret = nl_get_multicast_id(global, "nl80211", "mlme");
    1444          46 :         if (ret >= 0)
    1445          46 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    1446          46 :         if (ret < 0) {
    1447           0 :                 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
    1448             :                            "membership for mlme events: %d (%s)",
    1449             :                            ret, strerror(-ret));
    1450           0 :                 goto err;
    1451             :         }
    1452             : 
    1453          46 :         ret = nl_get_multicast_id(global, "nl80211", "regulatory");
    1454          46 :         if (ret >= 0)
    1455          46 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    1456          46 :         if (ret < 0) {
    1457           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
    1458             :                            "membership for regulatory events: %d (%s)",
    1459             :                            ret, strerror(-ret));
    1460             :                 /* Continue without regulatory events */
    1461             :         }
    1462             : 
    1463          46 :         ret = nl_get_multicast_id(global, "nl80211", "vendor");
    1464          46 :         if (ret >= 0)
    1465          46 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    1466          46 :         if (ret < 0) {
    1467           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
    1468             :                            "membership for vendor events: %d (%s)",
    1469             :                            ret, strerror(-ret));
    1470             :                 /* Continue without vendor events */
    1471             :         }
    1472             : 
    1473          46 :         nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
    1474             :                   no_seq_check, NULL);
    1475          46 :         nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
    1476             :                   process_global_event, global);
    1477             : 
    1478          46 :         nl80211_register_eloop_read(&global->nl_event,
    1479             :                                     wpa_driver_nl80211_event_receive,
    1480          46 :                                     global->nl_cb);
    1481             : 
    1482          46 :         return 0;
    1483             : 
    1484             : err:
    1485           0 :         nl_destroy_handles(&global->nl_event);
    1486           0 :         nl_destroy_handles(&global->nl);
    1487           0 :         nl_cb_put(global->nl_cb);
    1488           0 :         global->nl_cb = NULL;
    1489           0 :         return -1;
    1490             : }
    1491             : 
    1492             : 
    1493        2171 : static void nl80211_check_global(struct nl80211_global *global)
    1494             : {
    1495             :         struct nl_handle *handle;
    1496        2171 :         const char *groups[] = { "scan", "mlme", "regulatory", "vendor", NULL };
    1497             :         int ret;
    1498             :         unsigned int i;
    1499             : 
    1500             :         /*
    1501             :          * Try to re-add memberships to handle case of cfg80211 getting reloaded
    1502             :          * and all registration having been cleared.
    1503             :          */
    1504        2171 :         handle = (void *) (((intptr_t) global->nl_event) ^
    1505             :                            ELOOP_SOCKET_INVALID);
    1506             : 
    1507       10855 :         for (i = 0; groups[i]; i++) {
    1508        8684 :                 ret = nl_get_multicast_id(global, "nl80211", groups[i]);
    1509        8684 :                 if (ret >= 0)
    1510        8684 :                         ret = nl_socket_add_membership(handle, ret);
    1511        8684 :                 if (ret < 0) {
    1512           0 :                         wpa_printf(MSG_INFO,
    1513             :                                    "nl80211: Could not re-add multicast membership for %s events: %d (%s)",
    1514             :                                    groups[i], ret, strerror(-ret));
    1515             :                 }
    1516             :         }
    1517        2171 : }
    1518             : 
    1519             : 
    1520          27 : static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
    1521             : {
    1522          27 :         wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
    1523             :         /*
    1524             :          * This may be for any interface; use ifdown event to disable
    1525             :          * interface.
    1526             :          */
    1527          27 : }
    1528             : 
    1529             : 
    1530          26 : static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
    1531             : {
    1532          26 :         struct wpa_driver_nl80211_data *drv = ctx;
    1533          26 :         wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
    1534          26 :         if (i802_set_iface_flags(drv->first_bss, 1)) {
    1535           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
    1536             :                            "after rfkill unblock");
    1537           0 :                 return;
    1538             :         }
    1539             :         /* rtnetlink ifup handler will report interface as enabled */
    1540             : }
    1541             : 
    1542             : 
    1543       11096 : static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
    1544             :                                                       void *eloop_ctx,
    1545             :                                                       void *handle)
    1546             : {
    1547       11096 :         struct wpa_driver_nl80211_data *drv = eloop_ctx;
    1548             :         u8 data[2048];
    1549             :         struct msghdr msg;
    1550             :         struct iovec entry;
    1551             :         u8 control[512];
    1552             :         struct cmsghdr *cmsg;
    1553       11096 :         int res, found_ee = 0, found_wifi = 0, acked = 0;
    1554             :         union wpa_event_data event;
    1555             : 
    1556       11096 :         memset(&msg, 0, sizeof(msg));
    1557       11096 :         msg.msg_iov = &entry;
    1558       11096 :         msg.msg_iovlen = 1;
    1559       11096 :         entry.iov_base = data;
    1560       11096 :         entry.iov_len = sizeof(data);
    1561       11096 :         msg.msg_control = &control;
    1562       11096 :         msg.msg_controllen = sizeof(control);
    1563             : 
    1564       11096 :         res = recvmsg(sock, &msg, MSG_ERRQUEUE);
    1565             :         /* if error or not fitting 802.3 header, return */
    1566       11096 :         if (res < 14)
    1567           0 :                 return;
    1568             : 
    1569       33288 :         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
    1570             :         {
    1571       33288 :                 if (cmsg->cmsg_level == SOL_SOCKET &&
    1572       11096 :                     cmsg->cmsg_type == SCM_WIFI_STATUS) {
    1573             :                         int *ack;
    1574             : 
    1575       11096 :                         found_wifi = 1;
    1576       11096 :                         ack = (void *)CMSG_DATA(cmsg);
    1577       11096 :                         acked = *ack;
    1578             :                 }
    1579             : 
    1580       33288 :                 if (cmsg->cmsg_level == SOL_PACKET &&
    1581       11096 :                     cmsg->cmsg_type == PACKET_TX_TIMESTAMP) {
    1582       11096 :                         struct sock_extended_err *err =
    1583             :                                 (struct sock_extended_err *)CMSG_DATA(cmsg);
    1584             : 
    1585       11096 :                         if (err->ee_origin == SO_EE_ORIGIN_TXSTATUS)
    1586       11096 :                                 found_ee = 1;
    1587             :                 }
    1588             :         }
    1589             : 
    1590       11096 :         if (!found_ee || !found_wifi)
    1591           0 :                 return;
    1592             : 
    1593       11096 :         memset(&event, 0, sizeof(event));
    1594       11096 :         event.eapol_tx_status.dst = data;
    1595       11096 :         event.eapol_tx_status.data = data + 14;
    1596       11096 :         event.eapol_tx_status.data_len = res - 14;
    1597       11096 :         event.eapol_tx_status.ack = acked;
    1598       11096 :         wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
    1599             : }
    1600             : 
    1601             : 
    1602        2221 : static int nl80211_init_bss(struct i802_bss *bss)
    1603             : {
    1604        2221 :         bss->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
    1605        2221 :         if (!bss->nl_cb)
    1606           0 :                 return -1;
    1607             : 
    1608        2221 :         nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
    1609             :                   no_seq_check, NULL);
    1610        2221 :         nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
    1611             :                   process_bss_event, bss);
    1612             : 
    1613        2221 :         return 0;
    1614             : }
    1615             : 
    1616             : 
    1617        2221 : static void nl80211_destroy_bss(struct i802_bss *bss)
    1618             : {
    1619        2221 :         nl_cb_put(bss->nl_cb);
    1620        2221 :         bss->nl_cb = NULL;
    1621        2221 : }
    1622             : 
    1623             : 
    1624        2186 : static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
    1625             :                                           void *global_priv, int hostapd,
    1626             :                                           const u8 *set_addr,
    1627             :                                           const char *driver_params)
    1628             : {
    1629             :         struct wpa_driver_nl80211_data *drv;
    1630             :         struct rfkill_config *rcfg;
    1631             :         struct i802_bss *bss;
    1632             : 
    1633        2186 :         if (global_priv == NULL)
    1634           0 :                 return NULL;
    1635        2186 :         drv = os_zalloc(sizeof(*drv));
    1636        2186 :         if (drv == NULL)
    1637           4 :                 return NULL;
    1638        2182 :         drv->global = global_priv;
    1639        2182 :         drv->ctx = ctx;
    1640        2182 :         drv->hostapd = !!hostapd;
    1641        2182 :         drv->eapol_sock = -1;
    1642             : 
    1643             :         /*
    1644             :          * There is no driver capability flag for this, so assume it is
    1645             :          * supported and disable this on first attempt to use if the driver
    1646             :          * rejects the command due to missing support.
    1647             :          */
    1648        2182 :         drv->set_rekey_offload = 1;
    1649             : 
    1650        2182 :         drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
    1651        2182 :         drv->if_indices = drv->default_if_indices;
    1652             : 
    1653        2182 :         drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
    1654        2182 :         if (!drv->first_bss) {
    1655           4 :                 os_free(drv);
    1656           4 :                 return NULL;
    1657             :         }
    1658        2178 :         bss = drv->first_bss;
    1659        2178 :         bss->drv = drv;
    1660        2178 :         bss->ctx = ctx;
    1661             : 
    1662        2178 :         os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
    1663        2178 :         drv->monitor_ifidx = -1;
    1664        2178 :         drv->monitor_sock = -1;
    1665        2178 :         drv->eapol_tx_sock = -1;
    1666        2178 :         drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
    1667             : 
    1668        2178 :         if (nl80211_init_bss(bss))
    1669           0 :                 goto failed;
    1670             : 
    1671        2178 :         rcfg = os_zalloc(sizeof(*rcfg));
    1672        2178 :         if (rcfg == NULL)
    1673           4 :                 goto failed;
    1674        2174 :         rcfg->ctx = drv;
    1675        2174 :         os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
    1676        2174 :         rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
    1677        2174 :         rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
    1678        2174 :         drv->rfkill = rfkill_init(rcfg);
    1679        2174 :         if (drv->rfkill == NULL) {
    1680           3 :                 wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
    1681           3 :                 os_free(rcfg);
    1682             :         }
    1683             : 
    1684        2174 :         if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
    1685           0 :                 drv->start_iface_up = 1;
    1686             : 
    1687        2174 :         if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params))
    1688           3 :                 goto failed;
    1689             : 
    1690        2171 :         drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
    1691        2171 :         if (drv->eapol_tx_sock < 0)
    1692           0 :                 goto failed;
    1693             : 
    1694        2171 :         if (drv->data_tx_status) {
    1695        2171 :                 int enabled = 1;
    1696             : 
    1697        2171 :                 if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
    1698             :                                &enabled, sizeof(enabled)) < 0) {
    1699           0 :                         wpa_printf(MSG_DEBUG,
    1700             :                                 "nl80211: wifi status sockopt failed\n");
    1701           0 :                         drv->data_tx_status = 0;
    1702           0 :                         if (!drv->use_monitor)
    1703           0 :                                 drv->capa.flags &=
    1704             :                                         ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
    1705             :                 } else {
    1706        2171 :                         eloop_register_read_sock(drv->eapol_tx_sock,
    1707             :                                 wpa_driver_nl80211_handle_eapol_tx_status,
    1708             :                                 drv, NULL);
    1709             :                 }
    1710             :         }
    1711             : 
    1712        2171 :         if (drv->global) {
    1713        2171 :                 nl80211_check_global(drv->global);
    1714        2171 :                 dl_list_add(&drv->global->interfaces, &drv->list);
    1715        2171 :                 drv->in_interface_list = 1;
    1716             :         }
    1717             : 
    1718        2171 :         return bss;
    1719             : 
    1720             : failed:
    1721           7 :         wpa_driver_nl80211_deinit(bss);
    1722           7 :         return NULL;
    1723             : }
    1724             : 
    1725             : 
    1726             : /**
    1727             :  * wpa_driver_nl80211_init - Initialize nl80211 driver interface
    1728             :  * @ctx: context to be used when calling wpa_supplicant functions,
    1729             :  * e.g., wpa_supplicant_event()
    1730             :  * @ifname: interface name, e.g., wlan0
    1731             :  * @global_priv: private driver global data from global_init()
    1732             :  * Returns: Pointer to private data, %NULL on failure
    1733             :  */
    1734         535 : static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
    1735             :                                       void *global_priv)
    1736             : {
    1737         535 :         return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL,
    1738             :                                            NULL);
    1739             : }
    1740             : 
    1741             : 
    1742       45380 : static int nl80211_register_frame(struct i802_bss *bss,
    1743             :                                   struct nl_handle *nl_handle,
    1744             :                                   u16 type, const u8 *match, size_t match_len)
    1745             : {
    1746       45380 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1747             :         struct nl_msg *msg;
    1748             :         int ret;
    1749             :         char buf[30];
    1750             : 
    1751       45380 :         buf[0] = '\0';
    1752       45380 :         wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
    1753       45380 :         wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x (%s) nl_handle=%p match=%s",
    1754             :                    type, fc2str(type), nl_handle, buf);
    1755             : 
    1756       90760 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_ACTION)) ||
    1757       90760 :             nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, type) ||
    1758       45380 :             nla_put(msg, NL80211_ATTR_FRAME_MATCH, match_len, match)) {
    1759           0 :                 nlmsg_free(msg);
    1760           0 :                 return -1;
    1761             :         }
    1762             : 
    1763       45380 :         ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL);
    1764       45380 :         if (ret) {
    1765           5 :                 wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
    1766             :                            "failed (type=%u): ret=%d (%s)",
    1767             :                            type, ret, strerror(-ret));
    1768           5 :                 wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
    1769             :                             match, match_len);
    1770             :         }
    1771       45380 :         return ret;
    1772             : }
    1773             : 
    1774             : 
    1775        3534 : static int nl80211_alloc_mgmt_handle(struct i802_bss *bss)
    1776             : {
    1777        3534 :         if (bss->nl_mgmt) {
    1778           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Mgmt reporting "
    1779             :                            "already on! (nl_mgmt=%p)", bss->nl_mgmt);
    1780           0 :                 return -1;
    1781             :         }
    1782             : 
    1783        3534 :         bss->nl_mgmt = nl_create_handle(bss->nl_cb, "mgmt");
    1784        3534 :         if (bss->nl_mgmt == NULL)
    1785           0 :                 return -1;
    1786             : 
    1787        3534 :         return 0;
    1788             : }
    1789             : 
    1790             : 
    1791        3534 : static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
    1792             : {
    1793        3534 :         nl80211_register_eloop_read(&bss->nl_mgmt,
    1794             :                                     wpa_driver_nl80211_event_receive,
    1795        3534 :                                     bss->nl_cb);
    1796        3534 : }
    1797             : 
    1798             : 
    1799       29139 : static int nl80211_register_action_frame(struct i802_bss *bss,
    1800             :                                          const u8 *match, size_t match_len)
    1801             : {
    1802       29139 :         u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
    1803       29139 :         return nl80211_register_frame(bss, bss->nl_mgmt,
    1804             :                                       type, match, match_len);
    1805             : }
    1806             : 
    1807             : 
    1808        1382 : static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
    1809             : {
    1810        1382 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1811        1382 :         int ret = 0;
    1812             : 
    1813        1382 :         if (nl80211_alloc_mgmt_handle(bss))
    1814           0 :                 return -1;
    1815        1382 :         wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
    1816             :                    "handle %p", bss->nl_mgmt);
    1817             : 
    1818        1382 :         if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
    1819          21 :                 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
    1820             : 
    1821             :                 /* register for any AUTH message */
    1822          21 :                 nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
    1823             :         }
    1824             : 
    1825             : #ifdef CONFIG_INTERWORKING
    1826             :         /* QoS Map Configure */
    1827        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
    1828           0 :                 ret = -1;
    1829             : #endif /* CONFIG_INTERWORKING */
    1830             : #if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
    1831             :         /* GAS Initial Request */
    1832        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
    1833           0 :                 ret = -1;
    1834             :         /* GAS Initial Response */
    1835        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
    1836           0 :                 ret = -1;
    1837             :         /* GAS Comeback Request */
    1838        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
    1839           0 :                 ret = -1;
    1840             :         /* GAS Comeback Response */
    1841        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
    1842           0 :                 ret = -1;
    1843             :         /* Protected GAS Initial Request */
    1844        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
    1845           0 :                 ret = -1;
    1846             :         /* Protected GAS Initial Response */
    1847        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
    1848           0 :                 ret = -1;
    1849             :         /* Protected GAS Comeback Request */
    1850        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
    1851           0 :                 ret = -1;
    1852             :         /* Protected GAS Comeback Response */
    1853        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
    1854           0 :                 ret = -1;
    1855             : #endif /* CONFIG_P2P || CONFIG_INTERWORKING */
    1856             : #ifdef CONFIG_P2P
    1857             :         /* P2P Public Action */
    1858        1382 :         if (nl80211_register_action_frame(bss,
    1859             :                                           (u8 *) "\x04\x09\x50\x6f\x9a\x09",
    1860             :                                           6) < 0)
    1861           0 :                 ret = -1;
    1862             :         /* P2P Action */
    1863        1382 :         if (nl80211_register_action_frame(bss,
    1864             :                                           (u8 *) "\x7f\x50\x6f\x9a\x09",
    1865             :                                           5) < 0)
    1866           0 :                 ret = -1;
    1867             : #endif /* CONFIG_P2P */
    1868             : #ifdef CONFIG_IEEE80211W
    1869             :         /* SA Query Response */
    1870        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
    1871           0 :                 ret = -1;
    1872             : #endif /* CONFIG_IEEE80211W */
    1873             : #ifdef CONFIG_TDLS
    1874        1382 :         if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
    1875             :                 /* TDLS Discovery Response */
    1876        1382 :                 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
    1877             :                     0)
    1878           0 :                         ret = -1;
    1879             :         }
    1880             : #endif /* CONFIG_TDLS */
    1881             : #ifdef CONFIG_FST
    1882             :         /* FST Action frames */
    1883        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x12", 1) < 0)
    1884           0 :                 ret = -1;
    1885             : #endif /* CONFIG_FST */
    1886             : 
    1887             :         /* FT Action frames */
    1888        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
    1889           0 :                 ret = -1;
    1890             :         else
    1891        1382 :                 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
    1892             :                         WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
    1893             : 
    1894             :         /* WNM - BSS Transition Management Request */
    1895        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
    1896           0 :                 ret = -1;
    1897             :         /* WNM-Sleep Mode Response */
    1898        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
    1899           0 :                 ret = -1;
    1900             : 
    1901             : #ifdef CONFIG_HS20
    1902             :         /* WNM-Notification */
    1903        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
    1904           0 :                 ret = -1;
    1905             : #endif /* CONFIG_HS20 */
    1906             : 
    1907             :         /* WMM-AC ADDTS Response */
    1908        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x11\x01", 2) < 0)
    1909           0 :                 ret = -1;
    1910             : 
    1911             :         /* WMM-AC DELTS */
    1912        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x11\x02", 2) < 0)
    1913           0 :                 ret = -1;
    1914             : 
    1915             :         /* Radio Measurement - Neighbor Report Response */
    1916        1382 :         if (nl80211_register_action_frame(bss, (u8 *) "\x05\x05", 2) < 0)
    1917           0 :                 ret = -1;
    1918             : 
    1919             :         /* Radio Measurement - Link Measurement Request */
    1920        1382 :         if ((drv->capa.rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION) &&
    1921           0 :             (nl80211_register_action_frame(bss, (u8 *) "\x05\x02", 2) < 0))
    1922           0 :                 ret = -1;
    1923             : 
    1924        1382 :         nl80211_mgmt_handle_register_eloop(bss);
    1925             : 
    1926        1382 :         return ret;
    1927             : }
    1928             : 
    1929             : 
    1930          39 : static int nl80211_mgmt_subscribe_mesh(struct i802_bss *bss)
    1931             : {
    1932          39 :         int ret = 0;
    1933             : 
    1934          39 :         if (nl80211_alloc_mgmt_handle(bss))
    1935           0 :                 return -1;
    1936             : 
    1937          39 :         wpa_printf(MSG_DEBUG,
    1938             :                    "nl80211: Subscribe to mgmt frames with mesh handle %p",
    1939             :                    bss->nl_mgmt);
    1940             : 
    1941             :         /* Auth frames for mesh SAE */
    1942          39 :         if (nl80211_register_frame(bss, bss->nl_mgmt,
    1943             :                                    (WLAN_FC_TYPE_MGMT << 2) |
    1944             :                                    (WLAN_FC_STYPE_AUTH << 4),
    1945             :                                    NULL, 0) < 0)
    1946           0 :                 ret = -1;
    1947             : 
    1948             :         /* Mesh peering open */
    1949          39 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x01", 2) < 0)
    1950           0 :                 ret = -1;
    1951             :         /* Mesh peering confirm */
    1952          39 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x02", 2) < 0)
    1953           0 :                 ret = -1;
    1954             :         /* Mesh peering close */
    1955          39 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x03", 2) < 0)
    1956           0 :                 ret = -1;
    1957             : 
    1958          39 :         nl80211_mgmt_handle_register_eloop(bss);
    1959             : 
    1960          39 :         return ret;
    1961             : }
    1962             : 
    1963             : 
    1964        2113 : static int nl80211_register_spurious_class3(struct i802_bss *bss)
    1965             : {
    1966             :         struct nl_msg *msg;
    1967             :         int ret;
    1968             : 
    1969        2113 :         msg = nl80211_bss_msg(bss, 0, NL80211_CMD_UNEXPECTED_FRAME);
    1970        2113 :         ret = send_and_recv(bss->drv->global, bss->nl_mgmt, msg, NULL, NULL);
    1971        2113 :         if (ret) {
    1972           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
    1973             :                            "failed: ret=%d (%s)",
    1974             :                            ret, strerror(-ret));
    1975             :         }
    1976        2113 :         return ret;
    1977             : }
    1978             : 
    1979             : 
    1980        2113 : static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
    1981             : {
    1982             :         static const int stypes[] = {
    1983             :                 WLAN_FC_STYPE_AUTH,
    1984             :                 WLAN_FC_STYPE_ASSOC_REQ,
    1985             :                 WLAN_FC_STYPE_REASSOC_REQ,
    1986             :                 WLAN_FC_STYPE_DISASSOC,
    1987             :                 WLAN_FC_STYPE_DEAUTH,
    1988             :                 WLAN_FC_STYPE_ACTION,
    1989             :                 WLAN_FC_STYPE_PROBE_REQ,
    1990             : /* Beacon doesn't work as mac80211 doesn't currently allow
    1991             :  * it, but it wouldn't really be the right thing anyway as
    1992             :  * it isn't per interface ... maybe just dump the scan
    1993             :  * results periodically for OLBC?
    1994             :  */
    1995             :                 /* WLAN_FC_STYPE_BEACON, */
    1996             :         };
    1997             :         unsigned int i;
    1998             : 
    1999        2113 :         if (nl80211_alloc_mgmt_handle(bss))
    2000           0 :                 return -1;
    2001        2113 :         wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
    2002             :                    "handle %p", bss->nl_mgmt);
    2003             : 
    2004       16904 :         for (i = 0; i < ARRAY_SIZE(stypes); i++) {
    2005       14791 :                 if (nl80211_register_frame(bss, bss->nl_mgmt,
    2006             :                                            (WLAN_FC_TYPE_MGMT << 2) |
    2007       14791 :                                            (stypes[i] << 4),
    2008             :                                            NULL, 0) < 0) {
    2009           0 :                         goto out_err;
    2010             :                 }
    2011             :         }
    2012             : 
    2013        2113 :         if (nl80211_register_spurious_class3(bss))
    2014           0 :                 goto out_err;
    2015             : 
    2016        2113 :         if (nl80211_get_wiphy_data_ap(bss) == NULL)
    2017           0 :                 goto out_err;
    2018             : 
    2019        2113 :         nl80211_mgmt_handle_register_eloop(bss);
    2020        2113 :         return 0;
    2021             : 
    2022             : out_err:
    2023           0 :         nl_destroy_handles(&bss->nl_mgmt);
    2024           0 :         return -1;
    2025             : }
    2026             : 
    2027             : 
    2028           0 : static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
    2029             : {
    2030           0 :         if (nl80211_alloc_mgmt_handle(bss))
    2031           0 :                 return -1;
    2032           0 :         wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
    2033             :                    "handle %p (device SME)", bss->nl_mgmt);
    2034             : 
    2035           0 :         if (nl80211_register_frame(bss, bss->nl_mgmt,
    2036             :                                    (WLAN_FC_TYPE_MGMT << 2) |
    2037             :                                    (WLAN_FC_STYPE_ACTION << 4),
    2038             :                                    NULL, 0) < 0)
    2039           0 :                 goto out_err;
    2040             : 
    2041           0 :         nl80211_mgmt_handle_register_eloop(bss);
    2042           0 :         return 0;
    2043             : 
    2044             : out_err:
    2045           0 :         nl_destroy_handles(&bss->nl_mgmt);
    2046           0 :         return -1;
    2047             : }
    2048             : 
    2049             : 
    2050        7853 : static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
    2051             : {
    2052        7853 :         if (bss->nl_mgmt == NULL)
    2053       12172 :                 return;
    2054        3534 :         wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
    2055             :                    "(%s)", bss->nl_mgmt, reason);
    2056        3534 :         nl80211_destroy_eloop_handle(&bss->nl_mgmt);
    2057             : 
    2058        3534 :         nl80211_put_wiphy_data_ap(bss);
    2059             : }
    2060             : 
    2061             : 
    2062           1 : static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
    2063             : {
    2064           1 :         wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
    2065           1 : }
    2066             : 
    2067             : 
    2068           8 : static void nl80211_del_p2pdev(struct i802_bss *bss)
    2069             : {
    2070             :         struct nl_msg *msg;
    2071             :         int ret;
    2072             : 
    2073           8 :         msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_INTERFACE);
    2074           8 :         ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
    2075             : 
    2076          16 :         wpa_printf(MSG_DEBUG, "nl80211: Delete P2P Device %s (0x%llx): %s",
    2077           8 :                    bss->ifname, (long long unsigned int) bss->wdev_id,
    2078             :                    strerror(-ret));
    2079           8 : }
    2080             : 
    2081             : 
    2082           8 : static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
    2083             : {
    2084             :         struct nl_msg *msg;
    2085             :         int ret;
    2086             : 
    2087           8 :         msg = nl80211_cmd_msg(bss, 0, start ? NL80211_CMD_START_P2P_DEVICE :
    2088             :                               NL80211_CMD_STOP_P2P_DEVICE);
    2089           8 :         ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
    2090             : 
    2091          16 :         wpa_printf(MSG_DEBUG, "nl80211: %s P2P Device %s (0x%llx): %s",
    2092             :                    start ? "Start" : "Stop",
    2093           8 :                    bss->ifname, (long long unsigned int) bss->wdev_id,
    2094             :                    strerror(-ret));
    2095           8 :         return ret;
    2096             : }
    2097             : 
    2098             : 
    2099        4442 : static int i802_set_iface_flags(struct i802_bss *bss, int up)
    2100             : {
    2101             :         enum nl80211_iftype nlmode;
    2102             : 
    2103        4442 :         nlmode = nl80211_get_ifmode(bss);
    2104        4442 :         if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
    2105        4434 :                 return linux_set_iface_flags(bss->drv->global->ioctl_sock,
    2106        4434 :                                              bss->ifname, up);
    2107             :         }
    2108             : 
    2109             :         /* P2P Device has start/stop which is equivalent */
    2110           8 :         return nl80211_set_p2pdev(bss, up);
    2111             : }
    2112             : 
    2113             : 
    2114             : #ifdef CONFIG_TESTING_OPTIONS
    2115        2163 : static int qca_vendor_test_cmd_handler(struct nl_msg *msg, void *arg)
    2116             : {
    2117             :         /* struct wpa_driver_nl80211_data *drv = arg; */
    2118             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    2119        2163 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    2120             : 
    2121             : 
    2122        2163 :         wpa_printf(MSG_DEBUG,
    2123             :                    "nl80211: QCA vendor test command response received");
    2124             : 
    2125        2163 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    2126             :                   genlmsg_attrlen(gnlh, 0), NULL);
    2127        2163 :         if (!tb[NL80211_ATTR_VENDOR_DATA]) {
    2128           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No vendor data attribute");
    2129           0 :                 return NL_SKIP;
    2130             :         }
    2131             : 
    2132        4326 :         wpa_hexdump(MSG_DEBUG,
    2133             :                     "nl80211: Received QCA vendor test command response",
    2134        2163 :                     nla_data(tb[NL80211_ATTR_VENDOR_DATA]),
    2135        2163 :                     nla_len(tb[NL80211_ATTR_VENDOR_DATA]));
    2136             : 
    2137        2163 :         return NL_SKIP;
    2138             : }
    2139             : #endif /* CONFIG_TESTING_OPTIONS */
    2140             : 
    2141             : 
    2142        2163 : static void qca_vendor_test(struct wpa_driver_nl80211_data *drv)
    2143             : {
    2144             : #ifdef CONFIG_TESTING_OPTIONS
    2145             :         struct nl_msg *msg;
    2146             :         struct nlattr *params;
    2147             :         int ret;
    2148             : 
    2149        4326 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    2150        4326 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    2151        2163 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    2152        2163 :                         QCA_NL80211_VENDOR_SUBCMD_TEST) ||
    2153        2163 :             !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
    2154        2163 :             nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TEST, 123)) {
    2155           0 :                 nlmsg_free(msg);
    2156        2163 :                 return;
    2157             :         }
    2158        2163 :         nla_nest_end(msg, params);
    2159             : 
    2160        2163 :         ret = send_and_recv_msgs(drv, msg, qca_vendor_test_cmd_handler, drv);
    2161        2163 :         wpa_printf(MSG_DEBUG,
    2162             :                    "nl80211: QCA vendor test command returned %d (%s)",
    2163             :                    ret, strerror(-ret));
    2164             : #endif /* CONFIG_TESTING_OPTIONS */
    2165             : }
    2166             : 
    2167             : 
    2168             : static int
    2169        2174 : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
    2170             :                                    const u8 *set_addr, int first,
    2171             :                                    const char *driver_params)
    2172             : {
    2173        2174 :         struct i802_bss *bss = drv->first_bss;
    2174        2174 :         int send_rfkill_event = 0;
    2175             :         enum nl80211_iftype nlmode;
    2176             : 
    2177        2174 :         drv->ifindex = if_nametoindex(bss->ifname);
    2178        2174 :         bss->ifindex = drv->ifindex;
    2179        2174 :         bss->wdev_id = drv->global->if_add_wdevid;
    2180        2174 :         bss->wdev_id_set = drv->global->if_add_wdevid_set;
    2181             : 
    2182        2174 :         bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
    2183        2174 :         bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
    2184        2174 :         drv->global->if_add_wdevid_set = 0;
    2185             : 
    2186        2174 :         if (!bss->if_dynamic && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
    2187           3 :                 bss->static_ap = 1;
    2188             : 
    2189        2174 :         if (wpa_driver_nl80211_capa(drv))
    2190           3 :                 return -1;
    2191             : 
    2192        2171 :         if (driver_params && nl80211_set_param(bss, driver_params) < 0)
    2193           0 :                 return -1;
    2194             : 
    2195        2171 :         wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
    2196        2171 :                    bss->ifname, drv->phyname);
    2197             : 
    2198        2219 :         if (set_addr &&
    2199          96 :             (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
    2200          48 :              linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    2201             :                                 set_addr)))
    2202           0 :                 return -1;
    2203             : 
    2204        2171 :         if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
    2205           3 :                 drv->start_mode_ap = 1;
    2206             : 
    2207        2171 :         if (drv->hostapd || bss->static_ap)
    2208        1639 :                 nlmode = NL80211_IFTYPE_AP;
    2209         532 :         else if (bss->if_dynamic)
    2210         159 :                 nlmode = nl80211_get_ifmode(bss);
    2211             :         else
    2212         373 :                 nlmode = NL80211_IFTYPE_STATION;
    2213             : 
    2214        2171 :         if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
    2215           0 :                 wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
    2216           0 :                 return -1;
    2217             :         }
    2218             : 
    2219        2171 :         if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    2220           8 :                 nl80211_get_macaddr(bss);
    2221             : 
    2222        2171 :         if (!rfkill_is_blocked(drv->rfkill)) {
    2223        2169 :                 int ret = i802_set_iface_flags(bss, 1);
    2224        2169 :                 if (ret) {
    2225           0 :                         wpa_printf(MSG_ERROR, "nl80211: Could not set "
    2226           0 :                                    "interface '%s' UP", bss->ifname);
    2227           0 :                         return ret;
    2228             :                 }
    2229        2169 :                 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    2230           8 :                         return ret;
    2231             :         } else {
    2232           2 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
    2233           2 :                            "interface '%s' due to rfkill", bss->ifname);
    2234           2 :                 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    2235           0 :                         return 0;
    2236           2 :                 drv->if_disabled = 1;
    2237           2 :                 send_rfkill_event = 1;
    2238             :         }
    2239             : 
    2240        2163 :         if (!drv->hostapd)
    2241         524 :                 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
    2242             :                                        1, IF_OPER_DORMANT);
    2243             : 
    2244        2163 :         if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    2245        2163 :                                bss->addr))
    2246           0 :                 return -1;
    2247        2163 :         os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
    2248             : 
    2249        2163 :         if (send_rfkill_event) {
    2250           2 :                 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
    2251             :                                        drv, drv->ctx);
    2252             :         }
    2253             : 
    2254        2163 :         if (drv->vendor_cmd_test_avail)
    2255        2163 :                 qca_vendor_test(drv);
    2256             : 
    2257        2163 :         return 0;
    2258             : }
    2259             : 
    2260             : 
    2261        2083 : static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
    2262             : {
    2263             :         struct nl_msg *msg;
    2264             : 
    2265        2083 :         wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
    2266             :                    drv->ifindex);
    2267        2083 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
    2268        2083 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    2269             : }
    2270             : 
    2271             : 
    2272             : /**
    2273             :  * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
    2274             :  * @bss: Pointer to private nl80211 data from wpa_driver_nl80211_init()
    2275             :  *
    2276             :  * Shut down driver interface and processing of driver events. Free
    2277             :  * private data buffer if one was allocated in wpa_driver_nl80211_init().
    2278             :  */
    2279        2178 : static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
    2280             : {
    2281        2178 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2282             : 
    2283        4356 :         wpa_printf(MSG_INFO, "nl80211: deinit ifname=%s disabled_11b_rates=%d",
    2284        4356 :                    bss->ifname, drv->disabled_11b_rates);
    2285             : 
    2286        2178 :         bss->in_deinit = 1;
    2287        2178 :         if (drv->data_tx_status)
    2288        2171 :                 eloop_unregister_read_sock(drv->eapol_tx_sock);
    2289        2178 :         if (drv->eapol_tx_sock >= 0)
    2290        2171 :                 close(drv->eapol_tx_sock);
    2291             : 
    2292        2178 :         if (bss->nl_preq)
    2293           0 :                 wpa_driver_nl80211_probe_req_report(bss, 0);
    2294        2178 :         if (bss->added_if_into_bridge) {
    2295          19 :                 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
    2296          19 :                                     bss->ifname) < 0)
    2297          34 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
    2298             :                                    "interface %s from bridge %s: %s",
    2299          34 :                                    bss->ifname, bss->brname, strerror(errno));
    2300          19 :                 if (drv->rtnl_sk)
    2301          19 :                         nl80211_handle_destroy(drv->rtnl_sk);
    2302             :         }
    2303        2178 :         if (bss->added_bridge) {
    2304          12 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname,
    2305             :                                           0) < 0)
    2306          10 :                         wpa_printf(MSG_INFO,
    2307             :                                    "nl80211: Could not set bridge %s down",
    2308          10 :                                    bss->brname);
    2309          12 :                 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
    2310          20 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
    2311             :                                    "bridge %s: %s",
    2312          20 :                                    bss->brname, strerror(errno));
    2313             :         }
    2314             : 
    2315        2178 :         nl80211_remove_monitor_interface(drv);
    2316             : 
    2317        2178 :         if (is_ap_interface(drv->nlmode))
    2318        1743 :                 wpa_driver_nl80211_del_beacon(drv);
    2319             : 
    2320        2178 :         if (drv->eapol_sock >= 0) {
    2321        1639 :                 eloop_unregister_read_sock(drv->eapol_sock);
    2322        1639 :                 close(drv->eapol_sock);
    2323             :         }
    2324             : 
    2325        2178 :         if (drv->if_indices != drv->default_if_indices)
    2326           1 :                 os_free(drv->if_indices);
    2327             : 
    2328        2178 :         if (drv->disabled_11b_rates)
    2329         106 :                 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
    2330             : 
    2331        2178 :         netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
    2332             :                                IF_OPER_UP);
    2333        2178 :         eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
    2334        2178 :         rfkill_deinit(drv->rfkill);
    2335             : 
    2336        2178 :         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
    2337             : 
    2338        2178 :         if (!drv->start_iface_up)
    2339        2178 :                 (void) i802_set_iface_flags(bss, 0);
    2340             : 
    2341        2178 :         if (drv->addr_changed) {
    2342           3 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
    2343             :                                           0) < 0) {
    2344           0 :                         wpa_printf(MSG_DEBUG,
    2345             :                                    "nl80211: Could not set interface down to restore permanent MAC address");
    2346             :                 }
    2347           3 :                 if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    2348           3 :                                        drv->perm_addr) < 0) {
    2349           0 :                         wpa_printf(MSG_DEBUG,
    2350             :                                    "nl80211: Could not restore permanent MAC address");
    2351             :                 }
    2352             :         }
    2353             : 
    2354        2178 :         if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
    2355        2170 :                 if (!drv->hostapd || !drv->start_mode_ap)
    2356        2167 :                         wpa_driver_nl80211_set_mode(bss,
    2357             :                                                     NL80211_IFTYPE_STATION);
    2358        2170 :                 nl80211_mgmt_unsubscribe(bss, "deinit");
    2359             :         } else {
    2360           8 :                 nl80211_mgmt_unsubscribe(bss, "deinit");
    2361           8 :                 nl80211_del_p2pdev(bss);
    2362             :         }
    2363             : 
    2364        2178 :         nl80211_destroy_bss(drv->first_bss);
    2365             : 
    2366        2178 :         os_free(drv->filter_ssids);
    2367             : 
    2368        2178 :         os_free(drv->auth_ie);
    2369             : 
    2370        2178 :         if (drv->in_interface_list)
    2371        2171 :                 dl_list_del(&drv->list);
    2372             : 
    2373        2178 :         os_free(drv->extended_capa);
    2374        2178 :         os_free(drv->extended_capa_mask);
    2375        2178 :         os_free(drv->first_bss);
    2376        2178 :         os_free(drv);
    2377        2178 : }
    2378             : 
    2379             : 
    2380        8546 : static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
    2381             : {
    2382        8546 :         switch (alg) {
    2383             :         case WPA_ALG_WEP:
    2384         114 :                 if (key_len == 5)
    2385          52 :                         return WLAN_CIPHER_SUITE_WEP40;
    2386          62 :                 return WLAN_CIPHER_SUITE_WEP104;
    2387             :         case WPA_ALG_TKIP:
    2388         197 :                 return WLAN_CIPHER_SUITE_TKIP;
    2389             :         case WPA_ALG_CCMP:
    2390        7812 :                 return WLAN_CIPHER_SUITE_CCMP;
    2391             :         case WPA_ALG_GCMP:
    2392          18 :                 return WLAN_CIPHER_SUITE_GCMP;
    2393             :         case WPA_ALG_CCMP_256:
    2394           5 :                 return WLAN_CIPHER_SUITE_CCMP_256;
    2395             :         case WPA_ALG_GCMP_256:
    2396          34 :                 return WLAN_CIPHER_SUITE_GCMP_256;
    2397             :         case WPA_ALG_IGTK:
    2398         341 :                 return WLAN_CIPHER_SUITE_AES_CMAC;
    2399             :         case WPA_ALG_BIP_GMAC_128:
    2400          10 :                 return WLAN_CIPHER_SUITE_BIP_GMAC_128;
    2401             :         case WPA_ALG_BIP_GMAC_256:
    2402          10 :                 return WLAN_CIPHER_SUITE_BIP_GMAC_256;
    2403             :         case WPA_ALG_BIP_CMAC_256:
    2404           3 :                 return WLAN_CIPHER_SUITE_BIP_CMAC_256;
    2405             :         case WPA_ALG_SMS4:
    2406           0 :                 return WLAN_CIPHER_SUITE_SMS4;
    2407             :         case WPA_ALG_KRK:
    2408           0 :                 return WLAN_CIPHER_SUITE_KRK;
    2409             :         case WPA_ALG_NONE:
    2410             :         case WPA_ALG_PMK:
    2411           0 :                 wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
    2412             :                            alg);
    2413           0 :                 return 0;
    2414             :         }
    2415             : 
    2416           2 :         wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
    2417             :                    alg);
    2418           2 :         return 0;
    2419             : }
    2420             : 
    2421             : 
    2422        8922 : static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
    2423             : {
    2424        8922 :         switch (cipher) {
    2425             :         case WPA_CIPHER_CCMP_256:
    2426           3 :                 return WLAN_CIPHER_SUITE_CCMP_256;
    2427             :         case WPA_CIPHER_GCMP_256:
    2428          19 :                 return WLAN_CIPHER_SUITE_GCMP_256;
    2429             :         case WPA_CIPHER_CCMP:
    2430        7179 :                 return WLAN_CIPHER_SUITE_CCMP;
    2431             :         case WPA_CIPHER_GCMP:
    2432          11 :                 return WLAN_CIPHER_SUITE_GCMP;
    2433             :         case WPA_CIPHER_TKIP:
    2434         300 :                 return WLAN_CIPHER_SUITE_TKIP;
    2435             :         case WPA_CIPHER_WEP104:
    2436          32 :                 return WLAN_CIPHER_SUITE_WEP104;
    2437             :         case WPA_CIPHER_WEP40:
    2438          52 :                 return WLAN_CIPHER_SUITE_WEP40;
    2439             :         case WPA_CIPHER_GTK_NOT_USED:
    2440           0 :                 return WLAN_CIPHER_SUITE_NO_GROUP_ADDR;
    2441             :         }
    2442             : 
    2443        1326 :         return 0;
    2444             : }
    2445             : 
    2446             : 
    2447        4442 : static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
    2448             :                                        int max_suites)
    2449             : {
    2450        4442 :         int num_suites = 0;
    2451             : 
    2452        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
    2453           1 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
    2454        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
    2455           5 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
    2456        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
    2457        2948 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
    2458        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
    2459           3 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
    2460        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
    2461         143 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
    2462        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
    2463           0 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
    2464        4442 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
    2465           0 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
    2466             : 
    2467        4442 :         return num_suites;
    2468             : }
    2469             : 
    2470             : 
    2471           6 : static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
    2472             :                                   const u8 *key, size_t key_len)
    2473             : {
    2474             :         struct nl_msg *msg;
    2475             :         int ret;
    2476             : 
    2477           6 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
    2478           6 :                 return 0;
    2479             : 
    2480           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    2481           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    2482           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    2483           0 :                         QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY) ||
    2484           0 :             nla_put(msg, NL80211_ATTR_VENDOR_DATA, key_len, key)) {
    2485           0 :                 nl80211_nlmsg_clear(msg);
    2486           0 :                 nlmsg_free(msg);
    2487           0 :                 return -1;
    2488             :         }
    2489           0 :         ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
    2490           0 :         if (ret) {
    2491           0 :                 wpa_printf(MSG_DEBUG,
    2492             :                            "nl80211: Key management set key failed: ret=%d (%s)",
    2493             :                            ret, strerror(-ret));
    2494             :         }
    2495             : 
    2496           0 :         return ret;
    2497             : }
    2498             : 
    2499             : 
    2500       37074 : static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
    2501             :                                       enum wpa_alg alg, const u8 *addr,
    2502             :                                       int key_idx, int set_tx,
    2503             :                                       const u8 *seq, size_t seq_len,
    2504             :                                       const u8 *key, size_t key_len)
    2505             : {
    2506       37074 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2507             :         int ifindex;
    2508       37074 :         struct nl_msg *msg = NULL;
    2509             :         int ret;
    2510       37074 :         int tdls = 0;
    2511             : 
    2512             :         /* Ignore for P2P Device */
    2513       37074 :         if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
    2514          48 :                 return 0;
    2515             : 
    2516       37026 :         ifindex = if_nametoindex(ifname);
    2517       37026 :         wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
    2518             :                    "set_tx=%d seq_len=%lu key_len=%lu",
    2519             :                    __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
    2520             :                    (unsigned long) seq_len, (unsigned long) key_len);
    2521             : #ifdef CONFIG_TDLS
    2522       15517 :         if (key_idx == -1) {
    2523          78 :                 key_idx = 0;
    2524          78 :                 tdls = 1;
    2525             :         }
    2526             : #endif /* CONFIG_TDLS */
    2527             : 
    2528       37026 :         if (alg == WPA_ALG_PMK &&
    2529           0 :             (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
    2530           0 :                 wpa_printf(MSG_DEBUG, "%s: calling issue_key_mgmt_set_key",
    2531             :                            __func__);
    2532           0 :                 ret = issue_key_mgmt_set_key(drv, key, key_len);
    2533           0 :                 return ret;
    2534             :         }
    2535             : 
    2536       37026 :         if (alg == WPA_ALG_NONE) {
    2537       28504 :                 msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY);
    2538       28504 :                 if (!msg)
    2539           0 :                         return -ENOBUFS;
    2540             :         } else {
    2541             :                 u32 suite;
    2542             : 
    2543        8522 :                 suite = wpa_alg_to_cipher_suite(alg, key_len);
    2544        8522 :                 if (!suite)
    2545           2 :                         goto fail;
    2546        8520 :                 msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY);
    2547       17040 :                 if (!msg ||
    2548       17040 :                     nla_put(msg, NL80211_ATTR_KEY_DATA, key_len, key) ||
    2549        8520 :                     nla_put_u32(msg, NL80211_ATTR_KEY_CIPHER, suite))
    2550             :                         goto fail;
    2551        8520 :                 wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
    2552             :         }
    2553             : 
    2554       37024 :         if (seq && seq_len) {
    2555        4020 :                 if (nla_put(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq))
    2556           0 :                         goto fail;
    2557        4020 :                 wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
    2558             :         }
    2559             : 
    2560       37024 :         if (addr && !is_broadcast_ether_addr(addr)) {
    2561       17141 :                 wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));
    2562       17141 :                 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
    2563           0 :                         goto fail;
    2564             : 
    2565       34282 :                 if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
    2566          28 :                         wpa_printf(MSG_DEBUG, "   RSN IBSS RX GTK");
    2567          28 :                         if (nla_put_u32(msg, NL80211_ATTR_KEY_TYPE,
    2568             :                                         NL80211_KEYTYPE_GROUP))
    2569           0 :                                 goto fail;
    2570             :                 }
    2571       19883 :         } else if (addr && is_broadcast_ether_addr(addr)) {
    2572             :                 struct nlattr *types;
    2573             : 
    2574        4283 :                 wpa_printf(MSG_DEBUG, "   broadcast key");
    2575             : 
    2576        4283 :                 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
    2577        8566 :                 if (!types ||
    2578        4283 :                     nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
    2579             :                         goto fail;
    2580        4283 :                 nla_nest_end(msg, types);
    2581             :         }
    2582       37024 :         if (nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
    2583           0 :                 goto fail;
    2584             : 
    2585       37024 :         ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL);
    2586       37024 :         if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
    2587       26938 :                 ret = 0;
    2588       37024 :         if (ret)
    2589         354 :                 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
    2590             :                            ret, strerror(-ret));
    2591             : 
    2592             :         /*
    2593             :          * If we failed or don't need to set the default TX key (below),
    2594             :          * we're done here.
    2595             :          */
    2596       37024 :         if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
    2597       30747 :                 return ret;
    2598       10700 :         if (is_ap_interface(drv->nlmode) && addr &&
    2599        4423 :             !is_broadcast_ether_addr(addr))
    2600        1984 :                 return ret;
    2601             : 
    2602        4293 :         msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY);
    2603        8586 :         if (!msg ||
    2604        8586 :             nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx) ||
    2605        4591 :             nla_put_flag(msg, (alg == WPA_ALG_IGTK ||
    2606        4003 :                                alg == WPA_ALG_BIP_GMAC_128 ||
    2607        3997 :                                alg == WPA_ALG_BIP_GMAC_256 ||
    2608             :                                alg == WPA_ALG_BIP_CMAC_256) ?
    2609             :                          NL80211_ATTR_KEY_DEFAULT_MGMT :
    2610             :                          NL80211_ATTR_KEY_DEFAULT))
    2611             :                 goto fail;
    2612        6744 :         if (addr && is_broadcast_ether_addr(addr)) {
    2613             :                 struct nlattr *types;
    2614             : 
    2615        2451 :                 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
    2616        4902 :                 if (!types ||
    2617        2451 :                     nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
    2618             :                         goto fail;
    2619        2451 :                 nla_nest_end(msg, types);
    2620        1842 :         } else if (addr) {
    2621             :                 struct nlattr *types;
    2622             : 
    2623        1780 :                 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
    2624        3560 :                 if (!types ||
    2625        1780 :                     nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST))
    2626             :                         goto fail;
    2627        1780 :                 nla_nest_end(msg, types);
    2628             :         }
    2629             : 
    2630        4293 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    2631        4293 :         if (ret == -ENOENT)
    2632           0 :                 ret = 0;
    2633        4293 :         if (ret)
    2634           0 :                 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
    2635             :                            "err=%d %s)", ret, strerror(-ret));
    2636        4293 :         return ret;
    2637             : 
    2638             : fail:
    2639           2 :         nl80211_nlmsg_clear(msg);
    2640           2 :         nlmsg_free(msg);
    2641           2 :         return -ENOBUFS;
    2642             : }
    2643             : 
    2644             : 
    2645          24 : static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
    2646             :                       int key_idx, int defkey,
    2647             :                       const u8 *seq, size_t seq_len,
    2648             :                       const u8 *key, size_t key_len)
    2649             : {
    2650          24 :         struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
    2651             :         u32 suite;
    2652             : 
    2653          24 :         if (!key_attr)
    2654           0 :                 return -1;
    2655             : 
    2656          24 :         suite = wpa_alg_to_cipher_suite(alg, key_len);
    2657          24 :         if (!suite)
    2658           0 :                 return -1;
    2659             : 
    2660          24 :         if (defkey && alg == WPA_ALG_IGTK) {
    2661           0 :                 if (nla_put_flag(msg, NL80211_KEY_DEFAULT_MGMT))
    2662           0 :                         return -1;
    2663          24 :         } else if (defkey) {
    2664          24 :                 if (nla_put_flag(msg, NL80211_KEY_DEFAULT))
    2665           0 :                         return -1;
    2666             :         }
    2667             : 
    2668          48 :         if (nla_put_u8(msg, NL80211_KEY_IDX, key_idx) ||
    2669          48 :             nla_put_u32(msg, NL80211_KEY_CIPHER, suite) ||
    2670           0 :             (seq && seq_len &&
    2671          24 :              nla_put(msg, NL80211_KEY_SEQ, seq_len, seq)) ||
    2672          24 :             nla_put(msg, NL80211_KEY_DATA, key_len, key))
    2673           0 :                 return -1;
    2674             : 
    2675          24 :         nla_nest_end(msg, key_attr);
    2676             : 
    2677          24 :         return 0;
    2678             : }
    2679             : 
    2680             : 
    2681         299 : static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
    2682             :                                  struct nl_msg *msg)
    2683             : {
    2684         299 :         int i, privacy = 0;
    2685             :         struct nlattr *nl_keys, *nl_key;
    2686             : 
    2687        2950 :         for (i = 0; i < 4; i++) {
    2688        1181 :                 if (!params->wep_key[i])
    2689        1176 :                         continue;
    2690           5 :                 privacy = 1;
    2691           5 :                 break;
    2692             :         }
    2693         299 :         if (params->wps == WPS_MODE_PRIVACY)
    2694           2 :                 privacy = 1;
    2695         598 :         if (params->pairwise_suite &&
    2696         299 :             params->pairwise_suite != WPA_CIPHER_NONE)
    2697          30 :                 privacy = 1;
    2698             : 
    2699         299 :         if (!privacy)
    2700         267 :                 return 0;
    2701             : 
    2702          32 :         if (nla_put_flag(msg, NL80211_ATTR_PRIVACY))
    2703           0 :                 return -ENOBUFS;
    2704             : 
    2705          32 :         nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
    2706          32 :         if (!nl_keys)
    2707           0 :                 return -ENOBUFS;
    2708             : 
    2709         160 :         for (i = 0; i < 4; i++) {
    2710         128 :                 if (!params->wep_key[i])
    2711         123 :                         continue;
    2712             : 
    2713           5 :                 nl_key = nla_nest_start(msg, i);
    2714          10 :                 if (!nl_key ||
    2715           5 :                     nla_put(msg, NL80211_KEY_DATA, params->wep_key_len[i],
    2716          10 :                             params->wep_key[i]) ||
    2717           5 :                     nla_put_u32(msg, NL80211_KEY_CIPHER,
    2718           5 :                                 params->wep_key_len[i] == 5 ?
    2719             :                                 WLAN_CIPHER_SUITE_WEP40 :
    2720           5 :                                 WLAN_CIPHER_SUITE_WEP104) ||
    2721          10 :                     nla_put_u8(msg, NL80211_KEY_IDX, i) ||
    2722          10 :                     (i == params->wep_tx_keyidx &&
    2723           5 :                      nla_put_flag(msg, NL80211_KEY_DEFAULT)))
    2724           0 :                         return -ENOBUFS;
    2725             : 
    2726           5 :                 nla_nest_end(msg, nl_key);
    2727             :         }
    2728          32 :         nla_nest_end(msg, nl_keys);
    2729             : 
    2730          32 :         return 0;
    2731             : }
    2732             : 
    2733             : 
    2734        2951 : int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
    2735             :                             const u8 *addr, int cmd, u16 reason_code,
    2736             :                             int local_state_change)
    2737             : {
    2738             :         int ret;
    2739             :         struct nl_msg *msg;
    2740             : 
    2741        5902 :         if (!(msg = nl80211_drv_msg(drv, 0, cmd)) ||
    2742        5902 :             nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code) ||
    2743        2687 :             (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
    2744           0 :             (local_state_change &&
    2745           0 :              nla_put_flag(msg, NL80211_ATTR_LOCAL_STATE_CHANGE))) {
    2746           0 :                 nlmsg_free(msg);
    2747           0 :                 return -1;
    2748             :         }
    2749             : 
    2750        2951 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    2751        2951 :         if (ret) {
    2752         353 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    2753             :                         "nl80211: MLME command failed: reason=%u ret=%d (%s)",
    2754             :                         reason_code, ret, strerror(-ret));
    2755             :         }
    2756        2951 :         return ret;
    2757             : }
    2758             : 
    2759             : 
    2760         264 : static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
    2761             :                                          int reason_code)
    2762             : {
    2763             :         int ret;
    2764             : 
    2765         264 :         wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
    2766         264 :         nl80211_mark_disconnected(drv);
    2767             :         /* Disconnect command doesn't need BSSID - it uses cached value */
    2768         264 :         ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
    2769             :                                       reason_code, 0);
    2770             :         /*
    2771             :          * For locally generated disconnect, supplicant already generates a
    2772             :          * DEAUTH event, so ignore the event from NL80211.
    2773             :          */
    2774         264 :         drv->ignore_next_local_disconnect = ret == 0;
    2775             : 
    2776         264 :         return ret;
    2777             : }
    2778             : 
    2779             : 
    2780        2968 : static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
    2781             :                                              const u8 *addr, int reason_code)
    2782             : {
    2783        2968 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2784             :         int ret;
    2785             : 
    2786        2968 :         if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
    2787          21 :                 nl80211_mark_disconnected(drv);
    2788          21 :                 return nl80211_leave_ibss(drv, 1);
    2789             :         }
    2790        2947 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
    2791         260 :                 return wpa_driver_nl80211_disconnect(drv, reason_code);
    2792       16122 :         wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
    2793       16122 :                    __func__, MAC2STR(addr), reason_code);
    2794        2687 :         nl80211_mark_disconnected(drv);
    2795        2687 :         ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
    2796             :                                       reason_code, 0);
    2797             :         /*
    2798             :          * For locally generated deauthenticate, supplicant already generates a
    2799             :          * DEAUTH event, so ignore the event from NL80211.
    2800             :          */
    2801        2687 :         drv->ignore_next_local_deauth = ret == 0;
    2802        2687 :         return ret;
    2803             : }
    2804             : 
    2805             : 
    2806           6 : static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
    2807             :                                      struct wpa_driver_auth_params *params)
    2808             : {
    2809             :         int i;
    2810             : 
    2811           6 :         drv->auth_freq = params->freq;
    2812           6 :         drv->auth_alg = params->auth_alg;
    2813           6 :         drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
    2814           6 :         drv->auth_local_state_change = params->local_state_change;
    2815           6 :         drv->auth_p2p = params->p2p;
    2816             : 
    2817           6 :         if (params->bssid)
    2818           6 :                 os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
    2819             :         else
    2820           0 :                 os_memset(drv->auth_bssid_, 0, ETH_ALEN);
    2821             : 
    2822           6 :         if (params->ssid) {
    2823           6 :                 os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
    2824           6 :                 drv->auth_ssid_len = params->ssid_len;
    2825             :         } else
    2826           0 :                 drv->auth_ssid_len = 0;
    2827             : 
    2828             : 
    2829           6 :         os_free(drv->auth_ie);
    2830           6 :         drv->auth_ie = NULL;
    2831           6 :         drv->auth_ie_len = 0;
    2832           6 :         if (params->ie) {
    2833           0 :                 drv->auth_ie = os_malloc(params->ie_len);
    2834           0 :                 if (drv->auth_ie) {
    2835           0 :                         os_memcpy(drv->auth_ie, params->ie, params->ie_len);
    2836           0 :                         drv->auth_ie_len = params->ie_len;
    2837             :                 }
    2838             :         }
    2839             : 
    2840          30 :         for (i = 0; i < 4; i++) {
    2841          25 :                 if (params->wep_key[i] && params->wep_key_len[i] &&
    2842           1 :                     params->wep_key_len[i] <= 16) {
    2843           1 :                         os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
    2844             :                                   params->wep_key_len[i]);
    2845           1 :                         drv->auth_wep_key_len[i] = params->wep_key_len[i];
    2846             :                 } else
    2847          23 :                         drv->auth_wep_key_len[i] = 0;
    2848             :         }
    2849           6 : }
    2850             : 
    2851             : 
    2852        7016 : static void nl80211_unmask_11b_rates(struct i802_bss *bss)
    2853             : {
    2854        7016 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2855             : 
    2856        7016 :         if (is_p2p_net_interface(drv->nlmode) || !drv->disabled_11b_rates)
    2857       14031 :                 return;
    2858             : 
    2859             :         /*
    2860             :          * Looks like we failed to unmask 11b rates previously. This could
    2861             :          * happen, e.g., if the interface was down at the point in time when a
    2862             :          * P2P group was terminated.
    2863             :          */
    2864           1 :         wpa_printf(MSG_DEBUG,
    2865             :                    "nl80211: Interface %s mode is for non-P2P, but 11b rates were disabled - re-enable them",
    2866           1 :                    bss->ifname);
    2867           1 :         nl80211_disable_11b_rates(drv, drv->ifindex, 0);
    2868             : }
    2869             : 
    2870             : 
    2871        3326 : static int wpa_driver_nl80211_authenticate(
    2872             :         struct i802_bss *bss, struct wpa_driver_auth_params *params)
    2873             : {
    2874        3326 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2875        3326 :         int ret = -1, i;
    2876             :         struct nl_msg *msg;
    2877             :         enum nl80211_auth_type type;
    2878             :         enum nl80211_iftype nlmode;
    2879        3326 :         int count = 0;
    2880             :         int is_retry;
    2881             : 
    2882        3326 :         nl80211_unmask_11b_rates(bss);
    2883             : 
    2884        3326 :         is_retry = drv->retry_auth;
    2885        3326 :         drv->retry_auth = 0;
    2886        3326 :         drv->ignore_deauth_event = 0;
    2887             : 
    2888        3326 :         nl80211_mark_disconnected(drv);
    2889        3326 :         os_memset(drv->auth_bssid, 0, ETH_ALEN);
    2890        3326 :         if (params->bssid)
    2891        3326 :                 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
    2892             :         else
    2893           0 :                 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
    2894             :         /* FIX: IBSS mode */
    2895        3326 :         nlmode = params->p2p ?
    2896             :                 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
    2897        3511 :         if (drv->nlmode != nlmode &&
    2898         185 :             wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
    2899           0 :                 return -1;
    2900             : 
    2901             : retry:
    2902        3370 :         wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
    2903             :                    drv->ifindex);
    2904             : 
    2905        3370 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_AUTHENTICATE);
    2906        3370 :         if (!msg)
    2907           0 :                 goto fail;
    2908             : 
    2909       16850 :         for (i = 0; i < 4; i++) {
    2910       13480 :                 if (!params->wep_key[i])
    2911       13450 :                         continue;
    2912          60 :                 wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
    2913             :                                            NULL, i,
    2914          30 :                                            i == params->wep_tx_keyidx, NULL, 0,
    2915             :                                            params->wep_key[i],
    2916             :                                            params->wep_key_len[i]);
    2917          30 :                 if (params->wep_tx_keyidx != i)
    2918           6 :                         continue;
    2919          24 :                 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
    2920             :                                params->wep_key[i], params->wep_key_len[i]))
    2921           0 :                         goto fail;
    2922             :         }
    2923             : 
    2924        3370 :         if (params->bssid) {
    2925       20220 :                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
    2926       20220 :                            MAC2STR(params->bssid));
    2927        3370 :                 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
    2928           0 :                         goto fail;
    2929             :         }
    2930        3370 :         if (params->freq) {
    2931        3370 :                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
    2932        3370 :                 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq))
    2933           0 :                         goto fail;
    2934             :         }
    2935        3370 :         if (params->ssid) {
    2936        6740 :                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
    2937        3370 :                                   params->ssid, params->ssid_len);
    2938        3370 :                 if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
    2939        3370 :                             params->ssid))
    2940           0 :                         goto fail;
    2941             :         }
    2942        3370 :         wpa_hexdump(MSG_DEBUG, "  * IEs", params->ie, params->ie_len);
    2943        3497 :         if (params->ie &&
    2944         127 :             nla_put(msg, NL80211_ATTR_IE, params->ie_len, params->ie))
    2945           0 :                 goto fail;
    2946        3370 :         if (params->sae_data) {
    2947         153 :                 wpa_hexdump(MSG_DEBUG, "  * SAE data", params->sae_data,
    2948             :                             params->sae_data_len);
    2949         153 :                 if (nla_put(msg, NL80211_ATTR_SAE_DATA, params->sae_data_len,
    2950         153 :                             params->sae_data))
    2951           0 :                         goto fail;
    2952             :         }
    2953        3370 :         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
    2954        2849 :                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
    2955         521 :         else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
    2956          12 :                 type = NL80211_AUTHTYPE_SHARED_KEY;
    2957         509 :         else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
    2958           3 :                 type = NL80211_AUTHTYPE_NETWORK_EAP;
    2959         506 :         else if (params->auth_alg & WPA_AUTH_ALG_FT)
    2960         353 :                 type = NL80211_AUTHTYPE_FT;
    2961         153 :         else if (params->auth_alg & WPA_AUTH_ALG_SAE)
    2962         153 :                 type = NL80211_AUTHTYPE_SAE;
    2963             :         else
    2964           0 :                 goto fail;
    2965        3370 :         wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
    2966        3370 :         if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
    2967           0 :                 goto fail;
    2968        3370 :         if (params->local_state_change) {
    2969         226 :                 wpa_printf(MSG_DEBUG, "  * Local state change only");
    2970         226 :                 if (nla_put_flag(msg, NL80211_ATTR_LOCAL_STATE_CHANGE))
    2971           0 :                         goto fail;
    2972             :         }
    2973             : 
    2974        3370 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    2975        3370 :         msg = NULL;
    2976        3370 :         if (ret) {
    2977          54 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    2978             :                         "nl80211: MLME command failed (auth): ret=%d (%s)",
    2979             :                         ret, strerror(-ret));
    2980          54 :                 count++;
    2981          98 :                 if (ret == -EALREADY && count == 1 && params->bssid &&
    2982          44 :                     !params->local_state_change) {
    2983             :                         /*
    2984             :                          * mac80211 does not currently accept new
    2985             :                          * authentication if we are already authenticated. As a
    2986             :                          * workaround, force deauthentication and try again.
    2987             :                          */
    2988          44 :                         wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
    2989             :                                    "after forced deauthentication");
    2990          44 :                         drv->ignore_deauth_event = 1;
    2991          44 :                         wpa_driver_nl80211_deauthenticate(
    2992             :                                 bss, params->bssid,
    2993             :                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
    2994          44 :                         nlmsg_free(msg);
    2995          44 :                         goto retry;
    2996             :                 }
    2997             : 
    2998          16 :                 if (ret == -ENOENT && params->freq && !is_retry) {
    2999             :                         /*
    3000             :                          * cfg80211 has likely expired the BSS entry even
    3001             :                          * though it was previously available in our internal
    3002             :                          * BSS table. To recover quickly, start a single
    3003             :                          * channel scan on the specified channel.
    3004             :                          */
    3005             :                         struct wpa_driver_scan_params scan;
    3006             :                         int freqs[2];
    3007             : 
    3008           6 :                         os_memset(&scan, 0, sizeof(scan));
    3009           6 :                         scan.num_ssids = 1;
    3010           6 :                         if (params->ssid) {
    3011           6 :                                 scan.ssids[0].ssid = params->ssid;
    3012           6 :                                 scan.ssids[0].ssid_len = params->ssid_len;
    3013             :                         }
    3014           6 :                         freqs[0] = params->freq;
    3015           6 :                         freqs[1] = 0;
    3016           6 :                         scan.freqs = freqs;
    3017           6 :                         wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
    3018             :                                    "channel scan to refresh cfg80211 BSS "
    3019             :                                    "entry");
    3020           6 :                         ret = wpa_driver_nl80211_scan(bss, &scan);
    3021           6 :                         if (ret == 0) {
    3022           6 :                                 nl80211_copy_auth_params(drv, params);
    3023           6 :                                 drv->scan_for_auth = 1;
    3024             :                         }
    3025           4 :                 } else if (is_retry) {
    3026             :                         /*
    3027             :                          * Need to indicate this with an event since the return
    3028             :                          * value from the retry is not delivered to core code.
    3029             :                          */
    3030             :                         union wpa_event_data event;
    3031           4 :                         wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
    3032             :                                    "failed");
    3033           4 :                         os_memset(&event, 0, sizeof(event));
    3034           4 :                         os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
    3035             :                                   ETH_ALEN);
    3036           4 :                         wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
    3037             :                                              &event);
    3038             :                 }
    3039             :         } else {
    3040        3316 :                 wpa_printf(MSG_DEBUG,
    3041             :                            "nl80211: Authentication request send successfully");
    3042             :         }
    3043             : 
    3044             : fail:
    3045        3326 :         nlmsg_free(msg);
    3046        3326 :         return ret;
    3047             : }
    3048             : 
    3049             : 
    3050           6 : int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
    3051             : {
    3052             :         struct wpa_driver_auth_params params;
    3053           6 :         struct i802_bss *bss = drv->first_bss;
    3054             :         int i;
    3055             : 
    3056           6 :         wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
    3057             : 
    3058           6 :         os_memset(&params, 0, sizeof(params));
    3059           6 :         params.freq = drv->auth_freq;
    3060           6 :         params.auth_alg = drv->auth_alg;
    3061           6 :         params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
    3062           6 :         params.local_state_change = drv->auth_local_state_change;
    3063           6 :         params.p2p = drv->auth_p2p;
    3064             : 
    3065           6 :         if (!is_zero_ether_addr(drv->auth_bssid_))
    3066           6 :                 params.bssid = drv->auth_bssid_;
    3067             : 
    3068           6 :         if (drv->auth_ssid_len) {
    3069           6 :                 params.ssid = drv->auth_ssid;
    3070           6 :                 params.ssid_len = drv->auth_ssid_len;
    3071             :         }
    3072             : 
    3073           6 :         params.ie = drv->auth_ie;
    3074           6 :         params.ie_len = drv->auth_ie_len;
    3075             : 
    3076          30 :         for (i = 0; i < 4; i++) {
    3077          24 :                 if (drv->auth_wep_key_len[i]) {
    3078           1 :                         params.wep_key[i] = drv->auth_wep_key[i];
    3079           1 :                         params.wep_key_len[i] = drv->auth_wep_key_len[i];
    3080             :                 }
    3081             :         }
    3082             : 
    3083           6 :         drv->retry_auth = 1;
    3084           6 :         return wpa_driver_nl80211_authenticate(bss, &params);
    3085             : }
    3086             : 
    3087             : 
    3088       16653 : static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
    3089             :                                          const void *data, size_t len,
    3090             :                                          int encrypt, int noack,
    3091             :                                          unsigned int freq, int no_cck,
    3092             :                                          int offchanok, unsigned int wait_time)
    3093             : {
    3094       16653 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3095             :         u64 cookie;
    3096             :         int res;
    3097             : 
    3098       16653 :         if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
    3099          26 :                 freq = nl80211_get_assoc_freq(drv);
    3100          26 :                 wpa_printf(MSG_DEBUG,
    3101             :                            "nl80211: send_frame - Use assoc_freq=%u for IBSS",
    3102             :                            freq);
    3103             :         }
    3104       16653 :         if (freq == 0) {
    3105       15937 :                 wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
    3106             :                            bss->freq);
    3107       15937 :                 freq = bss->freq;
    3108             :         }
    3109             : 
    3110       16653 :         if (drv->use_monitor) {
    3111         102 :                 wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
    3112             :                            freq, bss->freq);
    3113         102 :                 return nl80211_send_monitor(drv, data, len, encrypt, noack);
    3114             :         }
    3115             : 
    3116       16551 :         wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
    3117       16551 :         res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
    3118             :                                      &cookie, no_cck, noack, offchanok);
    3119       16551 :         if (res == 0 && !noack) {
    3120             :                 const struct ieee80211_mgmt *mgmt;
    3121             :                 u16 fc;
    3122             : 
    3123       11241 :                 mgmt = (const struct ieee80211_mgmt *) data;
    3124       11241 :                 fc = le_to_host16(mgmt->frame_control);
    3125       22482 :                 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    3126       11241 :                     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
    3127        2264 :                         wpa_printf(MSG_MSGDUMP,
    3128             :                                    "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
    3129             :                                    (long long unsigned int)
    3130        1132 :                                    drv->send_action_cookie,
    3131             :                                    (long long unsigned int) cookie);
    3132        1132 :                         drv->send_action_cookie = cookie;
    3133             :                 }
    3134             :         }
    3135             : 
    3136       16551 :         return res;
    3137             : }
    3138             : 
    3139             : 
    3140       17316 : static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
    3141             :                                         size_t data_len, int noack,
    3142             :                                         unsigned int freq, int no_cck,
    3143             :                                         int offchanok,
    3144             :                                         unsigned int wait_time)
    3145             : {
    3146       17316 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3147             :         struct ieee80211_mgmt *mgmt;
    3148       17316 :         int encrypt = 1;
    3149             :         u16 fc;
    3150             : 
    3151       17316 :         mgmt = (struct ieee80211_mgmt *) data;
    3152       17316 :         fc = le_to_host16(mgmt->frame_control);
    3153      121212 :         wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
    3154             :                    " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x (%s) nlmode=%d",
    3155      103896 :                    MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
    3156       17316 :                    fc, fc2str(fc), drv->nlmode);
    3157             : 
    3158       33865 :         if ((is_sta_interface(drv->nlmode) ||
    3159       17320 :              drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
    3160        1542 :             WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    3161         771 :             WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
    3162             :                 /*
    3163             :                  * The use of last_mgmt_freq is a bit of a hack,
    3164             :                  * but it works due to the single-threaded nature
    3165             :                  * of wpa_supplicant.
    3166             :                  */
    3167         740 :                 if (freq == 0) {
    3168           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
    3169             :                                    drv->last_mgmt_freq);
    3170           0 :                         freq = drv->last_mgmt_freq;
    3171             :                 }
    3172         740 :                 return nl80211_send_frame_cmd(bss, freq, 0,
    3173             :                                               data, data_len, NULL, 1, noack,
    3174             :                                               1);
    3175             :         }
    3176             : 
    3177       16576 :         if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
    3178           0 :                 if (freq == 0) {
    3179           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
    3180             :                                    bss->freq);
    3181           0 :                         freq = bss->freq;
    3182             :                 }
    3183           0 :                 return nl80211_send_frame_cmd(bss, freq,
    3184           0 :                                               (int) freq == bss->freq ? 0 :
    3185             :                                               wait_time,
    3186             :                                               data, data_len,
    3187             :                                               &drv->send_action_cookie,
    3188             :                                               no_cck, noack, offchanok);
    3189             :         }
    3190             : 
    3191       33152 :         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    3192       16576 :             WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
    3193             :                 /*
    3194             :                  * Only one of the authentication frame types is encrypted.
    3195             :                  * In order for static WEP encryption to work properly (i.e.,
    3196             :                  * to not encrypt the frame), we need to tell mac80211 about
    3197             :                  * the frames that must not be encrypted.
    3198             :                  */
    3199        3659 :                 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
    3200        3659 :                 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
    3201        3659 :                 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
    3202        3659 :                         encrypt = 0;
    3203             :         }
    3204             : 
    3205       16576 :         wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
    3206       16576 :         return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
    3207             :                                              noack, freq, no_cck, offchanok,
    3208             :                                              wait_time);
    3209             : }
    3210             : 
    3211             : 
    3212        4412 : static int nl80211_put_basic_rates(struct nl_msg *msg, const int *basic_rates)
    3213             : {
    3214             :         u8 rates[NL80211_MAX_SUPP_RATES];
    3215        4412 :         u8 rates_len = 0;
    3216             :         int i;
    3217             : 
    3218        4412 :         if (!basic_rates)
    3219           0 :                 return 0;
    3220             : 
    3221       20042 :         for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
    3222       15630 :                 rates[rates_len++] = basic_rates[i] / 5;
    3223             : 
    3224        4412 :         return nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
    3225             : }
    3226             : 
    3227             : 
    3228        4379 : static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
    3229             :                            int slot, int ht_opmode, int ap_isolate,
    3230             :                            const int *basic_rates)
    3231             : {
    3232        4379 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3233             :         struct nl_msg *msg;
    3234             : 
    3235        4379 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_BSS)) ||
    3236        4379 :             (cts >= 0 &&
    3237        8758 :              nla_put_u8(msg, NL80211_ATTR_BSS_CTS_PROT, cts)) ||
    3238        4379 :             (preamble >= 0 &&
    3239        8758 :              nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble)) ||
    3240        3840 :             (slot >= 0 &&
    3241        8219 :              nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot)) ||
    3242        4259 :             (ht_opmode >= 0 &&
    3243        8638 :              nla_put_u16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode)) ||
    3244        4379 :             (ap_isolate >= 0 &&
    3245        8758 :              nla_put_u8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate)) ||
    3246        4379 :             nl80211_put_basic_rates(msg, basic_rates)) {
    3247           0 :                 nlmsg_free(msg);
    3248           0 :                 return -ENOBUFS;
    3249             :         }
    3250             : 
    3251        4379 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    3252             : }
    3253             : 
    3254             : 
    3255           0 : static int wpa_driver_nl80211_set_acl(void *priv,
    3256             :                                       struct hostapd_acl_params *params)
    3257             : {
    3258           0 :         struct i802_bss *bss = priv;
    3259           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3260             :         struct nl_msg *msg;
    3261             :         struct nl_msg *acl;
    3262             :         unsigned int i;
    3263             :         int ret;
    3264             : 
    3265           0 :         if (!(drv->capa.max_acl_mac_addrs))
    3266           0 :                 return -ENOTSUP;
    3267             : 
    3268           0 :         if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
    3269           0 :                 return -ENOTSUP;
    3270             : 
    3271           0 :         wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
    3272           0 :                    params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
    3273             : 
    3274           0 :         acl = nlmsg_alloc();
    3275           0 :         if (!acl)
    3276           0 :                 return -ENOMEM;
    3277           0 :         for (i = 0; i < params->num_mac_acl; i++) {
    3278           0 :                 if (nla_put(acl, i + 1, ETH_ALEN, params->mac_acl[i].addr)) {
    3279           0 :                         nlmsg_free(acl);
    3280           0 :                         return -ENOMEM;
    3281             :                 }
    3282             :         }
    3283             : 
    3284           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_MAC_ACL)) ||
    3285           0 :             nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
    3286             :                         NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
    3287           0 :                         NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) ||
    3288           0 :             nla_put_nested(msg, NL80211_ATTR_MAC_ADDRS, acl)) {
    3289           0 :                 nlmsg_free(msg);
    3290           0 :                 nlmsg_free(acl);
    3291           0 :                 return -ENOMEM;
    3292             :         }
    3293           0 :         nlmsg_free(acl);
    3294             : 
    3295           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    3296           0 :         if (ret) {
    3297           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
    3298             :                            ret, strerror(-ret));
    3299             :         }
    3300             : 
    3301           0 :         return ret;
    3302             : }
    3303             : 
    3304             : 
    3305        4497 : static int nl80211_put_beacon_int(struct nl_msg *msg, int beacon_int)
    3306             : {
    3307        4497 :         if (beacon_int > 0) {
    3308        4453 :                 wpa_printf(MSG_DEBUG, "  * beacon_int=%d", beacon_int);
    3309        4453 :                 return nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL,
    3310             :                                    beacon_int);
    3311             :         }
    3312             : 
    3313          44 :         return 0;
    3314             : }
    3315             : 
    3316             : 
    3317        4442 : static int wpa_driver_nl80211_set_ap(void *priv,
    3318             :                                      struct wpa_driver_ap_params *params)
    3319             : {
    3320        4442 :         struct i802_bss *bss = priv;
    3321        4442 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3322             :         struct nl_msg *msg;
    3323        4442 :         u8 cmd = NL80211_CMD_NEW_BEACON;
    3324             :         int ret;
    3325             :         int beacon_set;
    3326             :         int num_suites;
    3327             :         int smps_mode;
    3328             :         u32 suites[10], suite;
    3329             :         u32 ver;
    3330             : 
    3331        4442 :         beacon_set = params->reenable ? 0 : bss->beacon_set;
    3332             : 
    3333        4442 :         wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
    3334             :                    beacon_set);
    3335        4442 :         if (beacon_set)
    3336        2381 :                 cmd = NL80211_CMD_SET_BEACON;
    3337             : 
    3338        8884 :         wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
    3339        4442 :                     params->head, params->head_len);
    3340        8884 :         wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
    3341        4442 :                     params->tail, params->tail_len);
    3342        4442 :         wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", bss->ifindex);
    3343        4442 :         wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
    3344        4442 :         wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
    3345        8884 :         wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
    3346        4442 :                           params->ssid, params->ssid_len);
    3347        8884 :         if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
    3348        4442 :             nla_put(msg, NL80211_ATTR_BEACON_HEAD, params->head_len,
    3349        8884 :                     params->head) ||
    3350        4442 :             nla_put(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len,
    3351        8884 :                     params->tail) ||
    3352        8884 :             nl80211_put_beacon_int(msg, params->beacon_int) ||
    3353        8884 :             nla_put_u32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period) ||
    3354        4442 :             nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
    3355             :                 goto fail;
    3356        4442 :         if (params->proberesp && params->proberesp_len) {
    3357           0 :                 wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
    3358           0 :                             params->proberesp, params->proberesp_len);
    3359           0 :                 if (nla_put(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
    3360           0 :                             params->proberesp))
    3361           0 :                         goto fail;
    3362             :         }
    3363        4442 :         switch (params->hide_ssid) {
    3364             :         case NO_SSID_HIDING:
    3365        4432 :                 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
    3366        4432 :                 if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
    3367             :                                 NL80211_HIDDEN_SSID_NOT_IN_USE))
    3368           0 :                         goto fail;
    3369        4432 :                 break;
    3370             :         case HIDDEN_SSID_ZERO_LEN:
    3371           9 :                 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
    3372           9 :                 if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
    3373             :                                 NL80211_HIDDEN_SSID_ZERO_LEN))
    3374           0 :                         goto fail;
    3375           9 :                 break;
    3376             :         case HIDDEN_SSID_ZERO_CONTENTS:
    3377           1 :                 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
    3378           1 :                 if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
    3379             :                                 NL80211_HIDDEN_SSID_ZERO_CONTENTS))
    3380           0 :                         goto fail;
    3381           1 :                 break;
    3382             :         }
    3383        4442 :         wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
    3384        7514 :         if (params->privacy &&
    3385        3072 :             nla_put_flag(msg, NL80211_ATTR_PRIVACY))
    3386           0 :                 goto fail;
    3387        4442 :         wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
    3388        4442 :         if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
    3389             :             (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
    3390             :                 /* Leave out the attribute */
    3391        1685 :         } else if (params->auth_algs & WPA_AUTH_ALG_SHARED) {
    3392          22 :                 if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE,
    3393             :                                 NL80211_AUTHTYPE_SHARED_KEY))
    3394           0 :                         goto fail;
    3395             :         } else {
    3396        1663 :                 if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE,
    3397             :                                 NL80211_AUTHTYPE_OPEN_SYSTEM))
    3398           0 :                         goto fail;
    3399             :         }
    3400             : 
    3401        4442 :         wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
    3402        4442 :         ver = 0;
    3403        4442 :         if (params->wpa_version & WPA_PROTO_WPA)
    3404         138 :                 ver |= NL80211_WPA_VERSION_1;
    3405        4442 :         if (params->wpa_version & WPA_PROTO_RSN)
    3406        2983 :                 ver |= NL80211_WPA_VERSION_2;
    3407        7469 :         if (ver &&
    3408        3027 :             nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
    3409           0 :                 goto fail;
    3410             : 
    3411        4442 :         wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
    3412             :                    params->key_mgmt_suites);
    3413        4442 :         num_suites = 0;
    3414        4442 :         if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
    3415         458 :                 suites[num_suites++] = WLAN_AKM_SUITE_8021X;
    3416        4442 :         if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
    3417        2514 :                 suites[num_suites++] = WLAN_AKM_SUITE_PSK;
    3418        7394 :         if (num_suites &&
    3419        2952 :             nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32),
    3420             :                     suites))
    3421           0 :                 goto fail;
    3422             : 
    3423        4456 :         if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
    3424          14 :             params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40) &&
    3425           0 :             nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))
    3426           0 :                 goto fail;
    3427             : 
    3428        4442 :         wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
    3429             :                    params->pairwise_ciphers);
    3430        4442 :         num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
    3431             :                                                  suites, ARRAY_SIZE(suites));
    3432        7469 :         if (num_suites &&
    3433        3027 :             nla_put(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
    3434             :                     num_suites * sizeof(u32), suites))
    3435           0 :                 goto fail;
    3436             : 
    3437        4442 :         wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
    3438             :                    params->group_cipher);
    3439        4442 :         suite = wpa_cipher_to_cipher_suite(params->group_cipher);
    3440        7558 :         if (suite &&
    3441        3116 :             nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
    3442           0 :                 goto fail;
    3443             : 
    3444        4442 :         switch (params->smps_mode) {
    3445             :         case HT_CAP_INFO_SMPS_DYNAMIC:
    3446           1 :                 wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - dynamic");
    3447           1 :                 smps_mode = NL80211_SMPS_DYNAMIC;
    3448           1 :                 break;
    3449             :         case HT_CAP_INFO_SMPS_STATIC:
    3450           1 :                 wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - static");
    3451           1 :                 smps_mode = NL80211_SMPS_STATIC;
    3452           1 :                 break;
    3453             :         default:
    3454             :                 /* invalid - fallback to smps off */
    3455             :         case HT_CAP_INFO_SMPS_DISABLED:
    3456        4440 :                 wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - off");
    3457        4440 :                 smps_mode = NL80211_SMPS_OFF;
    3458        4440 :                 break;
    3459             :         }
    3460        4442 :         if (nla_put_u32(msg, NL80211_ATTR_SMPS_MODE, smps_mode))
    3461           0 :                 goto fail;
    3462             : 
    3463        4442 :         if (params->beacon_ies) {
    3464        4442 :                 wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
    3465             :                                 params->beacon_ies);
    3466        8884 :                 if (nla_put(msg, NL80211_ATTR_IE,
    3467        4442 :                             wpabuf_len(params->beacon_ies),
    3468             :                             wpabuf_head(params->beacon_ies)))
    3469           0 :                         goto fail;
    3470             :         }
    3471        4442 :         if (params->proberesp_ies) {
    3472        4442 :                 wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
    3473             :                                 params->proberesp_ies);
    3474        8884 :                 if (nla_put(msg, NL80211_ATTR_IE_PROBE_RESP,
    3475        4442 :                             wpabuf_len(params->proberesp_ies),
    3476             :                             wpabuf_head(params->proberesp_ies)))
    3477           0 :                         goto fail;
    3478             :         }
    3479        4442 :         if (params->assocresp_ies) {
    3480        4442 :                 wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
    3481             :                                 params->assocresp_ies);
    3482        8884 :                 if (nla_put(msg, NL80211_ATTR_IE_ASSOC_RESP,
    3483        4442 :                             wpabuf_len(params->assocresp_ies),
    3484             :                             wpabuf_head(params->assocresp_ies)))
    3485           0 :                         goto fail;
    3486             :         }
    3487             : 
    3488        4442 :         if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)  {
    3489           0 :                 wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
    3490             :                            params->ap_max_inactivity);
    3491           0 :                 if (nla_put_u16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
    3492           0 :                                 params->ap_max_inactivity))
    3493           0 :                         goto fail;
    3494             :         }
    3495             : 
    3496             : #ifdef CONFIG_P2P
    3497        1694 :         if (params->p2p_go_ctwindow > 0) {
    3498           0 :                 if (drv->p2p_go_ctwindow_supported) {
    3499           0 :                         wpa_printf(MSG_DEBUG, "nl80211: P2P GO ctwindow=%d",
    3500           0 :                                    params->p2p_go_ctwindow);
    3501           0 :                         if (nla_put_u8(msg, NL80211_ATTR_P2P_CTWINDOW,
    3502           0 :                                        params->p2p_go_ctwindow))
    3503           0 :                                 goto fail;
    3504             :                 } else {
    3505           0 :                         wpa_printf(MSG_INFO,
    3506             :                                    "nl80211: Driver does not support CTWindow configuration - ignore this parameter");
    3507             :                 }
    3508             :         }
    3509             : #endif /* CONFIG_P2P */
    3510             : 
    3511        4442 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    3512        4442 :         if (ret) {
    3513          63 :                 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
    3514             :                            ret, strerror(-ret));
    3515             :         } else {
    3516        4379 :                 bss->beacon_set = 1;
    3517        4379 :                 nl80211_set_bss(bss, params->cts_protect, params->preamble,
    3518             :                                 params->short_slot_time, params->ht_opmode,
    3519        4379 :                                 params->isolate, params->basic_rates);
    3520        6760 :                 if (beacon_set && params->freq &&
    3521        2381 :                     params->freq->bandwidth != bss->bandwidth) {
    3522          16 :                         wpa_printf(MSG_DEBUG,
    3523             :                                    "nl80211: Update BSS %s bandwidth: %d -> %d",
    3524           8 :                                    bss->ifname, bss->bandwidth,
    3525           8 :                                    params->freq->bandwidth);
    3526           8 :                         ret = nl80211_set_channel(bss, params->freq, 1);
    3527          16 :                         if (ret) {
    3528           0 :                                 wpa_printf(MSG_DEBUG,
    3529             :                                            "nl80211: Frequency set failed: %d (%s)",
    3530             :                                            ret, strerror(-ret));
    3531             :                         } else {
    3532           8 :                                 wpa_printf(MSG_DEBUG,
    3533             :                                            "nl80211: Frequency set succeeded for ht2040 coex");
    3534           8 :                                 bss->bandwidth = params->freq->bandwidth;
    3535             :                         }
    3536        4371 :                 } else if (!beacon_set) {
    3537             :                         /*
    3538             :                          * cfg80211 updates the driver on frequence change in AP
    3539             :                          * mode only at the point when beaconing is started, so
    3540             :                          * set the initial value here.
    3541             :                          */
    3542        1998 :                         bss->bandwidth = params->freq->bandwidth;
    3543             :                 }
    3544             :         }
    3545        4442 :         return ret;
    3546             : fail:
    3547           0 :         nlmsg_free(msg);
    3548           0 :         return -ENOBUFS;
    3549             : }
    3550             : 
    3551             : 
    3552        2403 : static int nl80211_put_freq_params(struct nl_msg *msg,
    3553             :                                    const struct hostapd_freq_params *freq)
    3554             : {
    3555        2403 :         wpa_printf(MSG_DEBUG, "  * freq=%d", freq->freq);
    3556        2403 :         if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq))
    3557           0 :                 return -ENOBUFS;
    3558             : 
    3559        2403 :         wpa_printf(MSG_DEBUG, "  * vht_enabled=%d", freq->vht_enabled);
    3560        2403 :         wpa_printf(MSG_DEBUG, "  * ht_enabled=%d", freq->ht_enabled);
    3561             : 
    3562        2403 :         if (freq->vht_enabled) {
    3563             :                 enum nl80211_chan_width cw;
    3564             : 
    3565          26 :                 wpa_printf(MSG_DEBUG, "  * bandwidth=%d", freq->bandwidth);
    3566          26 :                 switch (freq->bandwidth) {
    3567             :                 case 20:
    3568           4 :                         cw = NL80211_CHAN_WIDTH_20;
    3569           4 :                         break;
    3570             :                 case 40:
    3571           2 :                         cw = NL80211_CHAN_WIDTH_40;
    3572           2 :                         break;
    3573             :                 case 80:
    3574          15 :                         if (freq->center_freq2)
    3575           2 :                                 cw = NL80211_CHAN_WIDTH_80P80;
    3576             :                         else
    3577          13 :                                 cw = NL80211_CHAN_WIDTH_80;
    3578          15 :                         break;
    3579             :                 case 160:
    3580           4 :                         cw = NL80211_CHAN_WIDTH_160;
    3581           4 :                         break;
    3582             :                 default:
    3583           1 :                         return -EINVAL;
    3584             :                 }
    3585             : 
    3586          25 :                 wpa_printf(MSG_DEBUG, "  * channel_width=%d", cw);
    3587          25 :                 wpa_printf(MSG_DEBUG, "  * center_freq1=%d",
    3588             :                            freq->center_freq1);
    3589          25 :                 wpa_printf(MSG_DEBUG, "  * center_freq2=%d",
    3590             :                            freq->center_freq2);
    3591          50 :                 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw) ||
    3592          25 :                     nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1,
    3593          50 :                                 freq->center_freq1) ||
    3594          27 :                     (freq->center_freq2 &&
    3595           2 :                      nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2,
    3596           2 :                                  freq->center_freq2)))
    3597           0 :                         return -ENOBUFS;
    3598        2377 :         } else if (freq->ht_enabled) {
    3599             :                 enum nl80211_channel_type ct;
    3600             : 
    3601        2001 :                 wpa_printf(MSG_DEBUG, "  * sec_channel_offset=%d",
    3602             :                            freq->sec_channel_offset);
    3603        2001 :                 switch (freq->sec_channel_offset) {
    3604             :                 case -1:
    3605          16 :                         ct = NL80211_CHAN_HT40MINUS;
    3606          16 :                         break;
    3607             :                 case 1:
    3608          32 :                         ct = NL80211_CHAN_HT40PLUS;
    3609          32 :                         break;
    3610             :                 default:
    3611        1953 :                         ct = NL80211_CHAN_HT20;
    3612        1953 :                         break;
    3613             :                 }
    3614             : 
    3615        2001 :                 wpa_printf(MSG_DEBUG, "  * channel_type=%d", ct);
    3616        2001 :                 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ct))
    3617           0 :                         return -ENOBUFS;
    3618             :         }
    3619        2402 :         return 0;
    3620             : }
    3621             : 
    3622             : 
    3623        2311 : static int nl80211_set_channel(struct i802_bss *bss,
    3624             :                                struct hostapd_freq_params *freq, int set_chan)
    3625             : {
    3626        2311 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3627             :         struct nl_msg *msg;
    3628             :         int ret;
    3629             : 
    3630        2311 :         wpa_printf(MSG_DEBUG,
    3631             :                    "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
    3632             :                    freq->freq, freq->ht_enabled, freq->vht_enabled,
    3633             :                    freq->bandwidth, freq->center_freq1, freq->center_freq2);
    3634             : 
    3635        2311 :         msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
    3636             :                               NL80211_CMD_SET_WIPHY);
    3637        2311 :         if (!msg || nl80211_put_freq_params(msg, freq) < 0) {
    3638           0 :                 nlmsg_free(msg);
    3639           0 :                 return -1;
    3640             :         }
    3641             : 
    3642        2311 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    3643        2311 :         if (ret == 0) {
    3644        2310 :                 bss->freq = freq->freq;
    3645        2310 :                 return 0;
    3646             :         }
    3647           1 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
    3648             :                    "%d (%s)", freq->freq, ret, strerror(-ret));
    3649           1 :         return -1;
    3650             : }
    3651             : 
    3652             : 
    3653       24212 : static u32 sta_flags_nl80211(int flags)
    3654             : {
    3655       24212 :         u32 f = 0;
    3656             : 
    3657       24212 :         if (flags & WPA_STA_AUTHORIZED)
    3658        9537 :                 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
    3659       24212 :         if (flags & WPA_STA_WMM)
    3660       10037 :                 f |= BIT(NL80211_STA_FLAG_WME);
    3661       24212 :         if (flags & WPA_STA_SHORT_PREAMBLE)
    3662        9560 :                 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
    3663       24212 :         if (flags & WPA_STA_MFP)
    3664        3446 :                 f |= BIT(NL80211_STA_FLAG_MFP);
    3665       24212 :         if (flags & WPA_STA_TDLS_PEER)
    3666         111 :                 f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
    3667       24212 :         if (flags & WPA_STA_AUTHENTICATED)
    3668          98 :                 f |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
    3669             : 
    3670       24212 :         return f;
    3671             : }
    3672             : 
    3673             : 
    3674             : #ifdef CONFIG_MESH
    3675         208 : static u32 sta_plink_state_nl80211(enum mesh_plink_state state)
    3676             : {
    3677         208 :         switch (state) {
    3678             :         case PLINK_LISTEN:
    3679          54 :                 return NL80211_PLINK_LISTEN;
    3680             :         case PLINK_OPEN_SENT:
    3681          42 :                 return NL80211_PLINK_OPN_SNT;
    3682             :         case PLINK_OPEN_RCVD:
    3683          31 :                 return NL80211_PLINK_OPN_RCVD;
    3684             :         case PLINK_CNF_RCVD:
    3685           0 :                 return NL80211_PLINK_CNF_RCVD;
    3686             :         case PLINK_ESTAB:
    3687          26 :                 return NL80211_PLINK_ESTAB;
    3688             :         case PLINK_HOLDING:
    3689          53 :                 return NL80211_PLINK_HOLDING;
    3690             :         case PLINK_BLOCKED:
    3691           2 :                 return NL80211_PLINK_BLOCKED;
    3692             :         default:
    3693           0 :                 wpa_printf(MSG_ERROR, "nl80211: Invalid mesh plink state %d",
    3694             :                            state);
    3695             :         }
    3696           0 :         return -1;
    3697             : }
    3698             : #endif /* CONFIG_MESH */
    3699             : 
    3700             : 
    3701        3633 : static int wpa_driver_nl80211_sta_add(void *priv,
    3702             :                                       struct hostapd_sta_add_params *params)
    3703             : {
    3704        3633 :         struct i802_bss *bss = priv;
    3705        3633 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3706             :         struct nl_msg *msg;
    3707             :         struct nl80211_sta_flag_update upd;
    3708        3633 :         int ret = -ENOBUFS;
    3709             : 
    3710        3744 :         if ((params->flags & WPA_STA_TDLS_PEER) &&
    3711         111 :             !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
    3712           0 :                 return -EOPNOTSUPP;
    3713             : 
    3714       25431 :         wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
    3715       25431 :                    params->set ? "Set" : "Add", MAC2STR(params->addr));
    3716        3633 :         msg = nl80211_bss_msg(bss, 0, params->set ? NL80211_CMD_SET_STATION :
    3717             :                               NL80211_CMD_NEW_STATION);
    3718        3633 :         if (!msg || nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr))
    3719             :                 goto fail;
    3720             : 
    3721        3633 :         if (!params->set || (params->flags & WPA_STA_TDLS_PEER)) {
    3722        6942 :                 wpa_hexdump(MSG_DEBUG, "  * supported rates",
    3723        3471 :                             params->supp_rates, params->supp_rates_len);
    3724        3471 :                 wpa_printf(MSG_DEBUG, "  * capability=0x%x",
    3725        3471 :                            params->capability);
    3726        3471 :                 if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_RATES,
    3727        6942 :                             params->supp_rates_len, params->supp_rates) ||
    3728        3471 :                     nla_put_u16(msg, NL80211_ATTR_STA_CAPABILITY,
    3729        3471 :                                 params->capability))
    3730             :                         goto fail;
    3731             : 
    3732        3471 :                 if (params->ht_capabilities) {
    3733        3335 :                         wpa_hexdump(MSG_DEBUG, "  * ht_capabilities",
    3734        3335 :                                     (u8 *) params->ht_capabilities,
    3735             :                                     sizeof(*params->ht_capabilities));
    3736        3335 :                         if (nla_put(msg, NL80211_ATTR_HT_CAPABILITY,
    3737             :                                     sizeof(*params->ht_capabilities),
    3738        3335 :                                     params->ht_capabilities))
    3739           0 :                                 goto fail;
    3740             :                 }
    3741             : 
    3742        3471 :                 if (params->vht_capabilities) {
    3743          24 :                         wpa_hexdump(MSG_DEBUG, "  * vht_capabilities",
    3744          24 :                                     (u8 *) params->vht_capabilities,
    3745             :                                     sizeof(*params->vht_capabilities));
    3746          24 :                         if (nla_put(msg, NL80211_ATTR_VHT_CAPABILITY,
    3747             :                                     sizeof(*params->vht_capabilities),
    3748          24 :                                     params->vht_capabilities))
    3749           0 :                                 goto fail;
    3750             :                 }
    3751             : 
    3752        3471 :                 if (params->ext_capab) {
    3753         158 :                         wpa_hexdump(MSG_DEBUG, "  * ext_capab",
    3754          79 :                                     params->ext_capab, params->ext_capab_len);
    3755          79 :                         if (nla_put(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
    3756          79 :                                     params->ext_capab_len, params->ext_capab))
    3757           0 :                                 goto fail;
    3758             :                 }
    3759             :         }
    3760        3633 :         if (!params->set) {
    3761        3420 :                 if (params->aid) {
    3762        3308 :                         wpa_printf(MSG_DEBUG, "  * aid=%u", params->aid);
    3763        3308 :                         if (nla_put_u16(msg, NL80211_ATTR_STA_AID, params->aid))
    3764           0 :                                 goto fail;
    3765             :                 } else {
    3766             :                         /*
    3767             :                          * cfg80211 validates that AID is non-zero, so we have
    3768             :                          * to make this a non-zero value for the TDLS case where
    3769             :                          * a dummy STA entry is used for now.
    3770             :                          */
    3771         112 :                         wpa_printf(MSG_DEBUG, "  * aid=1 (TDLS workaround)");
    3772         112 :                         if (nla_put_u16(msg, NL80211_ATTR_STA_AID, 1))
    3773           0 :                                 goto fail;
    3774             :                 }
    3775        3420 :                 wpa_printf(MSG_DEBUG, "  * listen_interval=%u",
    3776        3420 :                            params->listen_interval);
    3777        3420 :                 if (nla_put_u16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
    3778        3420 :                                 params->listen_interval))
    3779           0 :                         goto fail;
    3780         213 :         } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
    3781           4 :                 wpa_printf(MSG_DEBUG, "  * peer_aid=%u", params->aid);
    3782           4 :                 if (nla_put_u16(msg, NL80211_ATTR_PEER_AID, params->aid))
    3783           0 :                         goto fail;
    3784             :         }
    3785             : 
    3786        3633 :         if (params->vht_opmode_enabled) {
    3787           0 :                 wpa_printf(MSG_DEBUG, "  * opmode=%u", params->vht_opmode);
    3788           0 :                 if (nla_put_u8(msg, NL80211_ATTR_OPMODE_NOTIF,
    3789           0 :                                params->vht_opmode))
    3790           0 :                         goto fail;
    3791             :         }
    3792             : 
    3793        3633 :         if (params->supp_channels) {
    3794         158 :                 wpa_hexdump(MSG_DEBUG, "  * supported channels",
    3795          79 :                             params->supp_channels, params->supp_channels_len);
    3796          79 :                 if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
    3797          79 :                             params->supp_channels_len, params->supp_channels))
    3798           0 :                         goto fail;
    3799             :         }
    3800             : 
    3801        3633 :         if (params->supp_oper_classes) {
    3802         158 :                 wpa_hexdump(MSG_DEBUG, "  * supported operating classes",
    3803          79 :                             params->supp_oper_classes,
    3804             :                             params->supp_oper_classes_len);
    3805          79 :                 if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
    3806          79 :                             params->supp_oper_classes_len,
    3807          79 :                             params->supp_oper_classes))
    3808           0 :                         goto fail;
    3809             :         }
    3810             : 
    3811        3633 :         os_memset(&upd, 0, sizeof(upd));
    3812        3633 :         upd.set = sta_flags_nl80211(params->flags);
    3813        3633 :         upd.mask = upd.set | sta_flags_nl80211(params->flags_mask);
    3814        3633 :         wpa_printf(MSG_DEBUG, "  * flags set=0x%x mask=0x%x",
    3815             :                    upd.set, upd.mask);
    3816        3633 :         if (nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd))
    3817           0 :                 goto fail;
    3818             : 
    3819             : #ifdef CONFIG_MESH
    3820         970 :         if (params->plink_state &&
    3821         208 :             nla_put_u8(msg, NL80211_ATTR_STA_PLINK_STATE,
    3822         208 :                        sta_plink_state_nl80211(params->plink_state)))
    3823           0 :                 goto fail;
    3824             : #endif /* CONFIG_MESH */
    3825             : 
    3826        3633 :         if (params->flags & WPA_STA_WMM) {
    3827        3432 :                 struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
    3828             : 
    3829        3432 :                 wpa_printf(MSG_DEBUG, "  * qosinfo=0x%x", params->qosinfo);
    3830        6864 :                 if (!wme ||
    3831        3432 :                     nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
    3832        6864 :                                params->qosinfo & WMM_QOSINFO_STA_AC_MASK) ||
    3833        3432 :                     nla_put_u8(msg, NL80211_STA_WME_MAX_SP,
    3834        3432 :                                (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
    3835             :                                WMM_QOSINFO_STA_SP_MASK))
    3836             :                         goto fail;
    3837        3432 :                 nla_nest_end(msg, wme);
    3838             :         }
    3839             : 
    3840        3633 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    3841        3633 :         msg = NULL;
    3842        3633 :         if (ret)
    3843          24 :                 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
    3844          12 :                            "result: %d (%s)", params->set ? "SET" : "NEW", ret,
    3845             :                            strerror(-ret));
    3846        3633 :         if (ret == -EEXIST)
    3847          12 :                 ret = 0;
    3848             : fail:
    3849        3633 :         nlmsg_free(msg);
    3850        3633 :         return ret;
    3851             : }
    3852             : 
    3853             : 
    3854          52 : static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
    3855             : {
    3856             : #ifdef CONFIG_LIBNL3_ROUTE
    3857          52 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3858             :         struct rtnl_neigh *rn;
    3859             :         struct nl_addr *nl_addr;
    3860             :         int err;
    3861             : 
    3862          52 :         rn = rtnl_neigh_alloc();
    3863          52 :         if (!rn)
    3864           0 :                 return;
    3865             : 
    3866          52 :         rtnl_neigh_set_family(rn, AF_BRIDGE);
    3867          52 :         rtnl_neigh_set_ifindex(rn, bss->ifindex);
    3868          52 :         nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
    3869          52 :         if (!nl_addr) {
    3870           0 :                 rtnl_neigh_put(rn);
    3871           0 :                 return;
    3872             :         }
    3873          52 :         rtnl_neigh_set_lladdr(rn, nl_addr);
    3874             : 
    3875          52 :         err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
    3876          52 :         if (err < 0) {
    3877         245 :                 wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
    3878         210 :                            MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
    3879             :                            bss->ifindex, nl_geterror(err));
    3880             :         } else {
    3881         102 :                 wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry for "
    3882         102 :                            MACSTR, MAC2STR(addr));
    3883             :         }
    3884             : 
    3885          52 :         nl_addr_put(nl_addr);
    3886          52 :         rtnl_neigh_put(rn);
    3887             : #endif /* CONFIG_LIBNL3_ROUTE */
    3888           0 : }
    3889             : 
    3890             : 
    3891        6217 : static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr,
    3892             :                                          int deauth, u16 reason_code)
    3893             : {
    3894        6217 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3895             :         struct nl_msg *msg;
    3896             :         int ret;
    3897             : 
    3898       12434 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION)) ||
    3899       12434 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
    3900           0 :             (deauth == 0 &&
    3901           0 :              nla_put_u8(msg, NL80211_ATTR_MGMT_SUBTYPE,
    3902        6217 :                         WLAN_FC_STYPE_DISASSOC)) ||
    3903           0 :             (deauth == 1 &&
    3904           0 :              nla_put_u8(msg, NL80211_ATTR_MGMT_SUBTYPE,
    3905        6217 :                         WLAN_FC_STYPE_DEAUTH)) ||
    3906           0 :             (reason_code &&
    3907           0 :              nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) {
    3908           0 :                 nlmsg_free(msg);
    3909           0 :                 return -ENOBUFS;
    3910             :         }
    3911             : 
    3912        6217 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    3913       49736 :         wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
    3914             :                    " --> %d (%s)",
    3915       43519 :                    bss->ifname, MAC2STR(addr), ret, strerror(-ret));
    3916             : 
    3917        6217 :         if (drv->rtnl_sk)
    3918          52 :                 rtnl_neigh_delete_fdb_entry(bss, addr);
    3919             : 
    3920        6217 :         if (ret == -ENOENT)
    3921        3076 :                 return 0;
    3922        3141 :         return ret;
    3923             : }
    3924             : 
    3925             : 
    3926         223 : void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx)
    3927             : {
    3928             :         struct nl_msg *msg;
    3929             :         struct wpa_driver_nl80211_data *drv2;
    3930             : 
    3931         223 :         wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
    3932             : 
    3933             :         /* stop listening for EAPOL on this interface */
    3934        2526 :         dl_list_for_each(drv2, &drv->global->interfaces,
    3935             :                          struct wpa_driver_nl80211_data, list)
    3936        2303 :                 del_ifidx(drv2, ifidx);
    3937             : 
    3938         223 :         msg = nl80211_ifindex_msg(drv, ifidx, 0, NL80211_CMD_DEL_INTERFACE);
    3939         223 :         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
    3940         446 :                 return;
    3941           0 :         wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
    3942             : }
    3943             : 
    3944             : 
    3945        5971 : static const char * nl80211_iftype_str(enum nl80211_iftype mode)
    3946             : {
    3947        5971 :         switch (mode) {
    3948             :         case NL80211_IFTYPE_ADHOC:
    3949          21 :                 return "ADHOC";
    3950             :         case NL80211_IFTYPE_STATION:
    3951        3343 :                 return "STATION";
    3952             :         case NL80211_IFTYPE_AP:
    3953        1699 :                 return "AP";
    3954             :         case NL80211_IFTYPE_AP_VLAN:
    3955          22 :                 return "AP_VLAN";
    3956             :         case NL80211_IFTYPE_WDS:
    3957           0 :                 return "WDS";
    3958             :         case NL80211_IFTYPE_MONITOR:
    3959           7 :                 return "MONITOR";
    3960             :         case NL80211_IFTYPE_MESH_POINT:
    3961          74 :                 return "MESH_POINT";
    3962             :         case NL80211_IFTYPE_P2P_CLIENT:
    3963         264 :                 return "P2P_CLIENT";
    3964             :         case NL80211_IFTYPE_P2P_GO:
    3965         525 :                 return "P2P_GO";
    3966             :         case NL80211_IFTYPE_P2P_DEVICE:
    3967          16 :                 return "P2P_DEVICE";
    3968             :         default:
    3969           0 :                 return "unknown";
    3970             :         }
    3971             : }
    3972             : 
    3973             : 
    3974         239 : static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
    3975             :                                      const char *ifname,
    3976             :                                      enum nl80211_iftype iftype,
    3977             :                                      const u8 *addr, int wds,
    3978             :                                      int (*handler)(struct nl_msg *, void *),
    3979             :                                      void *arg)
    3980             : {
    3981             :         struct nl_msg *msg;
    3982             :         int ifidx;
    3983         239 :         int ret = -ENOBUFS;
    3984             : 
    3985         239 :         wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
    3986             :                    iftype, nl80211_iftype_str(iftype));
    3987             : 
    3988         239 :         msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_NEW_INTERFACE);
    3989         478 :         if (!msg ||
    3990         478 :             nla_put_string(msg, NL80211_ATTR_IFNAME, ifname) ||
    3991         239 :             nla_put_u32(msg, NL80211_ATTR_IFTYPE, iftype))
    3992             :                 goto fail;
    3993             : 
    3994         239 :         if (iftype == NL80211_IFTYPE_MONITOR) {
    3995             :                 struct nlattr *flags;
    3996             : 
    3997           7 :                 flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
    3998          14 :                 if (!flags ||
    3999           7 :                     nla_put_flag(msg, NL80211_MNTR_FLAG_COOK_FRAMES))
    4000             :                         goto fail;
    4001             : 
    4002           7 :                 nla_nest_end(msg, flags);
    4003         232 :         } else if (wds) {
    4004           1 :                 if (nla_put_u8(msg, NL80211_ATTR_4ADDR, wds))
    4005           0 :                         goto fail;
    4006             :         }
    4007             : 
    4008             :         /*
    4009             :          * Tell cfg80211 that the interface belongs to the socket that created
    4010             :          * it, and the interface should be deleted when the socket is closed.
    4011             :          */
    4012         239 :         if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
    4013           0 :                 goto fail;
    4014             : 
    4015         239 :         ret = send_and_recv_msgs(drv, msg, handler, arg);
    4016         239 :         msg = NULL;
    4017         239 :         if (ret) {
    4018             :         fail:
    4019           2 :                 nlmsg_free(msg);
    4020           2 :                 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
    4021             :                            ifname, ret, strerror(-ret));
    4022           2 :                 return ret;
    4023             :         }
    4024             : 
    4025         237 :         if (iftype == NL80211_IFTYPE_P2P_DEVICE)
    4026           8 :                 return 0;
    4027             : 
    4028         229 :         ifidx = if_nametoindex(ifname);
    4029         229 :         wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
    4030             :                    ifname, ifidx);
    4031             : 
    4032         229 :         if (ifidx <= 0)
    4033           0 :                 return -1;
    4034             : 
    4035             :         /*
    4036             :          * Some virtual interfaces need to process EAPOL packets and events on
    4037             :          * the parent interface. This is used mainly with hostapd.
    4038             :          */
    4039         229 :         if (drv->hostapd ||
    4040         163 :             iftype == NL80211_IFTYPE_AP_VLAN ||
    4041         163 :             iftype == NL80211_IFTYPE_WDS ||
    4042             :             iftype == NL80211_IFTYPE_MONITOR) {
    4043             :                 /* start listening for EAPOL on this interface */
    4044          71 :                 add_ifidx(drv, ifidx);
    4045             :         }
    4046             : 
    4047         293 :         if (addr && iftype != NL80211_IFTYPE_MONITOR &&
    4048          64 :             linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
    4049           0 :                 nl80211_remove_iface(drv, ifidx);
    4050           0 :                 return -1;
    4051             :         }
    4052             : 
    4053         229 :         return ifidx;
    4054             : }
    4055             : 
    4056             : 
    4057         238 : int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
    4058             :                          const char *ifname, enum nl80211_iftype iftype,
    4059             :                          const u8 *addr, int wds,
    4060             :                          int (*handler)(struct nl_msg *, void *),
    4061             :                          void *arg, int use_existing)
    4062             : {
    4063             :         int ret;
    4064             : 
    4065         238 :         ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
    4066             :                                         arg);
    4067             : 
    4068             :         /* if error occurred and interface exists already */
    4069         238 :         if (ret == -ENFILE && if_nametoindex(ifname)) {
    4070           2 :                 if (use_existing) {
    4071           1 :                         wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
    4072             :                                    ifname);
    4073           2 :                         if (addr && iftype != NL80211_IFTYPE_MONITOR &&
    4074           1 :                             linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
    4075           0 :                                                addr) < 0 &&
    4076           0 :                             (linux_set_iface_flags(drv->global->ioctl_sock,
    4077           0 :                                                    ifname, 0) < 0 ||
    4078           0 :                              linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
    4079           0 :                                                 addr) < 0 ||
    4080           0 :                              linux_set_iface_flags(drv->global->ioctl_sock,
    4081             :                                                    ifname, 1) < 0))
    4082           0 :                                         return -1;
    4083           1 :                         return -ENFILE;
    4084             :                 }
    4085           1 :                 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
    4086             : 
    4087             :                 /* Try to remove the interface that was already there. */
    4088           1 :                 nl80211_remove_iface(drv, if_nametoindex(ifname));
    4089             : 
    4090             :                 /* Try to create the interface again */
    4091           1 :                 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
    4092             :                                                 wds, handler, arg);
    4093             :         }
    4094             : 
    4095         237 :         if (ret >= 0 && is_p2p_net_interface(iftype)) {
    4096         143 :                 wpa_printf(MSG_DEBUG,
    4097             :                            "nl80211: Interface %s created for P2P - disable 11b rates",
    4098             :                            ifname);
    4099         143 :                 nl80211_disable_11b_rates(drv, ret, 1);
    4100             :         }
    4101             : 
    4102         237 :         return ret;
    4103             : }
    4104             : 
    4105             : 
    4106        2121 : static int nl80211_setup_ap(struct i802_bss *bss)
    4107             : {
    4108        2121 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4109             : 
    4110        6363 :         wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
    4111        6363 :                    bss->ifname, drv->device_ap_sme, drv->use_monitor);
    4112             : 
    4113             :         /*
    4114             :          * Disable Probe Request reporting unless we need it in this way for
    4115             :          * devices that include the AP SME, in the other case (unless using
    4116             :          * monitor iface) we'll get it through the nl_mgmt socket instead.
    4117             :          */
    4118        2121 :         if (!drv->device_ap_sme)
    4119        2121 :                 wpa_driver_nl80211_probe_req_report(bss, 0);
    4120             : 
    4121        2121 :         if (!drv->device_ap_sme && !drv->use_monitor)
    4122        2113 :                 if (nl80211_mgmt_subscribe_ap(bss))
    4123           0 :                         return -1;
    4124             : 
    4125        2121 :         if (drv->device_ap_sme && !drv->use_monitor)
    4126           0 :                 if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
    4127           0 :                         return -1;
    4128             : 
    4129        2129 :         if (!drv->device_ap_sme && drv->use_monitor &&
    4130           8 :             nl80211_create_monitor_interface(drv) &&
    4131           0 :             !drv->device_ap_sme)
    4132           0 :                 return -1;
    4133             : 
    4134        2121 :         if (drv->device_ap_sme &&
    4135           0 :             wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
    4136           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
    4137             :                            "Probe Request frame reporting in AP mode");
    4138             :                 /* Try to survive without this */
    4139             :         }
    4140             : 
    4141        2121 :         return 0;
    4142             : }
    4143             : 
    4144             : 
    4145        2017 : static void nl80211_teardown_ap(struct i802_bss *bss)
    4146             : {
    4147        2017 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4148             : 
    4149        6051 :         wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
    4150        6051 :                    bss->ifname, drv->device_ap_sme, drv->use_monitor);
    4151        2017 :         if (drv->device_ap_sme) {
    4152           0 :                 wpa_driver_nl80211_probe_req_report(bss, 0);
    4153           0 :                 if (!drv->use_monitor)
    4154           0 :                         nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
    4155        2017 :         } else if (drv->use_monitor)
    4156           8 :                 nl80211_remove_monitor_interface(drv);
    4157             :         else
    4158        2009 :                 nl80211_mgmt_unsubscribe(bss, "AP teardown");
    4159             : 
    4160        2017 :         bss->beacon_set = 0;
    4161        2017 : }
    4162             : 
    4163             : 
    4164       11096 : static int nl80211_send_eapol_data(struct i802_bss *bss,
    4165             :                                    const u8 *addr, const u8 *data,
    4166             :                                    size_t data_len)
    4167             : {
    4168             :         struct sockaddr_ll ll;
    4169             :         int ret;
    4170             : 
    4171       11096 :         if (bss->drv->eapol_tx_sock < 0) {
    4172           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
    4173           0 :                 return -1;
    4174             :         }
    4175             : 
    4176       11096 :         os_memset(&ll, 0, sizeof(ll));
    4177       11096 :         ll.sll_family = AF_PACKET;
    4178       11096 :         ll.sll_ifindex = bss->ifindex;
    4179       11096 :         ll.sll_protocol = htons(ETH_P_PAE);
    4180       11096 :         ll.sll_halen = ETH_ALEN;
    4181       11096 :         os_memcpy(ll.sll_addr, addr, ETH_ALEN);
    4182       11096 :         ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
    4183             :                      (struct sockaddr *) &ll, sizeof(ll));
    4184       11096 :         if (ret < 0)
    4185           0 :                 wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
    4186           0 :                            strerror(errno));
    4187             : 
    4188       11096 :         return ret;
    4189             : }
    4190             : 
    4191             : 
    4192             : static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
    4193             : 
    4194       11108 : static int wpa_driver_nl80211_hapd_send_eapol(
    4195             :         void *priv, const u8 *addr, const u8 *data,
    4196             :         size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
    4197             : {
    4198       11108 :         struct i802_bss *bss = priv;
    4199       11108 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4200             :         struct ieee80211_hdr *hdr;
    4201             :         size_t len;
    4202             :         u8 *pos;
    4203             :         int res;
    4204       11108 :         int qos = flags & WPA_STA_WMM;
    4205             : 
    4206       11108 :         if (drv->device_ap_sme || !drv->use_monitor)
    4207       11096 :                 return nl80211_send_eapol_data(bss, addr, data, data_len);
    4208             : 
    4209          12 :         len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
    4210             :                 data_len;
    4211          12 :         hdr = os_zalloc(len);
    4212          12 :         if (hdr == NULL) {
    4213           0 :                 wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
    4214             :                            (unsigned long) len);
    4215           0 :                 return -1;
    4216             :         }
    4217             : 
    4218          12 :         hdr->frame_control =
    4219             :                 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
    4220          12 :         hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
    4221          12 :         if (encrypt)
    4222           0 :                 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
    4223          12 :         if (qos) {
    4224          12 :                 hdr->frame_control |=
    4225             :                         host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
    4226             :         }
    4227             : 
    4228          12 :         memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
    4229          12 :         memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
    4230          12 :         memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
    4231          12 :         pos = (u8 *) (hdr + 1);
    4232             : 
    4233          12 :         if (qos) {
    4234             :                 /* Set highest priority in QoS header */
    4235          12 :                 pos[0] = 7;
    4236          12 :                 pos[1] = 0;
    4237          12 :                 pos += 2;
    4238             :         }
    4239             : 
    4240          12 :         memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
    4241          12 :         pos += sizeof(rfc1042_header);
    4242          12 :         WPA_PUT_BE16(pos, ETH_P_PAE);
    4243          12 :         pos += 2;
    4244          12 :         memcpy(pos, data, data_len);
    4245             : 
    4246          12 :         res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
    4247             :                                             0, 0, 0, 0);
    4248          12 :         if (res < 0) {
    4249           0 :                 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
    4250             :                            "failed: %d (%s)",
    4251           0 :                            (unsigned long) len, errno, strerror(errno));
    4252             :         }
    4253          12 :         os_free(hdr);
    4254             : 
    4255          12 :         return res;
    4256             : }
    4257             : 
    4258             : 
    4259        8473 : static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
    4260             :                                             unsigned int total_flags,
    4261             :                                             unsigned int flags_or,
    4262             :                                             unsigned int flags_and)
    4263             : {
    4264        8473 :         struct i802_bss *bss = priv;
    4265             :         struct nl_msg *msg;
    4266             :         struct nlattr *flags;
    4267             :         struct nl80211_sta_flag_update upd;
    4268             : 
    4269       67784 :         wpa_printf(MSG_DEBUG, "nl80211: Set STA flags - ifname=%s addr=" MACSTR
    4270             :                    " total_flags=0x%x flags_or=0x%x flags_and=0x%x authorized=%d",
    4271       59311 :                    bss->ifname, MAC2STR(addr), total_flags, flags_or, flags_and,
    4272        8473 :                    !!(total_flags & WPA_STA_AUTHORIZED));
    4273             : 
    4274       16946 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
    4275        8473 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
    4276             :                 goto fail;
    4277             : 
    4278             :         /*
    4279             :          * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
    4280             :          * can be removed eventually.
    4281             :          */
    4282        8473 :         flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
    4283       16946 :         if (!flags ||
    4284       10938 :             ((total_flags & WPA_STA_AUTHORIZED) &&
    4285       10938 :              nla_put_flag(msg, NL80211_STA_FLAG_AUTHORIZED)) ||
    4286       16901 :             ((total_flags & WPA_STA_WMM) &&
    4287       16901 :              nla_put_flag(msg, NL80211_STA_FLAG_WME)) ||
    4288       16694 :             ((total_flags & WPA_STA_SHORT_PREAMBLE) &&
    4289       16694 :              nla_put_flag(msg, NL80211_STA_FLAG_SHORT_PREAMBLE)) ||
    4290        8666 :             ((total_flags & WPA_STA_MFP) &&
    4291        8666 :              nla_put_flag(msg, NL80211_STA_FLAG_MFP)) ||
    4292        8473 :             ((total_flags & WPA_STA_TDLS_PEER) &&
    4293           0 :              nla_put_flag(msg, NL80211_STA_FLAG_TDLS_PEER)))
    4294             :                 goto fail;
    4295             : 
    4296        8473 :         nla_nest_end(msg, flags);
    4297             : 
    4298        8473 :         os_memset(&upd, 0, sizeof(upd));
    4299        8473 :         upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
    4300        8473 :         upd.set = sta_flags_nl80211(flags_or);
    4301        8473 :         if (nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd))
    4302           0 :                 goto fail;
    4303             : 
    4304        8473 :         return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
    4305             : fail:
    4306           0 :         nlmsg_free(msg);
    4307           0 :         return -ENOBUFS;
    4308             : }
    4309             : 
    4310             : 
    4311         339 : static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
    4312             :                                  struct wpa_driver_associate_params *params)
    4313             : {
    4314             :         enum nl80211_iftype nlmode, old_mode;
    4315             : 
    4316         339 :         if (params->p2p) {
    4317         322 :                 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
    4318             :                            "group (GO)");
    4319         322 :                 nlmode = NL80211_IFTYPE_P2P_GO;
    4320             :         } else
    4321          17 :                 nlmode = NL80211_IFTYPE_AP;
    4322             : 
    4323         339 :         old_mode = drv->nlmode;
    4324         339 :         if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
    4325           0 :                 nl80211_remove_monitor_interface(drv);
    4326           0 :                 return -1;
    4327             :         }
    4328             : 
    4329         677 :         if (params->freq.freq &&
    4330         338 :             nl80211_set_channel(drv->first_bss, &params->freq, 0)) {
    4331           1 :                 if (old_mode != nlmode)
    4332           1 :                         wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
    4333           1 :                 nl80211_remove_monitor_interface(drv);
    4334           1 :                 return -1;
    4335             :         }
    4336             : 
    4337         338 :         return 0;
    4338             : }
    4339             : 
    4340             : 
    4341          22 : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
    4342             :                               int reset_mode)
    4343             : {
    4344             :         struct nl_msg *msg;
    4345             :         int ret;
    4346             : 
    4347          22 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_IBSS);
    4348          22 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4349          22 :         if (ret) {
    4350           1 :                 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
    4351             :                            "(%s)", ret, strerror(-ret));
    4352             :         } else {
    4353          21 :                 wpa_printf(MSG_DEBUG,
    4354             :                            "nl80211: Leave IBSS request sent successfully");
    4355             :         }
    4356             : 
    4357          43 :         if (reset_mode &&
    4358          21 :             wpa_driver_nl80211_set_mode(drv->first_bss,
    4359             :                                         NL80211_IFTYPE_STATION)) {
    4360           0 :                 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
    4361             :                            "station mode");
    4362             :         }
    4363             : 
    4364          22 :         return ret;
    4365             : }
    4366             : 
    4367             : 
    4368        3356 : static int nl80211_ht_vht_overrides(struct nl_msg *msg,
    4369             :                                     struct wpa_driver_associate_params *params)
    4370             : {
    4371        3356 :         if (params->disable_ht && nla_put_flag(msg, NL80211_ATTR_DISABLE_HT))
    4372           0 :                 return -1;
    4373             : 
    4374        3356 :         if (params->htcaps && params->htcaps_mask) {
    4375        3356 :                 int sz = sizeof(struct ieee80211_ht_capabilities);
    4376        3356 :                 wpa_hexdump(MSG_DEBUG, "  * htcaps", params->htcaps, sz);
    4377        6712 :                 wpa_hexdump(MSG_DEBUG, "  * htcaps_mask",
    4378        3356 :                             params->htcaps_mask, sz);
    4379        3356 :                 if (nla_put(msg, NL80211_ATTR_HT_CAPABILITY, sz,
    4380        6712 :                             params->htcaps) ||
    4381        3356 :                     nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
    4382        3356 :                             params->htcaps_mask))
    4383           0 :                         return -1;
    4384             :         }
    4385             : 
    4386             : #ifdef CONFIG_VHT_OVERRIDES
    4387        3356 :         if (params->disable_vht) {
    4388           1 :                 wpa_printf(MSG_DEBUG, "  * VHT disabled");
    4389           1 :                 if (nla_put_flag(msg, NL80211_ATTR_DISABLE_VHT))
    4390           0 :                         return -1;
    4391             :         }
    4392             : 
    4393        3356 :         if (params->vhtcaps && params->vhtcaps_mask) {
    4394        3356 :                 int sz = sizeof(struct ieee80211_vht_capabilities);
    4395        3356 :                 wpa_hexdump(MSG_DEBUG, "  * vhtcaps", params->vhtcaps, sz);
    4396        6712 :                 wpa_hexdump(MSG_DEBUG, "  * vhtcaps_mask",
    4397        3356 :                             params->vhtcaps_mask, sz);
    4398        3356 :                 if (nla_put(msg, NL80211_ATTR_VHT_CAPABILITY, sz,
    4399        6712 :                             params->vhtcaps) ||
    4400        3356 :                     nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
    4401        3356 :                             params->vhtcaps_mask))
    4402           0 :                         return -1;
    4403             :         }
    4404             : #endif /* CONFIG_VHT_OVERRIDES */
    4405             : 
    4406        3356 :         return 0;
    4407             : }
    4408             : 
    4409             : 
    4410          21 : static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
    4411             :                                    struct wpa_driver_associate_params *params)
    4412             : {
    4413             :         struct nl_msg *msg;
    4414          21 :         int ret = -1;
    4415          21 :         int count = 0;
    4416             : 
    4417          21 :         wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
    4418             : 
    4419          21 :         if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, &params->freq)) {
    4420           0 :                 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
    4421             :                            "IBSS mode");
    4422           0 :                 return -1;
    4423             :         }
    4424             : 
    4425             : retry:
    4426          44 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_IBSS)) ||
    4427          44 :             params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
    4428             :                 goto fail;
    4429             : 
    4430          44 :         wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
    4431          22 :                           params->ssid, params->ssid_len);
    4432          22 :         if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
    4433           0 :                 goto fail;
    4434          22 :         os_memcpy(drv->ssid, params->ssid, params->ssid_len);
    4435          22 :         drv->ssid_len = params->ssid_len;
    4436             : 
    4437          44 :         if (nl80211_put_freq_params(msg, &params->freq) < 0 ||
    4438          22 :             nl80211_put_beacon_int(msg, params->beacon_int))
    4439             :                 goto fail;
    4440             : 
    4441          22 :         ret = nl80211_set_conn_keys(params, msg);
    4442          22 :         if (ret)
    4443           0 :                 goto fail;
    4444             : 
    4445          22 :         if (params->bssid && params->fixed_bssid) {
    4446          24 :                 wpa_printf(MSG_DEBUG, "  * BSSID=" MACSTR,
    4447          24 :                            MAC2STR(params->bssid));
    4448           4 :                 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
    4449           0 :                         goto fail;
    4450             :         }
    4451             : 
    4452          22 :         if (params->fixed_freq) {
    4453           0 :                 wpa_printf(MSG_DEBUG, "  * fixed_freq");
    4454           0 :                 if (nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED))
    4455           0 :                         goto fail;
    4456             :         }
    4457             : 
    4458          44 :         if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
    4459          37 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    4460          30 :             params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
    4461          15 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
    4462           7 :                 wpa_printf(MSG_DEBUG, "  * control port");
    4463           7 :                 if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT))
    4464           0 :                         goto fail;
    4465             :         }
    4466             : 
    4467          22 :         if (params->wpa_ie) {
    4468          44 :                 wpa_hexdump(MSG_DEBUG,
    4469             :                             "  * Extra IEs for Beacon/Probe Response frames",
    4470          22 :                             params->wpa_ie, params->wpa_ie_len);
    4471          22 :                 if (nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len,
    4472          22 :                             params->wpa_ie))
    4473           0 :                         goto fail;
    4474             :         }
    4475             : 
    4476          22 :         if (nl80211_ht_vht_overrides(msg, params) < 0)
    4477           0 :                 return -1;
    4478             : 
    4479          22 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4480          22 :         msg = NULL;
    4481          22 :         if (ret) {
    4482           1 :                 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
    4483             :                            ret, strerror(-ret));
    4484           1 :                 count++;
    4485           1 :                 if (ret == -EALREADY && count == 1) {
    4486           1 :                         wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
    4487             :                                    "forced leave");
    4488           1 :                         nl80211_leave_ibss(drv, 0);
    4489           1 :                         nlmsg_free(msg);
    4490           1 :                         goto retry;
    4491             :                 }
    4492             :         } else {
    4493          21 :                 wpa_printf(MSG_DEBUG,
    4494             :                            "nl80211: Join IBSS request sent successfully");
    4495             :         }
    4496             : 
    4497             : fail:
    4498          21 :         nlmsg_free(msg);
    4499          21 :         return ret;
    4500             : }
    4501             : 
    4502             : 
    4503        3334 : static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
    4504             :                                   struct wpa_driver_associate_params *params,
    4505             :                                   struct nl_msg *msg)
    4506             : {
    4507        3334 :         if (params->bssid) {
    4508       19962 :                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
    4509       19962 :                            MAC2STR(params->bssid));
    4510        3327 :                 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
    4511           0 :                         return -1;
    4512             :         }
    4513             : 
    4514        3334 :         if (params->bssid_hint) {
    4515        1626 :                 wpa_printf(MSG_DEBUG, "  * bssid_hint=" MACSTR,
    4516        1626 :                            MAC2STR(params->bssid_hint));
    4517         271 :                 if (nla_put(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
    4518         271 :                             params->bssid_hint))
    4519           0 :                         return -1;
    4520             :         }
    4521             : 
    4522        3334 :         if (params->freq.freq) {
    4523        3327 :                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
    4524        3327 :                 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
    4525        3327 :                                 params->freq.freq))
    4526           0 :                         return -1;
    4527        3327 :                 drv->assoc_freq = params->freq.freq;
    4528             :         } else
    4529           7 :                 drv->assoc_freq = 0;
    4530             : 
    4531        3334 :         if (params->freq_hint) {
    4532         271 :                 wpa_printf(MSG_DEBUG, "  * freq_hint=%d", params->freq_hint);
    4533         271 :                 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
    4534         271 :                                 params->freq_hint))
    4535           0 :                         return -1;
    4536             :         }
    4537             : 
    4538        3334 :         if (params->bg_scan_period >= 0) {
    4539           6 :                 wpa_printf(MSG_DEBUG, "  * bg scan period=%d",
    4540             :                            params->bg_scan_period);
    4541           6 :                 if (nla_put_u16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
    4542           6 :                                 params->bg_scan_period))
    4543           0 :                         return -1;
    4544             :         }
    4545             : 
    4546        3334 :         if (params->ssid) {
    4547        6668 :                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
    4548        3334 :                                   params->ssid, params->ssid_len);
    4549        3334 :                 if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
    4550        3334 :                             params->ssid))
    4551           0 :                         return -1;
    4552        3334 :                 if (params->ssid_len > sizeof(drv->ssid))
    4553           0 :                         return -1;
    4554        3334 :                 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
    4555        3334 :                 drv->ssid_len = params->ssid_len;
    4556             :         }
    4557             : 
    4558        3334 :         wpa_hexdump(MSG_DEBUG, "  * IEs", params->wpa_ie, params->wpa_ie_len);
    4559        6668 :         if (params->wpa_ie &&
    4560        3334 :             nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len, params->wpa_ie))
    4561           0 :                 return -1;
    4562             : 
    4563        3334 :         if (params->wpa_proto) {
    4564        2927 :                 enum nl80211_wpa_versions ver = 0;
    4565             : 
    4566        2927 :                 if (params->wpa_proto & WPA_PROTO_WPA)
    4567          60 :                         ver |= NL80211_WPA_VERSION_1;
    4568        2927 :                 if (params->wpa_proto & WPA_PROTO_RSN)
    4569        2865 :                         ver |= NL80211_WPA_VERSION_2;
    4570             : 
    4571        2927 :                 wpa_printf(MSG_DEBUG, "  * WPA Versions 0x%x", ver);
    4572        2927 :                 if (nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
    4573           0 :                         return -1;
    4574             :         }
    4575             : 
    4576        3334 :         if (params->pairwise_suite != WPA_CIPHER_NONE) {
    4577        2241 :                 u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
    4578        2241 :                 wpa_printf(MSG_DEBUG, "  * pairwise=0x%x", cipher);
    4579        2241 :                 if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
    4580             :                                 cipher))
    4581           0 :                         return -1;
    4582             :         }
    4583             : 
    4584        3336 :         if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
    4585           2 :             !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
    4586             :                 /*
    4587             :                  * This is likely to work even though many drivers do not
    4588             :                  * advertise support for operations without GTK.
    4589             :                  */
    4590           2 :                 wpa_printf(MSG_DEBUG, "  * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
    4591        3332 :         } else if (params->group_suite != WPA_CIPHER_NONE) {
    4592        2239 :                 u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
    4593        2239 :                 wpa_printf(MSG_DEBUG, "  * group=0x%x", cipher);
    4594        2239 :                 if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher))
    4595           0 :                         return -1;
    4596             :         }
    4597             : 
    4598        5531 :         if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
    4599        3674 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    4600        2946 :             params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
    4601        2681 :             params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
    4602        2424 :             params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
    4603        2422 :             params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
    4604        2415 :             params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
    4605        2390 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
    4606        2367 :             params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
    4607        1182 :             params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
    4608        2155 :                 int mgmt = WLAN_AKM_SUITE_PSK;
    4609             : 
    4610        2155 :                 switch (params->key_mgmt_suite) {
    4611             :                 case WPA_KEY_MGMT_CCKM:
    4612           0 :                         mgmt = WLAN_AKM_SUITE_CCKM;
    4613           0 :                         break;
    4614             :                 case WPA_KEY_MGMT_IEEE8021X:
    4615        1137 :                         mgmt = WLAN_AKM_SUITE_8021X;
    4616        1137 :                         break;
    4617             :                 case WPA_KEY_MGMT_FT_IEEE8021X:
    4618           8 :                         mgmt = WLAN_AKM_SUITE_FT_8021X;
    4619           8 :                         break;
    4620             :                 case WPA_KEY_MGMT_FT_PSK:
    4621         257 :                         mgmt = WLAN_AKM_SUITE_FT_PSK;
    4622         257 :                         break;
    4623             :                 case WPA_KEY_MGMT_IEEE8021X_SHA256:
    4624           5 :                         mgmt = WLAN_AKM_SUITE_8021X_SHA256;
    4625           5 :                         break;
    4626             :                 case WPA_KEY_MGMT_PSK_SHA256:
    4627          20 :                         mgmt = WLAN_AKM_SUITE_PSK_SHA256;
    4628          20 :                         break;
    4629             :                 case WPA_KEY_MGMT_OSEN:
    4630           2 :                         mgmt = WLAN_AKM_SUITE_OSEN;
    4631           2 :                         break;
    4632             :                 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
    4633           3 :                         mgmt = WLAN_AKM_SUITE_8021X_SUITE_B;
    4634           3 :                         break;
    4635             :                 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
    4636           3 :                         mgmt = WLAN_AKM_SUITE_8021X_SUITE_B_192;
    4637           3 :                         break;
    4638             :                 case WPA_KEY_MGMT_PSK:
    4639             :                 default:
    4640         720 :                         mgmt = WLAN_AKM_SUITE_PSK;
    4641         720 :                         break;
    4642             :                 }
    4643        2155 :                 wpa_printf(MSG_DEBUG, "  * akm=0x%x", mgmt);
    4644        2155 :                 if (nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, mgmt))
    4645           0 :                         return -1;
    4646             :         }
    4647             : 
    4648        3334 :         if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT))
    4649           0 :                 return -1;
    4650             : 
    4651        3392 :         if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED &&
    4652          58 :             nla_put_u32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED))
    4653           0 :                 return -1;
    4654             : 
    4655        3334 :         if (params->rrm_used) {
    4656           1 :                 u32 drv_rrm_flags = drv->capa.rrm_flags;
    4657           1 :                 if (!(drv_rrm_flags &
    4658           1 :                       WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) ||
    4659           2 :                     !(drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET) ||
    4660           1 :                     nla_put_flag(msg, NL80211_ATTR_USE_RRM))
    4661           0 :                         return -1;
    4662             :         }
    4663             : 
    4664        3334 :         if (nl80211_ht_vht_overrides(msg, params) < 0)
    4665           0 :                 return -1;
    4666             : 
    4667        3334 :         if (params->p2p)
    4668         392 :                 wpa_printf(MSG_DEBUG, "  * P2P group");
    4669             : 
    4670        3334 :         return 0;
    4671             : }
    4672             : 
    4673             : 
    4674         277 : static int wpa_driver_nl80211_try_connect(
    4675             :         struct wpa_driver_nl80211_data *drv,
    4676             :         struct wpa_driver_associate_params *params)
    4677             : {
    4678             :         struct nl_msg *msg;
    4679             :         enum nl80211_auth_type type;
    4680             :         int ret;
    4681             :         int algs;
    4682             : 
    4683         283 :         if (params->req_key_mgmt_offload && params->psk &&
    4684           6 :             (params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    4685           0 :              params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
    4686           0 :              params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
    4687           6 :                 wpa_printf(MSG_DEBUG, "nl80211: Key management set PSK");
    4688           6 :                 ret = issue_key_mgmt_set_key(drv, params->psk, 32);
    4689           6 :                 if (ret)
    4690           0 :                         return ret;
    4691             :         }
    4692             : 
    4693         277 :         wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
    4694         277 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT);
    4695         277 :         if (!msg)
    4696           0 :                 return -1;
    4697             : 
    4698         277 :         ret = nl80211_connect_common(drv, params, msg);
    4699         277 :         if (ret)
    4700           0 :                 goto fail;
    4701             : 
    4702         277 :         algs = 0;
    4703         277 :         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
    4704         276 :                 algs++;
    4705         277 :         if (params->auth_alg & WPA_AUTH_ALG_SHARED)
    4706           2 :                 algs++;
    4707         277 :         if (params->auth_alg & WPA_AUTH_ALG_LEAP)
    4708           0 :                 algs++;
    4709         277 :         if (algs > 1) {
    4710           1 :                 wpa_printf(MSG_DEBUG, "  * Leave out Auth Type for automatic "
    4711             :                            "selection");
    4712           1 :                 goto skip_auth_type;
    4713             :         }
    4714             : 
    4715         276 :         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
    4716         275 :                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
    4717           1 :         else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
    4718           1 :                 type = NL80211_AUTHTYPE_SHARED_KEY;
    4719           0 :         else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
    4720           0 :                 type = NL80211_AUTHTYPE_NETWORK_EAP;
    4721           0 :         else if (params->auth_alg & WPA_AUTH_ALG_FT)
    4722           0 :                 type = NL80211_AUTHTYPE_FT;
    4723             :         else
    4724           0 :                 goto fail;
    4725             : 
    4726         276 :         wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
    4727         276 :         if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
    4728           0 :                 goto fail;
    4729             : 
    4730             : skip_auth_type:
    4731         277 :         ret = nl80211_set_conn_keys(params, msg);
    4732         277 :         if (ret)
    4733           0 :                 goto fail;
    4734             : 
    4735         277 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4736         277 :         msg = NULL;
    4737         277 :         if (ret) {
    4738           4 :                 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
    4739             :                            "(%s)", ret, strerror(-ret));
    4740             :         } else {
    4741         273 :                 wpa_printf(MSG_DEBUG,
    4742             :                            "nl80211: Connect request send successfully");
    4743             :         }
    4744             : 
    4745             : fail:
    4746         277 :         nlmsg_free(msg);
    4747         277 :         return ret;
    4748             : 
    4749             : }
    4750             : 
    4751             : 
    4752         273 : static int wpa_driver_nl80211_connect(
    4753             :         struct wpa_driver_nl80211_data *drv,
    4754             :         struct wpa_driver_associate_params *params)
    4755             : {
    4756             :         int ret;
    4757             : 
    4758             :         /* Store the connection attempted bssid for future use */
    4759         273 :         if (params->bssid)
    4760         266 :                 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
    4761             :         else
    4762           7 :                 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
    4763             : 
    4764         273 :         ret = wpa_driver_nl80211_try_connect(drv, params);
    4765         273 :         if (ret == -EALREADY) {
    4766             :                 /*
    4767             :                  * cfg80211 does not currently accept new connections if
    4768             :                  * we are already connected. As a workaround, force
    4769             :                  * disconnection and try again.
    4770             :                  */
    4771           4 :                 wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
    4772             :                            "disconnecting before reassociation "
    4773             :                            "attempt");
    4774           4 :                 if (wpa_driver_nl80211_disconnect(
    4775             :                             drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
    4776           0 :                         return -1;
    4777           4 :                 ret = wpa_driver_nl80211_try_connect(drv, params);
    4778             :         }
    4779         273 :         return ret;
    4780             : }
    4781             : 
    4782             : 
    4783        3690 : static int wpa_driver_nl80211_associate(
    4784             :         void *priv, struct wpa_driver_associate_params *params)
    4785             : {
    4786        3690 :         struct i802_bss *bss = priv;
    4787        3690 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4788        3690 :         int ret = -1;
    4789             :         struct nl_msg *msg;
    4790             : 
    4791        3690 :         nl80211_unmask_11b_rates(bss);
    4792             : 
    4793        3690 :         if (params->mode == IEEE80211_MODE_AP)
    4794         339 :                 return wpa_driver_nl80211_ap(drv, params);
    4795             : 
    4796        3351 :         if (params->mode == IEEE80211_MODE_IBSS)
    4797          21 :                 return wpa_driver_nl80211_ibss(drv, params);
    4798             : 
    4799        3330 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
    4800         273 :                 enum nl80211_iftype nlmode = params->p2p ?
    4801             :                         NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
    4802             : 
    4803         273 :                 if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
    4804           0 :                         return -1;
    4805         273 :                 return wpa_driver_nl80211_connect(drv, params);
    4806             :         }
    4807             : 
    4808        3057 :         nl80211_mark_disconnected(drv);
    4809             : 
    4810        3057 :         wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
    4811             :                    drv->ifindex);
    4812        3057 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_ASSOCIATE);
    4813        3057 :         if (!msg)
    4814           0 :                 return -1;
    4815             : 
    4816        3057 :         ret = nl80211_connect_common(drv, params, msg);
    4817        3057 :         if (ret)
    4818           0 :                 goto fail;
    4819             : 
    4820        3057 :         if (params->prev_bssid) {
    4821        1854 :                 wpa_printf(MSG_DEBUG, "  * prev_bssid=" MACSTR,
    4822        1854 :                            MAC2STR(params->prev_bssid));
    4823         309 :                 if (nla_put(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
    4824         309 :                             params->prev_bssid))
    4825           0 :                         goto fail;
    4826             :         }
    4827             : 
    4828        3057 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4829        3057 :         msg = NULL;
    4830        3057 :         if (ret) {
    4831           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    4832             :                         "nl80211: MLME command failed (assoc): ret=%d (%s)",
    4833             :                         ret, strerror(-ret));
    4834           0 :                 nl80211_dump_scan(drv);
    4835             :         } else {
    4836        3057 :                 wpa_printf(MSG_DEBUG,
    4837             :                            "nl80211: Association request send successfully");
    4838             :         }
    4839             : 
    4840             : fail:
    4841        3057 :         nlmsg_free(msg);
    4842        3057 :         return ret;
    4843             : }
    4844             : 
    4845             : 
    4846        5732 : static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
    4847             :                             int ifindex, enum nl80211_iftype mode)
    4848             : {
    4849             :         struct nl_msg *msg;
    4850        5732 :         int ret = -ENOBUFS;
    4851             : 
    4852        5732 :         wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
    4853             :                    ifindex, mode, nl80211_iftype_str(mode));
    4854             : 
    4855        5732 :         msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
    4856        5732 :         if (!msg || nla_put_u32(msg, NL80211_ATTR_IFTYPE, mode))
    4857             :                 goto fail;
    4858             : 
    4859        5732 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4860        5732 :         msg = NULL;
    4861        5732 :         if (!ret)
    4862        5632 :                 return 0;
    4863             : fail:
    4864         100 :         nlmsg_free(msg);
    4865         100 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
    4866             :                    " %d (%s)", ifindex, mode, ret, strerror(-ret));
    4867         100 :         return ret;
    4868             : }
    4869             : 
    4870             : 
    4871        5666 : static int wpa_driver_nl80211_set_mode_impl(
    4872             :                 struct i802_bss *bss,
    4873             :                 enum nl80211_iftype nlmode,
    4874             :                 struct hostapd_freq_params *desired_freq_params)
    4875             : {
    4876        5666 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4877        5666 :         int ret = -1;
    4878             :         int i;
    4879        5666 :         int was_ap = is_ap_interface(drv->nlmode);
    4880             :         int res;
    4881             :         int mode_switch_res;
    4882             : 
    4883        5666 :         mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
    4884        5666 :         if (mode_switch_res && nlmode == nl80211_get_ifmode(bss))
    4885           8 :                 mode_switch_res = 0;
    4886             : 
    4887        5666 :         if (mode_switch_res == 0) {
    4888        5574 :                 drv->nlmode = nlmode;
    4889        5574 :                 ret = 0;
    4890        5574 :                 goto done;
    4891             :         }
    4892             : 
    4893          92 :         if (mode_switch_res == -ENODEV)
    4894          26 :                 return -1;
    4895             : 
    4896          66 :         if (nlmode == drv->nlmode) {
    4897           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
    4898             :                            "requested mode - ignore error");
    4899           0 :                 ret = 0;
    4900           0 :                 goto done; /* Already in the requested mode */
    4901             :         }
    4902             : 
    4903             :         /* mac80211 doesn't allow mode changes while the device is up, so
    4904             :          * take the device down, try to set the mode again, and bring the
    4905             :          * device back up.
    4906             :          */
    4907          66 :         wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
    4908             :                    "interface down");
    4909          66 :         for (i = 0; i < 10; i++) {
    4910          66 :                 res = i802_set_iface_flags(bss, 0);
    4911          66 :                 if (res == -EACCES || res == -ENODEV)
    4912             :                         break;
    4913          66 :                 if (res != 0) {
    4914           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
    4915             :                                    "interface down");
    4916           0 :                         os_sleep(0, 100000);
    4917           0 :                         continue;
    4918             :                 }
    4919             : 
    4920             :                 /*
    4921             :                  * Setting the mode will fail for some drivers if the phy is
    4922             :                  * on a frequency that the mode is disallowed in.
    4923             :                  */
    4924          66 :                 if (desired_freq_params) {
    4925           0 :                         res = nl80211_set_channel(bss, desired_freq_params, 0);
    4926           0 :                         if (res) {
    4927           0 :                                 wpa_printf(MSG_DEBUG,
    4928             :                                            "nl80211: Failed to set frequency on interface");
    4929             :                         }
    4930             :                 }
    4931             : 
    4932             :                 /* Try to set the mode again while the interface is down */
    4933          66 :                 mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
    4934          66 :                 if (mode_switch_res == -EBUSY) {
    4935           0 :                         wpa_printf(MSG_DEBUG,
    4936             :                                    "nl80211: Delaying mode set while interface going down");
    4937           0 :                         os_sleep(0, 100000);
    4938           0 :                         continue;
    4939             :                 }
    4940          66 :                 ret = mode_switch_res;
    4941          66 :                 break;
    4942             :         }
    4943             : 
    4944          66 :         if (!ret) {
    4945          66 :                 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
    4946             :                            "interface is down");
    4947          66 :                 drv->nlmode = nlmode;
    4948          66 :                 drv->ignore_if_down_event = 1;
    4949             :         }
    4950             : 
    4951             :         /* Bring the interface back up */
    4952          66 :         res = linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
    4953          66 :         if (res != 0) {
    4954           0 :                 wpa_printf(MSG_DEBUG,
    4955             :                            "nl80211: Failed to set interface up after switching mode");
    4956           0 :                 ret = -1;
    4957             :         }
    4958             : 
    4959             : done:
    4960        5640 :         if (ret) {
    4961           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
    4962           0 :                            "from %d failed", nlmode, drv->nlmode);
    4963           0 :                 return ret;
    4964             :         }
    4965             : 
    4966        5640 :         if (is_p2p_net_interface(nlmode)) {
    4967         645 :                 wpa_printf(MSG_DEBUG,
    4968             :                            "nl80211: Interface %s mode change to P2P - disable 11b rates",
    4969         645 :                            bss->ifname);
    4970         645 :                 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
    4971        4995 :         } else if (drv->disabled_11b_rates) {
    4972         404 :                 wpa_printf(MSG_DEBUG,
    4973             :                            "nl80211: Interface %s mode changed to non-P2P - re-enable 11b rates",
    4974         404 :                            bss->ifname);
    4975         404 :                 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
    4976             :         }
    4977             : 
    4978        5640 :         if (is_ap_interface(nlmode)) {
    4979        2078 :                 nl80211_mgmt_unsubscribe(bss, "start AP");
    4980             :                 /* Setup additional AP mode functionality if needed */
    4981        2078 :                 if (nl80211_setup_ap(bss))
    4982           0 :                         return -1;
    4983        3562 :         } else if (was_ap) {
    4984             :                 /* Remove additional AP mode functionality */
    4985        1974 :                 nl80211_teardown_ap(bss);
    4986             :         } else {
    4987        1588 :                 nl80211_mgmt_unsubscribe(bss, "mode change");
    4988             :         }
    4989             : 
    4990        5679 :         if (is_mesh_interface(nlmode) &&
    4991          39 :             nl80211_mgmt_subscribe_mesh(bss))
    4992           0 :                 return -1;
    4993             : 
    4994        7061 :         if (!bss->in_deinit && !is_ap_interface(nlmode) &&
    4995        2803 :             !is_mesh_interface(nlmode) &&
    4996        1382 :             nl80211_mgmt_subscribe_non_ap(bss) < 0)
    4997           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
    4998             :                            "frame processing - ignore for now");
    4999             : 
    5000        5640 :         return 0;
    5001             : }
    5002             : 
    5003             : 
    5004        5645 : int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
    5005             :                                 enum nl80211_iftype nlmode)
    5006             : {
    5007        5645 :         return wpa_driver_nl80211_set_mode_impl(bss, nlmode, NULL);
    5008             : }
    5009             : 
    5010             : 
    5011          21 : static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
    5012             :                                             struct hostapd_freq_params *freq)
    5013             : {
    5014          21 :         return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
    5015             :                                                 freq);
    5016             : }
    5017             : 
    5018             : 
    5019        2804 : static int wpa_driver_nl80211_get_capa(void *priv,
    5020             :                                        struct wpa_driver_capa *capa)
    5021             : {
    5022        2804 :         struct i802_bss *bss = priv;
    5023        2804 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5024             : 
    5025        2804 :         if (!drv->has_capability)
    5026           0 :                 return -1;
    5027        2804 :         os_memcpy(capa, &drv->capa, sizeof(*capa));
    5028        2804 :         if (drv->extended_capa && drv->extended_capa_mask) {
    5029        2804 :                 capa->extended_capa = drv->extended_capa;
    5030        2804 :                 capa->extended_capa_mask = drv->extended_capa_mask;
    5031        2804 :                 capa->extended_capa_len = drv->extended_capa_len;
    5032             :         }
    5033             : 
    5034        2804 :         return 0;
    5035             : }
    5036             : 
    5037             : 
    5038       19516 : static int wpa_driver_nl80211_set_operstate(void *priv, int state)
    5039             : {
    5040       19516 :         struct i802_bss *bss = priv;
    5041       19516 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5042             : 
    5043       39032 :         wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
    5044       19516 :                    bss->ifname, drv->operstate, state,
    5045             :                    state ? "UP" : "DORMANT");
    5046       19516 :         drv->operstate = state;
    5047       19516 :         return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
    5048             :                                       state ? IF_OPER_UP : IF_OPER_DORMANT);
    5049             : }
    5050             : 
    5051             : 
    5052        6894 : static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
    5053             : {
    5054        6894 :         struct i802_bss *bss = priv;
    5055        6894 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5056             :         struct nl_msg *msg;
    5057             :         struct nl80211_sta_flag_update upd;
    5058             :         int ret;
    5059             : 
    5060        6894 :         if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
    5061        3532 :                 wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
    5062        3532 :                 return 0;
    5063             :         }
    5064             : 
    5065       20172 :         wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
    5066       20172 :                    MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
    5067             : 
    5068        3362 :         os_memset(&upd, 0, sizeof(upd));
    5069        3362 :         upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
    5070        3362 :         if (authorized)
    5071        2332 :                 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
    5072             : 
    5073        6724 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
    5074        6724 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid) ||
    5075        3362 :             nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd)) {
    5076           0 :                 nlmsg_free(msg);
    5077           0 :                 return -ENOBUFS;
    5078             :         }
    5079             : 
    5080        3362 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5081        3362 :         if (!ret)
    5082        3330 :                 return 0;
    5083          32 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
    5084             :                    ret, strerror(-ret));
    5085          32 :         return ret;
    5086             : }
    5087             : 
    5088             : 
    5089             : /* Set kernel driver on given frequency (MHz) */
    5090        1965 : static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
    5091             : {
    5092        1965 :         struct i802_bss *bss = priv;
    5093        1965 :         return nl80211_set_channel(bss, freq, 0);
    5094             : }
    5095             : 
    5096             : 
    5097        1870 : static inline int min_int(int a, int b)
    5098             : {
    5099        1870 :         if (a < b)
    5100           0 :                 return a;
    5101        1870 :         return b;
    5102             : }
    5103             : 
    5104             : 
    5105        1870 : static int get_key_handler(struct nl_msg *msg, void *arg)
    5106             : {
    5107             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    5108        1870 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    5109             : 
    5110        1870 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    5111             :                   genlmsg_attrlen(gnlh, 0), NULL);
    5112             : 
    5113             :         /*
    5114             :          * TODO: validate the key index and mac address!
    5115             :          * Otherwise, there's a race condition as soon as
    5116             :          * the kernel starts sending key notifications.
    5117             :          */
    5118             : 
    5119        1870 :         if (tb[NL80211_ATTR_KEY_SEQ])
    5120        1870 :                 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
    5121        1870 :                        min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
    5122        1870 :         return NL_SKIP;
    5123             : }
    5124             : 
    5125             : 
    5126        1870 : static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
    5127             :                            int idx, u8 *seq)
    5128             : {
    5129        1870 :         struct i802_bss *bss = priv;
    5130        1870 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5131             :         struct nl_msg *msg;
    5132             : 
    5133        1870 :         msg = nl80211_ifindex_msg(drv, if_nametoindex(iface), 0,
    5134             :                                   NL80211_CMD_GET_KEY);
    5135        1870 :         if (!msg ||
    5136        1870 :             (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
    5137        1870 :             nla_put_u8(msg, NL80211_ATTR_KEY_IDX, idx)) {
    5138           0 :                 nlmsg_free(msg);
    5139           0 :                 return -ENOBUFS;
    5140             :         }
    5141             : 
    5142        1870 :         memset(seq, 0, 6);
    5143             : 
    5144        1870 :         return send_and_recv_msgs(drv, msg, get_key_handler, seq);
    5145             : }
    5146             : 
    5147             : 
    5148           1 : static int i802_set_rts(void *priv, int rts)
    5149             : {
    5150           1 :         struct i802_bss *bss = priv;
    5151           1 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5152             :         struct nl_msg *msg;
    5153             :         int ret;
    5154             :         u32 val;
    5155             : 
    5156           1 :         if (rts >= 2347)
    5157           0 :                 val = (u32) -1;
    5158             :         else
    5159           1 :                 val = rts;
    5160             : 
    5161           2 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
    5162           1 :             nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
    5163           0 :                 nlmsg_free(msg);
    5164           0 :                 return -ENOBUFS;
    5165             :         }
    5166             : 
    5167           1 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5168           1 :         if (!ret)
    5169           1 :                 return 0;
    5170           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
    5171             :                    "%d (%s)", rts, ret, strerror(-ret));
    5172           0 :         return ret;
    5173             : }
    5174             : 
    5175             : 
    5176           3 : static int i802_set_frag(void *priv, int frag)
    5177             : {
    5178           3 :         struct i802_bss *bss = priv;
    5179           3 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5180             :         struct nl_msg *msg;
    5181             :         int ret;
    5182             :         u32 val;
    5183             : 
    5184           3 :         if (frag >= 2346)
    5185           0 :                 val = (u32) -1;
    5186             :         else
    5187           3 :                 val = frag;
    5188             : 
    5189           6 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
    5190           3 :             nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val)) {
    5191           0 :                 nlmsg_free(msg);
    5192           0 :                 return -ENOBUFS;
    5193             :         }
    5194             : 
    5195           3 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5196           3 :         if (!ret)
    5197           3 :                 return 0;
    5198           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
    5199             :                    "%d: %d (%s)", frag, ret, strerror(-ret));
    5200           0 :         return ret;
    5201             : }
    5202             : 
    5203             : 
    5204        1810 : static int i802_flush(void *priv)
    5205             : {
    5206        1810 :         struct i802_bss *bss = priv;
    5207             :         struct nl_msg *msg;
    5208             :         int res;
    5209             : 
    5210        1810 :         wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
    5211        1810 :                    bss->ifname);
    5212             : 
    5213             :         /*
    5214             :          * XXX: FIX! this needs to flush all VLANs too
    5215             :          */
    5216        1810 :         msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION);
    5217        1810 :         res = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
    5218        1810 :         if (res) {
    5219          33 :                 wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
    5220             :                            "(%s)", res, strerror(-res));
    5221             :         }
    5222        1810 :         return res;
    5223             : }
    5224             : 
    5225             : 
    5226         434 : static int get_sta_handler(struct nl_msg *msg, void *arg)
    5227             : {
    5228             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    5229         434 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    5230         434 :         struct hostap_sta_driver_data *data = arg;
    5231             :         struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
    5232             :         static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
    5233             :                 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
    5234             :                 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
    5235             :                 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
    5236             :                 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
    5237             :                 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
    5238             :                 [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
    5239             :         };
    5240             : 
    5241         434 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    5242             :                   genlmsg_attrlen(gnlh, 0), NULL);
    5243             : 
    5244             :         /*
    5245             :          * TODO: validate the interface and mac address!
    5246             :          * Otherwise, there's a race condition as soon as
    5247             :          * the kernel starts sending station notifications.
    5248             :          */
    5249             : 
    5250         434 :         if (!tb[NL80211_ATTR_STA_INFO]) {
    5251           0 :                 wpa_printf(MSG_DEBUG, "sta stats missing!");
    5252           0 :                 return NL_SKIP;
    5253             :         }
    5254         434 :         if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
    5255             :                              tb[NL80211_ATTR_STA_INFO],
    5256             :                              stats_policy)) {
    5257           0 :                 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
    5258           0 :                 return NL_SKIP;
    5259             :         }
    5260             : 
    5261         434 :         if (stats[NL80211_STA_INFO_INACTIVE_TIME])
    5262         434 :                 data->inactive_msec =
    5263         434 :                         nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
    5264         434 :         if (stats[NL80211_STA_INFO_RX_BYTES])
    5265         434 :                 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
    5266         434 :         if (stats[NL80211_STA_INFO_TX_BYTES])
    5267         434 :                 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
    5268         434 :         if (stats[NL80211_STA_INFO_RX_PACKETS])
    5269         434 :                 data->rx_packets =
    5270         434 :                         nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
    5271         434 :         if (stats[NL80211_STA_INFO_TX_PACKETS])
    5272         434 :                 data->tx_packets =
    5273         434 :                         nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
    5274         434 :         if (stats[NL80211_STA_INFO_TX_FAILED])
    5275         434 :                 data->tx_retry_failed =
    5276         434 :                         nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
    5277             : 
    5278         434 :         return NL_SKIP;
    5279             : }
    5280             : 
    5281         435 : static int i802_read_sta_data(struct i802_bss *bss,
    5282             :                               struct hostap_sta_driver_data *data,
    5283             :                               const u8 *addr)
    5284             : {
    5285             :         struct nl_msg *msg;
    5286             : 
    5287         435 :         os_memset(data, 0, sizeof(*data));
    5288             : 
    5289         870 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_GET_STATION)) ||
    5290         435 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
    5291           0 :                 nlmsg_free(msg);
    5292           0 :                 return -ENOBUFS;
    5293             :         }
    5294             : 
    5295         435 :         return send_and_recv_msgs(bss->drv, msg, get_sta_handler, data);
    5296             : }
    5297             : 
    5298             : 
    5299        6600 : static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
    5300             :                                     int cw_min, int cw_max, int burst_time)
    5301             : {
    5302        6600 :         struct i802_bss *bss = priv;
    5303        6600 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5304             :         struct nl_msg *msg;
    5305             :         struct nlattr *txq, *params;
    5306             : 
    5307        6600 :         msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_WIPHY);
    5308        6600 :         if (!msg)
    5309           0 :                 return -1;
    5310             : 
    5311        6600 :         txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
    5312        6600 :         if (!txq)
    5313           0 :                 goto fail;
    5314             : 
    5315             :         /* We are only sending parameters for a single TXQ at a time */
    5316        6600 :         params = nla_nest_start(msg, 1);
    5317        6600 :         if (!params)
    5318           0 :                 goto fail;
    5319             : 
    5320        6600 :         switch (queue) {
    5321             :         case 0:
    5322        1650 :                 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO))
    5323           0 :                         goto fail;
    5324        1650 :                 break;
    5325             :         case 1:
    5326        1650 :                 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI))
    5327           0 :                         goto fail;
    5328        1650 :                 break;
    5329             :         case 2:
    5330        1650 :                 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE))
    5331           0 :                         goto fail;
    5332        1650 :                 break;
    5333             :         case 3:
    5334        1650 :                 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK))
    5335           0 :                         goto fail;
    5336        1650 :                 break;
    5337             :         }
    5338             :         /* Burst time is configured in units of 0.1 msec and TXOP parameter in
    5339             :          * 32 usec, so need to convert the value here. */
    5340        6600 :         if (nla_put_u16(msg, NL80211_TXQ_ATTR_TXOP,
    5341       13200 :                         (burst_time * 100 + 16) / 32) ||
    5342       13200 :             nla_put_u16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min) ||
    5343       13200 :             nla_put_u16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max) ||
    5344        6600 :             nla_put_u8(msg, NL80211_TXQ_ATTR_AIFS, aifs))
    5345             :                 goto fail;
    5346             : 
    5347        6600 :         nla_nest_end(msg, params);
    5348             : 
    5349        6600 :         nla_nest_end(msg, txq);
    5350             : 
    5351        6600 :         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
    5352        6460 :                 return 0;
    5353         140 :         msg = NULL;
    5354             : fail:
    5355         140 :         nlmsg_free(msg);
    5356         140 :         return -1;
    5357             : }
    5358             : 
    5359             : 
    5360        3465 : static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
    5361             :                              const char *ifname, int vlan_id)
    5362             : {
    5363        3465 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5364             :         struct nl_msg *msg;
    5365             :         int ret;
    5366             : 
    5367       31185 :         wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
    5368             :                    ", ifname=%s[%d], vlan_id=%d)",
    5369        6930 :                    bss->ifname, if_nametoindex(bss->ifname),
    5370       20790 :                    MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
    5371        6930 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
    5372        6930 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
    5373        3465 :             nla_put_u32(msg, NL80211_ATTR_STA_VLAN, if_nametoindex(ifname))) {
    5374           0 :                 nlmsg_free(msg);
    5375           0 :                 return -ENOBUFS;
    5376             :         }
    5377             : 
    5378        3465 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5379        3465 :         if (ret < 0) {
    5380           0 :                 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
    5381             :                            MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
    5382           0 :                            MAC2STR(addr), ifname, vlan_id, ret,
    5383             :                            strerror(-ret));
    5384             :         }
    5385        3465 :         return ret;
    5386             : }
    5387             : 
    5388             : 
    5389           8 : static int i802_get_inact_sec(void *priv, const u8 *addr)
    5390             : {
    5391             :         struct hostap_sta_driver_data data;
    5392             :         int ret;
    5393             : 
    5394           8 :         data.inactive_msec = (unsigned long) -1;
    5395           8 :         ret = i802_read_sta_data(priv, &data, addr);
    5396           8 :         if (ret == -ENOENT)
    5397           0 :                 return -ENOENT;
    5398           8 :         if (ret || data.inactive_msec == (unsigned long) -1)
    5399           0 :                 return -1;
    5400           8 :         return data.inactive_msec / 1000;
    5401             : }
    5402             : 
    5403             : 
    5404        1983 : static int i802_sta_clear_stats(void *priv, const u8 *addr)
    5405             : {
    5406             : #if 0
    5407             :         /* TODO */
    5408             : #endif
    5409        1983 :         return 0;
    5410             : }
    5411             : 
    5412             : 
    5413        4390 : static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
    5414             :                            int reason)
    5415             : {
    5416        4390 :         struct i802_bss *bss = priv;
    5417        4390 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5418             :         struct ieee80211_mgmt mgmt;
    5419             : 
    5420        4390 :         if (is_mesh_interface(drv->nlmode))
    5421          39 :                 return -1;
    5422             : 
    5423        4351 :         if (drv->device_ap_sme)
    5424           0 :                 return wpa_driver_nl80211_sta_remove(bss, addr, 1, reason);
    5425             : 
    5426        4351 :         memset(&mgmt, 0, sizeof(mgmt));
    5427        4351 :         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    5428             :                                           WLAN_FC_STYPE_DEAUTH);
    5429        4351 :         memcpy(mgmt.da, addr, ETH_ALEN);
    5430        4351 :         memcpy(mgmt.sa, own_addr, ETH_ALEN);
    5431        4351 :         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
    5432        4351 :         mgmt.u.deauth.reason_code = host_to_le16(reason);
    5433        4351 :         return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
    5434             :                                             IEEE80211_HDRLEN +
    5435             :                                             sizeof(mgmt.u.deauth), 0, 0, 0, 0,
    5436             :                                             0);
    5437             : }
    5438             : 
    5439             : 
    5440           5 : static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
    5441             :                              int reason)
    5442             : {
    5443           5 :         struct i802_bss *bss = priv;
    5444           5 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5445             :         struct ieee80211_mgmt mgmt;
    5446             : 
    5447           5 :         if (is_mesh_interface(drv->nlmode))
    5448           0 :                 return -1;
    5449             : 
    5450           5 :         if (drv->device_ap_sme)
    5451           0 :                 return wpa_driver_nl80211_sta_remove(bss, addr, 0, reason);
    5452             : 
    5453           5 :         memset(&mgmt, 0, sizeof(mgmt));
    5454           5 :         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    5455             :                                           WLAN_FC_STYPE_DISASSOC);
    5456           5 :         memcpy(mgmt.da, addr, ETH_ALEN);
    5457           5 :         memcpy(mgmt.sa, own_addr, ETH_ALEN);
    5458           5 :         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
    5459           5 :         mgmt.u.disassoc.reason_code = host_to_le16(reason);
    5460           5 :         return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
    5461             :                                             IEEE80211_HDRLEN +
    5462             :                                             sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
    5463             :                                             0);
    5464             : }
    5465             : 
    5466             : 
    5467        4087 : static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
    5468             : {
    5469             :         char buf[200], *pos, *end;
    5470             :         int i, res;
    5471             : 
    5472        4087 :         pos = buf;
    5473        4087 :         end = pos + sizeof(buf);
    5474             : 
    5475       69496 :         for (i = 0; i < drv->num_if_indices; i++) {
    5476       65409 :                 if (!drv->if_indices[i])
    5477       63046 :                         continue;
    5478        2363 :                 res = os_snprintf(pos, end - pos, " %d", drv->if_indices[i]);
    5479        2363 :                 if (os_snprintf_error(end - pos, res))
    5480           0 :                         break;
    5481        2363 :                 pos += res;
    5482             :         }
    5483        4087 :         *pos = '\0';
    5484             : 
    5485        4087 :         wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
    5486             :                    drv->num_if_indices, buf);
    5487        4087 : }
    5488             : 
    5489             : 
    5490        2040 : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
    5491             : {
    5492             :         int i;
    5493             :         int *old;
    5494             : 
    5495        2040 :         wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
    5496             :                    ifidx);
    5497        2040 :         if (have_ifidx(drv, ifidx)) {
    5498         283 :                 wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
    5499             :                            ifidx);
    5500         283 :                 return;
    5501             :         }
    5502        2060 :         for (i = 0; i < drv->num_if_indices; i++) {
    5503        2059 :                 if (drv->if_indices[i] == 0) {
    5504        1756 :                         drv->if_indices[i] = ifidx;
    5505        1756 :                         dump_ifidx(drv);
    5506        1756 :                         return;
    5507             :                 }
    5508             :         }
    5509             : 
    5510           1 :         if (drv->if_indices != drv->default_if_indices)
    5511           0 :                 old = drv->if_indices;
    5512             :         else
    5513           1 :                 old = NULL;
    5514             : 
    5515           1 :         drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
    5516             :                                            sizeof(int));
    5517           1 :         if (!drv->if_indices) {
    5518           0 :                 if (!old)
    5519           0 :                         drv->if_indices = drv->default_if_indices;
    5520             :                 else
    5521           0 :                         drv->if_indices = old;
    5522           0 :                 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
    5523             :                            "interfaces");
    5524           0 :                 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
    5525           0 :                 return;
    5526           1 :         } else if (!old)
    5527           1 :                 os_memcpy(drv->if_indices, drv->default_if_indices,
    5528             :                           sizeof(drv->default_if_indices));
    5529           1 :         drv->if_indices[drv->num_if_indices] = ifidx;
    5530           1 :         drv->num_if_indices++;
    5531           1 :         dump_ifidx(drv);
    5532             : }
    5533             : 
    5534             : 
    5535        2330 : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
    5536             : {
    5537             :         int i;
    5538             : 
    5539       38286 :         for (i = 0; i < drv->num_if_indices; i++) {
    5540       36054 :                 if (drv->if_indices[i] == ifidx) {
    5541          98 :                         drv->if_indices[i] = 0;
    5542          98 :                         break;
    5543             :                 }
    5544             :         }
    5545        2330 :         dump_ifidx(drv);
    5546        2330 : }
    5547             : 
    5548             : 
    5549      141527 : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
    5550             : {
    5551             :         int i;
    5552             : 
    5553     2264740 :         for (i = 0; i < drv->num_if_indices; i++)
    5554     2132180 :                 if (drv->if_indices[i] == ifidx)
    5555        8967 :                         return 1;
    5556             : 
    5557      132560 :         return 0;
    5558             : }
    5559             : 
    5560             : 
    5561           2 : static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
    5562             :                             const char *bridge_ifname, char *ifname_wds)
    5563             : {
    5564           2 :         struct i802_bss *bss = priv;
    5565           2 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5566             :         char name[IFNAMSIZ + 1];
    5567             : 
    5568           2 :         os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
    5569           2 :         if (ifname_wds)
    5570           1 :                 os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
    5571             : 
    5572          12 :         wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
    5573          12 :                    " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
    5574           2 :         if (val) {
    5575           1 :                 if (!if_nametoindex(name)) {
    5576           1 :                         if (nl80211_create_iface(drv, name,
    5577             :                                                  NL80211_IFTYPE_AP_VLAN,
    5578           1 :                                                  bss->addr, 1, NULL, NULL, 0) <
    5579             :                             0)
    5580           0 :                                 return -1;
    5581           2 :                         if (bridge_ifname &&
    5582           1 :                             linux_br_add_if(drv->global->ioctl_sock,
    5583             :                                             bridge_ifname, name) < 0)
    5584           0 :                                 return -1;
    5585             :                 }
    5586           1 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
    5587           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
    5588             :                                    "interface %s up", name);
    5589             :                 }
    5590           1 :                 return i802_set_sta_vlan(priv, addr, name, 0);
    5591             :         } else {
    5592           1 :                 if (bridge_ifname)
    5593           1 :                         linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
    5594             :                                         name);
    5595             : 
    5596           1 :                 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
    5597           1 :                 nl80211_remove_iface(drv, if_nametoindex(name));
    5598           1 :                 return 0;
    5599             :         }
    5600             : }
    5601             : 
    5602             : 
    5603       19332 : static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
    5604             : {
    5605       19332 :         struct wpa_driver_nl80211_data *drv = eloop_ctx;
    5606             :         struct sockaddr_ll lladdr;
    5607             :         unsigned char buf[3000];
    5608             :         int len;
    5609       19332 :         socklen_t fromlen = sizeof(lladdr);
    5610             : 
    5611       19332 :         len = recvfrom(sock, buf, sizeof(buf), 0,
    5612             :                        (struct sockaddr *)&lladdr, &fromlen);
    5613       19332 :         if (len < 0) {
    5614           0 :                 wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
    5615           0 :                            strerror(errno));
    5616       19332 :                 return;
    5617             :         }
    5618             : 
    5619       19332 :         if (have_ifidx(drv, lladdr.sll_ifindex))
    5620        8105 :                 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
    5621             : }
    5622             : 
    5623             : 
    5624          19 : static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
    5625             :                              struct i802_bss *bss,
    5626             :                              const char *brname, const char *ifname)
    5627             : {
    5628             :         int br_ifindex;
    5629             :         char in_br[IFNAMSIZ];
    5630             : 
    5631          19 :         os_strlcpy(bss->brname, brname, IFNAMSIZ);
    5632          19 :         br_ifindex = if_nametoindex(brname);
    5633          19 :         if (br_ifindex == 0) {
    5634             :                 /*
    5635             :                  * Bridge was configured, but the bridge device does
    5636             :                  * not exist. Try to add it now.
    5637             :                  */
    5638          12 :                 if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
    5639           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
    5640             :                                    "bridge interface %s: %s",
    5641           0 :                                    brname, strerror(errno));
    5642           0 :                         return -1;
    5643             :                 }
    5644          12 :                 bss->added_bridge = 1;
    5645          12 :                 br_ifindex = if_nametoindex(brname);
    5646          12 :                 add_ifidx(drv, br_ifindex);
    5647             :         }
    5648          19 :         bss->br_ifindex = br_ifindex;
    5649             : 
    5650          19 :         if (linux_br_get(in_br, ifname) == 0) {
    5651           1 :                 if (os_strcmp(in_br, brname) == 0)
    5652           0 :                         return 0; /* already in the bridge */
    5653             : 
    5654           1 :                 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
    5655             :                            "bridge %s", ifname, in_br);
    5656           1 :                 if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
    5657             :                     0) {
    5658           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to "
    5659             :                                    "remove interface %s from bridge "
    5660             :                                    "%s: %s",
    5661           0 :                                    ifname, brname, strerror(errno));
    5662           0 :                         return -1;
    5663             :                 }
    5664             :         }
    5665             : 
    5666          19 :         wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
    5667             :                    ifname, brname);
    5668          19 :         if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
    5669           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
    5670             :                            "into bridge %s: %s",
    5671           0 :                            ifname, brname, strerror(errno));
    5672           0 :                 return -1;
    5673             :         }
    5674          19 :         bss->added_if_into_bridge = 1;
    5675             : 
    5676          19 :         return 0;
    5677             : }
    5678             : 
    5679             : 
    5680        1651 : static void *i802_init(struct hostapd_data *hapd,
    5681             :                        struct wpa_init_params *params)
    5682             : {
    5683             :         struct wpa_driver_nl80211_data *drv;
    5684             :         struct i802_bss *bss;
    5685             :         size_t i;
    5686             :         char master_ifname[IFNAMSIZ];
    5687        1651 :         int ifindex, br_ifindex = 0;
    5688        1651 :         int br_added = 0;
    5689             : 
    5690        1651 :         bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
    5691             :                                           params->global_priv, 1,
    5692             :                                           params->bssid, params->driver_params);
    5693        1651 :         if (bss == NULL)
    5694          12 :                 return NULL;
    5695             : 
    5696        1639 :         drv = bss->drv;
    5697             : 
    5698        1639 :         if (linux_br_get(master_ifname, params->ifname) == 0) {
    5699           2 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
    5700             :                            params->ifname, master_ifname);
    5701           2 :                 br_ifindex = if_nametoindex(master_ifname);
    5702           2 :                 os_strlcpy(bss->brname, master_ifname, IFNAMSIZ);
    5703        3256 :         } else if ((params->num_bridge == 0 || !params->bridge[0]) &&
    5704        1619 :                    linux_master_get(master_ifname, params->ifname) == 0) {
    5705           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in master %s",
    5706             :                         params->ifname, master_ifname);
    5707             :                 /* start listening for EAPOL on the master interface */
    5708           0 :                 add_ifidx(drv, if_nametoindex(master_ifname));
    5709             :         } else {
    5710        1637 :                 master_ifname[0] = '\0';
    5711             :         }
    5712             : 
    5713        1639 :         bss->br_ifindex = br_ifindex;
    5714             : 
    5715        3286 :         for (i = 0; i < params->num_bridge; i++) {
    5716        1647 :                 if (params->bridge[i]) {
    5717          19 :                         ifindex = if_nametoindex(params->bridge[i]);
    5718          19 :                         if (ifindex)
    5719           7 :                                 add_ifidx(drv, ifindex);
    5720          19 :                         if (ifindex == br_ifindex)
    5721          11 :                                 br_added = 1;
    5722             :                 }
    5723             :         }
    5724             : 
    5725             :         /* start listening for EAPOL on the default AP interface */
    5726        1639 :         add_ifidx(drv, drv->ifindex);
    5727             : 
    5728        1639 :         if (params->num_bridge && params->bridge[0]) {
    5729          19 :                 if (i802_check_bridge(drv, bss, params->bridge[0],
    5730             :                                       params->ifname) < 0)
    5731           0 :                         goto failed;
    5732          19 :                 if (os_strcmp(params->bridge[0], master_ifname) != 0)
    5733          19 :                         br_added = 1;
    5734             :         }
    5735             : 
    5736        1640 :         if (!br_added && br_ifindex &&
    5737           2 :             (params->num_bridge == 0 || !params->bridge[0]))
    5738           1 :                 add_ifidx(drv, br_ifindex);
    5739             : 
    5740             : #ifdef CONFIG_LIBNL3_ROUTE
    5741        1639 :         if (bss->added_if_into_bridge) {
    5742          19 :                 drv->rtnl_sk = nl_socket_alloc();
    5743          19 :                 if (drv->rtnl_sk == NULL) {
    5744           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
    5745           0 :                         goto failed;
    5746             :                 }
    5747             : 
    5748          19 :                 if (nl_connect(drv->rtnl_sk, NETLINK_ROUTE)) {
    5749           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
    5750           0 :                                    strerror(errno));
    5751           0 :                         goto failed;
    5752             :                 }
    5753             :         }
    5754             : #endif /* CONFIG_LIBNL3_ROUTE */
    5755             : 
    5756        1639 :         drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
    5757        1639 :         if (drv->eapol_sock < 0) {
    5758           0 :                 wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
    5759           0 :                            strerror(errno));
    5760           0 :                 goto failed;
    5761             :         }
    5762             : 
    5763        1639 :         if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
    5764             :         {
    5765           1 :                 wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
    5766           1 :                 goto failed;
    5767             :         }
    5768             : 
    5769        1638 :         if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    5770             :                                params->own_addr))
    5771           0 :                 goto failed;
    5772        1638 :         os_memcpy(drv->perm_addr, params->own_addr, ETH_ALEN);
    5773             : 
    5774        1638 :         memcpy(bss->addr, params->own_addr, ETH_ALEN);
    5775             : 
    5776        1638 :         return bss;
    5777             : 
    5778             : failed:
    5779           1 :         wpa_driver_nl80211_deinit(bss);
    5780           1 :         return NULL;
    5781             : }
    5782             : 
    5783             : 
    5784        1638 : static void i802_deinit(void *priv)
    5785             : {
    5786        1638 :         struct i802_bss *bss = priv;
    5787        1638 :         wpa_driver_nl80211_deinit(bss);
    5788        1638 : }
    5789             : 
    5790             : 
    5791         230 : static enum nl80211_iftype wpa_driver_nl80211_if_type(
    5792             :         enum wpa_driver_if_type type)
    5793             : {
    5794         230 :         switch (type) {
    5795             :         case WPA_IF_STATION:
    5796          11 :                 return NL80211_IFTYPE_STATION;
    5797             :         case WPA_IF_P2P_CLIENT:
    5798             :         case WPA_IF_P2P_GROUP:
    5799          41 :                 return NL80211_IFTYPE_P2P_CLIENT;
    5800             :         case WPA_IF_AP_VLAN:
    5801          21 :                 return NL80211_IFTYPE_AP_VLAN;
    5802             :         case WPA_IF_AP_BSS:
    5803          43 :                 return NL80211_IFTYPE_AP;
    5804             :         case WPA_IF_P2P_GO:
    5805         102 :                 return NL80211_IFTYPE_P2P_GO;
    5806             :         case WPA_IF_P2P_DEVICE:
    5807           8 :                 return NL80211_IFTYPE_P2P_DEVICE;
    5808             :         case WPA_IF_MESH:
    5809           4 :                 return NL80211_IFTYPE_MESH_POINT;
    5810             :         default:
    5811           0 :                 return -1;
    5812             :         }
    5813             : }
    5814             : 
    5815             : 
    5816        2332 : static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
    5817             : {
    5818             :         struct wpa_driver_nl80211_data *drv;
    5819       50179 :         dl_list_for_each(drv, &global->interfaces,
    5820             :                          struct wpa_driver_nl80211_data, list) {
    5821       50022 :                 if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
    5822        2175 :                         return 1;
    5823             :         }
    5824         157 :         return 0;
    5825             : }
    5826             : 
    5827             : 
    5828          81 : static int nl80211_vif_addr(struct wpa_driver_nl80211_data *drv, u8 *new_addr)
    5829             : {
    5830             :         unsigned int idx;
    5831             : 
    5832          81 :         if (!drv->global)
    5833           0 :                 return -1;
    5834             : 
    5835          81 :         os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
    5836        2175 :         for (idx = 0; idx < 64; idx++) {
    5837        2174 :                 new_addr[0] = drv->first_bss->addr[0] | 0x02;
    5838        2174 :                 new_addr[0] ^= idx << 2;
    5839        2174 :                 if (!nl80211_addr_in_use(drv->global, new_addr))
    5840          80 :                         break;
    5841             :         }
    5842          81 :         if (idx == 64)
    5843           1 :                 return -1;
    5844             : 
    5845         480 :         wpa_printf(MSG_DEBUG, "nl80211: Assigned new virtual interface address "
    5846         480 :                    MACSTR, MAC2STR(new_addr));
    5847             : 
    5848          80 :         return 0;
    5849             : }
    5850             : 
    5851             : 
    5852             : struct wdev_info {
    5853             :         u64 wdev_id;
    5854             :         int wdev_id_set;
    5855             :         u8 macaddr[ETH_ALEN];
    5856             : };
    5857             : 
    5858           8 : static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
    5859             : {
    5860           8 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    5861             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    5862           8 :         struct wdev_info *wi = arg;
    5863             : 
    5864           8 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    5865             :                   genlmsg_attrlen(gnlh, 0), NULL);
    5866           8 :         if (tb[NL80211_ATTR_WDEV]) {
    5867           8 :                 wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
    5868           8 :                 wi->wdev_id_set = 1;
    5869             :         }
    5870             : 
    5871           8 :         if (tb[NL80211_ATTR_MAC])
    5872           8 :                 os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
    5873             :                           ETH_ALEN);
    5874             : 
    5875           8 :         return NL_SKIP;
    5876             : }
    5877             : 
    5878             : 
    5879         230 : static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
    5880             :                                      const char *ifname, const u8 *addr,
    5881             :                                      void *bss_ctx, void **drv_priv,
    5882             :                                      char *force_ifname, u8 *if_addr,
    5883             :                                      const char *bridge, int use_existing)
    5884             : {
    5885             :         enum nl80211_iftype nlmode;
    5886         230 :         struct i802_bss *bss = priv;
    5887         230 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5888             :         int ifidx;
    5889         230 :         int added = 1;
    5890             : 
    5891         230 :         if (addr)
    5892          64 :                 os_memcpy(if_addr, addr, ETH_ALEN);
    5893         230 :         nlmode = wpa_driver_nl80211_if_type(type);
    5894         230 :         if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
    5895             :                 struct wdev_info p2pdev_info;
    5896             : 
    5897           8 :                 os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
    5898           8 :                 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
    5899             :                                              0, nl80211_wdev_handler,
    5900             :                                              &p2pdev_info, use_existing);
    5901           8 :                 if (!p2pdev_info.wdev_id_set || ifidx != 0) {
    5902           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
    5903             :                                    ifname);
    5904           0 :                         return -1;
    5905             :                 }
    5906             : 
    5907           8 :                 drv->global->if_add_wdevid = p2pdev_info.wdev_id;
    5908           8 :                 drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
    5909           8 :                 if (!is_zero_ether_addr(p2pdev_info.macaddr))
    5910           8 :                         os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
    5911           8 :                 wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
    5912             :                            ifname,
    5913           8 :                            (long long unsigned int) p2pdev_info.wdev_id);
    5914             :         } else {
    5915         222 :                 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
    5916             :                                              0, NULL, NULL, use_existing);
    5917         222 :                 if (use_existing && ifidx == -ENFILE) {
    5918           1 :                         added = 0;
    5919           1 :                         ifidx = if_nametoindex(ifname);
    5920         221 :                 } else if (ifidx < 0) {
    5921           0 :                         return -1;
    5922             :                 }
    5923             :         }
    5924             : 
    5925         230 :         if (!addr) {
    5926         166 :                 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    5927           8 :                         os_memcpy(if_addr, bss->addr, ETH_ALEN);
    5928         158 :                 else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
    5929             :                                             ifname, if_addr) < 0) {
    5930           0 :                         if (added)
    5931           0 :                                 nl80211_remove_iface(drv, ifidx);
    5932           0 :                         return -1;
    5933             :                 }
    5934             :         }
    5935             : 
    5936         230 :         if (!addr &&
    5937         152 :             (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
    5938          23 :              type == WPA_IF_P2P_GO || type == WPA_IF_MESH ||
    5939             :              type == WPA_IF_STATION)) {
    5940             :                 /* Enforce unique address */
    5941             :                 u8 new_addr[ETH_ALEN];
    5942             : 
    5943         158 :                 if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
    5944             :                                        new_addr) < 0) {
    5945           0 :                         if (added)
    5946           0 :                                 nl80211_remove_iface(drv, ifidx);
    5947           1 :                         return -1;
    5948             :                 }
    5949         158 :                 if (nl80211_addr_in_use(drv->global, new_addr)) {
    5950          81 :                         wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
    5951             :                                    "for interface %s type %d", ifname, type);
    5952          81 :                         if (nl80211_vif_addr(drv, new_addr) < 0) {
    5953           1 :                                 if (added)
    5954           1 :                                         nl80211_remove_iface(drv, ifidx);
    5955           1 :                                 return -1;
    5956             :                         }
    5957          80 :                         if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
    5958             :                                                new_addr) < 0) {
    5959           0 :                                 if (added)
    5960           0 :                                         nl80211_remove_iface(drv, ifidx);
    5961           0 :                                 return -1;
    5962             :                         }
    5963             :                 }
    5964         157 :                 os_memcpy(if_addr, new_addr, ETH_ALEN);
    5965             :         }
    5966             : 
    5967         229 :         if (type == WPA_IF_AP_BSS) {
    5968          43 :                 struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
    5969          43 :                 if (new_bss == NULL) {
    5970           0 :                         if (added)
    5971           0 :                                 nl80211_remove_iface(drv, ifidx);
    5972           0 :                         return -1;
    5973             :                 }
    5974             : 
    5975          43 :                 if (bridge &&
    5976           0 :                     i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
    5977           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
    5978             :                                    "interface %s to a bridge %s",
    5979             :                                    ifname, bridge);
    5980           0 :                         if (added)
    5981           0 :                                 nl80211_remove_iface(drv, ifidx);
    5982           0 :                         os_free(new_bss);
    5983           0 :                         return -1;
    5984             :                 }
    5985             : 
    5986          43 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
    5987             :                 {
    5988           0 :                         if (added)
    5989           0 :                                 nl80211_remove_iface(drv, ifidx);
    5990           0 :                         os_free(new_bss);
    5991           0 :                         return -1;
    5992             :                 }
    5993          43 :                 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
    5994          43 :                 os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
    5995          43 :                 new_bss->ifindex = ifidx;
    5996          43 :                 new_bss->drv = drv;
    5997          43 :                 new_bss->next = drv->first_bss->next;
    5998          43 :                 new_bss->freq = drv->first_bss->freq;
    5999          43 :                 new_bss->ctx = bss_ctx;
    6000          43 :                 new_bss->added_if = added;
    6001          43 :                 drv->first_bss->next = new_bss;
    6002          43 :                 if (drv_priv)
    6003          43 :                         *drv_priv = new_bss;
    6004          43 :                 nl80211_init_bss(new_bss);
    6005             : 
    6006             :                 /* Subscribe management frames for this WPA_IF_AP_BSS */
    6007          43 :                 if (nl80211_setup_ap(new_bss))
    6008           0 :                         return -1;
    6009             :         }
    6010             : 
    6011         229 :         if (drv->global)
    6012         229 :                 drv->global->if_add_ifindex = ifidx;
    6013             : 
    6014             :         /*
    6015             :          * Some virtual interfaces need to process EAPOL packets and events on
    6016             :          * the parent interface. This is used mainly with hostapd.
    6017             :          */
    6018         450 :         if (ifidx > 0 &&
    6019         378 :             (drv->hostapd ||
    6020         157 :              nlmode == NL80211_IFTYPE_AP_VLAN ||
    6021         157 :              nlmode == NL80211_IFTYPE_WDS ||
    6022             :              nlmode == NL80211_IFTYPE_MONITOR))
    6023          64 :                 add_ifidx(drv, ifidx);
    6024             : 
    6025         229 :         return 0;
    6026             : }
    6027             : 
    6028             : 
    6029         217 : static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
    6030             :                                         enum wpa_driver_if_type type,
    6031             :                                         const char *ifname)
    6032             : {
    6033         217 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6034         217 :         int ifindex = if_nametoindex(ifname);
    6035             : 
    6036         217 :         wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
    6037         217 :                    __func__, type, ifname, ifindex, bss->added_if);
    6038         217 :         if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
    6039         213 :                 nl80211_remove_iface(drv, ifindex);
    6040           4 :         else if (ifindex > 0 && !bss->added_if) {
    6041             :                 struct wpa_driver_nl80211_data *drv2;
    6042           2 :                 dl_list_for_each(drv2, &drv->global->interfaces,
    6043             :                                  struct wpa_driver_nl80211_data, list)
    6044           1 :                         del_ifidx(drv2, ifindex);
    6045             :         }
    6046             : 
    6047         217 :         if (type != WPA_IF_AP_BSS)
    6048         174 :                 return 0;
    6049             : 
    6050          43 :         if (bss->added_if_into_bridge) {
    6051           0 :                 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
    6052           0 :                                     bss->ifname) < 0)
    6053           0 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
    6054             :                                    "interface %s from bridge %s: %s",
    6055           0 :                                    bss->ifname, bss->brname, strerror(errno));
    6056             :         }
    6057          43 :         if (bss->added_bridge) {
    6058           0 :                 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
    6059           0 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
    6060             :                                    "bridge %s: %s",
    6061           0 :                                    bss->brname, strerror(errno));
    6062             :         }
    6063             : 
    6064          43 :         if (bss != drv->first_bss) {
    6065             :                 struct i802_bss *tbss;
    6066             : 
    6067          43 :                 wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
    6068         166 :                 for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
    6069         166 :                         if (tbss->next == bss) {
    6070          43 :                                 tbss->next = bss->next;
    6071             :                                 /* Unsubscribe management frames */
    6072          43 :                                 nl80211_teardown_ap(bss);
    6073          43 :                                 nl80211_destroy_bss(bss);
    6074          43 :                                 if (!bss->added_if)
    6075           1 :                                         i802_set_iface_flags(bss, 0);
    6076          43 :                                 os_free(bss);
    6077          43 :                                 bss = NULL;
    6078          43 :                                 break;
    6079             :                         }
    6080             :                 }
    6081          43 :                 if (bss)
    6082           0 :                         wpa_printf(MSG_INFO, "nl80211: %s - could not find "
    6083             :                                    "BSS %p in the list", __func__, bss);
    6084             :         } else {
    6085           0 :                 wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
    6086           0 :                 nl80211_teardown_ap(bss);
    6087           0 :                 if (!bss->added_if && !drv->first_bss->next)
    6088           0 :                         wpa_driver_nl80211_del_beacon(drv);
    6089           0 :                 nl80211_destroy_bss(bss);
    6090           0 :                 if (!bss->added_if)
    6091           0 :                         i802_set_iface_flags(bss, 0);
    6092           0 :                 if (drv->first_bss->next) {
    6093           0 :                         drv->first_bss = drv->first_bss->next;
    6094           0 :                         drv->ctx = drv->first_bss->ctx;
    6095           0 :                         os_free(bss);
    6096             :                 } else {
    6097           0 :                         wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
    6098             :                 }
    6099             :         }
    6100             : 
    6101          43 :         return 0;
    6102             : }
    6103             : 
    6104             : 
    6105       15686 : static int cookie_handler(struct nl_msg *msg, void *arg)
    6106             : {
    6107             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    6108       15686 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    6109       15686 :         u64 *cookie = arg;
    6110       15686 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    6111             :                   genlmsg_attrlen(gnlh, 0), NULL);
    6112       15686 :         if (tb[NL80211_ATTR_COOKIE])
    6113       15686 :                 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
    6114       15686 :         return NL_SKIP;
    6115             : }
    6116             : 
    6117             : 
    6118       19966 : static int nl80211_send_frame_cmd(struct i802_bss *bss,
    6119             :                                   unsigned int freq, unsigned int wait,
    6120             :                                   const u8 *buf, size_t buf_len,
    6121             :                                   u64 *cookie_out, int no_cck, int no_ack,
    6122             :                                   int offchanok)
    6123             : {
    6124       19966 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6125             :         struct nl_msg *msg;
    6126             :         u64 cookie;
    6127       19966 :         int ret = -1;
    6128             : 
    6129       19966 :         wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
    6130             :                    "no_ack=%d offchanok=%d",
    6131             :                    freq, wait, no_cck, no_ack, offchanok);
    6132       19966 :         wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
    6133             : 
    6134       19966 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME)) ||
    6135       19925 :             (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
    6136        1793 :             (wait && nla_put_u32(msg, NL80211_ATTR_DURATION, wait)) ||
    6137        4102 :             (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
    6138        4102 :                            drv->test_use_roc_tx) &&
    6139       24068 :              nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) ||
    6140        2134 :             (no_cck && nla_put_flag(msg, NL80211_ATTR_TX_NO_CCK_RATE)) ||
    6141       24267 :             (no_ack && nla_put_flag(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK)) ||
    6142       19966 :             nla_put(msg, NL80211_ATTR_FRAME, buf_len, buf))
    6143             :                 goto fail;
    6144             : 
    6145       19966 :         cookie = 0;
    6146       19966 :         ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
    6147       19966 :         msg = NULL;
    6148       19966 :         if (ret) {
    6149        1778 :                 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
    6150             :                            "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
    6151             :                            freq, wait);
    6152             :         } else {
    6153       18188 :                 wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
    6154             :                            "cookie 0x%llx", no_ack ? " (no ACK)" : "",
    6155             :                            (long long unsigned int) cookie);
    6156             : 
    6157       18188 :                 if (cookie_out)
    6158       17448 :                         *cookie_out = no_ack ? (u64) -1 : cookie;
    6159             :         }
    6160             : 
    6161             : fail:
    6162       19966 :         nlmsg_free(msg);
    6163       19966 :         return ret;
    6164             : }
    6165             : 
    6166             : 
    6167        3363 : static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
    6168             :                                           unsigned int freq,
    6169             :                                           unsigned int wait_time,
    6170             :                                           const u8 *dst, const u8 *src,
    6171             :                                           const u8 *bssid,
    6172             :                                           const u8 *data, size_t data_len,
    6173             :                                           int no_cck)
    6174             : {
    6175        3363 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6176        3363 :         int ret = -1;
    6177             :         u8 *buf;
    6178             :         struct ieee80211_hdr *hdr;
    6179             : 
    6180        3363 :         wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
    6181             :                    "freq=%u MHz wait=%d ms no_cck=%d)",
    6182             :                    drv->ifindex, freq, wait_time, no_cck);
    6183             : 
    6184        3363 :         buf = os_zalloc(24 + data_len);
    6185        3363 :         if (buf == NULL)
    6186           1 :                 return ret;
    6187        3362 :         os_memcpy(buf + 24, data, data_len);
    6188        3362 :         hdr = (struct ieee80211_hdr *) buf;
    6189        3362 :         hdr->frame_control =
    6190             :                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
    6191        3362 :         os_memcpy(hdr->addr1, dst, ETH_ALEN);
    6192        3362 :         os_memcpy(hdr->addr2, src, ETH_ALEN);
    6193        3362 :         os_memcpy(hdr->addr3, bssid, ETH_ALEN);
    6194             : 
    6195        4049 :         if (is_ap_interface(drv->nlmode) &&
    6196        1374 :             (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
    6197         705 :              (int) freq == bss->freq || drv->device_ap_sme ||
    6198           9 :              !drv->use_monitor))
    6199         687 :                 ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
    6200             :                                                    0, freq, no_cck, 1,
    6201             :                                                    wait_time);
    6202             :         else
    6203        2675 :                 ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
    6204             :                                              24 + data_len,
    6205             :                                              &drv->send_action_cookie,
    6206             :                                              no_cck, 0, 1);
    6207             : 
    6208        3362 :         os_free(buf);
    6209        3362 :         return ret;
    6210             : }
    6211             : 
    6212             : 
    6213        1174 : static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
    6214             : {
    6215        1174 :         struct i802_bss *bss = priv;
    6216        1174 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6217             :         struct nl_msg *msg;
    6218             :         int ret;
    6219             : 
    6220        1174 :         wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
    6221        1174 :                    (long long unsigned int) drv->send_action_cookie);
    6222        2348 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME_WAIT_CANCEL)) ||
    6223        1174 :             nla_put_u64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie)) {
    6224           0 :                 nlmsg_free(msg);
    6225        1174 :                 return;
    6226             :         }
    6227             : 
    6228        1174 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    6229        1174 :         if (ret)
    6230         121 :                 wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
    6231             :                            "(%s)", ret, strerror(-ret));
    6232             : }
    6233             : 
    6234             : 
    6235        1795 : static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
    6236             :                                                 unsigned int duration)
    6237             : {
    6238        1795 :         struct i802_bss *bss = priv;
    6239        1795 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6240             :         struct nl_msg *msg;
    6241             :         int ret;
    6242             :         u64 cookie;
    6243             : 
    6244        3590 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REMAIN_ON_CHANNEL)) ||
    6245        3590 :             nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
    6246        1795 :             nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) {
    6247           0 :                 nlmsg_free(msg);
    6248           0 :                 return -1;
    6249             :         }
    6250             : 
    6251        1795 :         cookie = 0;
    6252        1795 :         ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
    6253        1795 :         if (ret == 0) {
    6254        1795 :                 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
    6255             :                            "0x%llx for freq=%u MHz duration=%u",
    6256             :                            (long long unsigned int) cookie, freq, duration);
    6257        1795 :                 drv->remain_on_chan_cookie = cookie;
    6258        1795 :                 drv->pending_remain_on_chan = 1;
    6259        1795 :                 return 0;
    6260             :         }
    6261           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
    6262             :                    "(freq=%d duration=%u): %d (%s)",
    6263             :                    freq, duration, ret, strerror(-ret));
    6264           0 :         return -1;
    6265             : }
    6266             : 
    6267             : 
    6268         831 : static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
    6269             : {
    6270         831 :         struct i802_bss *bss = priv;
    6271         831 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6272             :         struct nl_msg *msg;
    6273             :         int ret;
    6274             : 
    6275         831 :         if (!drv->pending_remain_on_chan) {
    6276           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
    6277             :                            "to cancel");
    6278           0 :                 return -1;
    6279             :         }
    6280             : 
    6281         831 :         wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
    6282             :                    "0x%llx",
    6283         831 :                    (long long unsigned int) drv->remain_on_chan_cookie);
    6284             : 
    6285         831 :         msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
    6286        1662 :         if (!msg ||
    6287         831 :             nla_put_u64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie)) {
    6288           0 :                 nlmsg_free(msg);
    6289           0 :                 return -1;
    6290             :         }
    6291             : 
    6292         831 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    6293         831 :         if (ret == 0)
    6294         831 :                 return 0;
    6295           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
    6296             :                    "%d (%s)", ret, strerror(-ret));
    6297           0 :         return -1;
    6298             : }
    6299             : 
    6300             : 
    6301       31231 : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
    6302             : {
    6303       31231 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6304             : 
    6305       31231 :         if (!report) {
    6306       29429 :                 if (bss->nl_preq && drv->device_ap_sme &&
    6307           0 :                     is_ap_interface(drv->nlmode) && !bss->in_deinit &&
    6308           0 :                     !bss->static_ap) {
    6309             :                         /*
    6310             :                          * Do not disable Probe Request reporting that was
    6311             :                          * enabled in nl80211_setup_ap().
    6312             :                          */
    6313           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
    6314             :                                    "Probe Request reporting nl_preq=%p while "
    6315             :                                    "in AP mode", bss->nl_preq);
    6316       29429 :                 } else if (bss->nl_preq) {
    6317        1385 :                         wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
    6318             :                                    "reporting nl_preq=%p", bss->nl_preq);
    6319        1385 :                         nl80211_destroy_eloop_handle(&bss->nl_preq);
    6320             :                 }
    6321       29429 :                 return 0;
    6322             :         }
    6323             : 
    6324        1802 :         if (bss->nl_preq) {
    6325         412 :                 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
    6326             :                            "already on! nl_preq=%p", bss->nl_preq);
    6327         412 :                 return 0;
    6328             :         }
    6329             : 
    6330        1390 :         bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
    6331        1390 :         if (bss->nl_preq == NULL)
    6332           0 :                 return -1;
    6333        1390 :         wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
    6334             :                    "reporting nl_preq=%p", bss->nl_preq);
    6335             : 
    6336        1390 :         if (nl80211_register_frame(bss, bss->nl_preq,
    6337             :                                    (WLAN_FC_TYPE_MGMT << 2) |
    6338             :                                    (WLAN_FC_STYPE_PROBE_REQ << 4),
    6339             :                                    NULL, 0) < 0)
    6340           5 :                 goto out_err;
    6341             : 
    6342        1385 :         nl80211_register_eloop_read(&bss->nl_preq,
    6343             :                                     wpa_driver_nl80211_event_receive,
    6344        1385 :                                     bss->nl_cb);
    6345             : 
    6346        1385 :         return 0;
    6347             : 
    6348             :  out_err:
    6349           5 :         nl_destroy_handles(&bss->nl_preq);
    6350           5 :         return -1;
    6351             : }
    6352             : 
    6353             : 
    6354        1299 : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
    6355             :                                      int ifindex, int disabled)
    6356             : {
    6357             :         struct nl_msg *msg;
    6358             :         struct nlattr *bands, *band;
    6359             :         int ret;
    6360             : 
    6361        1299 :         wpa_printf(MSG_DEBUG,
    6362             :                    "nl80211: NL80211_CMD_SET_TX_BITRATE_MASK (ifindex=%d %s)",
    6363             :                    ifindex, disabled ? "NL80211_TXRATE_LEGACY=OFDM-only" :
    6364             :                    "no NL80211_TXRATE_LEGACY constraint");
    6365             : 
    6366        1299 :         msg = nl80211_ifindex_msg(drv, ifindex, 0,
    6367             :                                   NL80211_CMD_SET_TX_BITRATE_MASK);
    6368        1299 :         if (!msg)
    6369           0 :                 return -1;
    6370             : 
    6371        1299 :         bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
    6372        1299 :         if (!bands)
    6373           0 :                 goto fail;
    6374             : 
    6375             :         /*
    6376             :          * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
    6377             :          * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
    6378             :          * rates. All 5 GHz rates are left enabled.
    6379             :          */
    6380        1299 :         band = nla_nest_start(msg, NL80211_BAND_2GHZ);
    6381        1299 :         if (!band ||
    6382         788 :             (disabled && nla_put(msg, NL80211_TXRATE_LEGACY, 8,
    6383             :                                  "\x0c\x12\x18\x24\x30\x48\x60\x6c")))
    6384             :                 goto fail;
    6385        1299 :         nla_nest_end(msg, band);
    6386             : 
    6387        1299 :         nla_nest_end(msg, bands);
    6388             : 
    6389        1299 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    6390        1299 :         if (ret) {
    6391         286 :                 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
    6392             :                            "(%s)", ret, strerror(-ret));
    6393             :         } else
    6394        1013 :                 drv->disabled_11b_rates = disabled;
    6395             : 
    6396        1299 :         return ret;
    6397             : 
    6398             : fail:
    6399           0 :         nlmsg_free(msg);
    6400           0 :         return -1;
    6401             : }
    6402             : 
    6403             : 
    6404         338 : static int wpa_driver_nl80211_deinit_ap(void *priv)
    6405             : {
    6406         338 :         struct i802_bss *bss = priv;
    6407         338 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6408         338 :         if (!is_ap_interface(drv->nlmode))
    6409           0 :                 return -1;
    6410         338 :         wpa_driver_nl80211_del_beacon(drv);
    6411         338 :         bss->beacon_set = 0;
    6412             : 
    6413             :         /*
    6414             :          * If the P2P GO interface was dynamically added, then it is
    6415             :          * possible that the interface change to station is not possible.
    6416             :          */
    6417         338 :         if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
    6418         104 :                 return 0;
    6419             : 
    6420         234 :         return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
    6421             : }
    6422             : 
    6423             : 
    6424           2 : static int wpa_driver_nl80211_stop_ap(void *priv)
    6425             : {
    6426           2 :         struct i802_bss *bss = priv;
    6427           2 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6428           2 :         if (!is_ap_interface(drv->nlmode))
    6429           0 :                 return -1;
    6430           2 :         wpa_driver_nl80211_del_beacon(drv);
    6431           2 :         bss->beacon_set = 0;
    6432           2 :         return 0;
    6433             : }
    6434             : 
    6435             : 
    6436         185 : static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
    6437             : {
    6438         185 :         struct i802_bss *bss = priv;
    6439         185 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6440         185 :         if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
    6441           1 :                 return -1;
    6442             : 
    6443             :         /*
    6444             :          * If the P2P Client interface was dynamically added, then it is
    6445             :          * possible that the interface change to station is not possible.
    6446             :          */
    6447         184 :         if (bss->if_dynamic)
    6448           0 :                 return 0;
    6449             : 
    6450         184 :         return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
    6451             : }
    6452             : 
    6453             : 
    6454           2 : static void wpa_driver_nl80211_resume(void *priv)
    6455             : {
    6456           2 :         struct i802_bss *bss = priv;
    6457             : 
    6458           2 :         if (i802_set_iface_flags(bss, 1))
    6459           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
    6460           2 : }
    6461             : 
    6462             : 
    6463          10 : static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
    6464             : {
    6465          10 :         struct i802_bss *bss = priv;
    6466          10 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6467             :         struct nl_msg *msg;
    6468             :         struct nlattr *cqm;
    6469             : 
    6470          10 :         wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
    6471             :                    "hysteresis=%d", threshold, hysteresis);
    6472             : 
    6473          10 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_CQM)) ||
    6474          10 :             !(cqm = nla_nest_start(msg, NL80211_ATTR_CQM)) ||
    6475          20 :             nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold) ||
    6476          10 :             nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis)) {
    6477           0 :                 nlmsg_free(msg);
    6478           0 :                 return -1;
    6479             :         }
    6480          10 :         nla_nest_end(msg, cqm);
    6481             : 
    6482          10 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    6483             : }
    6484             : 
    6485             : 
    6486          45 : static int get_channel_width(struct nl_msg *msg, void *arg)
    6487             : {
    6488             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    6489          45 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    6490          45 :         struct wpa_signal_info *sig_change = arg;
    6491             : 
    6492          45 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    6493             :                   genlmsg_attrlen(gnlh, 0), NULL);
    6494             : 
    6495          45 :         sig_change->center_frq1 = -1;
    6496          45 :         sig_change->center_frq2 = -1;
    6497          45 :         sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
    6498             : 
    6499          45 :         if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
    6500          45 :                 sig_change->chanwidth = convert2width(
    6501          45 :                         nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
    6502          45 :                 if (tb[NL80211_ATTR_CENTER_FREQ1])
    6503          45 :                         sig_change->center_frq1 =
    6504          45 :                                 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
    6505          45 :                 if (tb[NL80211_ATTR_CENTER_FREQ2])
    6506           1 :                         sig_change->center_frq2 =
    6507           1 :                                 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
    6508             :         }
    6509             : 
    6510          45 :         return NL_SKIP;
    6511             : }
    6512             : 
    6513             : 
    6514          45 : static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
    6515             :                                      struct wpa_signal_info *sig)
    6516             : {
    6517             :         struct nl_msg *msg;
    6518             : 
    6519          45 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_INTERFACE);
    6520          45 :         return send_and_recv_msgs(drv, msg, get_channel_width, sig);
    6521             : }
    6522             : 
    6523             : 
    6524          45 : static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
    6525             : {
    6526          45 :         struct i802_bss *bss = priv;
    6527          45 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6528             :         int res;
    6529             : 
    6530          45 :         os_memset(si, 0, sizeof(*si));
    6531          45 :         res = nl80211_get_link_signal(drv, si);
    6532          45 :         if (res != 0)
    6533           0 :                 return res;
    6534             : 
    6535          45 :         res = nl80211_get_channel_width(drv, si);
    6536          45 :         if (res != 0)
    6537           0 :                 return res;
    6538             : 
    6539          45 :         return nl80211_get_link_noise(drv, si);
    6540             : }
    6541             : 
    6542             : 
    6543          65 : static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
    6544             :                               int encrypt)
    6545             : {
    6546          65 :         struct i802_bss *bss = priv;
    6547          65 :         return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
    6548             :                                              0, 0, 0, 0);
    6549             : }
    6550             : 
    6551             : 
    6552         534 : static int nl80211_set_param(void *priv, const char *param)
    6553             : {
    6554         534 :         wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
    6555         534 :         if (param == NULL)
    6556         254 :                 return 0;
    6557             : 
    6558             : #ifdef CONFIG_P2P
    6559         278 :         if (os_strstr(param, "use_p2p_group_interface=1")) {
    6560           0 :                 struct i802_bss *bss = priv;
    6561           0 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
    6562             : 
    6563           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
    6564             :                            "interface");
    6565           0 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
    6566           0 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
    6567             :         }
    6568             : #endif /* CONFIG_P2P */
    6569             : 
    6570         280 :         if (os_strstr(param, "use_monitor=1")) {
    6571           7 :                 struct i802_bss *bss = priv;
    6572           7 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
    6573           7 :                 drv->use_monitor = 1;
    6574             :         }
    6575             : 
    6576         280 :         if (os_strstr(param, "force_connect_cmd=1")) {
    6577         268 :                 struct i802_bss *bss = priv;
    6578         268 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
    6579         268 :                 drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
    6580         268 :                 drv->force_connect_cmd = 1;
    6581             :         }
    6582             : 
    6583         280 :         if (os_strstr(param, "no_offchannel_tx=1")) {
    6584           5 :                 struct i802_bss *bss = priv;
    6585           5 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
    6586           5 :                 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
    6587           5 :                 drv->test_use_roc_tx = 1;
    6588             :         }
    6589             : 
    6590         280 :         return 0;
    6591             : }
    6592             : 
    6593             : 
    6594          46 : static void * nl80211_global_init(void)
    6595             : {
    6596             :         struct nl80211_global *global;
    6597             :         struct netlink_config *cfg;
    6598             : 
    6599          46 :         global = os_zalloc(sizeof(*global));
    6600          46 :         if (global == NULL)
    6601           0 :                 return NULL;
    6602          46 :         global->ioctl_sock = -1;
    6603          46 :         dl_list_init(&global->interfaces);
    6604          46 :         global->if_add_ifindex = -1;
    6605             : 
    6606          46 :         cfg = os_zalloc(sizeof(*cfg));
    6607          46 :         if (cfg == NULL)
    6608           0 :                 goto err;
    6609             : 
    6610          46 :         cfg->ctx = global;
    6611          46 :         cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
    6612          46 :         cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
    6613          46 :         global->netlink = netlink_init(cfg);
    6614          46 :         if (global->netlink == NULL) {
    6615           0 :                 os_free(cfg);
    6616           0 :                 goto err;
    6617             :         }
    6618             : 
    6619          46 :         if (wpa_driver_nl80211_init_nl_global(global) < 0)
    6620           0 :                 goto err;
    6621             : 
    6622          46 :         global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
    6623          46 :         if (global->ioctl_sock < 0) {
    6624           0 :                 wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
    6625           0 :                            strerror(errno));
    6626           0 :                 goto err;
    6627             :         }
    6628             : 
    6629          46 :         return global;
    6630             : 
    6631             : err:
    6632           0 :         nl80211_global_deinit(global);
    6633           0 :         return NULL;
    6634             : }
    6635             : 
    6636             : 
    6637          46 : static void nl80211_global_deinit(void *priv)
    6638             : {
    6639          46 :         struct nl80211_global *global = priv;
    6640          46 :         if (global == NULL)
    6641          46 :                 return;
    6642          46 :         if (!dl_list_empty(&global->interfaces)) {
    6643           0 :                 wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
    6644             :                            "nl80211_global_deinit",
    6645             :                            dl_list_len(&global->interfaces));
    6646             :         }
    6647             : 
    6648          46 :         if (global->netlink)
    6649          46 :                 netlink_deinit(global->netlink);
    6650             : 
    6651          46 :         nl_destroy_handles(&global->nl);
    6652             : 
    6653          46 :         if (global->nl_event)
    6654          46 :                 nl80211_destroy_eloop_handle(&global->nl_event);
    6655             : 
    6656          46 :         nl_cb_put(global->nl_cb);
    6657             : 
    6658          46 :         if (global->ioctl_sock >= 0)
    6659          46 :                 close(global->ioctl_sock);
    6660             : 
    6661          46 :         os_free(global);
    6662             : }
    6663             : 
    6664             : 
    6665        2487 : static const char * nl80211_get_radio_name(void *priv)
    6666             : {
    6667        2487 :         struct i802_bss *bss = priv;
    6668        2487 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6669        2487 :         return drv->phyname;
    6670             : }
    6671             : 
    6672             : 
    6673        2087 : static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
    6674             :                          const u8 *pmkid)
    6675             : {
    6676             :         struct nl_msg *msg;
    6677             : 
    6678        2087 :         if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
    6679        1556 :             (pmkid && nla_put(msg, NL80211_ATTR_PMKID, 16, pmkid)) ||
    6680        1556 :             (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))) {
    6681           0 :                 nlmsg_free(msg);
    6682           0 :                 return -ENOBUFS;
    6683             :         }
    6684             : 
    6685        2087 :         return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
    6686             : }
    6687             : 
    6688             : 
    6689         778 : static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
    6690             : {
    6691         778 :         struct i802_bss *bss = priv;
    6692         778 :         wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
    6693         778 :         return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
    6694             : }
    6695             : 
    6696             : 
    6697         778 : static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
    6698             : {
    6699         778 :         struct i802_bss *bss = priv;
    6700        4668 :         wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
    6701        4668 :                    MAC2STR(bssid));
    6702         778 :         return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
    6703             : }
    6704             : 
    6705             : 
    6706         531 : static int nl80211_flush_pmkid(void *priv)
    6707             : {
    6708         531 :         struct i802_bss *bss = priv;
    6709         531 :         wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
    6710         531 :         return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
    6711             : }
    6712             : 
    6713             : 
    6714          50 : static void clean_survey_results(struct survey_results *survey_results)
    6715             : {
    6716             :         struct freq_survey *survey, *tmp;
    6717             : 
    6718          50 :         if (dl_list_empty(&survey_results->survey_list))
    6719          95 :                 return;
    6720             : 
    6721          10 :         dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
    6722             :                               struct freq_survey, list) {
    6723           5 :                 dl_list_del(&survey->list);
    6724           5 :                 os_free(survey);
    6725             :         }
    6726             : }
    6727             : 
    6728             : 
    6729          50 : static void add_survey(struct nlattr **sinfo, u32 ifidx,
    6730             :                        struct dl_list *survey_list)
    6731             : {
    6732             :         struct freq_survey *survey;
    6733             : 
    6734          50 :         survey = os_zalloc(sizeof(struct freq_survey));
    6735          50 :         if  (!survey)
    6736          50 :                 return;
    6737             : 
    6738          50 :         survey->ifidx = ifidx;
    6739          50 :         survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
    6740          50 :         survey->filled = 0;
    6741             : 
    6742          50 :         if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
    6743          50 :                 survey->nf = (int8_t)
    6744          50 :                         nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
    6745          50 :                 survey->filled |= SURVEY_HAS_NF;
    6746             :         }
    6747             : 
    6748          50 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
    6749           0 :                 survey->channel_time =
    6750           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
    6751           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME;
    6752             :         }
    6753             : 
    6754          50 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
    6755           0 :                 survey->channel_time_busy =
    6756           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
    6757           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
    6758             :         }
    6759             : 
    6760          50 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
    6761           0 :                 survey->channel_time_rx =
    6762           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
    6763           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
    6764             :         }
    6765             : 
    6766          50 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
    6767           0 :                 survey->channel_time_tx =
    6768           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
    6769           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
    6770             :         }
    6771             : 
    6772         100 :         wpa_printf(MSG_DEBUG, "nl80211: Freq survey dump event (freq=%d MHz noise=%d channel_time=%ld busy_time=%ld tx_time=%ld rx_time=%ld filled=%04x)",
    6773             :                    survey->freq,
    6774          50 :                    survey->nf,
    6775             :                    (unsigned long int) survey->channel_time,
    6776             :                    (unsigned long int) survey->channel_time_busy,
    6777             :                    (unsigned long int) survey->channel_time_tx,
    6778             :                    (unsigned long int) survey->channel_time_rx,
    6779             :                    survey->filled);
    6780             : 
    6781          50 :         dl_list_add_tail(survey_list, &survey->list);
    6782             : }
    6783             : 
    6784             : 
    6785          50 : static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
    6786             :                            unsigned int freq_filter)
    6787             : {
    6788          50 :         if (!freq_filter)
    6789          45 :                 return 1;
    6790             : 
    6791           5 :         return freq_filter == surveyed_freq;
    6792             : }
    6793             : 
    6794             : 
    6795          50 : static int survey_handler(struct nl_msg *msg, void *arg)
    6796             : {
    6797             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    6798          50 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    6799             :         struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
    6800             :         struct survey_results *survey_results;
    6801          50 :         u32 surveyed_freq = 0;
    6802             :         u32 ifidx;
    6803             : 
    6804             :         static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
    6805             :                 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
    6806             :                 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
    6807             :         };
    6808             : 
    6809          50 :         survey_results = (struct survey_results *) arg;
    6810             : 
    6811          50 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    6812             :                   genlmsg_attrlen(gnlh, 0), NULL);
    6813             : 
    6814          50 :         if (!tb[NL80211_ATTR_IFINDEX])
    6815           0 :                 return NL_SKIP;
    6816             : 
    6817          50 :         ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
    6818             : 
    6819          50 :         if (!tb[NL80211_ATTR_SURVEY_INFO])
    6820           0 :                 return NL_SKIP;
    6821             : 
    6822          50 :         if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
    6823             :                              tb[NL80211_ATTR_SURVEY_INFO],
    6824             :                              survey_policy))
    6825           0 :                 return NL_SKIP;
    6826             : 
    6827          50 :         if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
    6828           0 :                 wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
    6829           0 :                 return NL_SKIP;
    6830             :         }
    6831             : 
    6832          50 :         surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
    6833             : 
    6834          50 :         if (!check_survey_ok(sinfo, surveyed_freq,
    6835             :                              survey_results->freq_filter))
    6836           0 :                 return NL_SKIP;
    6837             : 
    6838          55 :         if (survey_results->freq_filter &&
    6839           5 :             survey_results->freq_filter != surveyed_freq) {
    6840           0 :                 wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
    6841             :                            surveyed_freq);
    6842           0 :                 return NL_SKIP;
    6843             :         }
    6844             : 
    6845          50 :         add_survey(sinfo, ifidx, &survey_results->survey_list);
    6846             : 
    6847          50 :         return NL_SKIP;
    6848             : }
    6849             : 
    6850             : 
    6851          50 : static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
    6852             : {
    6853          50 :         struct i802_bss *bss = priv;
    6854          50 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6855             :         struct nl_msg *msg;
    6856             :         int err;
    6857             :         union wpa_event_data data;
    6858             :         struct survey_results *survey_results;
    6859             : 
    6860          50 :         os_memset(&data, 0, sizeof(data));
    6861          50 :         survey_results = &data.survey_results;
    6862             : 
    6863          50 :         dl_list_init(&survey_results->survey_list);
    6864             : 
    6865          50 :         msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
    6866          50 :         if (!msg)
    6867           0 :                 return -ENOBUFS;
    6868             : 
    6869          50 :         if (freq)
    6870           5 :                 data.survey_results.freq_filter = freq;
    6871             : 
    6872             :         do {
    6873          50 :                 wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
    6874          50 :                 err = send_and_recv_msgs(drv, msg, survey_handler,
    6875             :                                          survey_results);
    6876          50 :         } while (err > 0);
    6877             : 
    6878          50 :         if (err)
    6879           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
    6880             :         else
    6881          50 :                 wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
    6882             : 
    6883          50 :         clean_survey_results(survey_results);
    6884          50 :         return err;
    6885             : }
    6886             : 
    6887             : 
    6888        1549 : static void nl80211_set_rekey_info(void *priv, const u8 *kek, size_t kek_len,
    6889             :                                    const u8 *kck, size_t kck_len,
    6890             :                                    const u8 *replay_ctr)
    6891             : {
    6892        1549 :         struct i802_bss *bss = priv;
    6893        1549 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6894             :         struct nlattr *replay_nested;
    6895             :         struct nl_msg *msg;
    6896             :         int ret;
    6897             : 
    6898        1549 :         if (!drv->set_rekey_offload)
    6899        1485 :                 return;
    6900             : 
    6901          64 :         wpa_printf(MSG_DEBUG, "nl80211: Set rekey offload");
    6902          64 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_REKEY_OFFLOAD)) ||
    6903          64 :             !(replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA)) ||
    6904         128 :             nla_put(msg, NL80211_REKEY_DATA_KEK, kek_len, kek) ||
    6905         128 :             nla_put(msg, NL80211_REKEY_DATA_KCK, kck_len, kck) ||
    6906          64 :             nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
    6907             :                     replay_ctr)) {
    6908           0 :                 nl80211_nlmsg_clear(msg);
    6909           0 :                 nlmsg_free(msg);
    6910           0 :                 return;
    6911             :         }
    6912             : 
    6913          64 :         nla_nest_end(msg, replay_nested);
    6914             : 
    6915          64 :         ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
    6916          64 :         if (ret == -EOPNOTSUPP) {
    6917          64 :                 wpa_printf(MSG_DEBUG,
    6918             :                            "nl80211: Driver does not support rekey offload");
    6919          64 :                 drv->set_rekey_offload = 0;
    6920             :         }
    6921             : }
    6922             : 
    6923             : 
    6924           0 : static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
    6925             :                                     const u8 *addr, int qos)
    6926             : {
    6927             :         /* send data frame to poll STA and check whether
    6928             :          * this frame is ACKed */
    6929             :         struct {
    6930             :                 struct ieee80211_hdr hdr;
    6931             :                 u16 qos_ctl;
    6932             :         } STRUCT_PACKED nulldata;
    6933             :         size_t size;
    6934             : 
    6935             :         /* Send data frame to poll STA and check whether this frame is ACKed */
    6936             : 
    6937           0 :         os_memset(&nulldata, 0, sizeof(nulldata));
    6938             : 
    6939           0 :         if (qos) {
    6940           0 :                 nulldata.hdr.frame_control =
    6941             :                         IEEE80211_FC(WLAN_FC_TYPE_DATA,
    6942             :                                      WLAN_FC_STYPE_QOS_NULL);
    6943           0 :                 size = sizeof(nulldata);
    6944             :         } else {
    6945           0 :                 nulldata.hdr.frame_control =
    6946             :                         IEEE80211_FC(WLAN_FC_TYPE_DATA,
    6947             :                                      WLAN_FC_STYPE_NULLFUNC);
    6948           0 :                 size = sizeof(struct ieee80211_hdr);
    6949             :         }
    6950             : 
    6951           0 :         nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
    6952           0 :         os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
    6953           0 :         os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
    6954           0 :         os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
    6955             : 
    6956           0 :         if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
    6957             :                                          0, 0) < 0)
    6958           0 :                 wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
    6959             :                            "send poll frame");
    6960           0 : }
    6961             : 
    6962           2 : static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
    6963             :                                 int qos)
    6964             : {
    6965           2 :         struct i802_bss *bss = priv;
    6966           2 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6967             :         struct nl_msg *msg;
    6968             :         int ret;
    6969             : 
    6970           2 :         if (!drv->poll_command_supported) {
    6971           0 :                 nl80211_send_null_frame(bss, own_addr, addr, qos);
    6972           0 :                 return;
    6973             :         }
    6974             : 
    6975           4 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_PROBE_CLIENT)) ||
    6976           2 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
    6977           0 :                 nlmsg_free(msg);
    6978           0 :                 return;
    6979             :         }
    6980             : 
    6981           2 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    6982           2 :         if (ret < 0) {
    6983           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Client probe request for "
    6984             :                            MACSTR " failed: ret=%d (%s)",
    6985           0 :                            MAC2STR(addr), ret, strerror(-ret));
    6986             :         }
    6987             : }
    6988             : 
    6989             : 
    6990           3 : static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
    6991             : {
    6992             :         struct nl_msg *msg;
    6993             : 
    6994           6 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_POWER_SAVE)) ||
    6995           3 :             nla_put_u32(msg, NL80211_ATTR_PS_STATE,
    6996             :                         enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED)) {
    6997           0 :                 nlmsg_free(msg);
    6998           0 :                 return -ENOBUFS;
    6999             :         }
    7000           3 :         return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
    7001             : }
    7002             : 
    7003             : 
    7004           8 : static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
    7005             :                                      int ctwindow)
    7006             : {
    7007           8 :         struct i802_bss *bss = priv;
    7008             : 
    7009           8 :         wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
    7010             :                    "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
    7011             : 
    7012           8 :         if (opp_ps != -1 || ctwindow != -1) {
    7013             : #ifdef ANDROID_P2P
    7014             :                 wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
    7015             : #else /* ANDROID_P2P */
    7016           2 :                 return -1; /* Not yet supported */
    7017             : #endif /* ANDROID_P2P */
    7018             :         }
    7019             : 
    7020           6 :         if (legacy_ps == -1)
    7021           1 :                 return 0;
    7022           5 :         if (legacy_ps != 0 && legacy_ps != 1)
    7023           2 :                 return -1; /* Not yet supported */
    7024             : 
    7025           3 :         return nl80211_set_power_save(bss, legacy_ps);
    7026             : }
    7027             : 
    7028             : 
    7029          13 : static int nl80211_start_radar_detection(void *priv,
    7030             :                                          struct hostapd_freq_params *freq)
    7031             : {
    7032          13 :         struct i802_bss *bss = priv;
    7033          13 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7034             :         struct nl_msg *msg;
    7035             :         int ret;
    7036             : 
    7037          13 :         wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC) %d MHz (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
    7038             :                    freq->freq, freq->ht_enabled, freq->vht_enabled,
    7039             :                    freq->bandwidth, freq->center_freq1, freq->center_freq2);
    7040             : 
    7041          13 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
    7042           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
    7043             :                            "detection");
    7044           0 :                 return -1;
    7045             :         }
    7046             : 
    7047          26 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_RADAR_DETECT)) ||
    7048          13 :             nl80211_put_freq_params(msg, freq) < 0) {
    7049           0 :                 nlmsg_free(msg);
    7050           0 :                 return -1;
    7051             :         }
    7052             : 
    7053          13 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7054          13 :         if (ret == 0)
    7055          12 :                 return 0;
    7056           1 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
    7057             :                    "%d (%s)", ret, strerror(-ret));
    7058           1 :         return -1;
    7059             : }
    7060             : 
    7061             : #ifdef CONFIG_TDLS
    7062             : 
    7063         132 : static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
    7064             :                                   u8 dialog_token, u16 status_code,
    7065             :                                   u32 peer_capab, int initiator, const u8 *buf,
    7066             :                                   size_t len)
    7067             : {
    7068         132 :         struct i802_bss *bss = priv;
    7069         132 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7070             :         struct nl_msg *msg;
    7071             : 
    7072         132 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
    7073           0 :                 return -EOPNOTSUPP;
    7074             : 
    7075         132 :         if (!dst)
    7076           0 :                 return -EINVAL;
    7077             : 
    7078         264 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_TDLS_MGMT)) ||
    7079         264 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
    7080         264 :             nla_put_u8(msg, NL80211_ATTR_TDLS_ACTION, action_code) ||
    7081         264 :             nla_put_u8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token) ||
    7082         132 :             nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status_code))
    7083             :                 goto fail;
    7084         132 :         if (peer_capab) {
    7085             :                 /*
    7086             :                  * The internal enum tdls_peer_capability definition is
    7087             :                  * currently identical with the nl80211 enum
    7088             :                  * nl80211_tdls_peer_capability, so no conversion is needed
    7089             :                  * here.
    7090             :                  */
    7091          26 :                 if (nla_put_u32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY,
    7092             :                                 peer_capab))
    7093           0 :                         goto fail;
    7094             :         }
    7095         218 :         if ((initiator &&
    7096         218 :              nla_put_flag(msg, NL80211_ATTR_TDLS_INITIATOR)) ||
    7097         132 :             nla_put(msg, NL80211_ATTR_IE, len, buf))
    7098             :                 goto fail;
    7099             : 
    7100         132 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    7101             : 
    7102             : fail:
    7103           0 :         nlmsg_free(msg);
    7104           0 :         return -ENOBUFS;
    7105             : }
    7106             : 
    7107             : 
    7108        4983 : static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
    7109             : {
    7110        4983 :         struct i802_bss *bss = priv;
    7111        4983 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7112             :         struct nl_msg *msg;
    7113             :         enum nl80211_tdls_operation nl80211_oper;
    7114             : 
    7115        4983 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
    7116           0 :                 return -EOPNOTSUPP;
    7117             : 
    7118        4983 :         switch (oper) {
    7119             :         case TDLS_DISCOVERY_REQ:
    7120           0 :                 nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
    7121           0 :                 break;
    7122             :         case TDLS_SETUP:
    7123           0 :                 nl80211_oper = NL80211_TDLS_SETUP;
    7124           0 :                 break;
    7125             :         case TDLS_TEARDOWN:
    7126           0 :                 nl80211_oper = NL80211_TDLS_TEARDOWN;
    7127           0 :                 break;
    7128             :         case TDLS_ENABLE_LINK:
    7129          51 :                 nl80211_oper = NL80211_TDLS_ENABLE_LINK;
    7130          51 :                 break;
    7131             :         case TDLS_DISABLE_LINK:
    7132          61 :                 nl80211_oper = NL80211_TDLS_DISABLE_LINK;
    7133          61 :                 break;
    7134             :         case TDLS_ENABLE:
    7135        4870 :                 return 0;
    7136             :         case TDLS_DISABLE:
    7137           1 :                 return 0;
    7138             :         default:
    7139           0 :                 return -EINVAL;
    7140             :         }
    7141             : 
    7142         224 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_TDLS_OPER)) ||
    7143         224 :             nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper) ||
    7144         112 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) {
    7145           0 :                 nlmsg_free(msg);
    7146           0 :                 return -ENOBUFS;
    7147             :         }
    7148             : 
    7149         112 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    7150             : }
    7151             : 
    7152             : 
    7153             : static int
    7154           1 : nl80211_tdls_enable_channel_switch(void *priv, const u8 *addr, u8 oper_class,
    7155             :                                    const struct hostapd_freq_params *params)
    7156             : {
    7157           1 :         struct i802_bss *bss = priv;
    7158           1 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7159             :         struct nl_msg *msg;
    7160           1 :         int ret = -ENOBUFS;
    7161             : 
    7162           2 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) ||
    7163           1 :             !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH))
    7164           0 :                 return -EOPNOTSUPP;
    7165             : 
    7166           7 :         wpa_printf(MSG_DEBUG, "nl80211: Enable TDLS channel switch " MACSTR
    7167             :                    " oper_class=%u freq=%u",
    7168           6 :                    MAC2STR(addr), oper_class, params->freq);
    7169           1 :         msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_TDLS_CHANNEL_SWITCH);
    7170           2 :         if (!msg ||
    7171           2 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
    7172           2 :             nla_put_u8(msg, NL80211_ATTR_OPER_CLASS, oper_class) ||
    7173             :             (ret = nl80211_put_freq_params(msg, params))) {
    7174           0 :                 nlmsg_free(msg);
    7175           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not build TDLS chan switch");
    7176           0 :                 return ret;
    7177             :         }
    7178             : 
    7179           1 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    7180             : }
    7181             : 
    7182             : 
    7183             : static int
    7184           1 : nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr)
    7185             : {
    7186           1 :         struct i802_bss *bss = priv;
    7187           1 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7188             :         struct nl_msg *msg;
    7189             : 
    7190           2 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) ||
    7191           1 :             !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH))
    7192           0 :                 return -EOPNOTSUPP;
    7193             : 
    7194           6 :         wpa_printf(MSG_DEBUG, "nl80211: Disable TDLS channel switch " MACSTR,
    7195           6 :                    MAC2STR(addr));
    7196           1 :         msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH);
    7197           2 :         if (!msg ||
    7198           1 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
    7199           0 :                 nlmsg_free(msg);
    7200           0 :                 wpa_printf(MSG_DEBUG,
    7201             :                            "nl80211: Could not build TDLS cancel chan switch");
    7202           0 :                 return -ENOBUFS;
    7203             :         }
    7204             : 
    7205           1 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    7206             : }
    7207             : 
    7208             : #endif /* CONFIG TDLS */
    7209             : 
    7210             : 
    7211       37044 : static int driver_nl80211_set_key(const char *ifname, void *priv,
    7212             :                                   enum wpa_alg alg, const u8 *addr,
    7213             :                                   int key_idx, int set_tx,
    7214             :                                   const u8 *seq, size_t seq_len,
    7215             :                                   const u8 *key, size_t key_len)
    7216             : {
    7217       37044 :         struct i802_bss *bss = priv;
    7218       37044 :         return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
    7219             :                                           set_tx, seq, seq_len, key, key_len);
    7220             : }
    7221             : 
    7222             : 
    7223        4788 : static int driver_nl80211_scan2(void *priv,
    7224             :                                 struct wpa_driver_scan_params *params)
    7225             : {
    7226        4788 :         struct i802_bss *bss = priv;
    7227        4788 :         return wpa_driver_nl80211_scan(bss, params);
    7228             : }
    7229             : 
    7230             : 
    7231        2924 : static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
    7232             :                                          int reason_code)
    7233             : {
    7234        2924 :         struct i802_bss *bss = priv;
    7235        2924 :         return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
    7236             : }
    7237             : 
    7238             : 
    7239        3320 : static int driver_nl80211_authenticate(void *priv,
    7240             :                                        struct wpa_driver_auth_params *params)
    7241             : {
    7242        3320 :         struct i802_bss *bss = priv;
    7243        3320 :         return wpa_driver_nl80211_authenticate(bss, params);
    7244             : }
    7245             : 
    7246             : 
    7247         532 : static void driver_nl80211_deinit(void *priv)
    7248             : {
    7249         532 :         struct i802_bss *bss = priv;
    7250         532 :         wpa_driver_nl80211_deinit(bss);
    7251         532 : }
    7252             : 
    7253             : 
    7254         217 : static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
    7255             :                                     const char *ifname)
    7256             : {
    7257         217 :         struct i802_bss *bss = priv;
    7258         217 :         return wpa_driver_nl80211_if_remove(bss, type, ifname);
    7259             : }
    7260             : 
    7261             : 
    7262       12273 : static int driver_nl80211_send_mlme(void *priv, const u8 *data,
    7263             :                                     size_t data_len, int noack,
    7264             :                                     unsigned int freq)
    7265             : {
    7266       12273 :         struct i802_bss *bss = priv;
    7267       12273 :         return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
    7268             :                                             freq, 0, 0, 0);
    7269             : }
    7270             : 
    7271             : 
    7272        6217 : static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
    7273             : {
    7274        6217 :         struct i802_bss *bss = priv;
    7275        6217 :         return wpa_driver_nl80211_sta_remove(bss, addr, -1, 0);
    7276             : }
    7277             : 
    7278             : 
    7279        3463 : static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
    7280             :                                        const char *ifname, int vlan_id)
    7281             : {
    7282        3463 :         struct i802_bss *bss = priv;
    7283        3463 :         return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
    7284             : }
    7285             : 
    7286             : 
    7287         427 : static int driver_nl80211_read_sta_data(void *priv,
    7288             :                                         struct hostap_sta_driver_data *data,
    7289             :                                         const u8 *addr)
    7290             : {
    7291         427 :         struct i802_bss *bss = priv;
    7292         427 :         return i802_read_sta_data(bss, data, addr);
    7293             : }
    7294             : 
    7295             : 
    7296        3363 : static int driver_nl80211_send_action(void *priv, unsigned int freq,
    7297             :                                       unsigned int wait_time,
    7298             :                                       const u8 *dst, const u8 *src,
    7299             :                                       const u8 *bssid,
    7300             :                                       const u8 *data, size_t data_len,
    7301             :                                       int no_cck)
    7302             : {
    7303        3363 :         struct i802_bss *bss = priv;
    7304        3363 :         return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
    7305             :                                               bssid, data, data_len, no_cck);
    7306             : }
    7307             : 
    7308             : 
    7309       29110 : static int driver_nl80211_probe_req_report(void *priv, int report)
    7310             : {
    7311       29110 :         struct i802_bss *bss = priv;
    7312       29110 :         return wpa_driver_nl80211_probe_req_report(bss, report);
    7313             : }
    7314             : 
    7315             : 
    7316           0 : static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
    7317             :                                             const u8 *ies, size_t ies_len)
    7318             : {
    7319             :         int ret;
    7320             :         struct nl_msg *msg;
    7321           0 :         struct i802_bss *bss = priv;
    7322           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7323           0 :         u16 mdid = WPA_GET_LE16(md);
    7324             : 
    7325           0 :         wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
    7326           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_UPDATE_FT_IES)) ||
    7327           0 :             nla_put(msg, NL80211_ATTR_IE, ies_len, ies) ||
    7328           0 :             nla_put_u16(msg, NL80211_ATTR_MDID, mdid)) {
    7329           0 :                 nlmsg_free(msg);
    7330           0 :                 return -ENOBUFS;
    7331             :         }
    7332             : 
    7333           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7334           0 :         if (ret) {
    7335           0 :                 wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
    7336             :                            "err=%d (%s)", ret, strerror(-ret));
    7337             :         }
    7338             : 
    7339           0 :         return ret;
    7340             : }
    7341             : 
    7342             : 
    7343         553 : const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
    7344             : {
    7345         553 :         struct i802_bss *bss = priv;
    7346         553 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7347             : 
    7348         553 :         if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
    7349         545 :                 return NULL;
    7350             : 
    7351           8 :         return bss->addr;
    7352             : }
    7353             : 
    7354             : 
    7355        5852 : static const char * scan_state_str(enum scan_states scan_state)
    7356             : {
    7357        5852 :         switch (scan_state) {
    7358             :         case NO_SCAN:
    7359         137 :                 return "NO_SCAN";
    7360             :         case SCAN_REQUESTED:
    7361           1 :                 return "SCAN_REQUESTED";
    7362             :         case SCAN_STARTED:
    7363          23 :                 return "SCAN_STARTED";
    7364             :         case SCAN_COMPLETED:
    7365        5655 :                 return "SCAN_COMPLETED";
    7366             :         case SCAN_ABORTED:
    7367          36 :                 return "SCAN_ABORTED";
    7368             :         case SCHED_SCAN_STARTED:
    7369           0 :                 return "SCHED_SCAN_STARTED";
    7370             :         case SCHED_SCAN_STOPPED:
    7371           0 :                 return "SCHED_SCAN_STOPPED";
    7372             :         case SCHED_SCAN_RESULTS:
    7373           0 :                 return "SCHED_SCAN_RESULTS";
    7374             :         }
    7375             : 
    7376           0 :         return "??";
    7377             : }
    7378             : 
    7379             : 
    7380        5852 : static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
    7381             : {
    7382        5852 :         struct i802_bss *bss = priv;
    7383        5852 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7384             :         int res;
    7385             :         char *pos, *end;
    7386             : 
    7387        5852 :         pos = buf;
    7388        5852 :         end = buf + buflen;
    7389             : 
    7390       70224 :         res = os_snprintf(pos, end - pos,
    7391             :                           "ifindex=%d\n"
    7392             :                           "ifname=%s\n"
    7393             :                           "brname=%s\n"
    7394             :                           "addr=" MACSTR "\n"
    7395             :                           "freq=%d\n"
    7396             :                           "%s%s%s%s%s",
    7397             :                           bss->ifindex,
    7398        5852 :                           bss->ifname,
    7399        5852 :                           bss->brname,
    7400       35112 :                           MAC2STR(bss->addr),
    7401             :                           bss->freq,
    7402        5852 :                           bss->beacon_set ? "beacon_set=1\n" : "",
    7403        5852 :                           bss->added_if_into_bridge ?
    7404             :                           "added_if_into_bridge=1\n" : "",
    7405        5852 :                           bss->added_bridge ? "added_bridge=1\n" : "",
    7406        5852 :                           bss->in_deinit ? "in_deinit=1\n" : "",
    7407        5852 :                           bss->if_dynamic ? "if_dynamic=1\n" : "");
    7408        5852 :         if (os_snprintf_error(end - pos, res))
    7409           0 :                 return pos - buf;
    7410        5852 :         pos += res;
    7411             : 
    7412        5852 :         if (bss->wdev_id_set) {
    7413           1 :                 res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
    7414           1 :                                   (unsigned long long) bss->wdev_id);
    7415           1 :                 if (os_snprintf_error(end - pos, res))
    7416           0 :                         return pos - buf;
    7417           1 :                 pos += res;
    7418             :         }
    7419             : 
    7420      257488 :         res = os_snprintf(pos, end - pos,
    7421             :                           "phyname=%s\n"
    7422             :                           "perm_addr=" MACSTR "\n"
    7423             :                           "drv_ifindex=%d\n"
    7424             :                           "operstate=%d\n"
    7425             :                           "scan_state=%s\n"
    7426             :                           "auth_bssid=" MACSTR "\n"
    7427             :                           "auth_attempt_bssid=" MACSTR "\n"
    7428             :                           "bssid=" MACSTR "\n"
    7429             :                           "prev_bssid=" MACSTR "\n"
    7430             :                           "associated=%d\n"
    7431             :                           "assoc_freq=%u\n"
    7432             :                           "monitor_sock=%d\n"
    7433             :                           "monitor_ifidx=%d\n"
    7434             :                           "monitor_refcount=%d\n"
    7435             :                           "last_mgmt_freq=%u\n"
    7436             :                           "eapol_tx_sock=%d\n"
    7437             :                           "%s%s%s%s%s%s%s%s%s%s%s%s%s",
    7438        5852 :                           drv->phyname,
    7439       35112 :                           MAC2STR(drv->perm_addr),
    7440             :                           drv->ifindex,
    7441             :                           drv->operstate,
    7442             :                           scan_state_str(drv->scan_state),
    7443       35112 :                           MAC2STR(drv->auth_bssid),
    7444       35112 :                           MAC2STR(drv->auth_attempt_bssid),
    7445       35112 :                           MAC2STR(drv->bssid),
    7446       35112 :                           MAC2STR(drv->prev_bssid),
    7447             :                           drv->associated,
    7448             :                           drv->assoc_freq,
    7449             :                           drv->monitor_sock,
    7450             :                           drv->monitor_ifidx,
    7451             :                           drv->monitor_refcount,
    7452             :                           drv->last_mgmt_freq,
    7453             :                           drv->eapol_tx_sock,
    7454        5852 :                           drv->ignore_if_down_event ?
    7455             :                           "ignore_if_down_event=1\n" : "",
    7456        5852 :                           drv->scan_complete_events ?
    7457             :                           "scan_complete_events=1\n" : "",
    7458        5852 :                           drv->disabled_11b_rates ?
    7459             :                           "disabled_11b_rates=1\n" : "",
    7460        5852 :                           drv->pending_remain_on_chan ?
    7461             :                           "pending_remain_on_chan=1\n" : "",
    7462        5852 :                           drv->in_interface_list ? "in_interface_list=1\n" : "",
    7463        5852 :                           drv->device_ap_sme ? "device_ap_sme=1\n" : "",
    7464        5852 :                           drv->poll_command_supported ?
    7465             :                           "poll_command_supported=1\n" : "",
    7466        5852 :                           drv->data_tx_status ? "data_tx_status=1\n" : "",
    7467        5852 :                           drv->scan_for_auth ? "scan_for_auth=1\n" : "",
    7468        5852 :                           drv->retry_auth ? "retry_auth=1\n" : "",
    7469        5852 :                           drv->use_monitor ? "use_monitor=1\n" : "",
    7470        5852 :                           drv->ignore_next_local_disconnect ?
    7471             :                           "ignore_next_local_disconnect=1\n" : "",
    7472        5852 :                           drv->ignore_next_local_deauth ?
    7473             :                           "ignore_next_local_deauth=1\n" : "");
    7474        5852 :         if (os_snprintf_error(end - pos, res))
    7475           0 :                 return pos - buf;
    7476        5852 :         pos += res;
    7477             : 
    7478        5852 :         if (drv->has_capability) {
    7479       23408 :                 res = os_snprintf(pos, end - pos,
    7480             :                                   "capa.key_mgmt=0x%x\n"
    7481             :                                   "capa.enc=0x%x\n"
    7482             :                                   "capa.auth=0x%x\n"
    7483             :                                   "capa.flags=0x%llx\n"
    7484             :                                   "capa.rrm_flags=0x%x\n"
    7485             :                                   "capa.max_scan_ssids=%d\n"
    7486             :                                   "capa.max_sched_scan_ssids=%d\n"
    7487             :                                   "capa.sched_scan_supported=%d\n"
    7488             :                                   "capa.max_match_sets=%d\n"
    7489             :                                   "capa.max_remain_on_chan=%u\n"
    7490             :                                   "capa.max_stations=%u\n"
    7491             :                                   "capa.probe_resp_offloads=0x%x\n"
    7492             :                                   "capa.max_acl_mac_addrs=%u\n"
    7493             :                                   "capa.num_multichan_concurrent=%u\n"
    7494             :                                   "capa.mac_addr_rand_sched_scan_supported=%d\n"
    7495             :                                   "capa.mac_addr_rand_scan_supported=%d\n"
    7496             :                                   "capa.conc_capab=%u\n"
    7497             :                                   "capa.max_conc_chan_2_4=%u\n"
    7498             :                                   "capa.max_conc_chan_5_0=%u\n",
    7499             :                                   drv->capa.key_mgmt,
    7500             :                                   drv->capa.enc,
    7501             :                                   drv->capa.auth,
    7502        5852 :                                   (unsigned long long) drv->capa.flags,
    7503             :                                   drv->capa.rrm_flags,
    7504             :                                   drv->capa.max_scan_ssids,
    7505             :                                   drv->capa.max_sched_scan_ssids,
    7506             :                                   drv->capa.sched_scan_supported,
    7507             :                                   drv->capa.max_match_sets,
    7508             :                                   drv->capa.max_remain_on_chan,
    7509             :                                   drv->capa.max_stations,
    7510             :                                   drv->capa.probe_resp_offloads,
    7511             :                                   drv->capa.max_acl_mac_addrs,
    7512             :                                   drv->capa.num_multichan_concurrent,
    7513        5852 :                                   drv->capa.mac_addr_rand_sched_scan_supported,
    7514        5852 :                                   drv->capa.mac_addr_rand_scan_supported,
    7515             :                                   drv->capa.conc_capab,
    7516             :                                   drv->capa.max_conc_chan_2_4,
    7517             :                                   drv->capa.max_conc_chan_5_0);
    7518        5852 :                 if (os_snprintf_error(end - pos, res))
    7519           0 :                         return pos - buf;
    7520        5852 :                 pos += res;
    7521             :         }
    7522             : 
    7523        5852 :         return pos - buf;
    7524             : }
    7525             : 
    7526             : 
    7527          44 : static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
    7528             : {
    7529          88 :         if ((settings->head &&
    7530          44 :              nla_put(msg, NL80211_ATTR_BEACON_HEAD,
    7531          88 :                      settings->head_len, settings->head)) ||
    7532          88 :             (settings->tail &&
    7533          44 :              nla_put(msg, NL80211_ATTR_BEACON_TAIL,
    7534          88 :                      settings->tail_len, settings->tail)) ||
    7535          88 :             (settings->beacon_ies &&
    7536          44 :              nla_put(msg, NL80211_ATTR_IE,
    7537          88 :                      settings->beacon_ies_len, settings->beacon_ies)) ||
    7538          88 :             (settings->proberesp_ies &&
    7539          44 :              nla_put(msg, NL80211_ATTR_IE_PROBE_RESP,
    7540          88 :                      settings->proberesp_ies_len, settings->proberesp_ies)) ||
    7541          88 :             (settings->assocresp_ies &&
    7542          44 :              nla_put(msg, NL80211_ATTR_IE_ASSOC_RESP,
    7543          88 :                      settings->assocresp_ies_len, settings->assocresp_ies)) ||
    7544          44 :             (settings->probe_resp &&
    7545           0 :              nla_put(msg, NL80211_ATTR_PROBE_RESP,
    7546           0 :                      settings->probe_resp_len, settings->probe_resp)))
    7547           0 :                 return -ENOBUFS;
    7548             : 
    7549          44 :         return 0;
    7550             : }
    7551             : 
    7552             : 
    7553          23 : static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
    7554             : {
    7555             :         struct nl_msg *msg;
    7556          23 :         struct i802_bss *bss = priv;
    7557          23 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7558             :         struct nlattr *beacon_csa;
    7559          23 :         int ret = -ENOBUFS;
    7560             : 
    7561          69 :         wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
    7562          46 :                    settings->cs_count, settings->block_tx,
    7563             :                    settings->freq_params.freq, settings->freq_params.bandwidth,
    7564             :                    settings->freq_params.center_freq1,
    7565             :                    settings->freq_params.center_freq2);
    7566             : 
    7567          23 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
    7568           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
    7569           0 :                 return -EOPNOTSUPP;
    7570             :         }
    7571             : 
    7572          24 :         if ((drv->nlmode != NL80211_IFTYPE_AP) &&
    7573           1 :             (drv->nlmode != NL80211_IFTYPE_P2P_GO))
    7574           0 :                 return -EOPNOTSUPP;
    7575             : 
    7576             :         /* check settings validity */
    7577          46 :         if (!settings->beacon_csa.tail ||
    7578          46 :             ((settings->beacon_csa.tail_len <=
    7579          46 :               settings->counter_offset_beacon) ||
    7580          23 :              (settings->beacon_csa.tail[settings->counter_offset_beacon] !=
    7581          23 :               settings->cs_count)))
    7582           0 :                 return -EINVAL;
    7583             : 
    7584          23 :         if (settings->beacon_csa.probe_resp &&
    7585           0 :             ((settings->beacon_csa.probe_resp_len <=
    7586           0 :               settings->counter_offset_presp) ||
    7587           0 :              (settings->beacon_csa.probe_resp[settings->counter_offset_presp] !=
    7588           0 :               settings->cs_count)))
    7589           0 :                 return -EINVAL;
    7590             : 
    7591          46 :         if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_CHANNEL_SWITCH)) ||
    7592          23 :             nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT,
    7593          46 :                         settings->cs_count) ||
    7594          45 :             (ret = nl80211_put_freq_params(msg, &settings->freq_params)) ||
    7595          25 :             (settings->block_tx &&
    7596           3 :              nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX)))
    7597             :                 goto error;
    7598             : 
    7599             :         /* beacon_after params */
    7600          22 :         ret = set_beacon_data(msg, &settings->beacon_after);
    7601          22 :         if (ret)
    7602           0 :                 goto error;
    7603             : 
    7604             :         /* beacon_csa params */
    7605          22 :         beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
    7606          22 :         if (!beacon_csa)
    7607           0 :                 goto fail;
    7608             : 
    7609          22 :         ret = set_beacon_data(msg, &settings->beacon_csa);
    7610          22 :         if (ret)
    7611           0 :                 goto error;
    7612             : 
    7613          22 :         if (nla_put_u16(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
    7614          44 :                         settings->counter_offset_beacon) ||
    7615          22 :             (settings->beacon_csa.probe_resp &&
    7616           0 :              nla_put_u16(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
    7617           0 :                          settings->counter_offset_presp)))
    7618             :                 goto fail;
    7619             : 
    7620          22 :         nla_nest_end(msg, beacon_csa);
    7621          22 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7622          22 :         if (ret) {
    7623           1 :                 wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
    7624             :                            ret, strerror(-ret));
    7625             :         }
    7626          22 :         return ret;
    7627             : 
    7628             : fail:
    7629           0 :         ret = -ENOBUFS;
    7630             : error:
    7631           1 :         nlmsg_free(msg);
    7632           1 :         wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
    7633           1 :         return ret;
    7634             : }
    7635             : 
    7636             : 
    7637           0 : static int nl80211_add_ts(void *priv, u8 tsid, const u8 *addr,
    7638             :                           u8 user_priority, u16 admitted_time)
    7639             : {
    7640           0 :         struct i802_bss *bss = priv;
    7641           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7642             :         struct nl_msg *msg;
    7643             :         int ret;
    7644             : 
    7645           0 :         wpa_printf(MSG_DEBUG,
    7646             :                    "nl80211: add_ts request: tsid=%u admitted_time=%u up=%d",
    7647             :                    tsid, admitted_time, user_priority);
    7648             : 
    7649           0 :         if (!is_sta_interface(drv->nlmode))
    7650           0 :                 return -ENOTSUP;
    7651             : 
    7652           0 :         msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_ADD_TX_TS);
    7653           0 :         if (!msg ||
    7654           0 :             nla_put_u8(msg, NL80211_ATTR_TSID, tsid) ||
    7655           0 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
    7656           0 :             nla_put_u8(msg, NL80211_ATTR_USER_PRIO, user_priority) ||
    7657           0 :             nla_put_u16(msg, NL80211_ATTR_ADMITTED_TIME, admitted_time)) {
    7658           0 :                 nlmsg_free(msg);
    7659           0 :                 return -ENOBUFS;
    7660             :         }
    7661             : 
    7662           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7663           0 :         if (ret)
    7664           0 :                 wpa_printf(MSG_DEBUG, "nl80211: add_ts failed err=%d (%s)",
    7665             :                            ret, strerror(-ret));
    7666           0 :         return ret;
    7667             : }
    7668             : 
    7669             : 
    7670           0 : static int nl80211_del_ts(void *priv, u8 tsid, const u8 *addr)
    7671             : {
    7672           0 :         struct i802_bss *bss = priv;
    7673           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7674             :         struct nl_msg *msg;
    7675             :         int ret;
    7676             : 
    7677           0 :         wpa_printf(MSG_DEBUG, "nl80211: del_ts request: tsid=%u", tsid);
    7678             : 
    7679           0 :         if (!is_sta_interface(drv->nlmode))
    7680           0 :                 return -ENOTSUP;
    7681             : 
    7682           0 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_TX_TS)) ||
    7683           0 :             nla_put_u8(msg, NL80211_ATTR_TSID, tsid) ||
    7684           0 :             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
    7685           0 :                 nlmsg_free(msg);
    7686           0 :                 return -ENOBUFS;
    7687             :         }
    7688             : 
    7689           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7690           0 :         if (ret)
    7691           0 :                 wpa_printf(MSG_DEBUG, "nl80211: del_ts failed err=%d (%s)",
    7692             :                            ret, strerror(-ret));
    7693           0 :         return ret;
    7694             : }
    7695             : 
    7696             : 
    7697             : #ifdef CONFIG_TESTING_OPTIONS
    7698           2 : static int cmd_reply_handler(struct nl_msg *msg, void *arg)
    7699             : {
    7700           2 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    7701           2 :         struct wpabuf *buf = arg;
    7702             : 
    7703           2 :         if (!buf)
    7704           0 :                 return NL_SKIP;
    7705             : 
    7706           2 :         if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
    7707           0 :                 wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
    7708           0 :                 return NL_SKIP;
    7709             :         }
    7710             : 
    7711           2 :         wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
    7712           2 :                         genlmsg_attrlen(gnlh, 0));
    7713             : 
    7714           2 :         return NL_SKIP;
    7715             : }
    7716             : #endif /* CONFIG_TESTING_OPTIONS */
    7717             : 
    7718             : 
    7719           0 : static int vendor_reply_handler(struct nl_msg *msg, void *arg)
    7720             : {
    7721             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    7722             :         struct nlattr *nl_vendor_reply, *nl;
    7723           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    7724           0 :         struct wpabuf *buf = arg;
    7725             :         int rem;
    7726             : 
    7727           0 :         if (!buf)
    7728           0 :                 return NL_SKIP;
    7729             : 
    7730           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    7731             :                   genlmsg_attrlen(gnlh, 0), NULL);
    7732           0 :         nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
    7733             : 
    7734           0 :         if (!nl_vendor_reply)
    7735           0 :                 return NL_SKIP;
    7736             : 
    7737           0 :         if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
    7738           0 :                 wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
    7739           0 :                 return NL_SKIP;
    7740             :         }
    7741             : 
    7742           0 :         nla_for_each_nested(nl, nl_vendor_reply, rem) {
    7743           0 :                 wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
    7744             :         }
    7745             : 
    7746           0 :         return NL_SKIP;
    7747             : }
    7748             : 
    7749             : 
    7750           5 : static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
    7751             :                               unsigned int subcmd, const u8 *data,
    7752             :                               size_t data_len, struct wpabuf *buf)
    7753             : {
    7754           5 :         struct i802_bss *bss = priv;
    7755           5 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7756             :         struct nl_msg *msg;
    7757             :         int ret;
    7758             : 
    7759             : #ifdef CONFIG_TESTING_OPTIONS
    7760           5 :         if (vendor_id == 0xffffffff) {
    7761           5 :                 msg = nlmsg_alloc();
    7762           5 :                 if (!msg)
    7763           0 :                         return -ENOMEM;
    7764             : 
    7765           5 :                 nl80211_cmd(drv, msg, 0, subcmd);
    7766           5 :                 if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
    7767             :                     0)
    7768           0 :                         goto fail;
    7769           5 :                 ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
    7770           5 :                 if (ret)
    7771           0 :                         wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
    7772             :                                    ret);
    7773           5 :                 return ret;
    7774             :         }
    7775             : #endif /* CONFIG_TESTING_OPTIONS */
    7776             : 
    7777           0 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) ||
    7778           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, vendor_id) ||
    7779           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd) ||
    7780           0 :             (data &&
    7781           0 :              nla_put(msg, NL80211_ATTR_VENDOR_DATA, data_len, data)))
    7782             :                 goto fail;
    7783             : 
    7784           0 :         ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
    7785           0 :         if (ret)
    7786           0 :                 wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
    7787             :                            ret);
    7788           0 :         return ret;
    7789             : 
    7790             : fail:
    7791           0 :         nlmsg_free(msg);
    7792           0 :         return -ENOBUFS;
    7793             : }
    7794             : 
    7795             : 
    7796           5 : static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
    7797             :                                u8 qos_map_set_len)
    7798             : {
    7799           5 :         struct i802_bss *bss = priv;
    7800           5 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7801             :         struct nl_msg *msg;
    7802             :         int ret;
    7803             : 
    7804           5 :         wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
    7805             :                     qos_map_set, qos_map_set_len);
    7806             : 
    7807          10 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) ||
    7808           5 :             nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) {
    7809           0 :                 nlmsg_free(msg);
    7810           0 :                 return -ENOBUFS;
    7811             :         }
    7812             : 
    7813           5 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7814           5 :         if (ret)
    7815           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
    7816             : 
    7817           5 :         return ret;
    7818             : }
    7819             : 
    7820             : 
    7821           0 : static int nl80211_set_wowlan(void *priv,
    7822             :                               const struct wowlan_triggers *triggers)
    7823             : {
    7824           0 :         struct i802_bss *bss = priv;
    7825           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7826             :         struct nl_msg *msg;
    7827             :         struct nlattr *wowlan_triggers;
    7828             :         int ret;
    7829             : 
    7830           0 :         wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan");
    7831             : 
    7832           0 :         if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_SET_WOWLAN)) ||
    7833             :             !(wowlan_triggers = nla_nest_start(msg,
    7834           0 :                                                NL80211_ATTR_WOWLAN_TRIGGERS)) ||
    7835           0 :             (triggers->any &&
    7836           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
    7837           0 :             (triggers->disconnect &&
    7838           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
    7839           0 :             (triggers->magic_pkt &&
    7840           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
    7841           0 :             (triggers->gtk_rekey_failure &&
    7842           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
    7843           0 :             (triggers->eap_identity_req &&
    7844           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
    7845           0 :             (triggers->four_way_handshake &&
    7846           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
    7847           0 :             (triggers->rfkill_release &&
    7848           0 :              nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) {
    7849           0 :                 nlmsg_free(msg);
    7850           0 :                 return -ENOBUFS;
    7851             :         }
    7852             : 
    7853           0 :         nla_nest_end(msg, wowlan_triggers);
    7854             : 
    7855           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7856           0 :         if (ret)
    7857           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan failed");
    7858             : 
    7859           0 :         return ret;
    7860             : }
    7861             : 
    7862             : 
    7863           3 : static int nl80211_roaming(void *priv, int allowed, const u8 *bssid)
    7864             : {
    7865           3 :         struct i802_bss *bss = priv;
    7866           3 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7867             :         struct nl_msg *msg;
    7868             :         struct nlattr *params;
    7869             : 
    7870           3 :         wpa_printf(MSG_DEBUG, "nl80211: Roaming policy: allowed=%d", allowed);
    7871             : 
    7872           3 :         if (!drv->roaming_vendor_cmd_avail) {
    7873           3 :                 wpa_printf(MSG_DEBUG,
    7874             :                            "nl80211: Ignore roaming policy change since driver does not provide command for setting it");
    7875           3 :                 return -1;
    7876             :         }
    7877             : 
    7878           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    7879           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    7880           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    7881           0 :                         QCA_NL80211_VENDOR_SUBCMD_ROAMING) ||
    7882           0 :             !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
    7883           0 :             nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY,
    7884             :                         allowed ? QCA_ROAMING_ALLOWED_WITHIN_ESS :
    7885           0 :                         QCA_ROAMING_NOT_ALLOWED) ||
    7886           0 :             (bssid &&
    7887           0 :              nla_put(msg, QCA_WLAN_VENDOR_ATTR_MAC_ADDR, ETH_ALEN, bssid))) {
    7888           0 :                 nlmsg_free(msg);
    7889           0 :                 return -1;
    7890             :         }
    7891           0 :         nla_nest_end(msg, params);
    7892             : 
    7893           0 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    7894             : }
    7895             : 
    7896             : 
    7897          11 : static int nl80211_set_mac_addr(void *priv, const u8 *addr)
    7898             : {
    7899          11 :         struct i802_bss *bss = priv;
    7900          11 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7901          11 :         int new_addr = addr != NULL;
    7902             : 
    7903          11 :         if (!addr)
    7904           2 :                 addr = drv->perm_addr;
    7905             : 
    7906          11 :         if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) < 0)
    7907           0 :                 return -1;
    7908             : 
    7909          11 :         if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname, addr) < 0)
    7910             :         {
    7911           0 :                 wpa_printf(MSG_DEBUG,
    7912             :                            "nl80211: failed to set_mac_addr for %s to " MACSTR,
    7913           0 :                            bss->ifname, MAC2STR(addr));
    7914           0 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
    7915             :                                           1) < 0) {
    7916           0 :                         wpa_printf(MSG_DEBUG,
    7917             :                                    "nl80211: Could not restore interface UP after failed set_mac_addr");
    7918             :                 }
    7919           0 :                 return -1;
    7920             :         }
    7921             : 
    7922          77 :         wpa_printf(MSG_DEBUG, "nl80211: set_mac_addr for %s to " MACSTR,
    7923          77 :                    bss->ifname, MAC2STR(addr));
    7924          11 :         drv->addr_changed = new_addr;
    7925          11 :         os_memcpy(bss->addr, addr, ETH_ALEN);
    7926             : 
    7927          11 :         if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1) < 0)
    7928             :         {
    7929           0 :                 wpa_printf(MSG_DEBUG,
    7930             :                            "nl80211: Could not restore interface UP after set_mac_addr");
    7931             :         }
    7932             : 
    7933          11 :         return 0;
    7934             : }
    7935             : 
    7936             : 
    7937             : #ifdef CONFIG_MESH
    7938             : 
    7939          35 : static int wpa_driver_nl80211_init_mesh(void *priv)
    7940             : {
    7941          35 :         if (wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_MESH_POINT)) {
    7942           0 :                 wpa_printf(MSG_INFO,
    7943             :                            "nl80211: Failed to set interface into mesh mode");
    7944           0 :                 return -1;
    7945             :         }
    7946          35 :         return 0;
    7947             : }
    7948             : 
    7949             : 
    7950          33 : static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id,
    7951             :                                size_t mesh_id_len)
    7952             : {
    7953          33 :         if (mesh_id) {
    7954          33 :                 wpa_hexdump_ascii(MSG_DEBUG, "  * Mesh ID (SSID)",
    7955             :                                   mesh_id, mesh_id_len);
    7956          33 :                 return nla_put(msg, NL80211_ATTR_MESH_ID, mesh_id_len, mesh_id);
    7957             :         }
    7958             : 
    7959           0 :         return 0;
    7960             : }
    7961             : 
    7962             : 
    7963          33 : static int nl80211_join_mesh(struct i802_bss *bss,
    7964             :                              struct wpa_driver_mesh_join_params *params)
    7965             : {
    7966          33 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7967             :         struct nl_msg *msg;
    7968             :         struct nlattr *container;
    7969          33 :         int ret = -1;
    7970             : 
    7971          33 :         wpa_printf(MSG_DEBUG, "nl80211: mesh join (ifindex=%d)", drv->ifindex);
    7972          33 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_MESH);
    7973          66 :         if (!msg ||
    7974          66 :             nl80211_put_freq_params(msg, &params->freq) ||
    7975          66 :             nl80211_put_basic_rates(msg, params->basic_rates) ||
    7976          66 :             nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
    7977          33 :             nl80211_put_beacon_int(msg, params->beacon_int))
    7978             :                 goto fail;
    7979             : 
    7980          33 :         wpa_printf(MSG_DEBUG, "  * flags=%08X", params->flags);
    7981             : 
    7982          33 :         container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP);
    7983          33 :         if (!container)
    7984           0 :                 goto fail;
    7985             : 
    7986          33 :         if (params->ies) {
    7987          12 :                 wpa_hexdump(MSG_DEBUG, "  * IEs", params->ies, params->ie_len);
    7988          12 :                 if (nla_put(msg, NL80211_MESH_SETUP_IE, params->ie_len,
    7989          12 :                             params->ies))
    7990           0 :                         goto fail;
    7991             :         }
    7992             :         /* WPA_DRIVER_MESH_FLAG_OPEN_AUTH is treated as default by nl80211 */
    7993          33 :         if (params->flags & WPA_DRIVER_MESH_FLAG_SAE_AUTH) {
    7994          24 :                 if (nla_put_u8(msg, NL80211_MESH_SETUP_AUTH_PROTOCOL, 0x1) ||
    7995          12 :                     nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AUTH))
    7996             :                         goto fail;
    7997             :         }
    7998          45 :         if ((params->flags & WPA_DRIVER_MESH_FLAG_AMPE) &&
    7999          12 :             nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AMPE))
    8000           0 :                 goto fail;
    8001          66 :         if ((params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM) &&
    8002          33 :             nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_MPM))
    8003           0 :                 goto fail;
    8004          33 :         nla_nest_end(msg, container);
    8005             : 
    8006          33 :         container = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
    8007          33 :         if (!container)
    8008           0 :                 goto fail;
    8009             : 
    8010          66 :         if (!(params->conf.flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
    8011          33 :             nla_put_u32(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, 0))
    8012           0 :                 goto fail;
    8013          33 :         if ((params->conf.flags & WPA_DRIVER_MESH_FLAG_DRIVER_MPM) &&
    8014           0 :             nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
    8015           0 :                         params->max_peer_links))
    8016           0 :                 goto fail;
    8017             : 
    8018             :         /*
    8019             :          * Set NL80211_MESHCONF_PLINK_TIMEOUT even if user mpm is used because
    8020             :          * the timer could disconnect stations even in that case.
    8021             :          */
    8022          33 :         if (nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
    8023          33 :                         params->conf.peer_link_timeout)) {
    8024           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to set PLINK_TIMEOUT");
    8025           0 :                 goto fail;
    8026             :         }
    8027             : 
    8028          33 :         nla_nest_end(msg, container);
    8029             : 
    8030          33 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8031          33 :         msg = NULL;
    8032          33 :         if (ret) {
    8033           0 :                 wpa_printf(MSG_DEBUG, "nl80211: mesh join failed: ret=%d (%s)",
    8034             :                            ret, strerror(-ret));
    8035           0 :                 goto fail;
    8036             :         }
    8037          33 :         ret = 0;
    8038          33 :         bss->freq = params->freq.freq;
    8039          33 :         wpa_printf(MSG_DEBUG, "nl80211: mesh join request send successfully");
    8040             : 
    8041             : fail:
    8042          33 :         nlmsg_free(msg);
    8043          33 :         return ret;
    8044             : }
    8045             : 
    8046             : 
    8047             : static int
    8048          33 : wpa_driver_nl80211_join_mesh(void *priv,
    8049             :                              struct wpa_driver_mesh_join_params *params)
    8050             : {
    8051          33 :         struct i802_bss *bss = priv;
    8052             :         int ret, timeout;
    8053             : 
    8054          33 :         timeout = params->conf.peer_link_timeout;
    8055             : 
    8056             :         /* Disable kernel inactivity timer */
    8057          33 :         if (params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM)
    8058          33 :                 params->conf.peer_link_timeout = 0;
    8059             : 
    8060          33 :         ret = nl80211_join_mesh(bss, params);
    8061          33 :         if (ret == -EINVAL && params->conf.peer_link_timeout == 0) {
    8062           0 :                 wpa_printf(MSG_DEBUG,
    8063             :                            "nl80211: Mesh join retry for peer_link_timeout");
    8064             :                 /*
    8065             :                  * Old kernel does not support setting
    8066             :                  * NL80211_MESHCONF_PLINK_TIMEOUT to zero, so set 60 seconds
    8067             :                  * into future from peer_link_timeout.
    8068             :                  */
    8069           0 :                 params->conf.peer_link_timeout = timeout + 60;
    8070           0 :                 ret = nl80211_join_mesh(priv, params);
    8071             :         }
    8072             : 
    8073          33 :         params->conf.peer_link_timeout = timeout;
    8074          33 :         return ret;
    8075             : }
    8076             : 
    8077             : 
    8078          35 : static int wpa_driver_nl80211_leave_mesh(void *priv)
    8079             : {
    8080          35 :         struct i802_bss *bss = priv;
    8081          35 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8082             :         struct nl_msg *msg;
    8083             :         int ret;
    8084             : 
    8085          35 :         wpa_printf(MSG_DEBUG, "nl80211: mesh leave (ifindex=%d)", drv->ifindex);
    8086          35 :         msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_MESH);
    8087          35 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8088          35 :         if (ret) {
    8089           2 :                 wpa_printf(MSG_DEBUG, "nl80211: mesh leave failed: ret=%d (%s)",
    8090             :                            ret, strerror(-ret));
    8091             :         } else {
    8092          33 :                 wpa_printf(MSG_DEBUG,
    8093             :                            "nl80211: mesh leave request send successfully");
    8094             :         }
    8095             : 
    8096          35 :         if (wpa_driver_nl80211_set_mode(drv->first_bss,
    8097             :                                         NL80211_IFTYPE_STATION)) {
    8098           0 :                 wpa_printf(MSG_INFO,
    8099             :                            "nl80211: Failed to set interface into station mode");
    8100             :         }
    8101          35 :         return ret;
    8102             : }
    8103             : 
    8104             : #endif /* CONFIG_MESH */
    8105             : 
    8106             : 
    8107          17 : static int wpa_driver_br_add_ip_neigh(void *priv, u8 version,
    8108             :                                       const u8 *ipaddr, int prefixlen,
    8109             :                                       const u8 *addr)
    8110             : {
    8111             : #ifdef CONFIG_LIBNL3_ROUTE
    8112          17 :         struct i802_bss *bss = priv;
    8113          17 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8114             :         struct rtnl_neigh *rn;
    8115          17 :         struct nl_addr *nl_ipaddr = NULL;
    8116          17 :         struct nl_addr *nl_lladdr = NULL;
    8117             :         int family, addrsize;
    8118             :         int res;
    8119             : 
    8120          17 :         if (!ipaddr || prefixlen == 0 || !addr)
    8121           0 :                 return -EINVAL;
    8122             : 
    8123          17 :         if (bss->br_ifindex == 0) {
    8124           0 :                 wpa_printf(MSG_DEBUG,
    8125             :                            "nl80211: bridge must be set before adding an ip neigh to it");
    8126           0 :                 return -1;
    8127             :         }
    8128             : 
    8129          17 :         if (!drv->rtnl_sk) {
    8130           0 :                 wpa_printf(MSG_DEBUG,
    8131             :                            "nl80211: nl_sock for NETLINK_ROUTE is not initialized");
    8132           0 :                 return -1;
    8133             :         }
    8134             : 
    8135          17 :         if (version == 4) {
    8136           6 :                 family = AF_INET;
    8137           6 :                 addrsize = 4;
    8138          11 :         } else if (version == 6) {
    8139          11 :                 family = AF_INET6;
    8140          11 :                 addrsize = 16;
    8141             :         } else {
    8142           0 :                 return -EINVAL;
    8143             :         }
    8144             : 
    8145          17 :         rn = rtnl_neigh_alloc();
    8146          17 :         if (rn == NULL)
    8147           0 :                 return -ENOMEM;
    8148             : 
    8149             :         /* set the destination ip address for neigh */
    8150          17 :         nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
    8151          17 :         if (nl_ipaddr == NULL) {
    8152           0 :                 wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
    8153           0 :                 res = -ENOMEM;
    8154           0 :                 goto errout;
    8155             :         }
    8156          17 :         nl_addr_set_prefixlen(nl_ipaddr, prefixlen);
    8157          17 :         res = rtnl_neigh_set_dst(rn, nl_ipaddr);
    8158          17 :         if (res) {
    8159           0 :                 wpa_printf(MSG_DEBUG,
    8160             :                            "nl80211: neigh set destination addr failed");
    8161           0 :                 goto errout;
    8162             :         }
    8163             : 
    8164             :         /* set the corresponding lladdr for neigh */
    8165          17 :         nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN);
    8166          17 :         if (nl_lladdr == NULL) {
    8167           0 :                 wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed");
    8168           0 :                 res = -ENOMEM;
    8169           0 :                 goto errout;
    8170             :         }
    8171          17 :         rtnl_neigh_set_lladdr(rn, nl_lladdr);
    8172             : 
    8173          17 :         rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
    8174          17 :         rtnl_neigh_set_state(rn, NUD_PERMANENT);
    8175             : 
    8176          17 :         res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
    8177          17 :         if (res) {
    8178           0 :                 wpa_printf(MSG_DEBUG,
    8179             :                            "nl80211: Adding bridge ip neigh failed: %s",
    8180           0 :                            strerror(errno));
    8181             :         }
    8182             : errout:
    8183          17 :         if (nl_lladdr)
    8184          17 :                 nl_addr_put(nl_lladdr);
    8185          17 :         if (nl_ipaddr)
    8186          17 :                 nl_addr_put(nl_ipaddr);
    8187          17 :         if (rn)
    8188          17 :                 rtnl_neigh_put(rn);
    8189          17 :         return res;
    8190             : #else /* CONFIG_LIBNL3_ROUTE */
    8191           0 :         return -1;
    8192             : #endif /* CONFIG_LIBNL3_ROUTE */
    8193             : }
    8194             : 
    8195             : 
    8196          28 : static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
    8197             :                                          const u8 *ipaddr)
    8198             : {
    8199             : #ifdef CONFIG_LIBNL3_ROUTE
    8200          28 :         struct i802_bss *bss = priv;
    8201          28 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8202             :         struct rtnl_neigh *rn;
    8203             :         struct nl_addr *nl_ipaddr;
    8204             :         int family, addrsize;
    8205             :         int res;
    8206             : 
    8207          28 :         if (!ipaddr)
    8208           0 :                 return -EINVAL;
    8209             : 
    8210          28 :         if (version == 4) {
    8211           6 :                 family = AF_INET;
    8212           6 :                 addrsize = 4;
    8213          22 :         } else if (version == 6) {
    8214          22 :                 family = AF_INET6;
    8215          22 :                 addrsize = 16;
    8216             :         } else {
    8217           0 :                 return -EINVAL;
    8218             :         }
    8219             : 
    8220          28 :         if (bss->br_ifindex == 0) {
    8221           0 :                 wpa_printf(MSG_DEBUG,
    8222             :                            "nl80211: bridge must be set to delete an ip neigh");
    8223           0 :                 return -1;
    8224             :         }
    8225             : 
    8226          28 :         if (!drv->rtnl_sk) {
    8227           0 :                 wpa_printf(MSG_DEBUG,
    8228             :                            "nl80211: nl_sock for NETLINK_ROUTE is not initialized");
    8229           0 :                 return -1;
    8230             :         }
    8231             : 
    8232          28 :         rn = rtnl_neigh_alloc();
    8233          28 :         if (rn == NULL)
    8234           0 :                 return -ENOMEM;
    8235             : 
    8236             :         /* set the destination ip address for neigh */
    8237          28 :         nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
    8238          28 :         if (nl_ipaddr == NULL) {
    8239           0 :                 wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
    8240           0 :                 res = -ENOMEM;
    8241           0 :                 goto errout;
    8242             :         }
    8243          28 :         res = rtnl_neigh_set_dst(rn, nl_ipaddr);
    8244          28 :         if (res) {
    8245           0 :                 wpa_printf(MSG_DEBUG,
    8246             :                            "nl80211: neigh set destination addr failed");
    8247           0 :                 goto errout;
    8248             :         }
    8249             : 
    8250          28 :         rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
    8251             : 
    8252          28 :         res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
    8253          28 :         if (res) {
    8254          11 :                 wpa_printf(MSG_DEBUG,
    8255             :                            "nl80211: Deleting bridge ip neigh failed: %s",
    8256          11 :                            strerror(errno));
    8257             :         }
    8258             : errout:
    8259          28 :         if (nl_ipaddr)
    8260          28 :                 nl_addr_put(nl_ipaddr);
    8261          28 :         if (rn)
    8262          28 :                 rtnl_neigh_put(rn);
    8263          28 :         return res;
    8264             : #else /* CONFIG_LIBNL3_ROUTE */
    8265           0 :         return -1;
    8266             : #endif /* CONFIG_LIBNL3_ROUTE */
    8267             : }
    8268             : 
    8269             : 
    8270        4895 : static int linux_write_system_file(const char *path, unsigned int val)
    8271             : {
    8272             :         char buf[50];
    8273             :         int fd, len;
    8274             : 
    8275        4895 :         len = os_snprintf(buf, sizeof(buf), "%u\n", val);
    8276        4895 :         if (os_snprintf_error(sizeof(buf), len))
    8277           0 :                 return -1;
    8278             : 
    8279        4895 :         fd = open(path, O_WRONLY);
    8280        4895 :         if (fd < 0)
    8281        4869 :                 return -1;
    8282             : 
    8283          26 :         if (write(fd, buf, len) < 0) {
    8284           0 :                 wpa_printf(MSG_DEBUG,
    8285             :                            "nl80211: Failed to write Linux system file: %s with the value of %d",
    8286             :                            path, val);
    8287           0 :                 close(fd);
    8288           0 :                 return -1;
    8289             :         }
    8290          26 :         close(fd);
    8291             : 
    8292          26 :         return 0;
    8293             : }
    8294             : 
    8295             : 
    8296        3260 : static const char * drv_br_port_attr_str(enum drv_br_port_attr attr)
    8297             : {
    8298        3260 :         switch (attr) {
    8299             :         case DRV_BR_PORT_ATTR_PROXYARP:
    8300        1630 :                 return "proxyarp_wifi";
    8301             :         case DRV_BR_PORT_ATTR_HAIRPIN_MODE:
    8302        1630 :                 return "hairpin_mode";
    8303             :         }
    8304             : 
    8305           0 :         return NULL;
    8306             : }
    8307             : 
    8308             : 
    8309        3260 : static int wpa_driver_br_port_set_attr(void *priv, enum drv_br_port_attr attr,
    8310             :                                        unsigned int val)
    8311             : {
    8312        3260 :         struct i802_bss *bss = priv;
    8313             :         char path[128];
    8314             :         const char *attr_txt;
    8315             : 
    8316        3260 :         attr_txt = drv_br_port_attr_str(attr);
    8317        3260 :         if (attr_txt == NULL)
    8318           0 :                 return -EINVAL;
    8319             : 
    8320        3260 :         os_snprintf(path, sizeof(path), "/sys/class/net/%s/brport/%s",
    8321        3260 :                     bss->ifname, attr_txt);
    8322             : 
    8323        3260 :         if (linux_write_system_file(path, val))
    8324        3246 :                 return -1;
    8325             : 
    8326          14 :         return 0;
    8327             : }
    8328             : 
    8329             : 
    8330        1630 : static const char * drv_br_net_param_str(enum drv_br_net_param param)
    8331             : {
    8332        1630 :         switch (param) {
    8333             :         case DRV_BR_NET_PARAM_GARP_ACCEPT:
    8334        1630 :                 return "arp_accept";
    8335             :         default:
    8336           0 :                 return NULL;
    8337             :         }
    8338             : }
    8339             : 
    8340             : 
    8341        1635 : static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
    8342             :                                        unsigned int val)
    8343             : {
    8344        1635 :         struct i802_bss *bss = priv;
    8345             :         char path[128];
    8346             :         const char *param_txt;
    8347        1635 :         int ip_version = 4;
    8348             : 
    8349        1635 :         if (param == DRV_BR_MULTICAST_SNOOPING) {
    8350           5 :                 os_snprintf(path, sizeof(path),
    8351             :                             "/sys/devices/virtual/net/%s/bridge/multicast_snooping",
    8352           5 :                             bss->brname);
    8353           5 :                 goto set_val;
    8354             :         }
    8355             : 
    8356        1630 :         param_txt = drv_br_net_param_str(param);
    8357        1630 :         if (param_txt == NULL)
    8358           0 :                 return -EINVAL;
    8359             : 
    8360        1630 :         switch (param) {
    8361             :                 case DRV_BR_NET_PARAM_GARP_ACCEPT:
    8362        1630 :                         ip_version = 4;
    8363        1630 :                         break;
    8364             :                 default:
    8365           0 :                         return -EINVAL;
    8366             :         }
    8367             : 
    8368        1630 :         os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s",
    8369        1630 :                     ip_version, bss->brname, param_txt);
    8370             : 
    8371             : set_val:
    8372        1635 :         if (linux_write_system_file(path, val))
    8373        1623 :                 return -1;
    8374             : 
    8375          12 :         return 0;
    8376             : }
    8377             : 
    8378             : 
    8379           0 : static int hw_mode_to_qca_acs(enum hostapd_hw_mode hw_mode)
    8380             : {
    8381           0 :         switch (hw_mode) {
    8382             :         case HOSTAPD_MODE_IEEE80211B:
    8383           0 :                 return QCA_ACS_MODE_IEEE80211B;
    8384             :         case HOSTAPD_MODE_IEEE80211G:
    8385           0 :                 return QCA_ACS_MODE_IEEE80211G;
    8386             :         case HOSTAPD_MODE_IEEE80211A:
    8387           0 :                 return QCA_ACS_MODE_IEEE80211A;
    8388             :         case HOSTAPD_MODE_IEEE80211AD:
    8389           0 :                 return QCA_ACS_MODE_IEEE80211AD;
    8390             :         case HOSTAPD_MODE_IEEE80211ANY:
    8391           0 :                 return QCA_ACS_MODE_IEEE80211ANY;
    8392             :         default:
    8393           0 :                 return -1;
    8394             :         }
    8395             : }
    8396             : 
    8397             : 
    8398           0 : static int add_acs_freq_list(struct nl_msg *msg, const int *freq_list)
    8399             : {
    8400             :         int i, len, ret;
    8401             :         u32 *freqs;
    8402             : 
    8403           0 :         if (!freq_list)
    8404           0 :                 return 0;
    8405           0 :         len = int_array_len(freq_list);
    8406           0 :         freqs = os_malloc(sizeof(u32) * len);
    8407           0 :         if (!freqs)
    8408           0 :                 return -1;
    8409           0 :         for (i = 0; i < len; i++)
    8410           0 :                 freqs[i] = freq_list[i];
    8411           0 :         ret = nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST,
    8412             :                       sizeof(u32) * len, freqs);
    8413           0 :         os_free(freqs);
    8414           0 :         return ret;
    8415             : }
    8416             : 
    8417             : 
    8418           0 : static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
    8419             : {
    8420           0 :         struct i802_bss *bss = priv;
    8421           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8422             :         struct nl_msg *msg;
    8423             :         struct nlattr *data;
    8424             :         int ret;
    8425             :         int mode;
    8426             : 
    8427           0 :         mode = hw_mode_to_qca_acs(params->hw_mode);
    8428           0 :         if (mode < 0)
    8429           0 :                 return -1;
    8430             : 
    8431           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    8432           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    8433           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    8434           0 :                         QCA_NL80211_VENDOR_SUBCMD_DO_ACS) ||
    8435           0 :             !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
    8436           0 :             nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, mode) ||
    8437           0 :             (params->ht_enabled &&
    8438           0 :              nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED)) ||
    8439           0 :             (params->ht40_enabled &&
    8440           0 :              nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED)) ||
    8441           0 :             (params->vht_enabled &&
    8442           0 :              nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED)) ||
    8443           0 :             nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
    8444           0 :                         params->ch_width) ||
    8445           0 :             (params->ch_list_len &&
    8446           0 :              nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST, params->ch_list_len,
    8447           0 :                      params->ch_list)) ||
    8448           0 :             add_acs_freq_list(msg, params->freq_list)) {
    8449           0 :                 nlmsg_free(msg);
    8450           0 :                 return -ENOBUFS;
    8451             :         }
    8452           0 :         nla_nest_end(msg, data);
    8453             : 
    8454           0 :         wpa_printf(MSG_DEBUG,
    8455             :                    "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d CH_LIST_LEN: %u",
    8456           0 :                    params->hw_mode, params->ht_enabled, params->ht40_enabled,
    8457           0 :                    params->vht_enabled, params->ch_width, params->ch_list_len);
    8458             : 
    8459           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8460           0 :         if (ret) {
    8461           0 :                 wpa_printf(MSG_DEBUG,
    8462             :                            "nl80211: Failed to invoke driver ACS function: %s",
    8463           0 :                            strerror(errno));
    8464             :         }
    8465           0 :         return ret;
    8466             : }
    8467             : 
    8468             : 
    8469           6 : static int nl80211_set_band(void *priv, enum set_band band)
    8470             : {
    8471           6 :         struct i802_bss *bss = priv;
    8472           6 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8473             :         struct nl_msg *msg;
    8474             :         struct nlattr *data;
    8475             :         int ret;
    8476             :         enum qca_set_band qca_band;
    8477             : 
    8478           6 :         if (!drv->setband_vendor_cmd_avail)
    8479           6 :                 return -1;
    8480             : 
    8481           0 :         switch (band) {
    8482             :         case WPA_SETBAND_AUTO:
    8483           0 :                 qca_band = QCA_SETBAND_AUTO;
    8484           0 :                 break;
    8485             :         case WPA_SETBAND_5G:
    8486           0 :                 qca_band = QCA_SETBAND_5G;
    8487           0 :                 break;
    8488             :         case WPA_SETBAND_2G:
    8489           0 :                 qca_band = QCA_SETBAND_2G;
    8490           0 :                 break;
    8491             :         default:
    8492           0 :                 return -1;
    8493             :         }
    8494             : 
    8495           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    8496           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    8497           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    8498           0 :                         QCA_NL80211_VENDOR_SUBCMD_SETBAND) ||
    8499           0 :             !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
    8500           0 :             nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE, qca_band)) {
    8501           0 :                 nlmsg_free(msg);
    8502           0 :                 return -ENOBUFS;
    8503             :         }
    8504           0 :         nla_nest_end(msg, data);
    8505             : 
    8506           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8507           0 :         if (ret) {
    8508           0 :                 wpa_printf(MSG_DEBUG,
    8509             :                            "nl80211: Driver setband function failed: %s",
    8510           0 :                            strerror(errno));
    8511             :         }
    8512           0 :         return ret;
    8513             : }
    8514             : 
    8515             : 
    8516             : struct nl80211_pcl {
    8517             :         unsigned int num;
    8518             :         unsigned int *freq_list;
    8519             : };
    8520             : 
    8521           0 : static int preferred_freq_info_handler(struct nl_msg *msg, void *arg)
    8522             : {
    8523             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    8524           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    8525           0 :         struct nl80211_pcl *param = arg;
    8526             :         struct nlattr *nl_vend, *attr;
    8527             :         enum qca_iface_type iface_type;
    8528             :         struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
    8529             :         unsigned int num, max_num;
    8530             :         u32 *freqs;
    8531             : 
    8532           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    8533             :                   genlmsg_attrlen(gnlh, 0), NULL);
    8534             : 
    8535           0 :         nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
    8536           0 :         if (!nl_vend)
    8537           0 :                 return NL_SKIP;
    8538             : 
    8539           0 :         nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
    8540           0 :                   nla_data(nl_vend), nla_len(nl_vend), NULL);
    8541             : 
    8542           0 :         attr = tb_vendor[
    8543             :                 QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE];
    8544           0 :         if (!attr) {
    8545           0 :                 wpa_printf(MSG_ERROR, "nl80211: iface_type couldn't be found");
    8546           0 :                 param->num = 0;
    8547           0 :                 return NL_SKIP;
    8548             :         }
    8549             : 
    8550           0 :         iface_type = (enum qca_iface_type) nla_get_u32(attr);
    8551           0 :         wpa_printf(MSG_DEBUG, "nl80211: Driver returned iface_type=%d",
    8552             :                    iface_type);
    8553             : 
    8554           0 :         attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST];
    8555           0 :         if (!attr) {
    8556           0 :                 wpa_printf(MSG_ERROR,
    8557             :                            "nl80211: preferred_freq_list couldn't be found");
    8558           0 :                 param->num = 0;
    8559           0 :                 return NL_SKIP;
    8560             :         }
    8561             : 
    8562             :         /*
    8563             :          * param->num has the maximum number of entries for which there
    8564             :          * is room in the freq_list provided by the caller.
    8565             :          */
    8566           0 :         freqs = nla_data(attr);
    8567           0 :         max_num = nla_len(attr) / sizeof(u32);
    8568           0 :         if (max_num > param->num)
    8569           0 :                 max_num = param->num;
    8570           0 :         for (num = 0; num < max_num; num++)
    8571           0 :                 param->freq_list[num] = freqs[num];
    8572           0 :         param->num = num;
    8573             : 
    8574           0 :         return NL_SKIP;
    8575             : }
    8576             : 
    8577             : 
    8578         538 : static int nl80211_get_pref_freq_list(void *priv,
    8579             :                                       enum wpa_driver_if_type if_type,
    8580             :                                       unsigned int *num,
    8581             :                                       unsigned int *freq_list)
    8582             : {
    8583         538 :         struct i802_bss *bss = priv;
    8584         538 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8585             :         struct nl_msg *msg;
    8586             :         int ret;
    8587             :         unsigned int i;
    8588             :         struct nlattr *params;
    8589             :         struct nl80211_pcl param;
    8590             :         enum qca_iface_type iface_type;
    8591             : 
    8592         538 :         if (!drv->get_pref_freq_list)
    8593         538 :                 return -1;
    8594             : 
    8595           0 :         switch (if_type) {
    8596             :         case WPA_IF_STATION:
    8597           0 :                 iface_type = QCA_IFACE_TYPE_STA;
    8598           0 :                 break;
    8599             :         case WPA_IF_AP_BSS:
    8600           0 :                 iface_type = QCA_IFACE_TYPE_AP;
    8601           0 :                 break;
    8602             :         case WPA_IF_P2P_GO:
    8603           0 :                 iface_type = QCA_IFACE_TYPE_P2P_GO;
    8604           0 :                 break;
    8605             :         case WPA_IF_P2P_CLIENT:
    8606           0 :                 iface_type = QCA_IFACE_TYPE_P2P_CLIENT;
    8607           0 :                 break;
    8608             :         case WPA_IF_IBSS:
    8609           0 :                 iface_type = QCA_IFACE_TYPE_IBSS;
    8610           0 :                 break;
    8611             :         case WPA_IF_TDLS:
    8612           0 :                 iface_type = QCA_IFACE_TYPE_TDLS;
    8613           0 :                 break;
    8614             :         default:
    8615           0 :                 return -1;
    8616             :         }
    8617             : 
    8618           0 :         param.num = *num;
    8619           0 :         param.freq_list = freq_list;
    8620             : 
    8621           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    8622           0 :             nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex) ||
    8623           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    8624           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    8625           0 :                         QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST) ||
    8626           0 :             !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
    8627           0 :             nla_put_u32(msg,
    8628             :                         QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE,
    8629             :                         iface_type)) {
    8630           0 :                 wpa_printf(MSG_ERROR,
    8631             :                            "%s: err in adding vendor_cmd and vendor_data",
    8632             :                            __func__);
    8633           0 :                 nlmsg_free(msg);
    8634           0 :                 return -1;
    8635             :         }
    8636           0 :         nla_nest_end(msg, params);
    8637             : 
    8638           0 :         os_memset(freq_list, 0, *num * sizeof(freq_list[0]));
    8639           0 :         ret = send_and_recv_msgs(drv, msg, preferred_freq_info_handler, &param);
    8640           0 :         if (ret) {
    8641           0 :                 wpa_printf(MSG_ERROR,
    8642             :                            "%s: err in send_and_recv_msgs", __func__);
    8643           0 :                 return ret;
    8644             :         }
    8645             : 
    8646           0 :         *num = param.num;
    8647             : 
    8648           0 :         for (i = 0; i < *num; i++) {
    8649           0 :                 wpa_printf(MSG_DEBUG, "nl80211: preferred_channel_list[%d]=%d",
    8650           0 :                            i, freq_list[i]);
    8651             :         }
    8652             : 
    8653           0 :         return 0;
    8654             : }
    8655             : 
    8656             : 
    8657         111 : static int nl80211_set_prob_oper_freq(void *priv, unsigned int freq)
    8658             : {
    8659         111 :         struct i802_bss *bss = priv;
    8660         111 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8661             :         struct nl_msg *msg;
    8662             :         int ret;
    8663             :         struct nlattr *params;
    8664             : 
    8665         111 :         if (!drv->set_prob_oper_freq)
    8666         111 :                 return -1;
    8667             : 
    8668           0 :         wpa_printf(MSG_DEBUG,
    8669             :                    "nl80211: Set P2P probable operating freq %u for ifindex %d",
    8670             :                    freq, bss->ifindex);
    8671             : 
    8672           0 :         if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
    8673           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
    8674           0 :             nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    8675           0 :                         QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL) ||
    8676           0 :             !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
    8677           0 :             nla_put_u32(msg,
    8678             :                         QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE,
    8679           0 :                         QCA_IFACE_TYPE_P2P_CLIENT) ||
    8680           0 :             nla_put_u32(msg,
    8681             :                         QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ,
    8682             :                         freq)) {
    8683           0 :                 wpa_printf(MSG_ERROR,
    8684             :                            "%s: err in adding vendor_cmd and vendor_data",
    8685             :                            __func__);
    8686           0 :                 nlmsg_free(msg);
    8687           0 :                 return -1;
    8688             :         }
    8689           0 :         nla_nest_end(msg, params);
    8690             : 
    8691           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8692           0 :         msg = NULL;
    8693           0 :         if (ret) {
    8694           0 :                 wpa_printf(MSG_ERROR, "%s: err in send_and_recv_msgs",
    8695             :                            __func__);
    8696           0 :                 return ret;
    8697             :         }
    8698           0 :         nlmsg_free(msg);
    8699           0 :         return 0;
    8700             : }
    8701             : 
    8702             : 
    8703             : const struct wpa_driver_ops wpa_driver_nl80211_ops = {
    8704             :         .name = "nl80211",
    8705             :         .desc = "Linux nl80211/cfg80211",
    8706             :         .get_bssid = wpa_driver_nl80211_get_bssid,
    8707             :         .get_ssid = wpa_driver_nl80211_get_ssid,
    8708             :         .set_key = driver_nl80211_set_key,
    8709             :         .scan2 = driver_nl80211_scan2,
    8710             :         .sched_scan = wpa_driver_nl80211_sched_scan,
    8711             :         .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
    8712             :         .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
    8713             :         .deauthenticate = driver_nl80211_deauthenticate,
    8714             :         .authenticate = driver_nl80211_authenticate,
    8715             :         .associate = wpa_driver_nl80211_associate,
    8716             :         .global_init = nl80211_global_init,
    8717             :         .global_deinit = nl80211_global_deinit,
    8718             :         .init2 = wpa_driver_nl80211_init,
    8719             :         .deinit = driver_nl80211_deinit,
    8720             :         .get_capa = wpa_driver_nl80211_get_capa,
    8721             :         .set_operstate = wpa_driver_nl80211_set_operstate,
    8722             :         .set_supp_port = wpa_driver_nl80211_set_supp_port,
    8723             :         .set_country = wpa_driver_nl80211_set_country,
    8724             :         .get_country = wpa_driver_nl80211_get_country,
    8725             :         .set_ap = wpa_driver_nl80211_set_ap,
    8726             :         .set_acl = wpa_driver_nl80211_set_acl,
    8727             :         .if_add = wpa_driver_nl80211_if_add,
    8728             :         .if_remove = driver_nl80211_if_remove,
    8729             :         .send_mlme = driver_nl80211_send_mlme,
    8730             :         .get_hw_feature_data = nl80211_get_hw_feature_data,
    8731             :         .sta_add = wpa_driver_nl80211_sta_add,
    8732             :         .sta_remove = driver_nl80211_sta_remove,
    8733             :         .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
    8734             :         .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
    8735             :         .hapd_init = i802_init,
    8736             :         .hapd_deinit = i802_deinit,
    8737             :         .set_wds_sta = i802_set_wds_sta,
    8738             :         .get_seqnum = i802_get_seqnum,
    8739             :         .flush = i802_flush,
    8740             :         .get_inact_sec = i802_get_inact_sec,
    8741             :         .sta_clear_stats = i802_sta_clear_stats,
    8742             :         .set_rts = i802_set_rts,
    8743             :         .set_frag = i802_set_frag,
    8744             :         .set_tx_queue_params = i802_set_tx_queue_params,
    8745             :         .set_sta_vlan = driver_nl80211_set_sta_vlan,
    8746             :         .sta_deauth = i802_sta_deauth,
    8747             :         .sta_disassoc = i802_sta_disassoc,
    8748             :         .read_sta_data = driver_nl80211_read_sta_data,
    8749             :         .set_freq = i802_set_freq,
    8750             :         .send_action = driver_nl80211_send_action,
    8751             :         .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
    8752             :         .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
    8753             :         .cancel_remain_on_channel =
    8754             :         wpa_driver_nl80211_cancel_remain_on_channel,
    8755             :         .probe_req_report = driver_nl80211_probe_req_report,
    8756             :         .deinit_ap = wpa_driver_nl80211_deinit_ap,
    8757             :         .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
    8758             :         .resume = wpa_driver_nl80211_resume,
    8759             :         .signal_monitor = nl80211_signal_monitor,
    8760             :         .signal_poll = nl80211_signal_poll,
    8761             :         .send_frame = nl80211_send_frame,
    8762             :         .set_param = nl80211_set_param,
    8763             :         .get_radio_name = nl80211_get_radio_name,
    8764             :         .add_pmkid = nl80211_add_pmkid,
    8765             :         .remove_pmkid = nl80211_remove_pmkid,
    8766             :         .flush_pmkid = nl80211_flush_pmkid,
    8767             :         .set_rekey_info = nl80211_set_rekey_info,
    8768             :         .poll_client = nl80211_poll_client,
    8769             :         .set_p2p_powersave = nl80211_set_p2p_powersave,
    8770             :         .start_dfs_cac = nl80211_start_radar_detection,
    8771             :         .stop_ap = wpa_driver_nl80211_stop_ap,
    8772             : #ifdef CONFIG_TDLS
    8773             :         .send_tdls_mgmt = nl80211_send_tdls_mgmt,
    8774             :         .tdls_oper = nl80211_tdls_oper,
    8775             :         .tdls_enable_channel_switch = nl80211_tdls_enable_channel_switch,
    8776             :         .tdls_disable_channel_switch = nl80211_tdls_disable_channel_switch,
    8777             : #endif /* CONFIG_TDLS */
    8778             :         .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
    8779             :         .get_mac_addr = wpa_driver_nl80211_get_macaddr,
    8780             :         .get_survey = wpa_driver_nl80211_get_survey,
    8781             :         .status = wpa_driver_nl80211_status,
    8782             :         .switch_channel = nl80211_switch_channel,
    8783             : #ifdef ANDROID_P2P
    8784             :         .set_noa = wpa_driver_set_p2p_noa,
    8785             :         .get_noa = wpa_driver_get_p2p_noa,
    8786             :         .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
    8787             : #endif /* ANDROID_P2P */
    8788             : #ifdef ANDROID
    8789             : #ifndef ANDROID_LIB_STUB
    8790             :         .driver_cmd = wpa_driver_nl80211_driver_cmd,
    8791             : #endif /* !ANDROID_LIB_STUB */
    8792             : #endif /* ANDROID */
    8793             :         .vendor_cmd = nl80211_vendor_cmd,
    8794             :         .set_qos_map = nl80211_set_qos_map,
    8795             :         .set_wowlan = nl80211_set_wowlan,
    8796             :         .roaming = nl80211_roaming,
    8797             :         .set_mac_addr = nl80211_set_mac_addr,
    8798             : #ifdef CONFIG_MESH
    8799             :         .init_mesh = wpa_driver_nl80211_init_mesh,
    8800             :         .join_mesh = wpa_driver_nl80211_join_mesh,
    8801             :         .leave_mesh = wpa_driver_nl80211_leave_mesh,
    8802             : #endif /* CONFIG_MESH */
    8803             :         .br_add_ip_neigh = wpa_driver_br_add_ip_neigh,
    8804             :         .br_delete_ip_neigh = wpa_driver_br_delete_ip_neigh,
    8805             :         .br_port_set_attr = wpa_driver_br_port_set_attr,
    8806             :         .br_set_net_param = wpa_driver_br_set_net_param,
    8807             :         .add_tx_ts = nl80211_add_ts,
    8808             :         .del_tx_ts = nl80211_del_ts,
    8809             :         .do_acs = wpa_driver_do_acs,
    8810             :         .set_band = nl80211_set_band,
    8811             :         .get_pref_freq_list = nl80211_get_pref_freq_list,
    8812             :         .set_prob_oper_freq = nl80211_set_prob_oper_freq,
    8813             : };

Generated by: LCOV version 1.10