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 1475438200 Lines: 3589 4558 78.7 %
Date: 2016-10-02 Functions: 241 250 96.4 %

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

Generated by: LCOV version 1.10