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 1422976643 Lines: 3303 4266 77.4 %
Date: 2015-02-03 Functions: 229 241 95.0 %

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

Generated by: LCOV version 1.10