]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211.c
driver: Remove unused send_frame() driver op
[thirdparty/hostap.git] / src / drivers / driver_nl80211.c
CommitLineData
3f5285e8 1/*
c5121837 2 * Driver interaction with Linux nl80211/cfg80211
98cd3d1c 3 * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
072ad14c
JM
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>
58f6fbe0 7 * Copyright (c) 2009-2010, Atheros Communications
3f5285e8 8 *
0f3d578e
JM
9 * This software may be distributed under the terms of the BSD license.
10 * See README for more details.
3f5285e8
JM
11 */
12
13#include "includes.h"
6859f1cb 14#include <sys/types.h>
73d2294f 15#include <fcntl.h>
37b7d082 16#include <net/if.h>
3f5285e8 17#include <netlink/genl/genl.h>
3f5285e8 18#include <netlink/genl/ctrl.h>
97ed9a06
KP
19#ifdef CONFIG_LIBNL3_ROUTE
20#include <netlink/route/neighbour.h>
21#endif /* CONFIG_LIBNL3_ROUTE */
8602b0f2 22#include <linux/rtnetlink.h>
1b648c7e 23#include <netpacket/packet.h>
32ab4855 24#include <linux/errqueue.h>
625f587b 25
3f5285e8 26#include "common.h"
1b648c7e 27#include "eloop.h"
1682c623 28#include "common/qca-vendor.h"
a26582cb 29#include "common/qca-vendor-attr.h"
1b648c7e 30#include "common/ieee802_11_defs.h"
9b90955e 31#include "common/ieee802_11_common.h"
3aa24db9 32#include "common/wpa_common.h"
f10bfc9a 33#include "l2_packet/l2_packet.h"
e2d02c29 34#include "netlink.h"
1474e6e9 35#include "linux_defines.h"
34f2f814 36#include "linux_ioctl.h"
e2d02c29
JM
37#include "radiotap.h"
38#include "radiotap_iter.h"
8401a6b0 39#include "rfkill.h"
1474e6e9 40#include "driver_nl80211.h"
32ab4855 41
1474e6e9 42
b14e8ea1
JM
43#ifndef NETLINK_CAP_ACK
44#define NETLINK_CAP_ACK 10
45#endif /* NETLINK_CAP_ACK */
40432e6e
JB
46/* support for extack if compilation headers are too old */
47#ifndef NETLINK_EXT_ACK
48#define NETLINK_EXT_ACK 11
49enum nlmsgerr_attrs {
50 NLMSGERR_ATTR_UNUSED,
51 NLMSGERR_ATTR_MSG,
52 NLMSGERR_ATTR_OFFS,
53 NLMSGERR_ATTR_COOKIE,
54
55 __NLMSGERR_ATTR_MAX,
56 NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
57};
58#endif
59#ifndef NLM_F_CAPPED
60#define NLM_F_CAPPED 0x100
61#endif
62#ifndef NLM_F_ACK_TLVS
63#define NLM_F_ACK_TLVS 0x200
64#endif
65#ifndef SOL_NETLINK
66#define SOL_NETLINK 270
67#endif
68
c5121837 69
1c6edec6
JM
70#ifdef ANDROID
71/* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
1c6edec6
JM
72#undef nl_socket_set_nonblocking
73#define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
70a96c81 74
1c6edec6
JM
75#endif /* ANDROID */
76
77
25ebd538 78static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
a92dfde8 79{
25ebd538 80 struct nl_sock *handle;
a92dfde8 81
25ebd538 82 handle = nl_socket_alloc_cb(cb);
481234cf 83 if (handle == NULL) {
a92dfde8
JB
84 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
85 "callbacks (%s)", dbg);
481234cf 86 return NULL;
a92dfde8
JB
87 }
88
481234cf 89 if (genl_connect(handle)) {
a92dfde8
JB
90 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
91 "netlink (%s)", dbg);
25ebd538 92 nl_socket_free(handle);
481234cf 93 return NULL;
a92dfde8
JB
94 }
95
481234cf 96 return handle;
a92dfde8
JB
97}
98
99
25ebd538 100static void nl_destroy_handles(struct nl_sock **handle)
a92dfde8 101{
481234cf 102 if (*handle == NULL)
a92dfde8 103 return;
25ebd538 104 nl_socket_free(*handle);
481234cf 105 *handle = NULL;
a92dfde8
JB
106}
107
108
10b85921
JB
109#if __WORDSIZE == 64
110#define ELOOP_SOCKET_INVALID (intptr_t) 0x8888888888888889ULL
111#else
112#define ELOOP_SOCKET_INVALID (intptr_t) 0x88888889ULL
113#endif
114
25ebd538 115static void nl80211_register_eloop_read(struct nl_sock **handle,
5f65e9f7 116 eloop_sock_handler handler,
40a68f33 117 void *eloop_data, int persist)
5f65e9f7 118{
630b3230
JM
119 /*
120 * libnl uses a pretty small buffer (32 kB that gets converted to 64 kB)
121 * by default. It is possible to hit that limit in some cases where
122 * operations are blocked, e.g., with a burst of Deauthentication frames
123 * to hostapd and STA entry deletion. Try to increase the buffer to make
124 * this less likely to occur.
125 */
3ea58a05
JM
126 int err;
127
128 err = nl_socket_set_buffer_size(*handle, 262144, 0);
129 if (err < 0) {
630b3230
JM
130 wpa_printf(MSG_DEBUG,
131 "nl80211: Could not set nl_socket RX buffer size: %s",
3ea58a05 132 nl_geterror(err));
630b3230
JM
133 /* continue anyway with the default (smaller) buffer */
134 }
135
10b85921 136 nl_socket_set_nonblocking(*handle);
5f65e9f7
JB
137 eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
138 eloop_data, *handle);
40a68f33
SD
139 if (!persist)
140 *handle = (void *) (((intptr_t) *handle) ^
141 ELOOP_SOCKET_INVALID);
5f65e9f7
JB
142}
143
144
25ebd538 145static void nl80211_destroy_eloop_handle(struct nl_sock **handle, int persist)
5f65e9f7 146{
40a68f33
SD
147 if (!persist)
148 *handle = (void *) (((intptr_t) *handle) ^
149 ELOOP_SOCKET_INVALID);
5f65e9f7
JB
150 eloop_unregister_read_sock(nl_socket_get_fd(*handle));
151 nl_destroy_handles(handle);
152}
153
154
36d84860 155static void nl80211_global_deinit(void *priv);
f51f54a0 156static void nl80211_check_global(struct nl80211_global *global);
36d84860 157
9ebce9c5 158static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
4ec68377
JD
159static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
160 struct hostapd_freq_params *freq);
3c5d34e3 161
362f781e 162static int
0d547d5f 163wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
0ecff8d7
JM
164 const u8 *set_addr, int first,
165 const char *driver_params);
88df0ef7 166static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f 167 unsigned int freq, unsigned int wait,
b106173a 168 const u8 *buf, size_t buf_len, u64 *cookie,
2d3943ce
AO
169 int no_cck, int no_ack, int offchanok,
170 const u16 *csa_offs, size_t csa_offs_len);
9ebce9c5
JM
171static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
172 int report);
0915d02c 173
732b1d20
MB
174#define IFIDX_ANY -1
175
176static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
177 int ifidx_reason);
178static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
179 int ifidx_reason);
180static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
181 int ifidx_reason);
072ad14c 182
e87ef751
PX
183static int nl80211_set_channel(struct i802_bss *bss,
184 struct hostapd_freq_params *freq, int set_chan);
4e5cb1a3
JM
185static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
186 int ifindex, int disabled);
504e905c 187
666e508c
JM
188static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
189 int reset_mode);
21bdbe38 190
bf83eab5 191static int i802_set_iface_flags(struct i802_bss *bss, int up);
0ecff8d7 192static int nl80211_set_param(void *priv, const char *param);
052b8d38
MH
193#ifdef CONFIG_MESH
194static int nl80211_put_mesh_config(struct nl_msg *msg,
195 struct wpa_driver_mesh_bss_params *params);
196#endif /* CONFIG_MESH */
05e5e615 197static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
4be17ffb 198 u16 reason);
bf83eab5 199
3f5285e8 200
8d1fdde7 201/* Converts nl80211_chan_width to a common format */
f3407c66 202enum chan_width convert2width(int width)
8d1fdde7
JD
203{
204 switch (width) {
205 case NL80211_CHAN_WIDTH_20_NOHT:
206 return CHAN_WIDTH_20_NOHT;
207 case NL80211_CHAN_WIDTH_20:
208 return CHAN_WIDTH_20;
209 case NL80211_CHAN_WIDTH_40:
210 return CHAN_WIDTH_40;
211 case NL80211_CHAN_WIDTH_80:
212 return CHAN_WIDTH_80;
213 case NL80211_CHAN_WIDTH_80P80:
214 return CHAN_WIDTH_80P80;
215 case NL80211_CHAN_WIDTH_160:
216 return CHAN_WIDTH_160;
217 }
218 return CHAN_WIDTH_UNKNOWN;
219}
220
221
f3407c66 222int is_ap_interface(enum nl80211_iftype nlmode)
b1f625e0 223{
0e80ea2c
JM
224 return nlmode == NL80211_IFTYPE_AP ||
225 nlmode == NL80211_IFTYPE_P2P_GO;
b1f625e0
EP
226}
227
228
477af8f8 229int is_sta_interface(enum nl80211_iftype nlmode)
b1f625e0 230{
0e80ea2c
JM
231 return nlmode == NL80211_IFTYPE_STATION ||
232 nlmode == NL80211_IFTYPE_P2P_CLIENT;
b1f625e0
EP
233}
234
235
6a71413e 236static int is_p2p_net_interface(enum nl80211_iftype nlmode)
b3af99d2 237{
0e80ea2c
JM
238 return nlmode == NL80211_IFTYPE_P2P_CLIENT ||
239 nlmode == NL80211_IFTYPE_P2P_GO;
b3af99d2
JM
240}
241
242
f3407c66
JM
243struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
244 int ifindex)
5dfbd725
JM
245{
246 struct i802_bss *bss;
247
248 for (bss = drv->first_bss; bss; bss = bss->next) {
249 if (bss->ifindex == ifindex)
250 return bss;
251 }
252
253 return NULL;
254}
255
256
afb0550a
BC
257static int is_mesh_interface(enum nl80211_iftype nlmode)
258{
259 return nlmode == NL80211_IFTYPE_MESH_POINT;
260}
261
262
f3407c66 263void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
add9b7a4
JM
264{
265 if (drv->associated)
266 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
267 drv->associated = 0;
268 os_memset(drv->bssid, 0, ETH_ALEN);
091c2277 269 drv->first_bss->freq = 0;
add9b7a4
JM
270}
271
272
6241fcb1
JM
273/* nl80211 code */
274static int ack_handler(struct nl_msg *msg, void *arg)
275{
276 int *err = arg;
277 *err = 0;
278 return NL_STOP;
279}
280
281static int finish_handler(struct nl_msg *msg, void *arg)
282{
8e8df255
JM
283 int *ret = arg;
284 *ret = 0;
6241fcb1
JM
285 return NL_SKIP;
286}
287
288static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
289 void *arg)
290{
40432e6e
JB
291 struct nlmsghdr *nlh = (struct nlmsghdr *) err - 1;
292 int len = nlh->nlmsg_len;
293 struct nlattr *attrs;
294 struct nlattr *tb[NLMSGERR_ATTR_MAX + 1];
6241fcb1 295 int *ret = arg;
40432e6e
JB
296 int ack_len = sizeof(*nlh) + sizeof(int) + sizeof(*nlh);
297
6241fcb1 298 *ret = err->error;
40432e6e
JB
299
300 if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
301 return NL_SKIP;
302
303 if (!(nlh->nlmsg_flags & NLM_F_CAPPED))
304 ack_len += err->msg.nlmsg_len - sizeof(*nlh);
305
306 if (len <= ack_len)
307 return NL_STOP;
308
309 attrs = (void *) ((unsigned char *) nlh + ack_len);
310 len -= ack_len;
311
312 nla_parse(tb, NLMSGERR_ATTR_MAX, attrs, len, NULL);
313 if (tb[NLMSGERR_ATTR_MSG]) {
314 len = strnlen((char *) nla_data(tb[NLMSGERR_ATTR_MSG]),
315 nla_len(tb[NLMSGERR_ATTR_MSG]));
316 wpa_printf(MSG_ERROR, "nl80211: kernel reports: %*s",
317 len, (char *) nla_data(tb[NLMSGERR_ATTR_MSG]));
318 }
319
6241fcb1
JM
320 return NL_SKIP;
321}
322
5b7b85f6
JM
323
324static int no_seq_check(struct nl_msg *msg, void *arg)
325{
326 return NL_OK;
327}
328
329
bbd89bfc
JM
330static void nl80211_nlmsg_clear(struct nl_msg *msg)
331{
332 /*
333 * Clear nlmsg data, e.g., to make sure key material is not left in
334 * heap memory for unnecessarily long time.
335 */
336 if (msg) {
337 struct nlmsghdr *hdr = nlmsg_hdr(msg);
338 void *data = nlmsg_data(hdr);
d58ade21
JM
339 /*
340 * This would use nlmsg_datalen() or the older nlmsg_len() if
341 * only libnl were to maintain a stable API.. Neither will work
342 * with all released versions, so just calculate the length
343 * here.
344 */
345 int len = hdr->nlmsg_len - NLMSG_HDRLEN;
bbd89bfc
JM
346
347 os_memset(data, 0, len);
348 }
349}
350
351
d6c9aab8 352static int send_and_recv(struct nl80211_global *global,
25ebd538 353 struct nl_sock *nl_handle, struct nl_msg *msg,
58f6fbe0
JM
354 int (*valid_handler)(struct nl_msg *, void *),
355 void *valid_data)
6241fcb1
JM
356{
357 struct nl_cb *cb;
40432e6e 358 int err = -ENOMEM, opt;
6241fcb1 359
9725b784
JM
360 if (!msg)
361 return -ENOMEM;
362
d6c9aab8 363 cb = nl_cb_clone(global->nl_cb);
6241fcb1
JM
364 if (!cb)
365 goto out;
366
40432e6e
JB
367 /* try to set NETLINK_EXT_ACK to 1, ignoring errors */
368 opt = 1;
369 setsockopt(nl_socket_get_fd(nl_handle), SOL_NETLINK,
370 NETLINK_EXT_ACK, &opt, sizeof(opt));
371
b14e8ea1
JM
372 /* try to set NETLINK_CAP_ACK to 1, ignoring errors */
373 opt = 1;
374 setsockopt(nl_socket_get_fd(nl_handle), SOL_NETLINK,
375 NETLINK_CAP_ACK, &opt, sizeof(opt));
376
58f6fbe0 377 err = nl_send_auto_complete(nl_handle, msg);
3ea58a05
JM
378 if (err < 0) {
379 wpa_printf(MSG_INFO,
380 "nl80211: nl_send_auto_complete() failed: %s",
381 nl_geterror(err));
382 /* Need to convert libnl error code to an errno value. For now,
383 * just hardcode this to EBADF; the real error reason is shown
384 * in that error print above. */
385 err = -EBADF;
6241fcb1 386 goto out;
3ea58a05 387 }
6241fcb1
JM
388
389 err = 1;
390
391 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
8e8df255 392 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
6241fcb1
JM
393 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
394
395 if (valid_handler)
396 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
397 valid_handler, valid_data);
398
34068ac3
JM
399 while (err > 0) {
400 int res = nl_recvmsgs(nl_handle, cb);
16a26672
JM
401
402 if (res == -NLE_DUMP_INTR) {
403 /* Most likely one of the nl80211 dump routines hit a
404 * case where internal results changed while the dump
405 * was being sent. The most common known case for this
406 * is scan results fetching while associated were every
407 * received Beacon frame from the AP may end up
408 * incrementing bss_generation. This
409 * NL80211_CMD_GET_SCAN case tries again in the caller;
410 * other cases (of which there are no known common ones)
411 * will stop and return an error. */
412 wpa_printf(MSG_DEBUG, "nl80211: %s; convert to -EAGAIN",
413 nl_geterror(res));
414 err = -EAGAIN;
415 } else if (res < 0) {
34068ac3 416 wpa_printf(MSG_INFO,
3ea58a05
JM
417 "nl80211: %s->nl_recvmsgs failed: %d (%s)",
418 __func__, res, nl_geterror(res));
34068ac3
JM
419 }
420 }
6241fcb1
JM
421 out:
422 nl_cb_put(cb);
bbd89bfc
JM
423 if (!valid_handler && valid_data == (void *) -1)
424 nl80211_nlmsg_clear(msg);
6241fcb1
JM
425 nlmsg_free(msg);
426 return err;
427}
428
429
f3407c66
JM
430int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
431 struct nl_msg *msg,
432 int (*valid_handler)(struct nl_msg *, void *),
433 void *valid_data)
58f6fbe0 434{
481234cf 435 return send_and_recv(drv->global, drv->global->nl, msg,
d6c9aab8 436 valid_handler, valid_data);
58f6fbe0
JM
437}
438
439
97865538
JM
440struct family_data {
441 const char *group;
442 int id;
443};
444
445
446static int family_handler(struct nl_msg *msg, void *arg)
447{
448 struct family_data *res = arg;
449 struct nlattr *tb[CTRL_ATTR_MAX + 1];
450 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
451 struct nlattr *mcgrp;
452 int i;
453
454 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
455 genlmsg_attrlen(gnlh, 0), NULL);
456 if (!tb[CTRL_ATTR_MCAST_GROUPS])
457 return NL_SKIP;
458
459 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
460 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
461 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
462 nla_len(mcgrp), NULL);
463 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
464 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
465 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
466 res->group,
467 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
468 continue;
469 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
470 break;
471 };
472
473 return NL_SKIP;
474}
475
476
d6c9aab8 477static int nl_get_multicast_id(struct nl80211_global *global,
97865538
JM
478 const char *family, const char *group)
479{
480 struct nl_msg *msg;
a862e4a3 481 int ret;
97865538
JM
482 struct family_data res = { group, -ENOENT };
483
484 msg = nlmsg_alloc();
485 if (!msg)
486 return -ENOMEM;
a862e4a3
JM
487 if (!genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
488 0, 0, CTRL_CMD_GETFAMILY, 0) ||
489 nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
490 nlmsg_free(msg);
491 return -1;
492 }
97865538 493
1033315f 494 ret = send_and_recv(global, global->nl, msg, family_handler, &res);
97865538
JM
495 if (ret == 0)
496 ret = res.id;
97865538
JM
497 return ret;
498}
499
500
f3407c66
JM
501void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
502 struct nl_msg *msg, int flags, uint8_t cmd)
9fb04070 503{
a5a187b0
JM
504 if (TEST_FAIL())
505 return NULL;
335d42b1 506 return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
276e2d67 507 0, flags, cmd, 0);
9fb04070
JM
508}
509
510
350acc35
JM
511static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
512{
513 if (bss->wdev_id_set)
514 return nla_put_u64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
515 return nla_put_u32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
516}
517
518
07c7757c
JM
519struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd)
520{
521 struct nl_msg *msg;
522
523 msg = nlmsg_alloc();
524 if (!msg)
525 return NULL;
526
527 if (!nl80211_cmd(bss->drv, msg, flags, cmd) ||
528 nl80211_set_iface_id(msg, bss) < 0) {
529 nlmsg_free(msg);
530 return NULL;
531 }
532
533 return msg;
534}
535
536
537static struct nl_msg *
538nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
539 int flags, uint8_t cmd)
540{
541 struct nl_msg *msg;
542
543 msg = nlmsg_alloc();
544 if (!msg)
545 return NULL;
546
547 if (!nl80211_cmd(drv, msg, flags, cmd) ||
548 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex)) {
549 nlmsg_free(msg);
550 return NULL;
551 }
552
553 return msg;
554}
555
556
557struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
558 uint8_t cmd)
559{
560 return nl80211_ifindex_msg(drv, drv->ifindex, flags, cmd);
561}
562
563
564struct nl_msg * nl80211_bss_msg(struct i802_bss *bss, int flags, uint8_t cmd)
565{
566 return nl80211_ifindex_msg(bss->drv, bss->ifindex, flags, cmd);
567}
568
569
e32ad281
JB
570struct wiphy_idx_data {
571 int wiphy_idx;
01517c8b 572 enum nl80211_iftype nlmode;
597b94f5 573 u8 *macaddr;
e32ad281
JB
574};
575
576
577static int netdev_info_handler(struct nl_msg *msg, void *arg)
578{
579 struct nlattr *tb[NL80211_ATTR_MAX + 1];
580 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
581 struct wiphy_idx_data *info = arg;
582
583 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
584 genlmsg_attrlen(gnlh, 0), NULL);
585
586 if (tb[NL80211_ATTR_WIPHY])
587 info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
588
01517c8b
JB
589 if (tb[NL80211_ATTR_IFTYPE])
590 info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
591
597b94f5
AS
592 if (tb[NL80211_ATTR_MAC] && info->macaddr)
593 os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
594 ETH_ALEN);
595
e32ad281
JB
596 return NL_SKIP;
597}
598
599
f3407c66 600int nl80211_get_wiphy_index(struct i802_bss *bss)
e32ad281
JB
601{
602 struct nl_msg *msg;
603 struct wiphy_idx_data data = {
604 .wiphy_idx = -1,
597b94f5 605 .macaddr = NULL,
e32ad281
JB
606 };
607
56f77852 608 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
a862e4a3 609 return -1;
e32ad281
JB
610
611 if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
612 return data.wiphy_idx;
e32ad281
JB
613 return -1;
614}
615
616
01517c8b
JB
617static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
618{
619 struct nl_msg *msg;
620 struct wiphy_idx_data data = {
597b94f5
AS
621 .nlmode = NL80211_IFTYPE_UNSPECIFIED,
622 .macaddr = NULL,
01517c8b
JB
623 };
624
56f77852 625 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
a862e4a3 626 return NL80211_IFTYPE_UNSPECIFIED;
01517c8b
JB
627
628 if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
629 return data.nlmode;
01517c8b
JB
630 return NL80211_IFTYPE_UNSPECIFIED;
631}
01517c8b
JB
632
633
597b94f5
AS
634static int nl80211_get_macaddr(struct i802_bss *bss)
635{
636 struct nl_msg *msg;
637 struct wiphy_idx_data data = {
638 .macaddr = bss->addr,
639 };
640
56f77852 641 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
a862e4a3 642 return -1;
597b94f5 643
597b94f5 644 return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
597b94f5 645}
597b94f5
AS
646
647
e32ad281
JB
648static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
649 struct nl80211_wiphy_data *w)
650{
651 struct nl_msg *msg;
a862e4a3 652 int ret;
e32ad281
JB
653
654 msg = nlmsg_alloc();
655 if (!msg)
656 return -1;
657
a862e4a3
JM
658 if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS) ||
659 nla_put_u32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx)) {
660 nlmsg_free(msg);
661 return -1;
662 }
e32ad281 663
481234cf 664 ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
e32ad281
JB
665 if (ret) {
666 wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
667 "failed: ret=%d (%s)",
668 ret, strerror(-ret));
e32ad281 669 }
e32ad281
JB
670 return ret;
671}
672
673
674static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
675{
676 struct nl80211_wiphy_data *w = eloop_ctx;
34068ac3 677 int res;
e32ad281 678
ee9fc67a 679 wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
e32ad281 680
34068ac3 681 res = nl_recvmsgs(handle, w->nl_cb);
d3d04831 682 if (res < 0) {
34068ac3
JM
683 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
684 __func__, res);
685 }
e32ad281
JB
686}
687
688
689static int process_beacon_event(struct nl_msg *msg, void *arg)
690{
691 struct nl80211_wiphy_data *w = arg;
692 struct wpa_driver_nl80211_data *drv;
693 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
694 struct nlattr *tb[NL80211_ATTR_MAX + 1];
695 union wpa_event_data event;
696
697 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
698 genlmsg_attrlen(gnlh, 0), NULL);
699
700 if (gnlh->cmd != NL80211_CMD_FRAME) {
701 wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
702 gnlh->cmd);
703 return NL_SKIP;
704 }
705
706 if (!tb[NL80211_ATTR_FRAME])
707 return NL_SKIP;
708
709 dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
710 wiphy_list) {
711 os_memset(&event, 0, sizeof(event));
712 event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
713 event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
714 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
715 }
716
717 return NL_SKIP;
718}
719
720
721static struct nl80211_wiphy_data *
722nl80211_get_wiphy_data_ap(struct i802_bss *bss)
723{
724 static DEFINE_DL_LIST(nl80211_wiphys);
725 struct nl80211_wiphy_data *w;
726 int wiphy_idx, found = 0;
727 struct i802_bss *tmp_bss;
a70cd0db 728 u8 channel;
e32ad281
JB
729
730 if (bss->wiphy_data != NULL)
731 return bss->wiphy_data;
732
733 wiphy_idx = nl80211_get_wiphy_index(bss);
734
735 dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
736 if (w->wiphy_idx == wiphy_idx)
737 goto add;
738 }
739
740 /* alloc new one */
741 w = os_zalloc(sizeof(*w));
742 if (w == NULL)
743 return NULL;
744 w->wiphy_idx = wiphy_idx;
745 dl_list_init(&w->bsss);
746 dl_list_init(&w->drvs);
747
a70cd0db
DL
748 /* Beacon frames not supported in IEEE 802.11ad */
749 if (ieee80211_freq_to_chan(bss->freq, &channel) !=
750 HOSTAPD_MODE_IEEE80211AD) {
751 w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
752 if (!w->nl_cb) {
753 os_free(w);
754 return NULL;
755 }
756 nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
757 no_seq_check, NULL);
758 nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
759 process_beacon_event, w);
760
761 w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
762 "wiphy beacons");
763 if (w->nl_beacons == NULL) {
764 os_free(w);
765 return NULL;
766 }
e32ad281 767
a70cd0db
DL
768 if (nl80211_register_beacons(bss->drv, w)) {
769 nl_destroy_handles(&w->nl_beacons);
770 os_free(w);
771 return NULL;
772 }
e32ad281 773
a70cd0db 774 nl80211_register_eloop_read(&w->nl_beacons,
40a68f33 775 nl80211_recv_beacons, w, 0);
e32ad281
JB
776 }
777
e32ad281
JB
778 dl_list_add(&nl80211_wiphys, &w->list);
779
780add:
781 /* drv entry for this bss already there? */
782 dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
783 if (tmp_bss->drv == bss->drv) {
784 found = 1;
785 break;
786 }
787 }
788 /* if not add it */
789 if (!found)
790 dl_list_add(&w->drvs, &bss->drv->wiphy_list);
791
792 dl_list_add(&w->bsss, &bss->wiphy_list);
793 bss->wiphy_data = w;
794 return w;
795}
796
797
798static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
799{
800 struct nl80211_wiphy_data *w = bss->wiphy_data;
801 struct i802_bss *tmp_bss;
802 int found = 0;
803
804 if (w == NULL)
805 return;
806 bss->wiphy_data = NULL;
807 dl_list_del(&bss->wiphy_list);
808
809 /* still any for this drv present? */
810 dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
811 if (tmp_bss->drv == bss->drv) {
812 found = 1;
813 break;
814 }
815 }
816 /* if not remove it */
817 if (!found)
818 dl_list_del(&bss->drv->wiphy_list);
819
820 if (!dl_list_empty(&w->bsss))
821 return;
822
a70cd0db 823 if (w->nl_beacons)
40a68f33 824 nl80211_destroy_eloop_handle(&w->nl_beacons, 0);
e32ad281
JB
825
826 nl_cb_put(w->nl_cb);
e32ad281
JB
827 dl_list_del(&w->list);
828 os_free(w);
829}
830
831
45e3fc72
RM
832static unsigned int nl80211_get_ifindex(void *priv)
833{
834 struct i802_bss *bss = priv;
835 struct wpa_driver_nl80211_data *drv = bss->drv;
836
837 return drv->ifindex;
838}
839
840
3f5285e8
JM
841static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
842{
a2e40bb6
FF
843 struct i802_bss *bss = priv;
844 struct wpa_driver_nl80211_data *drv = bss->drv;
c2a04078
JM
845 if (!drv->associated)
846 return -1;
847 os_memcpy(bssid, drv->bssid, ETH_ALEN);
848 return 0;
3f5285e8
JM
849}
850
851
3f5285e8
JM
852static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
853{
a2e40bb6
FF
854 struct i802_bss *bss = priv;
855 struct wpa_driver_nl80211_data *drv = bss->drv;
fd05d64e
JM
856 if (!drv->associated)
857 return -1;
858 os_memcpy(ssid, drv->ssid, drv->ssid_len);
859 return drv->ssid_len;
3f5285e8
JM
860}
861
862
90a545cc 863static void wpa_driver_nl80211_event_newlink(
45e3fc72
RM
864 struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
865 int ifindex, const char *ifname)
3f5285e8
JM
866{
867 union wpa_event_data event;
868
45e3fc72 869 if (drv && os_strcmp(drv->first_bss->ifname, ifname) == 0) {
90a545cc
JM
870 if (if_nametoindex(drv->first_bss->ifname) == 0) {
871 wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
872 drv->first_bss->ifname);
873 return;
874 }
875 if (!drv->if_removed)
876 return;
877 wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
878 drv->first_bss->ifname);
879 drv->if_removed = 0;
880 }
881
3f5285e8 882 os_memset(&event, 0, sizeof(event));
45e3fc72 883 event.interface_status.ifindex = ifindex;
90a545cc
JM
884 os_strlcpy(event.interface_status.ifname, ifname,
885 sizeof(event.interface_status.ifname));
886 event.interface_status.ievent = EVENT_INTERFACE_ADDED;
45e3fc72
RM
887 if (drv)
888 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
889 else
890 wpa_supplicant_event_global(global->ctx, EVENT_INTERFACE_STATUS,
891 &event);
90a545cc
JM
892}
893
894
895static void wpa_driver_nl80211_event_dellink(
45e3fc72
RM
896 struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
897 int ifindex, const char *ifname)
90a545cc
JM
898{
899 union wpa_event_data event;
900
45e3fc72 901 if (drv && os_strcmp(drv->first_bss->ifname, ifname) == 0) {
90a545cc
JM
902 if (drv->if_removed) {
903 wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
904 ifname);
905 return;
d1f4942b 906 }
90a545cc
JM
907 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
908 ifname);
909 drv->if_removed = 1;
910 } else {
911 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
912 ifname);
7524cfb1
JM
913 }
914
90a545cc 915 os_memset(&event, 0, sizeof(event));
45e3fc72 916 event.interface_status.ifindex = ifindex;
90a545cc
JM
917 os_strlcpy(event.interface_status.ifname, ifname,
918 sizeof(event.interface_status.ifname));
919 event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
45e3fc72
RM
920 if (drv)
921 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
922 else
923 wpa_supplicant_event_global(global->ctx, EVENT_INTERFACE_STATUS,
924 &event);
3f5285e8
JM
925}
926
927
7524cfb1 928static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
62d680c3 929 u8 *buf, size_t len)
7524cfb1 930{
62d680c3 931 int attrlen, rta_len;
7524cfb1
JM
932 struct rtattr *attr;
933
62d680c3
JM
934 attrlen = len;
935 attr = (struct rtattr *) buf;
7524cfb1
JM
936
937 rta_len = RTA_ALIGN(sizeof(struct rtattr));
938 while (RTA_OK(attr, attrlen)) {
939 if (attr->rta_type == IFLA_IFNAME) {
834ee56f
KP
940 if (os_strcmp(((char *) attr) + rta_len,
941 drv->first_bss->ifname) == 0)
7524cfb1
JM
942 return 1;
943 else
944 break;
945 }
946 attr = RTA_NEXT(attr, attrlen);
947 }
948
949 return 0;
950}
951
952
953static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
62d680c3 954 int ifindex, u8 *buf, size_t len)
7524cfb1
JM
955{
956 if (drv->ifindex == ifindex)
957 return 1;
958
62d680c3 959 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
f51f54a0 960 nl80211_check_global(drv->global);
7524cfb1
JM
961 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
962 "interface");
5e0c20ff
JM
963 if (wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL) < 0)
964 return -1;
7524cfb1
JM
965 return 1;
966 }
967
968 return 0;
969}
970
971
36d84860 972static struct wpa_driver_nl80211_data *
5e0c20ff
JM
973nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len,
974 int *init_failed)
36d84860
BG
975{
976 struct wpa_driver_nl80211_data *drv;
5e0c20ff
JM
977 int res;
978
979 if (init_failed)
980 *init_failed = 0;
36d84860
BG
981 dl_list_for_each(drv, &global->interfaces,
982 struct wpa_driver_nl80211_data, list) {
5e0c20ff
JM
983 res = wpa_driver_nl80211_own_ifindex(drv, idx, buf, len);
984 if (res < 0) {
985 wpa_printf(MSG_DEBUG,
986 "nl80211: Found matching own interface, but failed to complete reinitialization");
987 if (init_failed)
988 *init_failed = 1;
989 return drv;
990 }
991 if (res > 0 || have_ifidx(drv, idx, IFIDX_ANY))
36d84860
BG
992 return drv;
993 }
994 return NULL;
995}
996
997
290834df 998static void nl80211_refresh_mac(struct wpa_driver_nl80211_data *drv,
77a020a1 999 int ifindex, int notify)
290834df
BG
1000{
1001 struct i802_bss *bss;
1002 u8 addr[ETH_ALEN];
1003
1004 bss = get_bss_ifindex(drv, ifindex);
1005 if (bss &&
1006 linux_get_ifhwaddr(drv->global->ioctl_sock,
1007 bss->ifname, addr) < 0) {
1008 wpa_printf(MSG_DEBUG,
1009 "nl80211: %s: failed to re-read MAC address",
1010 bss->ifname);
1011 } else if (bss && os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
1012 wpa_printf(MSG_DEBUG,
1013 "nl80211: Own MAC address on ifindex %d (%s) changed from "
1014 MACSTR " to " MACSTR,
1015 ifindex, bss->ifname,
1016 MAC2STR(bss->addr), MAC2STR(addr));
1017 os_memcpy(bss->addr, addr, ETH_ALEN);
77a020a1
BG
1018 if (notify)
1019 wpa_supplicant_event(drv->ctx,
1020 EVENT_INTERFACE_MAC_CHANGED, NULL);
290834df
BG
1021 }
1022}
1023
1024
62d680c3
JM
1025static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
1026 struct ifinfomsg *ifi,
1027 u8 *buf, size_t len)
3f5285e8 1028{
36d84860
BG
1029 struct nl80211_global *global = ctx;
1030 struct wpa_driver_nl80211_data *drv;
90a545cc 1031 int attrlen;
62d680c3 1032 struct rtattr *attr;
97cfcf64 1033 u32 brid = 0;
aef85ba2 1034 char namebuf[IFNAMSIZ];
90a545cc
JM
1035 char ifname[IFNAMSIZ + 1];
1036 char extra[100], *pos, *end;
5e0c20ff 1037 int init_failed;
3f5285e8 1038
90a545cc
JM
1039 extra[0] = '\0';
1040 pos = extra;
1041 end = pos + sizeof(extra);
1042 ifname[0] = '\0';
1043
1044 attrlen = len;
1045 attr = (struct rtattr *) buf;
1046 while (RTA_OK(attr, attrlen)) {
1047 switch (attr->rta_type) {
1048 case IFLA_IFNAME:
1049 if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1050 break;
1051 os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1052 ifname[RTA_PAYLOAD(attr)] = '\0';
1053 break;
1054 case IFLA_MASTER:
1055 brid = nla_get_u32((struct nlattr *) attr);
1056 pos += os_snprintf(pos, end - pos, " master=%u", brid);
1057 break;
1058 case IFLA_WIRELESS:
1059 pos += os_snprintf(pos, end - pos, " wext");
1060 break;
1061 case IFLA_OPERSTATE:
1062 pos += os_snprintf(pos, end - pos, " operstate=%u",
1063 nla_get_u32((struct nlattr *) attr));
1064 break;
1065 case IFLA_LINKMODE:
1066 pos += os_snprintf(pos, end - pos, " linkmode=%u",
1067 nla_get_u32((struct nlattr *) attr));
1068 break;
1069 }
1070 attr = RTA_NEXT(attr, attrlen);
1071 }
1072 extra[sizeof(extra) - 1] = '\0';
1073
f2e90835
JM
1074 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
1075 ifi->ifi_index, ifname, extra, ifi->ifi_family,
1076 ifi->ifi_flags,
3f5285e8
JM
1077 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
1078 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
1079 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
1080 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
a63063b4 1081
5e0c20ff 1082 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, &init_failed);
45e3fc72
RM
1083 if (!drv)
1084 goto event_newlink;
5e0c20ff
JM
1085 if (init_failed)
1086 return; /* do not update interface state */
45e3fc72 1087
a63063b4 1088 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
106fa1e9 1089 namebuf[0] = '\0';
59d24925 1090 if (if_indextoname(ifi->ifi_index, namebuf) &&
106fa1e9 1091 linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) {
59d24925
JM
1092 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1093 "event since interface %s is up", namebuf);
7a94120e 1094 drv->ignore_if_down_event = 0;
77a020a1
BG
1095 /* Re-read MAC address as it may have changed */
1096 nl80211_refresh_mac(drv, ifi->ifi_index, 1);
59d24925
JM
1097 return;
1098 }
106fa1e9
JM
1099 wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
1100 namebuf, ifname);
1101 if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
1102 wpa_printf(MSG_DEBUG,
1103 "nl80211: Not the main interface (%s) - do not indicate interface down",
1104 drv->first_bss->ifname);
1105 } else if (drv->ignore_if_down_event) {
7d9c3698
JM
1106 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1107 "event generated by mode change");
1108 drv->ignore_if_down_event = 0;
1109 } else {
1110 drv->if_disabled = 1;
1111 wpa_supplicant_event(drv->ctx,
1112 EVENT_INTERFACE_DISABLED, NULL);
819f096f
AO
1113
1114 /*
1115 * Try to get drv again, since it may be removed as
1116 * part of the EVENT_INTERFACE_DISABLED handling for
1117 * dynamic interfaces
1118 */
1119 drv = nl80211_find_drv(global, ifi->ifi_index,
5e0c20ff 1120 buf, len, NULL);
819f096f
AO
1121 if (!drv)
1122 return;
7d9c3698 1123 }
a63063b4
JM
1124 }
1125
1126 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
8a9950f7 1127 namebuf[0] = '\0';
aef85ba2 1128 if (if_indextoname(ifi->ifi_index, namebuf) &&
106fa1e9 1129 linux_iface_up(drv->global->ioctl_sock, namebuf) == 0) {
aef85ba2
JM
1130 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1131 "event since interface %s is down",
1132 namebuf);
8a9950f7
HW
1133 return;
1134 }
1135 wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
1136 namebuf, ifname);
1137 if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
1138 wpa_printf(MSG_DEBUG,
1139 "nl80211: Not the main interface (%s) - do not indicate interface up",
1140 drv->first_bss->ifname);
834ee56f 1141 } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
d1f4942b
JM
1142 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1143 "event since interface %s does not exist",
834ee56f 1144 drv->first_bss->ifname);
d1f4942b
JM
1145 } else if (drv->if_removed) {
1146 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1147 "event since interface %s is marked "
834ee56f 1148 "removed", drv->first_bss->ifname);
aef85ba2 1149 } else {
3e0272ca 1150 /* Re-read MAC address as it may have changed */
77a020a1 1151 nl80211_refresh_mac(drv, ifi->ifi_index, 0);
3e0272ca 1152
aef85ba2
JM
1153 drv->if_disabled = 0;
1154 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
1155 NULL);
1156 }
a63063b4
JM
1157 }
1158
3f5285e8
JM
1159 /*
1160 * Some drivers send the association event before the operup event--in
1161 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
1162 * fails. This will hit us when wpa_supplicant does not need to do
1163 * IEEE 802.1X authentication
1164 */
1165 if (drv->operstate == 1 &&
1166 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
90a545cc
JM
1167 !(ifi->ifi_flags & IFF_RUNNING)) {
1168 wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
36d84860 1169 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
e2d02c29 1170 -1, IF_OPER_UP);
3f5285e8 1171 }
97cfcf64 1172
45e3fc72 1173event_newlink:
90a545cc 1174 if (ifname[0])
45e3fc72
RM
1175 wpa_driver_nl80211_event_newlink(global, drv, ifi->ifi_index,
1176 ifname);
90a545cc 1177
45e3fc72 1178 if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
392dfd37
JM
1179 struct i802_bss *bss;
1180
97cfcf64 1181 /* device has been added to bridge */
40e76396
JM
1182 if (!if_indextoname(brid, namebuf)) {
1183 wpa_printf(MSG_DEBUG,
1184 "nl80211: Could not find bridge ifname for ifindex %u",
1185 brid);
1186 return;
1187 }
97cfcf64
B
1188 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
1189 brid, namebuf);
732b1d20 1190 add_ifidx(drv, brid, ifi->ifi_index);
392dfd37
JM
1191
1192 for (bss = drv->first_bss; bss; bss = bss->next) {
1193 if (os_strcmp(ifname, bss->ifname) == 0) {
1194 os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
1195 break;
1196 }
1197 }
97cfcf64 1198 }
3f5285e8
JM
1199}
1200
1201
62d680c3
JM
1202static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
1203 struct ifinfomsg *ifi,
1204 u8 *buf, size_t len)
3f5285e8 1205{
36d84860
BG
1206 struct nl80211_global *global = ctx;
1207 struct wpa_driver_nl80211_data *drv;
90a545cc 1208 int attrlen;
62d680c3 1209 struct rtattr *attr;
97cfcf64 1210 u32 brid = 0;
90a545cc 1211 char ifname[IFNAMSIZ + 1];
f2e90835 1212 char extra[100], *pos, *end;
3f5285e8 1213
f2e90835
JM
1214 extra[0] = '\0';
1215 pos = extra;
1216 end = pos + sizeof(extra);
90a545cc
JM
1217 ifname[0] = '\0';
1218
62d680c3
JM
1219 attrlen = len;
1220 attr = (struct rtattr *) buf;
3f5285e8 1221 while (RTA_OK(attr, attrlen)) {
90a545cc
JM
1222 switch (attr->rta_type) {
1223 case IFLA_IFNAME:
1224 if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1225 break;
1226 os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1227 ifname[RTA_PAYLOAD(attr)] = '\0';
1228 break;
1229 case IFLA_MASTER:
97cfcf64 1230 brid = nla_get_u32((struct nlattr *) attr);
f2e90835
JM
1231 pos += os_snprintf(pos, end - pos, " master=%u", brid);
1232 break;
1233 case IFLA_OPERSTATE:
1234 pos += os_snprintf(pos, end - pos, " operstate=%u",
1235 nla_get_u32((struct nlattr *) attr));
1236 break;
1237 case IFLA_LINKMODE:
1238 pos += os_snprintf(pos, end - pos, " linkmode=%u",
1239 nla_get_u32((struct nlattr *) attr));
90a545cc
JM
1240 break;
1241 }
3f5285e8
JM
1242 attr = RTA_NEXT(attr, attrlen);
1243 }
f2e90835
JM
1244 extra[sizeof(extra) - 1] = '\0';
1245
1246 wpa_printf(MSG_DEBUG, "RTM_DELLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
1247 ifi->ifi_index, ifname, extra, ifi->ifi_family,
1248 ifi->ifi_flags,
1249 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
1250 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
1251 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
1252 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
97cfcf64 1253
5e0c20ff 1254 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, NULL);
90a545cc 1255
45e3fc72 1256 if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
97cfcf64
B
1257 /* device has been removed from bridge */
1258 char namebuf[IFNAMSIZ];
40e76396
JM
1259
1260 if (!if_indextoname(brid, namebuf)) {
1261 wpa_printf(MSG_DEBUG,
1262 "nl80211: Could not find bridge ifname for ifindex %u",
1263 brid);
1264 } else {
1265 wpa_printf(MSG_DEBUG,
1266 "nl80211: Remove ifindex %u for bridge %s",
1267 brid, namebuf);
1268 }
732b1d20 1269 del_ifidx(drv, brid, ifi->ifi_index);
97cfcf64 1270 }
45e3fc72
RM
1271
1272 if (ifi->ifi_family != AF_BRIDGE || !brid)
1273 wpa_driver_nl80211_event_dellink(global, drv, ifi->ifi_index,
1274 ifname);
3f5285e8
JM
1275}
1276
1277
a1fce391
JM
1278struct nl80211_get_assoc_freq_arg {
1279 struct wpa_driver_nl80211_data *drv;
1280 unsigned int assoc_freq;
1281 unsigned int ibss_freq;
1282 u8 assoc_bssid[ETH_ALEN];
ed0a4ddc
NW
1283 u8 assoc_ssid[SSID_MAX_LEN];
1284 u8 assoc_ssid_len;
a1fce391
JM
1285};
1286
1287static int nl80211_get_assoc_freq_handler(struct nl_msg *msg, void *arg)
1288{
1289 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1290 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1291 struct nlattr *bss[NL80211_BSS_MAX + 1];
1292 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
1293 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
1294 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
ed0a4ddc 1295 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
a1fce391
JM
1296 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
1297 };
1298 struct nl80211_get_assoc_freq_arg *ctx = arg;
1299 enum nl80211_bss_status status;
1300
1301 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1302 genlmsg_attrlen(gnlh, 0), NULL);
1303 if (!tb[NL80211_ATTR_BSS] ||
1304 nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
1305 bss_policy) ||
1306 !bss[NL80211_BSS_STATUS])
1307 return NL_SKIP;
1308
1309 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
1310 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
1311 bss[NL80211_BSS_FREQUENCY]) {
1312 ctx->assoc_freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
1313 wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
1314 ctx->assoc_freq);
1315 }
1316 if (status == NL80211_BSS_STATUS_IBSS_JOINED &&
1317 bss[NL80211_BSS_FREQUENCY]) {
1318 ctx->ibss_freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
1319 wpa_printf(MSG_DEBUG, "nl80211: IBSS-joined on %u MHz",
1320 ctx->ibss_freq);
1321 }
1322 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
1323 bss[NL80211_BSS_BSSID]) {
1324 os_memcpy(ctx->assoc_bssid,
1325 nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
1326 wpa_printf(MSG_DEBUG, "nl80211: Associated with "
1327 MACSTR, MAC2STR(ctx->assoc_bssid));
1328 }
1329
ed0a4ddc
NW
1330 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
1331 bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
1332 const u8 *ie, *ssid;
1333 size_t ie_len;
1334
1335 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1336 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1337 ssid = get_ie(ie, ie_len, WLAN_EID_SSID);
1338 if (ssid && ssid[1] > 0 && ssid[1] <= SSID_MAX_LEN) {
1339 ctx->assoc_ssid_len = ssid[1];
1340 os_memcpy(ctx->assoc_ssid, ssid + 2, ssid[1]);
1341 }
1342 }
1343
a1fce391
JM
1344 return NL_SKIP;
1345}
1346
1347
ed0a4ddc
NW
1348int nl80211_get_assoc_ssid(struct wpa_driver_nl80211_data *drv, u8 *ssid)
1349{
1350 struct nl_msg *msg;
1351 int ret;
1352 struct nl80211_get_assoc_freq_arg arg;
16a26672 1353 int count = 0;
ed0a4ddc 1354
16a26672 1355try_again:
ed0a4ddc
NW
1356 msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
1357 os_memset(&arg, 0, sizeof(arg));
1358 arg.drv = drv;
1359 ret = send_and_recv_msgs(drv, msg, nl80211_get_assoc_freq_handler,
1360 &arg);
16a26672
JM
1361 if (ret == -EAGAIN) {
1362 count++;
1363 if (count >= 10) {
1364 wpa_printf(MSG_INFO,
1365 "nl80211: Failed to receive consistent scan result dump for get_assoc_ssid");
1366 } else {
1367 wpa_printf(MSG_DEBUG,
1368 "nl80211: Failed to receive consistent scan result dump for get_assoc_ssid - try again");
1369 goto try_again;
1370 }
1371 }
ed0a4ddc
NW
1372 if (ret == 0) {
1373 os_memcpy(ssid, arg.assoc_ssid, arg.assoc_ssid_len);
1374 return arg.assoc_ssid_len;
1375 }
1376 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d (%s)",
1377 ret, strerror(-ret));
1378 return ret;
1379}
1380
1381
f3407c66 1382unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
f5a8d422
JM
1383{
1384 struct nl_msg *msg;
1385 int ret;
a1fce391 1386 struct nl80211_get_assoc_freq_arg arg;
16a26672 1387 int count = 0;
f5a8d422 1388
16a26672 1389try_again:
9725b784 1390 msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
f5a8d422 1391 os_memset(&arg, 0, sizeof(arg));
f5a8d422 1392 arg.drv = drv;
a1fce391
JM
1393 ret = send_and_recv_msgs(drv, msg, nl80211_get_assoc_freq_handler,
1394 &arg);
16a26672
JM
1395 if (ret == -EAGAIN) {
1396 count++;
1397 if (count >= 10) {
1398 wpa_printf(MSG_INFO,
1399 "nl80211: Failed to receive consistent scan result dump for get_assoc_freq");
1400 } else {
1401 wpa_printf(MSG_DEBUG,
1402 "nl80211: Failed to receive consistent scan result dump for get_assoc_freq - try again");
1403 goto try_again;
1404 }
1405 }
f5a8d422 1406 if (ret == 0) {
c7caac56
JM
1407 unsigned int freq = drv->nlmode == NL80211_IFTYPE_ADHOC ?
1408 arg.ibss_freq : arg.assoc_freq;
f5a8d422 1409 wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
c7caac56
JM
1410 "associated BSS from scan results: %u MHz", freq);
1411 if (freq)
1412 drv->assoc_freq = freq;
30158a0d 1413 return drv->assoc_freq;
f5a8d422
JM
1414 }
1415 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1416 "(%s)", ret, strerror(-ret));
f5a8d422
JM
1417 return drv->assoc_freq;
1418}
1419
1420
60a972a6
JM
1421static int get_link_signal(struct nl_msg *msg, void *arg)
1422{
1423 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1424 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1425 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
1426 static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
1427 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
95783298 1428 [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
74fa78b2 1429 [NL80211_STA_INFO_BEACON_SIGNAL_AVG] = { .type = NLA_U8 },
60a972a6 1430 };
7ee35bf3
PS
1431 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
1432 static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
1433 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
1434 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
1435 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
1436 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
1437 };
1c5c7273 1438 struct wpa_signal_info *sig_change = arg;
60a972a6
JM
1439
1440 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1441 genlmsg_attrlen(gnlh, 0), NULL);
1442 if (!tb[NL80211_ATTR_STA_INFO] ||
1443 nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
1444 tb[NL80211_ATTR_STA_INFO], policy))
1445 return NL_SKIP;
1446 if (!sinfo[NL80211_STA_INFO_SIGNAL])
1447 return NL_SKIP;
1448
7ee35bf3
PS
1449 sig_change->current_signal =
1450 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
1451
95783298
AO
1452 if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
1453 sig_change->avg_signal =
1454 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
1455 else
1456 sig_change->avg_signal = 0;
1457
74fa78b2
JM
1458 if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG])
1459 sig_change->avg_beacon_signal =
1460 (s8)
1461 nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]);
1462 else
1463 sig_change->avg_beacon_signal = 0;
1464
7ee35bf3
PS
1465 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
1466 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
1467 sinfo[NL80211_STA_INFO_TX_BITRATE],
1468 rate_policy)) {
1469 sig_change->current_txrate = 0;
1470 } else {
1471 if (rinfo[NL80211_RATE_INFO_BITRATE]) {
1472 sig_change->current_txrate =
1473 nla_get_u16(rinfo[
1474 NL80211_RATE_INFO_BITRATE]) * 100;
1475 }
1476 }
1477 }
1478
60a972a6
JM
1479 return NL_SKIP;
1480}
1481
1482
f3407c66
JM
1483int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
1484 struct wpa_signal_info *sig)
60a972a6
JM
1485{
1486 struct nl_msg *msg;
1487
941807f6 1488 sig->current_signal = -WPA_INVALID_NOISE;
7ee35bf3 1489 sig->current_txrate = 0;
60a972a6 1490
9725b784 1491 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_STATION)) ||
a862e4a3
JM
1492 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid)) {
1493 nlmsg_free(msg);
1494 return -ENOBUFS;
1495 }
60a972a6
JM
1496
1497 return send_and_recv_msgs(drv, msg, get_link_signal, sig);
60a972a6
JM
1498}
1499
1500
7ee35bf3
PS
1501static int get_link_noise(struct nl_msg *msg, void *arg)
1502{
1503 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1504 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1505 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
1506 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
1507 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
1508 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
1509 };
1c5c7273 1510 struct wpa_signal_info *sig_change = arg;
7ee35bf3
PS
1511
1512 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1513 genlmsg_attrlen(gnlh, 0), NULL);
1514
1515 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
1516 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
1517 return NL_SKIP;
1518 }
1519
1520 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
1521 tb[NL80211_ATTR_SURVEY_INFO],
1522 survey_policy)) {
1523 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
1524 "attributes!");
1525 return NL_SKIP;
1526 }
1527
1528 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
1529 return NL_SKIP;
1530
1531 if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
1532 sig_change->frequency)
1533 return NL_SKIP;
1534
1535 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
1536 return NL_SKIP;
1537
1538 sig_change->current_noise =
1539 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
1540
1541 return NL_SKIP;
1542}
1543
1544
f3407c66
JM
1545int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
1546 struct wpa_signal_info *sig_change)
7ee35bf3
PS
1547{
1548 struct nl_msg *msg;
1549
941807f6 1550 sig_change->current_noise = WPA_INVALID_NOISE;
7ee35bf3
PS
1551 sig_change->frequency = drv->assoc_freq;
1552
9725b784 1553 msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
7ee35bf3 1554 return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
7ee35bf3
PS
1555}
1556
1557
7f00dc6e
MV
1558static int get_channel_info(struct nl_msg *msg, void *arg)
1559{
1560 struct nlattr *tb[NL80211_ATTR_MAX + 1] = { 0 };
1561 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1562 struct wpa_channel_info *chan_info = arg;
1563
1564 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1565 genlmsg_attrlen(gnlh, 0), NULL);
1566
1567 os_memset(chan_info, 0, sizeof(struct wpa_channel_info));
1568 chan_info->chanwidth = CHAN_WIDTH_UNKNOWN;
1569
1570 if (tb[NL80211_ATTR_WIPHY_FREQ])
1571 chan_info->frequency =
1572 nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1573 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
1574 chan_info->chanwidth = convert2width(
1575 nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
1576 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1577 enum nl80211_channel_type ct =
1578 nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1579
1580 switch (ct) {
1581 case NL80211_CHAN_HT40MINUS:
1582 chan_info->sec_channel = -1;
1583 break;
1584 case NL80211_CHAN_HT40PLUS:
1585 chan_info->sec_channel = 1;
1586 break;
1587 default:
1588 chan_info->sec_channel = 0;
1589 break;
1590 }
1591 }
1592 if (tb[NL80211_ATTR_CENTER_FREQ1])
1593 chan_info->center_frq1 =
1594 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
1595 if (tb[NL80211_ATTR_CENTER_FREQ2])
1596 chan_info->center_frq2 =
1597 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
1598
1599 if (chan_info->center_frq2) {
1600 u8 seg1_idx = 0;
1601
1602 if (ieee80211_freq_to_chan(chan_info->center_frq2, &seg1_idx) !=
1603 NUM_HOSTAPD_MODES)
1604 chan_info->seg1_idx = seg1_idx;
1605 }
1606
1607 return NL_SKIP;
1608}
1609
1610
1611static int nl80211_channel_info(void *priv, struct wpa_channel_info *ci)
1612{
1613 struct i802_bss *bss = priv;
1614 struct wpa_driver_nl80211_data *drv = bss->drv;
1615 struct nl_msg *msg;
1616
1617 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_INTERFACE);
1618 return send_and_recv_msgs(drv, msg, get_channel_info, ci);
1619}
1620
1621
97865538 1622static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
5582a5d1 1623 void *handle)
97865538 1624{
a4ae123c 1625 struct nl_cb *cb = eloop_ctx;
34068ac3 1626 int res;
97865538 1627
cc2ada86 1628 wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
97865538 1629
34068ac3 1630 res = nl_recvmsgs(handle, cb);
d3d04831 1631 if (res < 0) {
34068ac3
JM
1632 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
1633 __func__, res);
1634 }
97865538
JM
1635}
1636
1637
6d158490
LR
1638/**
1639 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
1640 * @priv: driver_nl80211 private data
1641 * @alpha2_arg: country to which to switch to
1642 * Returns: 0 on success, -1 on failure
1643 *
1644 * This asks nl80211 to set the regulatory domain for given
1645 * country ISO / IEC alpha2.
1646 */
1647static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
1648{
a2e40bb6
FF
1649 struct i802_bss *bss = priv;
1650 struct wpa_driver_nl80211_data *drv = bss->drv;
6d158490
LR
1651 char alpha2[3];
1652 struct nl_msg *msg;
1653
1654 msg = nlmsg_alloc();
1655 if (!msg)
e785c2ba 1656 return -ENOMEM;
6d158490
LR
1657
1658 alpha2[0] = alpha2_arg[0];
1659 alpha2[1] = alpha2_arg[1];
1660 alpha2[2] = '\0';
1661
a862e4a3
JM
1662 if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG) ||
1663 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, alpha2)) {
1664 nlmsg_free(msg);
1665 return -EINVAL;
1666 }
6d158490
LR
1667 if (send_and_recv_msgs(drv, msg, NULL, NULL))
1668 return -EINVAL;
1669 return 0;
6d158490
LR
1670}
1671
1672
f0793bf1
JM
1673static int nl80211_get_country(struct nl_msg *msg, void *arg)
1674{
1675 char *alpha2 = arg;
1676 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
1677 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1678
1679 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1680 genlmsg_attrlen(gnlh, 0), NULL);
1681 if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
1682 wpa_printf(MSG_DEBUG, "nl80211: No country information available");
1683 return NL_SKIP;
1684 }
1685 os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
1686 return NL_SKIP;
1687}
1688
1689
1690static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
1691{
1692 struct i802_bss *bss = priv;
1693 struct wpa_driver_nl80211_data *drv = bss->drv;
1694 struct nl_msg *msg;
1695 int ret;
1696
1697 msg = nlmsg_alloc();
1698 if (!msg)
1699 return -ENOMEM;
1700
1701 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
1702 alpha2[0] = '\0';
1703 ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
1704 if (!alpha2[0])
1705 ret = -1;
1706
1707 return ret;
1708}
1709
1710
2a7b66f5
BG
1711static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
1712{
d6c9aab8
JB
1713 int ret;
1714
2a7b66f5
BG
1715 global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
1716 if (global->nl_cb == NULL) {
1717 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1718 "callbacks");
1719 return -1;
1720 }
1721
481234cf
JM
1722 global->nl = nl_create_handle(global->nl_cb, "nl");
1723 if (global->nl == NULL)
d6c9aab8 1724 goto err;
276e2d67 1725
481234cf 1726 global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");
335d42b1 1727 if (global->nl80211_id < 0) {
276e2d67
BG
1728 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
1729 "found");
d6c9aab8 1730 goto err;
276e2d67
BG
1731 }
1732
481234cf
JM
1733 global->nl_event = nl_create_handle(global->nl_cb, "event");
1734 if (global->nl_event == NULL)
d6c9aab8 1735 goto err;
9fff9fdc 1736
d6c9aab8 1737 ret = nl_get_multicast_id(global, "nl80211", "scan");
97865538 1738 if (ret >= 0)
481234cf 1739 ret = nl_socket_add_membership(global->nl_event, ret);
97865538
JM
1740 if (ret < 0) {
1741 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1742 "membership for scan events: %d (%s)",
3ea58a05 1743 ret, nl_geterror(ret));
d6c9aab8 1744 goto err;
97865538 1745 }
c2a04078 1746
d6c9aab8 1747 ret = nl_get_multicast_id(global, "nl80211", "mlme");
c2a04078 1748 if (ret >= 0)
481234cf 1749 ret = nl_socket_add_membership(global->nl_event, ret);
c2a04078
JM
1750 if (ret < 0) {
1751 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1752 "membership for mlme events: %d (%s)",
3ea58a05 1753 ret, nl_geterror(ret));
d6c9aab8 1754 goto err;
c2a04078 1755 }
c2a04078 1756
d6c9aab8 1757 ret = nl_get_multicast_id(global, "nl80211", "regulatory");
33c5deb8 1758 if (ret >= 0)
481234cf 1759 ret = nl_socket_add_membership(global->nl_event, ret);
33c5deb8
JM
1760 if (ret < 0) {
1761 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
1762 "membership for regulatory events: %d (%s)",
3ea58a05 1763 ret, nl_geterror(ret));
33c5deb8
JM
1764 /* Continue without regulatory events */
1765 }
1766
17b79e65
JM
1767 ret = nl_get_multicast_id(global, "nl80211", "vendor");
1768 if (ret >= 0)
1769 ret = nl_socket_add_membership(global->nl_event, ret);
1770 if (ret < 0) {
1771 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
1772 "membership for vendor events: %d (%s)",
3ea58a05 1773 ret, nl_geterror(ret));
17b79e65
JM
1774 /* Continue without vendor events */
1775 }
1776
d6c9aab8
JB
1777 nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
1778 no_seq_check, NULL);
1779 nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
1780 process_global_event, global);
1781
5f65e9f7
JB
1782 nl80211_register_eloop_read(&global->nl_event,
1783 wpa_driver_nl80211_event_receive,
40a68f33 1784 global->nl_cb, 0);
d6c9aab8
JB
1785
1786 return 0;
1787
1788err:
1789 nl_destroy_handles(&global->nl_event);
1790 nl_destroy_handles(&global->nl);
1791 nl_cb_put(global->nl_cb);
671a5039 1792 global->nl_cb = NULL;
d6c9aab8
JB
1793 return -1;
1794}
1795
1796
f51f54a0
JM
1797static void nl80211_check_global(struct nl80211_global *global)
1798{
25ebd538 1799 struct nl_sock *handle;
f51f54a0
JM
1800 const char *groups[] = { "scan", "mlme", "regulatory", "vendor", NULL };
1801 int ret;
1802 unsigned int i;
1803
1804 /*
1805 * Try to re-add memberships to handle case of cfg80211 getting reloaded
1806 * and all registration having been cleared.
1807 */
1808 handle = (void *) (((intptr_t) global->nl_event) ^
1809 ELOOP_SOCKET_INVALID);
1810
1811 for (i = 0; groups[i]; i++) {
1812 ret = nl_get_multicast_id(global, "nl80211", groups[i]);
1813 if (ret >= 0)
1814 ret = nl_socket_add_membership(handle, ret);
1815 if (ret < 0) {
1816 wpa_printf(MSG_INFO,
1817 "nl80211: Could not re-add multicast membership for %s events: %d (%s)",
3ea58a05 1818 groups[i], ret, nl_geterror(ret));
f51f54a0
JM
1819 }
1820 }
1821}
1822
1823
8401a6b0
JM
1824static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
1825{
6da504a1
IP
1826 struct wpa_driver_nl80211_data *drv = ctx;
1827
8401a6b0 1828 wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
6da504a1 1829
a63063b4 1830 /*
6da504a1
IP
1831 * rtnetlink ifdown handler will report interfaces other than the P2P
1832 * Device interface as disabled.
a63063b4 1833 */
6da504a1
IP
1834 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
1835 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
8401a6b0
JM
1836}
1837
1838
1839static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
1840{
1841 struct wpa_driver_nl80211_data *drv = ctx;
1842 wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
834ee56f 1843 if (i802_set_iface_flags(drv->first_bss, 1)) {
8401a6b0
JM
1844 wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
1845 "after rfkill unblock");
1846 return;
1847 }
e8dc205f
AO
1848
1849 if (is_p2p_net_interface(drv->nlmode))
1850 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
1851
6da504a1
IP
1852 /*
1853 * rtnetlink ifup handler will report interfaces other than the P2P
1854 * Device interface as enabled.
1855 */
1856 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
1857 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
8401a6b0
JM
1858}
1859
1860
32ab4855
JB
1861static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
1862 void *eloop_ctx,
1863 void *handle)
1864{
1865 struct wpa_driver_nl80211_data *drv = eloop_ctx;
1866 u8 data[2048];
1867 struct msghdr msg;
1868 struct iovec entry;
cad0f50e 1869 u8 control[512];
32ab4855
JB
1870 struct cmsghdr *cmsg;
1871 int res, found_ee = 0, found_wifi = 0, acked = 0;
1872 union wpa_event_data event;
1873
1874 memset(&msg, 0, sizeof(msg));
1875 msg.msg_iov = &entry;
1876 msg.msg_iovlen = 1;
1877 entry.iov_base = data;
1878 entry.iov_len = sizeof(data);
1879 msg.msg_control = &control;
1880 msg.msg_controllen = sizeof(control);
1881
1882 res = recvmsg(sock, &msg, MSG_ERRQUEUE);
1883 /* if error or not fitting 802.3 header, return */
1884 if (res < 14)
1885 return;
1886
1887 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1888 {
1889 if (cmsg->cmsg_level == SOL_SOCKET &&
1890 cmsg->cmsg_type == SCM_WIFI_STATUS) {
1891 int *ack;
1892
1893 found_wifi = 1;
1894 ack = (void *)CMSG_DATA(cmsg);
1895 acked = *ack;
1896 }
1897
1898 if (cmsg->cmsg_level == SOL_PACKET &&
1899 cmsg->cmsg_type == PACKET_TX_TIMESTAMP) {
1900 struct sock_extended_err *err =
1901 (struct sock_extended_err *)CMSG_DATA(cmsg);
1902
1903 if (err->ee_origin == SO_EE_ORIGIN_TXSTATUS)
1904 found_ee = 1;
1905 }
1906 }
1907
1908 if (!found_ee || !found_wifi)
1909 return;
1910
1911 memset(&event, 0, sizeof(event));
1912 event.eapol_tx_status.dst = data;
1913 event.eapol_tx_status.data = data + 14;
1914 event.eapol_tx_status.data_len = res - 14;
1915 event.eapol_tx_status.ack = acked;
1916 wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
1917}
1918
1919
cc7a48d1
JB
1920static int nl80211_init_bss(struct i802_bss *bss)
1921{
1922 bss->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
1923 if (!bss->nl_cb)
1924 return -1;
1925
1926 nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
1927 no_seq_check, NULL);
1928 nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
1929 process_bss_event, bss);
1930
1931 return 0;
1932}
1933
1934
1935static void nl80211_destroy_bss(struct i802_bss *bss)
1936{
1937 nl_cb_put(bss->nl_cb);
1938 bss->nl_cb = NULL;
1939}
1940
1941
0e92fb8f
JB
1942static void
1943wpa_driver_nl80211_drv_init_rfkill(struct wpa_driver_nl80211_data *drv)
1944{
1945 struct rfkill_config *rcfg;
1946
1947 if (drv->rfkill)
1948 return;
1949
1950 rcfg = os_zalloc(sizeof(*rcfg));
1951 if (!rcfg)
1952 return;
1953
1954 rcfg->ctx = drv;
1955
1956 /* rfkill uses netdev sysfs for initialization. However, P2P Device is
1957 * not associated with a netdev, so use the name of some other interface
1958 * sharing the same wiphy as the P2P Device interface.
1959 *
1960 * Note: This is valid, as a P2P Device interface is always dynamically
1961 * created and is created only once another wpa_s interface was added.
1962 */
1963 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) {
1964 struct nl80211_global *global = drv->global;
1965 struct wpa_driver_nl80211_data *tmp1;
1966
1967 dl_list_for_each(tmp1, &global->interfaces,
1968 struct wpa_driver_nl80211_data, list) {
1969 if (drv == tmp1 || drv->wiphy_idx != tmp1->wiphy_idx ||
1970 !tmp1->rfkill)
1971 continue;
1972
1973 wpa_printf(MSG_DEBUG,
1974 "nl80211: Use (%s) to initialize P2P Device rfkill",
1975 tmp1->first_bss->ifname);
1976 os_strlcpy(rcfg->ifname, tmp1->first_bss->ifname,
1977 sizeof(rcfg->ifname));
1978 break;
1979 }
1980 } else {
1981 os_strlcpy(rcfg->ifname, drv->first_bss->ifname,
1982 sizeof(rcfg->ifname));
1983 }
1984
1985 rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
1986 rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
1987 drv->rfkill = rfkill_init(rcfg);
1988 if (!drv->rfkill) {
1989 wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
1990 os_free(rcfg);
1991 }
1992}
1993
1994
0d547d5f
JM
1995static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
1996 void *global_priv, int hostapd,
0ecff8d7
JM
1997 const u8 *set_addr,
1998 const char *driver_params)
9fff9fdc 1999{
9fff9fdc 2000 struct wpa_driver_nl80211_data *drv;
a2e40bb6 2001 struct i802_bss *bss;
9fff9fdc 2002
a5c696ad
JM
2003 if (global_priv == NULL)
2004 return NULL;
9fff9fdc
JM
2005 drv = os_zalloc(sizeof(*drv));
2006 if (drv == NULL)
2007 return NULL;
f2ed8023 2008 drv->global = global_priv;
9fff9fdc 2009 drv->ctx = ctx;
0d547d5f
JM
2010 drv->hostapd = !!hostapd;
2011 drv->eapol_sock = -1;
64ae2447
JM
2012
2013 /*
2014 * There is no driver capability flag for this, so assume it is
2015 * supported and disable this on first attempt to use if the driver
2016 * rejects the command due to missing support.
2017 */
2018 drv->set_rekey_offload = 1;
2019
099224c1 2020 drv->num_if_indices = ARRAY_SIZE(drv->default_if_indices);
0d547d5f 2021 drv->if_indices = drv->default_if_indices;
834ee56f
KP
2022
2023 drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
2024 if (!drv->first_bss) {
2025 os_free(drv);
2026 return NULL;
2027 }
2028 bss = drv->first_bss;
a2e40bb6 2029 bss->drv = drv;
a5e1eb20
SE
2030 bss->ctx = ctx;
2031
a2e40bb6 2032 os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
9fff9fdc
JM
2033 drv->monitor_ifidx = -1;
2034 drv->monitor_sock = -1;
d12dab4c 2035 drv->eapol_tx_sock = -1;
b1f625e0 2036 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
9fff9fdc 2037
cc7a48d1
JB
2038 if (nl80211_init_bss(bss))
2039 goto failed;
2040
0ecff8d7 2041 if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params))
bbaf0837 2042 goto failed;
7524cfb1 2043
d12dab4c 2044 drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
32ab4855
JB
2045 if (drv->eapol_tx_sock < 0)
2046 goto failed;
2047
2048 if (drv->data_tx_status) {
2049 int enabled = 1;
2050
2051 if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
2052 &enabled, sizeof(enabled)) < 0) {
2053 wpa_printf(MSG_DEBUG,
2054 "nl80211: wifi status sockopt failed\n");
2055 drv->data_tx_status = 0;
a11241fa
JB
2056 if (!drv->use_monitor)
2057 drv->capa.flags &=
2058 ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
32ab4855
JB
2059 } else {
2060 eloop_register_read_sock(drv->eapol_tx_sock,
2061 wpa_driver_nl80211_handle_eapol_tx_status,
2062 drv, NULL);
2063 }
2064 }
f10bfc9a 2065
dac12351 2066 if (drv->global) {
f51f54a0 2067 nl80211_check_global(drv->global);
c4bb8817 2068 dl_list_add(&drv->global->interfaces, &drv->list);
dac12351
BG
2069 drv->in_interface_list = 1;
2070 }
c4bb8817 2071
a2e40bb6 2072 return bss;
7524cfb1 2073
bbaf0837 2074failed:
dac12351 2075 wpa_driver_nl80211_deinit(bss);
7524cfb1
JM
2076 return NULL;
2077}
2078
2079
0d547d5f
JM
2080/**
2081 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
2082 * @ctx: context to be used when calling wpa_supplicant functions,
2083 * e.g., wpa_supplicant_event()
2084 * @ifname: interface name, e.g., wlan0
2085 * @global_priv: private driver global data from global_init()
2086 * Returns: Pointer to private data, %NULL on failure
2087 */
2088static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
2089 void *global_priv)
2090{
0ecff8d7
JM
2091 return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL,
2092 NULL);
0d547d5f
JM
2093}
2094
2095
a11241fa 2096static int nl80211_register_frame(struct i802_bss *bss,
25ebd538 2097 struct nl_sock *nl_handle,
bd94971e 2098 u16 type, const u8 *match, size_t match_len)
58f6fbe0 2099{
a11241fa 2100 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0 2101 struct nl_msg *msg;
a862e4a3 2102 int ret;
880de885 2103 char buf[30];
58f6fbe0 2104
880de885
JM
2105 buf[0] = '\0';
2106 wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
dedfa440
PF
2107 wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x (%s) nl_handle=%p match=%s",
2108 type, fc2str(type), nl_handle, buf);
36488c05 2109
56f77852 2110 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_ACTION)) ||
a862e4a3
JM
2111 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, type) ||
2112 nla_put(msg, NL80211_ATTR_FRAME_MATCH, match_len, match)) {
2113 nlmsg_free(msg);
2114 return -1;
2115 }
58f6fbe0 2116
d6c9aab8 2117 ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL);
58f6fbe0 2118 if (ret) {
5582a5d1
JB
2119 wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
2120 "failed (type=%u): ret=%d (%s)",
2121 type, ret, strerror(-ret));
2122 wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
58f6fbe0 2123 match, match_len);
58f6fbe0 2124 }
58f6fbe0
JM
2125 return ret;
2126}
2127
2128
a11241fa
JB
2129static int nl80211_alloc_mgmt_handle(struct i802_bss *bss)
2130{
481234cf 2131 if (bss->nl_mgmt) {
a11241fa 2132 wpa_printf(MSG_DEBUG, "nl80211: Mgmt reporting "
36488c05 2133 "already on! (nl_mgmt=%p)", bss->nl_mgmt);
a11241fa
JB
2134 return -1;
2135 }
2136
ce20a370 2137 bss->nl_mgmt = nl_create_handle(bss->nl_cb, "mgmt");
481234cf 2138 if (bss->nl_mgmt == NULL)
a11241fa
JB
2139 return -1;
2140
a11241fa
JB
2141 return 0;
2142}
2143
2144
5f65e9f7
JB
2145static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
2146{
2147 nl80211_register_eloop_read(&bss->nl_mgmt,
2148 wpa_driver_nl80211_event_receive,
40a68f33 2149 bss->nl_cb, 0);
5f65e9f7
JB
2150}
2151
2152
a11241fa 2153static int nl80211_register_action_frame(struct i802_bss *bss,
bd94971e
JB
2154 const u8 *match, size_t match_len)
2155{
2156 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
481234cf 2157 return nl80211_register_frame(bss, bss->nl_mgmt,
5582a5d1 2158 type, match, match_len);
bd94971e
JB
2159}
2160
2161
40a68f33
SD
2162static int nl80211_init_connect_handle(struct i802_bss *bss)
2163{
2164 if (bss->nl_connect) {
2165 wpa_printf(MSG_DEBUG,
2166 "nl80211: Connect handle already created (nl_connect=%p)",
2167 bss->nl_connect);
2168 return -1;
2169 }
2170
2171 bss->nl_connect = nl_create_handle(bss->nl_cb, "connect");
2172 if (!bss->nl_connect)
2173 return -1;
2174 nl80211_register_eloop_read(&bss->nl_connect,
2175 wpa_driver_nl80211_event_receive,
2176 bss->nl_cb, 1);
2177 return 0;
2178}
2179
2180
a11241fa 2181static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
58f6fbe0 2182{
a11241fa 2183 struct wpa_driver_nl80211_data *drv = bss->drv;
6f06766e 2184 int ret = 0;
a11241fa
JB
2185
2186 if (nl80211_alloc_mgmt_handle(bss))
2187 return -1;
36488c05
JM
2188 wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
2189 "handle %p", bss->nl_mgmt);
a11241fa 2190
ba71cb82
SD
2191 if (drv->nlmode == NL80211_IFTYPE_ADHOC ||
2192 ((drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
2193 !(drv->capa.flags & WPA_DRIVER_FLAGS_SME))) {
e8d1168b
JB
2194 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
2195
2196 /* register for any AUTH message */
2197 nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
2198 }
2199
56f5af48
JM
2200#ifdef CONFIG_INTERWORKING
2201 /* QoS Map Configure */
2202 if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
6f06766e 2203 ret = -1;
56f5af48 2204#endif /* CONFIG_INTERWORKING */
00b02149 2205#if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING) || defined(CONFIG_DPP)
046b26a2 2206 /* GAS Initial Request */
a11241fa 2207 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
6f06766e 2208 ret = -1;
046b26a2 2209 /* GAS Initial Response */
a11241fa 2210 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
6f06766e 2211 ret = -1;
18708aad 2212 /* GAS Comeback Request */
a11241fa 2213 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
6f06766e 2214 ret = -1;
18708aad 2215 /* GAS Comeback Response */
a11241fa 2216 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
6f06766e 2217 ret = -1;
c5a64e2d
JM
2218 /* Protected GAS Initial Request */
2219 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
2220 ret = -1;
2221 /* Protected GAS Initial Response */
2222 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
2223 ret = -1;
2224 /* Protected GAS Comeback Request */
2225 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
2226 ret = -1;
2227 /* Protected GAS Comeback Response */
2228 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
2229 ret = -1;
00b02149 2230#endif /* CONFIG_P2P || CONFIG_INTERWORKING || CONFIG_DPP */
4fe9fa0d 2231#ifdef CONFIG_P2P
046b26a2 2232 /* P2P Public Action */
a11241fa 2233 if (nl80211_register_action_frame(bss,
046b26a2
JM
2234 (u8 *) "\x04\x09\x50\x6f\x9a\x09",
2235 6) < 0)
6f06766e 2236 ret = -1;
046b26a2 2237 /* P2P Action */
a11241fa 2238 if (nl80211_register_action_frame(bss,
046b26a2
JM
2239 (u8 *) "\x7f\x50\x6f\x9a\x09",
2240 5) < 0)
6f06766e 2241 ret = -1;
046b26a2 2242#endif /* CONFIG_P2P */
00b02149
JM
2243#ifdef CONFIG_DPP
2244 /* DPP Public Action */
2245 if (nl80211_register_action_frame(bss,
2246 (u8 *) "\x04\x09\x50\x6f\x9a\x1a",
2247 6) < 0)
2248 ret = -1;
2249#endif /* CONFIG_DPP */
f9da7505
MV
2250#ifdef CONFIG_OCV
2251 /* SA Query Request */
2252 if (nl80211_register_action_frame(bss, (u8 *) "\x08\x00", 2) < 0)
2253 ret = -1;
2254#endif /* CONFIG_OCV */
7d878ca7 2255 /* SA Query Response */
a11241fa 2256 if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
6f06766e 2257 ret = -1;
35287637
AN
2258#ifdef CONFIG_TDLS
2259 if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
2260 /* TDLS Discovery Response */
aa543c0c 2261 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
35287637 2262 0)
6f06766e 2263 ret = -1;
35287637
AN
2264 }
2265#endif /* CONFIG_TDLS */
46ab9b8c
AN
2266#ifdef CONFIG_FST
2267 /* FST Action frames */
2268 if (nl80211_register_action_frame(bss, (u8 *) "\x12", 1) < 0)
2269 ret = -1;
2270#endif /* CONFIG_FST */
046b26a2 2271
7b90c16a 2272 /* FT Action frames */
a11241fa 2273 if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
6f06766e 2274 ret = -1;
7b90c16a
JM
2275 else
2276 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
2277 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
2278
71269b37 2279 /* WNM - BSS Transition Management Request */
a11241fa 2280 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
6f06766e 2281 ret = -1;
bd896433
JM
2282 /* WNM-Sleep Mode Response */
2283 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
6f06766e 2284 ret = -1;
d514b502
JM
2285#ifdef CONFIG_WNM
2286 /* WNM - Collocated Interference Request */
2287 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x0b", 2) < 0)
2288 ret = -1;
2289#endif /* CONFIG_WNM */
a11241fa 2290
95a3ea94
JM
2291#ifdef CONFIG_HS20
2292 /* WNM-Notification */
2293 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
3ee18569 2294 ret = -1;
95a3ea94
JM
2295#endif /* CONFIG_HS20 */
2296
dfa87878
MB
2297 /* WMM-AC ADDTS Response */
2298 if (nl80211_register_action_frame(bss, (u8 *) "\x11\x01", 2) < 0)
730a0d16 2299 ret = -1;
dfa87878
MB
2300
2301 /* WMM-AC DELTS */
2302 if (nl80211_register_action_frame(bss, (u8 *) "\x11\x02", 2) < 0)
730a0d16 2303 ret = -1;
dfa87878 2304
2526ccd9
AK
2305 /* Radio Measurement - Neighbor Report Response */
2306 if (nl80211_register_action_frame(bss, (u8 *) "\x05\x05", 2) < 0)
2307 ret = -1;
2308
864b9522
DS
2309 /* Radio Measurement - Radio Measurement Request */
2310 if (nl80211_register_action_frame(bss, (u8 *) "\x05\x00", 2) < 0)
2311 ret = -1;
2312
7dc03388
AO
2313 /* Radio Measurement - Link Measurement Request */
2314 if ((drv->capa.rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION) &&
2315 (nl80211_register_action_frame(bss, (u8 *) "\x05\x02", 2) < 0))
2316 ret = -1;
2317
5f65e9f7
JB
2318 nl80211_mgmt_handle_register_eloop(bss);
2319
6f06766e 2320 return ret;
a11241fa
JB
2321}
2322
2323
afb0550a
BC
2324static int nl80211_mgmt_subscribe_mesh(struct i802_bss *bss)
2325{
2326 int ret = 0;
2327
2328 if (nl80211_alloc_mgmt_handle(bss))
2329 return -1;
2330
2331 wpa_printf(MSG_DEBUG,
2332 "nl80211: Subscribe to mgmt frames with mesh handle %p",
2333 bss->nl_mgmt);
2334
2335 /* Auth frames for mesh SAE */
2336 if (nl80211_register_frame(bss, bss->nl_mgmt,
2337 (WLAN_FC_TYPE_MGMT << 2) |
2338 (WLAN_FC_STYPE_AUTH << 4),
2339 NULL, 0) < 0)
2340 ret = -1;
2341
2342 /* Mesh peering open */
2343 if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x01", 2) < 0)
2344 ret = -1;
2345 /* Mesh peering confirm */
2346 if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x02", 2) < 0)
2347 ret = -1;
2348 /* Mesh peering close */
2349 if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x03", 2) < 0)
2350 ret = -1;
2351
2352 nl80211_mgmt_handle_register_eloop(bss);
2353
2354 return ret;
2355}
2356
2357
02bb32c3
JB
2358static int nl80211_register_spurious_class3(struct i802_bss *bss)
2359{
02bb32c3 2360 struct nl_msg *msg;
a862e4a3 2361 int ret;
02bb32c3 2362
13f83980
JM
2363 msg = nl80211_bss_msg(bss, 0, NL80211_CMD_UNEXPECTED_FRAME);
2364 ret = send_and_recv(bss->drv->global, bss->nl_mgmt, msg, NULL, NULL);
02bb32c3
JB
2365 if (ret) {
2366 wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
2367 "failed: ret=%d (%s)",
2368 ret, strerror(-ret));
02bb32c3 2369 }
02bb32c3
JB
2370 return ret;
2371}
2372
2373
4d916ed6
KV
2374static int nl80211_action_subscribe_ap(struct i802_bss *bss)
2375{
2376 int ret = 0;
2377
2378 /* Public Action frames */
2379 if (nl80211_register_action_frame(bss, (u8 *) "\x04", 1) < 0)
2380 ret = -1;
2381 /* RRM Measurement Report */
2382 if (nl80211_register_action_frame(bss, (u8 *) "\x05\x01", 2) < 0)
2383 ret = -1;
e4ec6bbf
JM
2384 /* RRM Link Measurement Report */
2385 if (nl80211_register_action_frame(bss, (u8 *) "\x05\x03", 2) < 0)
2386 ret = -1;
4d916ed6
KV
2387 /* RRM Neighbor Report Request */
2388 if (nl80211_register_action_frame(bss, (u8 *) "\x05\x04", 2) < 0)
2389 ret = -1;
2390 /* FT Action frames */
2391 if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
2392 ret = -1;
4d916ed6
KV
2393 /* SA Query */
2394 if (nl80211_register_action_frame(bss, (u8 *) "\x08", 1) < 0)
2395 ret = -1;
4d916ed6
KV
2396 /* Protected Dual of Public Action */
2397 if (nl80211_register_action_frame(bss, (u8 *) "\x09", 1) < 0)
2398 ret = -1;
2399 /* WNM */
2400 if (nl80211_register_action_frame(bss, (u8 *) "\x0a", 1) < 0)
2401 ret = -1;
2402 /* WMM */
2403 if (nl80211_register_action_frame(bss, (u8 *) "\x11", 1) < 0)
2404 ret = -1;
2405#ifdef CONFIG_FST
2406 /* FST Action frames */
2407 if (nl80211_register_action_frame(bss, (u8 *) "\x12", 1) < 0)
2408 ret = -1;
2409#endif /* CONFIG_FST */
2410 /* Vendor-specific */
2411 if (nl80211_register_action_frame(bss, (u8 *) "\x7f", 1) < 0)
2412 ret = -1;
2413
2414 return ret;
2415}
2416
2417
a11241fa
JB
2418static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
2419{
2420 static const int stypes[] = {
2421 WLAN_FC_STYPE_AUTH,
2422 WLAN_FC_STYPE_ASSOC_REQ,
2423 WLAN_FC_STYPE_REASSOC_REQ,
2424 WLAN_FC_STYPE_DISASSOC,
2425 WLAN_FC_STYPE_DEAUTH,
a11241fa
JB
2426 WLAN_FC_STYPE_PROBE_REQ,
2427/* Beacon doesn't work as mac80211 doesn't currently allow
2428 * it, but it wouldn't really be the right thing anyway as
2429 * it isn't per interface ... maybe just dump the scan
2430 * results periodically for OLBC?
2431 */
0e80ea2c 2432 /* WLAN_FC_STYPE_BEACON, */
a11241fa
JB
2433 };
2434 unsigned int i;
2435
2436 if (nl80211_alloc_mgmt_handle(bss))
71269b37 2437 return -1;
36488c05
JM
2438 wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
2439 "handle %p", bss->nl_mgmt);
71269b37 2440
e7ecab4a 2441 for (i = 0; i < ARRAY_SIZE(stypes); i++) {
481234cf 2442 if (nl80211_register_frame(bss, bss->nl_mgmt,
a11241fa
JB
2443 (WLAN_FC_TYPE_MGMT << 2) |
2444 (stypes[i] << 4),
2445 NULL, 0) < 0) {
2446 goto out_err;
2447 }
2448 }
2449
4d916ed6
KV
2450 if (nl80211_action_subscribe_ap(bss))
2451 goto out_err;
2452
02bb32c3
JB
2453 if (nl80211_register_spurious_class3(bss))
2454 goto out_err;
2455
5f65e9f7 2456 nl80211_mgmt_handle_register_eloop(bss);
58f6fbe0 2457 return 0;
a11241fa
JB
2458
2459out_err:
a11241fa
JB
2460 nl_destroy_handles(&bss->nl_mgmt);
2461 return -1;
2462}
2463
2464
a6cc0602
JM
2465static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
2466{
2467 if (nl80211_alloc_mgmt_handle(bss))
2468 return -1;
2469 wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
2470 "handle %p (device SME)", bss->nl_mgmt);
2471
4d916ed6 2472 if (nl80211_action_subscribe_ap(bss))
a6cc0602
JM
2473 goto out_err;
2474
236e793e
SD
2475 if (bss->drv->device_ap_sme) {
2476 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
2477
2478 /* Register for all Authentication frames */
2479 if (nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0)
2480 < 0)
2481 wpa_printf(MSG_DEBUG,
2482 "nl80211: Failed to subscribe to handle Authentication frames - SAE offload may not work");
2483 }
2484
5f65e9f7 2485 nl80211_mgmt_handle_register_eloop(bss);
a6cc0602
JM
2486 return 0;
2487
2488out_err:
a6cc0602
JM
2489 nl_destroy_handles(&bss->nl_mgmt);
2490 return -1;
2491}
2492
2493
36488c05 2494static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
a11241fa 2495{
481234cf 2496 if (bss->nl_mgmt == NULL)
a11241fa 2497 return;
36488c05
JM
2498 wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
2499 "(%s)", bss->nl_mgmt, reason);
40a68f33 2500 nl80211_destroy_eloop_handle(&bss->nl_mgmt, 0);
7813b7c3
MH
2501
2502 nl80211_put_wiphy_data_ap(bss);
58f6fbe0
JM
2503}
2504
2505
8401a6b0
JM
2506static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
2507{
2508 wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
2509}
2510
2511
eb4582f2
AS
2512static void nl80211_del_p2pdev(struct i802_bss *bss)
2513{
eb4582f2
AS
2514 struct nl_msg *msg;
2515 int ret;
2516
a3249fdf
JM
2517 msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_INTERFACE);
2518 ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
eb4582f2
AS
2519
2520 wpa_printf(MSG_DEBUG, "nl80211: Delete P2P Device %s (0x%llx): %s",
2521 bss->ifname, (long long unsigned int) bss->wdev_id,
6cb4f11d 2522 strerror(-ret));
eb4582f2
AS
2523}
2524
2525
eb4582f2 2526static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
f632e483 2527{
f632e483 2528 struct nl_msg *msg;
a862e4a3 2529 int ret;
f632e483 2530
a3249fdf
JM
2531 msg = nl80211_cmd_msg(bss, 0, start ? NL80211_CMD_START_P2P_DEVICE :
2532 NL80211_CMD_STOP_P2P_DEVICE);
2533 ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
f632e483 2534
eb4582f2
AS
2535 wpa_printf(MSG_DEBUG, "nl80211: %s P2P Device %s (0x%llx): %s",
2536 start ? "Start" : "Stop",
2537 bss->ifname, (long long unsigned int) bss->wdev_id,
6cb4f11d 2538 strerror(-ret));
f632e483
AS
2539 return ret;
2540}
f632e483
AS
2541
2542
91724d6f
AS
2543static int i802_set_iface_flags(struct i802_bss *bss, int up)
2544{
2545 enum nl80211_iftype nlmode;
2546
2547 nlmode = nl80211_get_ifmode(bss);
2548 if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
2549 return linux_set_iface_flags(bss->drv->global->ioctl_sock,
2550 bss->ifname, up);
2551 }
2552
2553 /* P2P Device has start/stop which is equivalent */
2554 return nl80211_set_p2pdev(bss, up);
2555}
2556
2557
1db718b3
JM
2558#ifdef CONFIG_TESTING_OPTIONS
2559static int qca_vendor_test_cmd_handler(struct nl_msg *msg, void *arg)
2560{
2561 /* struct wpa_driver_nl80211_data *drv = arg; */
2562 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2563 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2564
2565
2566 wpa_printf(MSG_DEBUG,
2567 "nl80211: QCA vendor test command response received");
2568
2569 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2570 genlmsg_attrlen(gnlh, 0), NULL);
2571 if (!tb[NL80211_ATTR_VENDOR_DATA]) {
2572 wpa_printf(MSG_DEBUG, "nl80211: No vendor data attribute");
2573 return NL_SKIP;
2574 }
2575
2576 wpa_hexdump(MSG_DEBUG,
2577 "nl80211: Received QCA vendor test command response",
2578 nla_data(tb[NL80211_ATTR_VENDOR_DATA]),
2579 nla_len(tb[NL80211_ATTR_VENDOR_DATA]));
2580
2581 return NL_SKIP;
2582}
2583#endif /* CONFIG_TESTING_OPTIONS */
2584
2585
2586static void qca_vendor_test(struct wpa_driver_nl80211_data *drv)
2587{
2588#ifdef CONFIG_TESTING_OPTIONS
2589 struct nl_msg *msg;
2590 struct nlattr *params;
2591 int ret;
2592
2593 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
2594 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2595 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2596 QCA_NL80211_VENDOR_SUBCMD_TEST) ||
2597 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2598 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TEST, 123)) {
2599 nlmsg_free(msg);
2600 return;
2601 }
2602 nla_nest_end(msg, params);
2603
2604 ret = send_and_recv_msgs(drv, msg, qca_vendor_test_cmd_handler, drv);
2605 wpa_printf(MSG_DEBUG,
2606 "nl80211: QCA vendor test command returned %d (%s)",
2607 ret, strerror(-ret));
2608#endif /* CONFIG_TESTING_OPTIONS */
2609}
2610
2611
362f781e 2612static int
0d547d5f 2613wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
0ecff8d7
JM
2614 const u8 *set_addr, int first,
2615 const char *driver_params)
7524cfb1 2616{
834ee56f 2617 struct i802_bss *bss = drv->first_bss;
8401a6b0 2618 int send_rfkill_event = 0;
0d547d5f 2619 enum nl80211_iftype nlmode;
a2e40bb6
FF
2620
2621 drv->ifindex = if_nametoindex(bss->ifname);
f632e483
AS
2622 bss->ifindex = drv->ifindex;
2623 bss->wdev_id = drv->global->if_add_wdevid;
2624 bss->wdev_id_set = drv->global->if_add_wdevid_set;
2625
60b13c20
IP
2626 bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
2627 bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
f632e483
AS
2628 drv->global->if_add_wdevid_set = 0;
2629
bf144cf6
AP
2630 if (!bss->if_dynamic && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
2631 bss->static_ap = 1;
2632
ef3866ab
IP
2633 if (first &&
2634 nl80211_get_ifmode(bss) != NL80211_IFTYPE_P2P_DEVICE &&
2635 linux_iface_up(drv->global->ioctl_sock, bss->ifname) > 0)
2636 drv->start_iface_up = 1;
2637
f632e483
AS
2638 if (wpa_driver_nl80211_capa(drv))
2639 return -1;
a87c9d96 2640
0ecff8d7
JM
2641 if (driver_params && nl80211_set_param(bss, driver_params) < 0)
2642 return -1;
2643
5fbcb45d
AS
2644 wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
2645 bss->ifname, drv->phyname);
2646
0d547d5f
JM
2647 if (set_addr &&
2648 (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
2649 linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2650 set_addr)))
2651 return -1;
2652
49b4b205
JM
2653 if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
2654 drv->start_mode_ap = 1;
2655
bf144cf6 2656 if (drv->hostapd || bss->static_ap)
0d547d5f 2657 nlmode = NL80211_IFTYPE_AP;
4fe726e2
FF
2658 else if (bss->if_dynamic ||
2659 nl80211_get_ifmode(bss) == NL80211_IFTYPE_MESH_POINT)
8e12685c 2660 nlmode = nl80211_get_ifmode(bss);
0d547d5f
JM
2661 else
2662 nlmode = NL80211_IFTYPE_STATION;
f632e483 2663
8e12685c 2664 if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
0d547d5f 2665 wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
8e12685c 2666 return -1;
a87c9d96
JM
2667 }
2668
8c06db70 2669 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
597b94f5 2670 nl80211_get_macaddr(bss);
f632e483 2671
0e92fb8f
JB
2672 wpa_driver_nl80211_drv_init_rfkill(drv);
2673
8c06db70
MB
2674 if (!rfkill_is_blocked(drv->rfkill)) {
2675 int ret = i802_set_iface_flags(bss, 1);
2676 if (ret) {
8401a6b0
JM
2677 wpa_printf(MSG_ERROR, "nl80211: Could not set "
2678 "interface '%s' UP", bss->ifname);
8c06db70 2679 return ret;
8401a6b0 2680 }
e8dc205f
AO
2681
2682 if (is_p2p_net_interface(nlmode))
2683 nl80211_disable_11b_rates(bss->drv,
2684 bss->drv->ifindex, 1);
2685
8c06db70
MB
2686 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
2687 return ret;
2688 } else {
2689 wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
2690 "interface '%s' due to rfkill", bss->ifname);
6da504a1
IP
2691 if (nlmode != NL80211_IFTYPE_P2P_DEVICE)
2692 drv->if_disabled = 1;
2693
8c06db70 2694 send_rfkill_event = 1;
362f781e 2695 }
3f5285e8 2696
6da504a1 2697 if (!drv->hostapd && nlmode != NL80211_IFTYPE_P2P_DEVICE)
0d547d5f
JM
2698 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
2699 1, IF_OPER_DORMANT);
362f781e 2700
6da504a1
IP
2701 if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
2702 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2703 bss->addr))
2704 return -1;
2705 os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
2706 }
f2ed8023 2707
8401a6b0
JM
2708 if (send_rfkill_event) {
2709 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
2710 drv, drv->ctx);
2711 }
2712
1db718b3
JM
2713 if (drv->vendor_cmd_test_avail)
2714 qca_vendor_test(drv);
2715
40a68f33
SD
2716 nl80211_init_connect_handle(bss);
2717
362f781e 2718 return 0;
3f5285e8
JM
2719}
2720
2721
a70cd0db 2722static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss)
8a27af5c
JM
2723{
2724 struct nl_msg *msg;
a70cd0db 2725 struct wpa_driver_nl80211_data *drv = bss->drv;
8a27af5c 2726
08e55ebb
JM
2727 wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
2728 drv->ifindex);
a70cd0db 2729 nl80211_put_wiphy_data_ap(bss);
9725b784 2730 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
8a27af5c 2731 return send_and_recv_msgs(drv, msg, NULL, NULL);
8a27af5c 2732}
8a27af5c
JM
2733
2734
3f5285e8 2735/**
7e5ba1b9 2736 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
9ebce9c5 2737 * @bss: Pointer to private nl80211 data from wpa_driver_nl80211_init()
3f5285e8
JM
2738 *
2739 * Shut down driver interface and processing of driver events. Free
2740 * private data buffer if one was allocated in wpa_driver_nl80211_init().
2741 */
9ebce9c5 2742static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
3f5285e8 2743{
a2e40bb6 2744 struct wpa_driver_nl80211_data *drv = bss->drv;
cc9a2575 2745 unsigned int i;
3f5285e8 2746
3e208481
JM
2747 wpa_printf(MSG_INFO, "nl80211: deinit ifname=%s disabled_11b_rates=%d",
2748 bss->ifname, drv->disabled_11b_rates);
2749
873d0fcf 2750 bss->in_deinit = 1;
32ab4855
JB
2751 if (drv->data_tx_status)
2752 eloop_unregister_read_sock(drv->eapol_tx_sock);
d12dab4c
JB
2753 if (drv->eapol_tx_sock >= 0)
2754 close(drv->eapol_tx_sock);
f10bfc9a 2755
481234cf 2756 if (bss->nl_preq)
5582a5d1 2757 wpa_driver_nl80211_probe_req_report(bss, 0);
e17a2477 2758 if (bss->added_if_into_bridge) {
c81eff1a
BG
2759 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
2760 bss->ifname) < 0)
94627f6c
JM
2761 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
2762 "interface %s from bridge %s: %s",
e17a2477 2763 bss->ifname, bss->brname, strerror(errno));
94627f6c 2764 }
c809756f
SM
2765
2766 if (drv->rtnl_sk)
25ebd538 2767 nl_socket_free(drv->rtnl_sk);
c809756f 2768
e17a2477 2769 if (bss->added_bridge) {
f2535da8
JM
2770 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname,
2771 0) < 0)
2772 wpa_printf(MSG_INFO,
2773 "nl80211: Could not set bridge %s down",
2774 bss->brname);
c81eff1a 2775 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
94627f6c
JM
2776 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
2777 "bridge %s: %s",
e17a2477 2778 bss->brname, strerror(errno));
94627f6c
JM
2779 }
2780
460456f8 2781 nl80211_remove_monitor_interface(drv);
8a27af5c 2782
b1f625e0 2783 if (is_ap_interface(drv->nlmode))
a70cd0db 2784 wpa_driver_nl80211_del_beacon(bss);
0915d02c 2785
bbaf0837
JM
2786 if (drv->eapol_sock >= 0) {
2787 eloop_unregister_read_sock(drv->eapol_sock);
2788 close(drv->eapol_sock);
2789 }
2790
2791 if (drv->if_indices != drv->default_if_indices)
2792 os_free(drv->if_indices);
3f5285e8 2793
b3af99d2 2794 if (drv->disabled_11b_rates)
4e5cb1a3
JM
2795 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
2796
36d84860
BG
2797 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
2798 IF_OPER_UP);
e390df05 2799 eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
8401a6b0 2800 rfkill_deinit(drv->rfkill);
3f5285e8 2801
bbaf0837
JM
2802 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
2803
146fa9b3
JM
2804 if (!drv->start_iface_up)
2805 (void) i802_set_iface_flags(bss, 0);
fee354c7
JM
2806
2807 if (drv->addr_changed) {
93da0498
JM
2808 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
2809 0) < 0) {
2810 wpa_printf(MSG_DEBUG,
2811 "nl80211: Could not set interface down to restore permanent MAC address");
2812 }
fee354c7
JM
2813 if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2814 drv->perm_addr) < 0) {
2815 wpa_printf(MSG_DEBUG,
2816 "nl80211: Could not restore permanent MAC address");
2817 }
2818 }
2819
8e12685c 2820 if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
49b4b205
JM
2821 if (!drv->hostapd || !drv->start_mode_ap)
2822 wpa_driver_nl80211_set_mode(bss,
2823 NL80211_IFTYPE_STATION);
b378c41f 2824 nl80211_mgmt_unsubscribe(bss, "deinit");
8e12685c
AS
2825 } else {
2826 nl80211_mgmt_unsubscribe(bss, "deinit");
eb4582f2 2827 nl80211_del_p2pdev(bss);
8e12685c 2828 }
3f5285e8 2829
40a68f33
SD
2830 if (bss->nl_connect)
2831 nl80211_destroy_eloop_handle(&bss->nl_connect, 1);
2832
834ee56f 2833 nl80211_destroy_bss(drv->first_bss);
cc7a48d1 2834
3812464c
JM
2835 os_free(drv->filter_ssids);
2836
536fd62d
JM
2837 os_free(drv->auth_ie);
2838
dac12351 2839 if (drv->in_interface_list)
f2ed8023
JM
2840 dl_list_del(&drv->list);
2841
8cd6b7bc
JB
2842 os_free(drv->extended_capa);
2843 os_free(drv->extended_capa_mask);
cc9a2575
KV
2844 for (i = 0; i < drv->num_iface_ext_capa; i++) {
2845 os_free(drv->iface_ext_capa[i].ext_capa);
2846 os_free(drv->iface_ext_capa[i].ext_capa_mask);
2847 }
834ee56f 2848 os_free(drv->first_bss);
3f5285e8
JM
2849 os_free(drv);
2850}
2851
2852
de4ed4a8
JM
2853static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
2854{
2855 switch (alg) {
2856 case WPA_ALG_WEP:
2857 if (key_len == 5)
a042e39a
JM
2858 return RSN_CIPHER_SUITE_WEP40;
2859 return RSN_CIPHER_SUITE_WEP104;
de4ed4a8 2860 case WPA_ALG_TKIP:
a042e39a 2861 return RSN_CIPHER_SUITE_TKIP;
de4ed4a8 2862 case WPA_ALG_CCMP:
a042e39a 2863 return RSN_CIPHER_SUITE_CCMP;
de4ed4a8 2864 case WPA_ALG_GCMP:
a042e39a 2865 return RSN_CIPHER_SUITE_GCMP;
de4ed4a8 2866 case WPA_ALG_CCMP_256:
a042e39a 2867 return RSN_CIPHER_SUITE_CCMP_256;
de4ed4a8 2868 case WPA_ALG_GCMP_256:
a042e39a 2869 return RSN_CIPHER_SUITE_GCMP_256;
de4ed4a8 2870 case WPA_ALG_IGTK:
a042e39a 2871 return RSN_CIPHER_SUITE_AES_128_CMAC;
de4ed4a8 2872 case WPA_ALG_BIP_GMAC_128:
a042e39a 2873 return RSN_CIPHER_SUITE_BIP_GMAC_128;
de4ed4a8 2874 case WPA_ALG_BIP_GMAC_256:
a042e39a 2875 return RSN_CIPHER_SUITE_BIP_GMAC_256;
de4ed4a8 2876 case WPA_ALG_BIP_CMAC_256:
a042e39a 2877 return RSN_CIPHER_SUITE_BIP_CMAC_256;
de4ed4a8 2878 case WPA_ALG_SMS4:
a042e39a 2879 return RSN_CIPHER_SUITE_SMS4;
de4ed4a8 2880 case WPA_ALG_KRK:
a042e39a 2881 return RSN_CIPHER_SUITE_KRK;
de4ed4a8
JM
2882 case WPA_ALG_NONE:
2883 case WPA_ALG_PMK:
2884 wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
2885 alg);
2886 return 0;
2887 }
2888
2889 wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
2890 alg);
2891 return 0;
2892}
2893
2894
2895static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
2896{
2897 switch (cipher) {
2898 case WPA_CIPHER_CCMP_256:
a042e39a 2899 return RSN_CIPHER_SUITE_CCMP_256;
de4ed4a8 2900 case WPA_CIPHER_GCMP_256:
a042e39a 2901 return RSN_CIPHER_SUITE_GCMP_256;
de4ed4a8 2902 case WPA_CIPHER_CCMP:
a042e39a 2903 return RSN_CIPHER_SUITE_CCMP;
de4ed4a8 2904 case WPA_CIPHER_GCMP:
a042e39a 2905 return RSN_CIPHER_SUITE_GCMP;
de4ed4a8 2906 case WPA_CIPHER_TKIP:
a042e39a 2907 return RSN_CIPHER_SUITE_TKIP;
de4ed4a8 2908 case WPA_CIPHER_WEP104:
a042e39a 2909 return RSN_CIPHER_SUITE_WEP104;
de4ed4a8 2910 case WPA_CIPHER_WEP40:
a042e39a 2911 return RSN_CIPHER_SUITE_WEP40;
ae6f9272 2912 case WPA_CIPHER_GTK_NOT_USED:
a042e39a 2913 return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
de4ed4a8
JM
2914 }
2915
2916 return 0;
2917}
2918
2919
2920static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
2921 int max_suites)
2922{
2923 int num_suites = 0;
2924
2925 if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
a042e39a 2926 suites[num_suites++] = RSN_CIPHER_SUITE_CCMP_256;
de4ed4a8 2927 if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
a042e39a 2928 suites[num_suites++] = RSN_CIPHER_SUITE_GCMP_256;
de4ed4a8 2929 if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
a042e39a 2930 suites[num_suites++] = RSN_CIPHER_SUITE_CCMP;
de4ed4a8 2931 if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
a042e39a 2932 suites[num_suites++] = RSN_CIPHER_SUITE_GCMP;
de4ed4a8 2933 if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
a042e39a 2934 suites[num_suites++] = RSN_CIPHER_SUITE_TKIP;
de4ed4a8 2935 if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
a042e39a 2936 suites[num_suites++] = RSN_CIPHER_SUITE_WEP104;
de4ed4a8 2937 if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
a042e39a 2938 suites[num_suites++] = RSN_CIPHER_SUITE_WEP40;
de4ed4a8
JM
2939
2940 return num_suites;
2941}
2942
2943
b658547d 2944#ifdef CONFIG_DRIVER_NL80211_QCA
b41f2684
CL
2945static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
2946 const u8 *key, size_t key_len)
2947{
2948 struct nl_msg *msg;
a862e4a3 2949 int ret;
b41f2684 2950
15badebd 2951 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
b41f2684
CL
2952 return 0;
2953
9725b784 2954 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
a862e4a3
JM
2955 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2956 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2957 QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY) ||
2958 nla_put(msg, NL80211_ATTR_VENDOR_DATA, key_len, key)) {
bbd89bfc 2959 nl80211_nlmsg_clear(msg);
a862e4a3
JM
2960 nlmsg_free(msg);
2961 return -1;
2962 }
bbd89bfc 2963 ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
b41f2684
CL
2964 if (ret) {
2965 wpa_printf(MSG_DEBUG,
2966 "nl80211: Key management set key failed: ret=%d (%s)",
2967 ret, strerror(-ret));
2968 }
2969
b41f2684
CL
2970 return ret;
2971}
b658547d 2972#endif /* CONFIG_DRIVER_NL80211_QCA */
b41f2684
CL
2973
2974
05fc7c68
AS
2975static int nl80211_set_pmk(struct wpa_driver_nl80211_data *drv,
2976 const u8 *key, size_t key_len,
2977 const u8 *addr)
2978{
2979 struct nl_msg *msg = NULL;
2980 int ret;
2981
2982 /*
2983 * If the authenticator address is not set, assume it is
2984 * the current BSSID.
2985 */
2986 if (!addr && drv->associated)
2987 addr = drv->bssid;
2988 else if (!addr)
2989 return -1;
2990
2991 wpa_printf(MSG_DEBUG, "nl80211: Set PMK to the driver for " MACSTR,
2992 MAC2STR(addr));
2993 wpa_hexdump_key(MSG_DEBUG, "nl80211: PMK", key, key_len);
2994 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_PMK);
2995 if (!msg ||
2996 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2997 nla_put(msg, NL80211_ATTR_PMK, key_len, key)) {
2998 nl80211_nlmsg_clear(msg);
2999 nlmsg_free(msg);
3000 return -ENOBUFS;
3001 }
3002
3003 ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
3004 if (ret) {
3005 wpa_printf(MSG_DEBUG, "nl80211: Set PMK failed: ret=%d (%s)",
3006 ret, strerror(-ret));
3007 }
3008
3009 return ret;
3010}
3011
3012
9ebce9c5 3013static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
71934751
JM
3014 enum wpa_alg alg, const u8 *addr,
3015 int key_idx, int set_tx,
642187d6
JM
3016 const u8 *seq, size_t seq_len,
3017 const u8 *key, size_t key_len)
3f5285e8 3018{
a2e40bb6 3019 struct wpa_driver_nl80211_data *drv = bss->drv;
e472e1b4 3020 int ifindex;
83b83b46
AW
3021 struct nl_msg *msg;
3022 struct nl_msg *key_msg;
1ad1cdc2 3023 int ret;
dc01de8a 3024 int tdls = 0;
3f5285e8 3025
e472e1b4
AS
3026 /* Ignore for P2P Device */
3027 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
3028 return 0;
3029
3030 ifindex = if_nametoindex(ifname);
8393e1a0 3031 wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
1ad1cdc2 3032 "set_tx=%d seq_len=%lu key_len=%lu",
8393e1a0 3033 __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
3f5285e8 3034 (unsigned long) seq_len, (unsigned long) key_len);
8c66e185 3035#ifdef CONFIG_TDLS
dc01de8a 3036 if (key_idx == -1) {
8c66e185 3037 key_idx = 0;
dc01de8a
JM
3038 tdls = 1;
3039 }
8c66e185 3040#endif /* CONFIG_TDLS */
3f5285e8 3041
b658547d 3042#ifdef CONFIG_DRIVER_NL80211_QCA
15badebd
CL
3043 if (alg == WPA_ALG_PMK &&
3044 (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
b41f2684
CL
3045 wpa_printf(MSG_DEBUG, "%s: calling issue_key_mgmt_set_key",
3046 __func__);
3047 ret = issue_key_mgmt_set_key(drv, key, key_len);
3048 return ret;
3049 }
b658547d 3050#endif /* CONFIG_DRIVER_NL80211_QCA */
b41f2684 3051
05fc7c68 3052 if (alg == WPA_ALG_PMK &&
436ee2fd 3053 (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
05fc7c68
AS
3054 return nl80211_set_pmk(drv, key, key_len, addr);
3055
83b83b46
AW
3056 key_msg = nlmsg_alloc();
3057 if (!key_msg)
3058 return -ENOBUFS;
3059
3f5285e8 3060 if (alg == WPA_ALG_NONE) {
95376e1a
JM
3061 msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY);
3062 if (!msg)
83b83b46 3063 goto fail2;
3f5285e8 3064 } else {
34651767
JM
3065 u32 suite;
3066
3067 suite = wpa_alg_to_cipher_suite(alg, key_len);
3068 if (!suite)
83b83b46 3069 goto fail2;
95376e1a 3070 msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY);
83b83b46
AW
3071 if (!msg)
3072 goto fail2;
3073 if (nla_put(key_msg, NL80211_KEY_DATA, key_len, key) ||
3074 nla_put_u32(key_msg, NL80211_KEY_CIPHER, suite))
a862e4a3 3075 goto fail;
e6ef73f1 3076 wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
3f5285e8
JM
3077 }
3078
e6ef73f1 3079 if (seq && seq_len) {
83b83b46 3080 if (nla_put(key_msg, NL80211_KEY_SEQ, seq_len, seq))
a862e4a3 3081 goto fail;
e6ef73f1
JM
3082 wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
3083 }
1ad1cdc2 3084
0382097e 3085 if (addr && !is_broadcast_ether_addr(addr)) {
3f5285e8 3086 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
a862e4a3
JM
3087 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
3088 goto fail;
89c38e32
JM
3089
3090 if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
3091 wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
83b83b46 3092 if (nla_put_u32(key_msg, NL80211_KEY_TYPE,
a862e4a3
JM
3093 NL80211_KEYTYPE_GROUP))
3094 goto fail;
89c38e32 3095 }
60ea8187 3096 } else if (addr && is_broadcast_ether_addr(addr)) {
8970bae8
JB
3097 struct nlattr *types;
3098
60ea8187 3099 wpa_printf(MSG_DEBUG, " broadcast key");
8970bae8 3100
83b83b46 3101 types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
a862e4a3 3102 if (!types ||
83b83b46 3103 nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
a862e4a3 3104 goto fail;
83b83b46 3105 nla_nest_end(key_msg, types);
3f5285e8 3106 }
83b83b46
AW
3107 if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) ||
3108 nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
a862e4a3 3109 goto fail;
83b83b46
AW
3110 nl80211_nlmsg_clear(key_msg);
3111 nlmsg_free(key_msg);
3112 key_msg = NULL;
3f5285e8 3113
bbd89bfc 3114 ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL);
15664ad0 3115 if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
1ad1cdc2
JM
3116 ret = 0;
3117 if (ret)
3118 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
3119 ret, strerror(-ret));
3f5285e8 3120
1ad1cdc2
JM
3121 /*
3122 * If we failed or don't need to set the default TX key (below),
3123 * we're done here.
3124 */
dc01de8a 3125 if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
1ad1cdc2 3126 return ret;
b1f625e0 3127 if (is_ap_interface(drv->nlmode) && addr &&
0382097e 3128 !is_broadcast_ether_addr(addr))
de12717a 3129 return ret;
3f5285e8 3130
83b83b46
AW
3131 key_msg = nlmsg_alloc();
3132 if (!key_msg)
3133 return -ENOBUFS;
3134
95376e1a 3135 msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY);
83b83b46
AW
3136 if (!msg)
3137 goto fail2;
3138 if (!key_msg ||
3139 nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) ||
3140 nla_put_flag(key_msg, (alg == WPA_ALG_IGTK ||
3141 alg == WPA_ALG_BIP_GMAC_128 ||
3142 alg == WPA_ALG_BIP_GMAC_256 ||
3143 alg == WPA_ALG_BIP_CMAC_256) ?
3144 NL80211_KEY_DEFAULT_MGMT :
3145 NL80211_KEY_DEFAULT))
a862e4a3 3146 goto fail;
60ea8187 3147 if (addr && is_broadcast_ether_addr(addr)) {
8970bae8
JB
3148 struct nlattr *types;
3149
83b83b46 3150 types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
a862e4a3 3151 if (!types ||
83b83b46 3152 nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
a862e4a3 3153 goto fail;
83b83b46 3154 nla_nest_end(key_msg, types);
60ea8187 3155 } else if (addr) {
8970bae8
JB
3156 struct nlattr *types;
3157
83b83b46 3158 types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES);
a862e4a3 3159 if (!types ||
83b83b46 3160 nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_UNICAST))
a862e4a3 3161 goto fail;
83b83b46 3162 nla_nest_end(key_msg, types);
60ea8187 3163 }
3f5285e8 3164
83b83b46
AW
3165 if (nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
3166 goto fail;
3167 nl80211_nlmsg_clear(key_msg);
3168 nlmsg_free(key_msg);
3169 key_msg = NULL;
3170
1ad1cdc2
JM
3171 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3172 if (ret == -ENOENT)
3173 ret = 0;
3174 if (ret)
3175 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
3176 "err=%d %s)", ret, strerror(-ret));
3177 return ret;
3f5285e8 3178
a862e4a3 3179fail:
bbd89bfc 3180 nl80211_nlmsg_clear(msg);
5883168a 3181 nlmsg_free(msg);
83b83b46
AW
3182fail2:
3183 nl80211_nlmsg_clear(key_msg);
3184 nlmsg_free(key_msg);
6241fcb1 3185 return -ENOBUFS;
3f5285e8
JM
3186}
3187
3188
71934751 3189static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
0194fedb
JB
3190 int key_idx, int defkey,
3191 const u8 *seq, size_t seq_len,
3192 const u8 *key, size_t key_len)
3193{
3194 struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
34651767
JM
3195 u32 suite;
3196
0194fedb
JB
3197 if (!key_attr)
3198 return -1;
3199
34651767
JM
3200 suite = wpa_alg_to_cipher_suite(alg, key_len);
3201 if (!suite)
3202 return -1;
3203
a862e4a3
JM
3204 if (defkey && alg == WPA_ALG_IGTK) {
3205 if (nla_put_flag(msg, NL80211_KEY_DEFAULT_MGMT))
3206 return -1;
3207 } else if (defkey) {
3208 if (nla_put_flag(msg, NL80211_KEY_DEFAULT))
3209 return -1;
3210 }
0194fedb 3211
a862e4a3 3212 if (nla_put_u8(msg, NL80211_KEY_IDX, key_idx) ||
34651767 3213 nla_put_u32(msg, NL80211_KEY_CIPHER, suite) ||
a862e4a3
JM
3214 (seq && seq_len &&
3215 nla_put(msg, NL80211_KEY_SEQ, seq_len, seq)) ||
3216 nla_put(msg, NL80211_KEY_DATA, key_len, key))
3217 return -1;
0194fedb
JB
3218
3219 nla_nest_end(msg, key_attr);
3220
3221 return 0;
0194fedb
JB
3222}
3223
c811d5bc 3224
cfaab580
ZY
3225static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
3226 struct nl_msg *msg)
3227{
3228 int i, privacy = 0;
3229 struct nlattr *nl_keys, *nl_key;
3230
3231 for (i = 0; i < 4; i++) {
3232 if (!params->wep_key[i])
3233 continue;
3234 privacy = 1;
3235 break;
3236 }
ce04af5a
JM
3237 if (params->wps == WPS_MODE_PRIVACY)
3238 privacy = 1;
3239 if (params->pairwise_suite &&
3240 params->pairwise_suite != WPA_CIPHER_NONE)
3241 privacy = 1;
3242
cfaab580
ZY
3243 if (!privacy)
3244 return 0;
3245
a862e4a3
JM
3246 if (nla_put_flag(msg, NL80211_ATTR_PRIVACY))
3247 return -ENOBUFS;
cfaab580
ZY
3248
3249 nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
3250 if (!nl_keys)
a862e4a3 3251 return -ENOBUFS;
cfaab580
ZY
3252
3253 for (i = 0; i < 4; i++) {
3254 if (!params->wep_key[i])
3255 continue;
3256
3257 nl_key = nla_nest_start(msg, i);
a862e4a3
JM
3258 if (!nl_key ||
3259 nla_put(msg, NL80211_KEY_DATA, params->wep_key_len[i],
3260 params->wep_key[i]) ||
3261 nla_put_u32(msg, NL80211_KEY_CIPHER,
3262 params->wep_key_len[i] == 5 ?
a042e39a
JM
3263 RSN_CIPHER_SUITE_WEP40 :
3264 RSN_CIPHER_SUITE_WEP104) ||
a862e4a3
JM
3265 nla_put_u8(msg, NL80211_KEY_IDX, i) ||
3266 (i == params->wep_tx_keyidx &&
3267 nla_put_flag(msg, NL80211_KEY_DEFAULT)))
3268 return -ENOBUFS;
cfaab580
ZY
3269
3270 nla_nest_end(msg, nl_key);
3271 }
3272 nla_nest_end(msg, nl_keys);
3273
3274 return 0;
cfaab580
ZY
3275}
3276
3277
477af8f8
JM
3278int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
3279 const u8 *addr, int cmd, u16 reason_code,
10d32e2c 3280 int local_state_change,
25ebd538 3281 struct nl_sock *nl_connect)
c2a04078 3282{
a862e4a3 3283 int ret;
c2a04078
JM
3284 struct nl_msg *msg;
3285
9725b784 3286 if (!(msg = nl80211_drv_msg(drv, 0, cmd)) ||
a862e4a3
JM
3287 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code) ||
3288 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
3289 (local_state_change &&
3290 nla_put_flag(msg, NL80211_ATTR_LOCAL_STATE_CHANGE))) {
3291 nlmsg_free(msg);
3292 return -1;
3293 }
c2a04078 3294
10d32e2c
CI
3295 if (nl_connect)
3296 ret = send_and_recv(drv->global, nl_connect, msg, NULL, NULL);
3297 else
3298 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
c2a04078 3299 if (ret) {
3b7ea880
BG
3300 wpa_dbg(drv->ctx, MSG_DEBUG,
3301 "nl80211: MLME command failed: reason=%u ret=%d (%s)",
3302 reason_code, ret, strerror(-ret));
c2a04078 3303 }
c2a04078
JM
3304 return ret;
3305}
3f5285e8
JM
3306
3307
cfaab580 3308static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
4be17ffb 3309 u16 reason_code,
25ebd538 3310 struct nl_sock *nl_connect)
cfaab580 3311{
3f53c006 3312 int ret;
b898b655 3313 int drv_associated = drv->associated;
3f53c006 3314
817762d9 3315 wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
add9b7a4 3316 nl80211_mark_disconnected(drv);
817762d9 3317 /* Disconnect command doesn't need BSSID - it uses cached value */
3f53c006 3318 ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
10d32e2c 3319 reason_code, 0, nl_connect);
3f53c006
JJ
3320 /*
3321 * For locally generated disconnect, supplicant already generates a
3322 * DEAUTH event, so ignore the event from NL80211.
3323 */
b898b655 3324 drv->ignore_next_local_disconnect = drv_associated && (ret == 0);
3f53c006
JJ
3325
3326 return ret;
cfaab580
ZY
3327}
3328
3329
9ebce9c5 3330static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
4be17ffb 3331 const u8 *addr, u16 reason_code)
3f5285e8 3332{
a2e40bb6 3333 struct wpa_driver_nl80211_data *drv = bss->drv;
d6a36f39 3334 int ret;
b898b655 3335 int drv_associated = drv->associated;
9392c9be
AS
3336
3337 if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
3338 nl80211_mark_disconnected(drv);
666e508c 3339 return nl80211_leave_ibss(drv, 1);
9392c9be 3340 }
10d32e2c 3341 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
25ebd538 3342 struct nl_sock *nl_connect = NULL;
10d32e2c
CI
3343
3344 if (bss->use_nl_connect)
3345 nl_connect = bss->nl_connect;
3346 return wpa_driver_nl80211_disconnect(drv, reason_code,
3347 nl_connect);
3348 }
2e75a2b3
JM
3349 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
3350 __func__, MAC2STR(addr), reason_code);
add9b7a4 3351 nl80211_mark_disconnected(drv);
d6a36f39 3352 ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
10d32e2c 3353 reason_code, 0, NULL);
d6a36f39
JM
3354 /*
3355 * For locally generated deauthenticate, supplicant already generates a
3356 * DEAUTH event, so ignore the event from NL80211.
3357 */
b898b655
HW
3358 drv->ignore_next_local_deauth = drv_associated && (ret == 0);
3359
d6a36f39 3360 return ret;
3f5285e8
JM
3361}
3362
3363
536fd62d
JM
3364static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
3365 struct wpa_driver_auth_params *params)
3366{
3367 int i;
3368
3369 drv->auth_freq = params->freq;
3370 drv->auth_alg = params->auth_alg;
3371 drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
3372 drv->auth_local_state_change = params->local_state_change;
3373 drv->auth_p2p = params->p2p;
3374
3375 if (params->bssid)
3376 os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
3377 else
3378 os_memset(drv->auth_bssid_, 0, ETH_ALEN);
3379
3380 if (params->ssid) {
3381 os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
3382 drv->auth_ssid_len = params->ssid_len;
3383 } else
3384 drv->auth_ssid_len = 0;
3385
3386
3387 os_free(drv->auth_ie);
3388 drv->auth_ie = NULL;
3389 drv->auth_ie_len = 0;
3390 if (params->ie) {
3391 drv->auth_ie = os_malloc(params->ie_len);
3392 if (drv->auth_ie) {
3393 os_memcpy(drv->auth_ie, params->ie, params->ie_len);
3394 drv->auth_ie_len = params->ie_len;
3395 }
3396 }
3397
3398 for (i = 0; i < 4; i++) {
3399 if (params->wep_key[i] && params->wep_key_len[i] &&
3400 params->wep_key_len[i] <= 16) {
3401 os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
3402 params->wep_key_len[i]);
3403 drv->auth_wep_key_len[i] = params->wep_key_len[i];
3404 } else
3405 drv->auth_wep_key_len[i] = 0;
3406 }
3407}
3408
3409
4bd71954
JM
3410static void nl80211_unmask_11b_rates(struct i802_bss *bss)
3411{
3412 struct wpa_driver_nl80211_data *drv = bss->drv;
3413
3414 if (is_p2p_net_interface(drv->nlmode) || !drv->disabled_11b_rates)
3415 return;
3416
3417 /*
3418 * Looks like we failed to unmask 11b rates previously. This could
3419 * happen, e.g., if the interface was down at the point in time when a
3420 * P2P group was terminated.
3421 */
3422 wpa_printf(MSG_DEBUG,
3423 "nl80211: Interface %s mode is for non-P2P, but 11b rates were disabled - re-enable them",
3424 bss->ifname);
3425 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
3426}
3427
3428
3c67e977
VK
3429static enum nl80211_auth_type get_nl_auth_type(int wpa_auth_alg)
3430{
3431 if (wpa_auth_alg & WPA_AUTH_ALG_OPEN)
3432 return NL80211_AUTHTYPE_OPEN_SYSTEM;
3433 if (wpa_auth_alg & WPA_AUTH_ALG_SHARED)
3434 return NL80211_AUTHTYPE_SHARED_KEY;
3435 if (wpa_auth_alg & WPA_AUTH_ALG_LEAP)
3436 return NL80211_AUTHTYPE_NETWORK_EAP;
3437 if (wpa_auth_alg & WPA_AUTH_ALG_FT)
3438 return NL80211_AUTHTYPE_FT;
3439 if (wpa_auth_alg & WPA_AUTH_ALG_SAE)
3440 return NL80211_AUTHTYPE_SAE;
3441 if (wpa_auth_alg & WPA_AUTH_ALG_FILS)
3442 return NL80211_AUTHTYPE_FILS_SK;
3443 if (wpa_auth_alg & WPA_AUTH_ALG_FILS_SK_PFS)
3444 return NL80211_AUTHTYPE_FILS_SK_PFS;
3445
3446 return NL80211_AUTHTYPE_MAX;
3447}
3448
3449
c2a04078 3450static int wpa_driver_nl80211_authenticate(
9ebce9c5 3451 struct i802_bss *bss, struct wpa_driver_auth_params *params)
c2a04078 3452{
a2e40bb6 3453 struct wpa_driver_nl80211_data *drv = bss->drv;
a0b2f99b 3454 int ret = -1, i;
c2a04078
JM
3455 struct nl_msg *msg;
3456 enum nl80211_auth_type type;
2f4f73b1 3457 enum nl80211_iftype nlmode;
6d6f4bb8 3458 int count = 0;
536fd62d
JM
3459 int is_retry;
3460
4bd71954
JM
3461 nl80211_unmask_11b_rates(bss);
3462
536fd62d
JM
3463 is_retry = drv->retry_auth;
3464 drv->retry_auth = 0;
e8d70a73 3465 drv->ignore_deauth_event = 0;
c2a04078 3466
add9b7a4 3467 nl80211_mark_disconnected(drv);
e6b8efeb 3468 os_memset(drv->auth_bssid, 0, ETH_ALEN);
add9b7a4
JM
3469 if (params->bssid)
3470 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
3471 else
3472 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
af473088 3473 /* FIX: IBSS mode */
2f4f73b1
EP
3474 nlmode = params->p2p ?
3475 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
3476 if (drv->nlmode != nlmode &&
9ebce9c5 3477 wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
4a867032
JM
3478 return -1;
3479
6d6f4bb8 3480retry:
c2a04078
JM
3481 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
3482 drv->ifindex);
a0b2f99b 3483
9725b784
JM
3484 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_AUTHENTICATE);
3485 if (!msg)
3486 goto fail;
0194fedb 3487
a0b2f99b
JM
3488 for (i = 0; i < 4; i++) {
3489 if (!params->wep_key[i])
3490 continue;
9ebce9c5 3491 wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
2ea2fcc7 3492 NULL, i,
a0b2f99b
JM
3493 i == params->wep_tx_keyidx, NULL, 0,
3494 params->wep_key[i],
3495 params->wep_key_len[i]);
0194fedb
JB
3496 if (params->wep_tx_keyidx != i)
3497 continue;
3498 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
9725b784
JM
3499 params->wep_key[i], params->wep_key_len[i]))
3500 goto fail;
a0b2f99b
JM
3501 }
3502
c2a04078
JM
3503 if (params->bssid) {
3504 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
3505 MAC2STR(params->bssid));
a862e4a3
JM
3506 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
3507 goto fail;
c2a04078
JM
3508 }
3509 if (params->freq) {
3510 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
a862e4a3
JM
3511 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq))
3512 goto fail;
c2a04078
JM
3513 }
3514 if (params->ssid) {
21cd8f83
JM
3515 wpa_printf(MSG_DEBUG, " * SSID=%s",
3516 wpa_ssid_txt(params->ssid, params->ssid_len));
a862e4a3
JM
3517 if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
3518 params->ssid))
3519 goto fail;
c2a04078
JM
3520 }
3521 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
a862e4a3
JM
3522 if (params->ie &&
3523 nla_put(msg, NL80211_ATTR_IE, params->ie_len, params->ie))
3524 goto fail;
ce16c489
JM
3525 if (params->auth_data) {
3526 wpa_hexdump(MSG_DEBUG, " * auth_data", params->auth_data,
3527 params->auth_data_len);
3528 if (nla_put(msg, NL80211_ATTR_SAE_DATA, params->auth_data_len,
3529 params->auth_data))
a862e4a3 3530 goto fail;
569fed90 3531 }
3c67e977 3532 type = get_nl_auth_type(params->auth_alg);
c2a04078 3533 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
3c67e977
VK
3534 if (type == NL80211_AUTHTYPE_MAX ||
3535 nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
a862e4a3 3536 goto fail;
77339912
JM
3537 if (params->local_state_change) {
3538 wpa_printf(MSG_DEBUG, " * Local state change only");
a862e4a3
JM
3539 if (nla_put_flag(msg, NL80211_ATTR_LOCAL_STATE_CHANGE))
3540 goto fail;
77339912 3541 }
c2a04078
JM
3542
3543 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3544 msg = NULL;
3545 if (ret) {
3b7ea880 3546 wpa_dbg(drv->ctx, MSG_DEBUG,
f875da04
BG
3547 "nl80211: MLME command failed (auth): count=%d ret=%d (%s)",
3548 count, ret, strerror(-ret));
6d6f4bb8 3549 count++;
f875da04
BG
3550 if ((ret == -EALREADY || ret == -EEXIST) && count == 1 &&
3551 params->bssid && !params->local_state_change) {
6d6f4bb8
JM
3552 /*
3553 * mac80211 does not currently accept new
3554 * authentication if we are already authenticated. As a
3555 * workaround, force deauthentication and try again.
3556 */
3557 wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
3558 "after forced deauthentication");
e8d70a73 3559 drv->ignore_deauth_event = 1;
6d6f4bb8 3560 wpa_driver_nl80211_deauthenticate(
5205c4f9 3561 bss, params->bssid,
6d6f4bb8
JM
3562 WLAN_REASON_PREV_AUTH_NOT_VALID);
3563 nlmsg_free(msg);
3564 goto retry;
3565 }
536fd62d
JM
3566
3567 if (ret == -ENOENT && params->freq && !is_retry) {
3568 /*
3569 * cfg80211 has likely expired the BSS entry even
3570 * though it was previously available in our internal
3571 * BSS table. To recover quickly, start a single
3572 * channel scan on the specified channel.
3573 */
3574 struct wpa_driver_scan_params scan;
3575 int freqs[2];
3576
3577 os_memset(&scan, 0, sizeof(scan));
3578 scan.num_ssids = 1;
3579 if (params->ssid) {
3580 scan.ssids[0].ssid = params->ssid;
3581 scan.ssids[0].ssid_len = params->ssid_len;
3582 }
3583 freqs[0] = params->freq;
3584 freqs[1] = 0;
3585 scan.freqs = freqs;
3586 wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
3587 "channel scan to refresh cfg80211 BSS "
3588 "entry");
3589 ret = wpa_driver_nl80211_scan(bss, &scan);
3590 if (ret == 0) {
3591 nl80211_copy_auth_params(drv, params);
3592 drv->scan_for_auth = 1;
3593 }
8c3ba078
JM
3594 } else if (is_retry) {
3595 /*
3596 * Need to indicate this with an event since the return
3597 * value from the retry is not delivered to core code.
3598 */
3599 union wpa_event_data event;
3600 wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
3601 "failed");
3602 os_memset(&event, 0, sizeof(event));
3603 os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
3604 ETH_ALEN);
3605 wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
3606 &event);
536fd62d 3607 }
a862e4a3
JM
3608 } else {
3609 wpa_printf(MSG_DEBUG,
3610 "nl80211: Authentication request send successfully");
c2a04078 3611 }
c2a04078 3612
a862e4a3 3613fail:
c2a04078
JM
3614 nlmsg_free(msg);
3615 return ret;
3616}
3617
3618
f3407c66 3619int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
536fd62d
JM
3620{
3621 struct wpa_driver_auth_params params;
834ee56f 3622 struct i802_bss *bss = drv->first_bss;
536fd62d
JM
3623 int i;
3624
3625 wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
3626
3627 os_memset(&params, 0, sizeof(params));
3628 params.freq = drv->auth_freq;
3629 params.auth_alg = drv->auth_alg;
3630 params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
3631 params.local_state_change = drv->auth_local_state_change;
3632 params.p2p = drv->auth_p2p;
3633
3634 if (!is_zero_ether_addr(drv->auth_bssid_))
3635 params.bssid = drv->auth_bssid_;
3636
3637 if (drv->auth_ssid_len) {
3638 params.ssid = drv->auth_ssid;
3639 params.ssid_len = drv->auth_ssid_len;
3640 }
3641
3642 params.ie = drv->auth_ie;
3643 params.ie_len = drv->auth_ie_len;
3644
3645 for (i = 0; i < 4; i++) {
3646 if (drv->auth_wep_key_len[i]) {
3647 params.wep_key[i] = drv->auth_wep_key[i];
3648 params.wep_key_len[i] = drv->auth_wep_key_len[i];
3649 }
3650 }
3651
3652 drv->retry_auth = 1;
3653 return wpa_driver_nl80211_authenticate(bss, &params);
3654}
3655
3656
a11241fa
JB
3657static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
3658 const void *data, size_t len,
55231068
JM
3659 int encrypt, int noack,
3660 unsigned int freq, int no_cck,
2d3943ce
AO
3661 int offchanok, unsigned int wait_time,
3662 const u16 *csa_offs,
3663 size_t csa_offs_len)
a11241fa
JB
3664{
3665 struct wpa_driver_nl80211_data *drv = bss->drv;
3666 u64 cookie;
41cc50d1 3667 int res;
a11241fa 3668
c7caac56
JM
3669 if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
3670 freq = nl80211_get_assoc_freq(drv);
3671 wpa_printf(MSG_DEBUG,
3672 "nl80211: send_frame - Use assoc_freq=%u for IBSS",
3673 freq);
3674 }
af964484
JM
3675 if (freq == 0) {
3676 wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
3677 bss->freq);
55231068 3678 freq = bss->freq;
af964484 3679 }
55231068 3680
739faee2 3681 if (drv->use_monitor) {
981cf85a 3682 wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
739faee2 3683 freq, bss->freq);
981cf85a 3684 return nl80211_send_monitor(drv, data, len, encrypt, noack);
739faee2 3685 }
a11241fa 3686
739faee2 3687 wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
41cc50d1 3688 res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
2d3943ce
AO
3689 &cookie, no_cck, noack, offchanok,
3690 csa_offs, csa_offs_len);
41cc50d1
JM
3691 if (res == 0 && !noack) {
3692 const struct ieee80211_mgmt *mgmt;
3693 u16 fc;
3694
3695 mgmt = (const struct ieee80211_mgmt *) data;
3696 fc = le_to_host16(mgmt->frame_control);
3697 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3698 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
3699 wpa_printf(MSG_MSGDUMP,
3700 "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
3701 (long long unsigned int)
3702 drv->send_action_cookie,
3703 (long long unsigned int) cookie);
3704 drv->send_action_cookie = cookie;
3705 }
3706 }
3707
3708 return res;
a11241fa
JB
3709}
3710
3711
9ebce9c5
JM
3712static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
3713 size_t data_len, int noack,
3714 unsigned int freq, int no_cck,
3715 int offchanok,
2d3943ce
AO
3716 unsigned int wait_time,
3717 const u16 *csa_offs,
27cc06d0 3718 size_t csa_offs_len, int no_encrypt)
2c2010ac 3719{
a2e40bb6 3720 struct wpa_driver_nl80211_data *drv = bss->drv;
2c2010ac 3721 struct ieee80211_mgmt *mgmt;
27cc06d0 3722 int encrypt = !no_encrypt;
2c2010ac
JM
3723 u16 fc;
3724
3725 mgmt = (struct ieee80211_mgmt *) data;
3726 fc = le_to_host16(mgmt->frame_control);
f95a4524 3727 wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
27cc06d0 3728 " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u no_encrypt=%d fc=0x%x (%s) nlmode=%d",
f95a4524 3729 MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
27cc06d0 3730 no_encrypt, fc, fc2str(fc), drv->nlmode);
2c2010ac 3731
8e12685c
AS
3732 if ((is_sta_interface(drv->nlmode) ||
3733 drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
5582a5d1
JB
3734 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3735 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
3736 /*
3737 * The use of last_mgmt_freq is a bit of a hack,
3738 * but it works due to the single-threaded nature
3739 * of wpa_supplicant.
3740 */
af964484
JM
3741 if (freq == 0) {
3742 wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
3743 drv->last_mgmt_freq);
55231068 3744 freq = drv->last_mgmt_freq;
af964484 3745 }
55231068 3746 return nl80211_send_frame_cmd(bss, freq, 0,
88df0ef7 3747 data, data_len, NULL, 1, noack,
2d3943ce 3748 1, csa_offs, csa_offs_len);
5582a5d1
JB
3749 }
3750
61cbe2ff 3751 if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
af964484
JM
3752 if (freq == 0) {
3753 wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
3754 bss->freq);
55231068 3755 freq = bss->freq;
af964484 3756 }
b5671498
JM
3757 return nl80211_send_frame_cmd(bss, freq,
3758 (int) freq == bss->freq ? 0 :
3759 wait_time,
d8d6b32e
DG
3760 data, data_len,
3761 &drv->send_action_cookie,
2d3943ce
AO
3762 no_cck, noack, offchanok,
3763 csa_offs, csa_offs_len);
86957e62
JM
3764 }
3765
2c2010ac
JM
3766 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3767 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
3768 /*
3769 * Only one of the authentication frame types is encrypted.
3770 * In order for static WEP encryption to work properly (i.e.,
3771 * to not encrypt the frame), we need to tell mac80211 about
3772 * the frames that must not be encrypted.
3773 */
3774 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
3775 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7a47d567
JB
3776 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
3777 encrypt = 0;
2c2010ac
JM
3778 }
3779
739faee2 3780 wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
a11241fa 3781 return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
55231068 3782 noack, freq, no_cck, offchanok,
2d3943ce
AO
3783 wait_time, csa_offs,
3784 csa_offs_len);
55231068
JM
3785}
3786
3787
cae87abd
JM
3788static int nl80211_put_basic_rates(struct nl_msg *msg, const int *basic_rates)
3789{
3790 u8 rates[NL80211_MAX_SUPP_RATES];
3791 u8 rates_len = 0;
3792 int i;
3793
3794 if (!basic_rates)
3795 return 0;
3796
3797 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
3798 rates[rates_len++] = basic_rates[i] / 5;
3799
3800 return nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
3801}
3802
3803
31357268 3804static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
e5693c47 3805 int slot, int ht_opmode, int ap_isolate,
cae87abd 3806 const int *basic_rates)
31357268
JM
3807{
3808 struct wpa_driver_nl80211_data *drv = bss->drv;
3809 struct nl_msg *msg;
3810
13f83980 3811 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_BSS)) ||
a862e4a3
JM
3812 (cts >= 0 &&
3813 nla_put_u8(msg, NL80211_ATTR_BSS_CTS_PROT, cts)) ||
3814 (preamble >= 0 &&
3815 nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble)) ||
3816 (slot >= 0 &&
3817 nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot)) ||
3818 (ht_opmode >= 0 &&
3819 nla_put_u16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode)) ||
3820 (ap_isolate >= 0 &&
cae87abd
JM
3821 nla_put_u8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate)) ||
3822 nl80211_put_basic_rates(msg, basic_rates)) {
3823 nlmsg_free(msg);
3824 return -ENOBUFS;
e5693c47
JM
3825 }
3826
31357268 3827 return send_and_recv_msgs(drv, msg, NULL, NULL);
31357268
JM
3828}
3829
3830
3c4ca363
VN
3831static int wpa_driver_nl80211_set_acl(void *priv,
3832 struct hostapd_acl_params *params)
3833{
3834 struct i802_bss *bss = priv;
3835 struct wpa_driver_nl80211_data *drv = bss->drv;
3836 struct nl_msg *msg;
f429ec44 3837 struct nl_msg *acl;
3c4ca363 3838 unsigned int i;
a862e4a3 3839 int ret;
3c4ca363
VN
3840
3841 if (!(drv->capa.max_acl_mac_addrs))
3842 return -ENOTSUP;
3843
3844 if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
3845 return -ENOTSUP;
3846
3c4ca363
VN
3847 wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
3848 params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
3849
f429ec44
JM
3850 acl = nlmsg_alloc();
3851 if (!acl)
3852 return -ENOMEM;
3853 for (i = 0; i < params->num_mac_acl; i++) {
3854 if (nla_put(acl, i + 1, ETH_ALEN, params->mac_acl[i].addr)) {
3855 nlmsg_free(acl);
3856 return -ENOMEM;
3857 }
3858 }
3859
9725b784 3860 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_MAC_ACL)) ||
a862e4a3
JM
3861 nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
3862 NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
3863 NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) ||
f429ec44 3864 nla_put_nested(msg, NL80211_ATTR_MAC_ADDRS, acl)) {
a862e4a3 3865 nlmsg_free(msg);
f429ec44 3866 nlmsg_free(acl);
a862e4a3
JM
3867 return -ENOMEM;
3868 }
f429ec44 3869 nlmsg_free(acl);
3c4ca363
VN
3870
3871 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3c4ca363
VN
3872 if (ret) {
3873 wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
3874 ret, strerror(-ret));
3875 }
3876
3c4ca363
VN
3877 return ret;
3878}
3879
3880
85e1fad8
JM
3881static int nl80211_put_beacon_int(struct nl_msg *msg, int beacon_int)
3882{
3883 if (beacon_int > 0) {
3884 wpa_printf(MSG_DEBUG, " * beacon_int=%d", beacon_int);
3885 return nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL,
3886 beacon_int);
3887 }
3888
3889 return 0;
3890}
3891
3892
4ac2ea57
MH
3893static int nl80211_put_dtim_period(struct nl_msg *msg, int dtim_period)
3894{
3895 if (dtim_period > 0) {
3896 wpa_printf(MSG_DEBUG, " * dtim_period=%d", dtim_period);
3897 return nla_put_u32(msg, NL80211_ATTR_DTIM_PERIOD, dtim_period);
3898 }
3899
3900 return 0;
3901}
3902
3903
052b8d38
MH
3904#ifdef CONFIG_MESH
3905static int nl80211_set_mesh_config(void *priv,
3906 struct wpa_driver_mesh_bss_params *params)
3907{
3908 struct i802_bss *bss = priv;
3909 struct wpa_driver_nl80211_data *drv = bss->drv;
3910 struct nl_msg *msg;
3911 int ret;
3912
3913 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_MESH_CONFIG);
3914 if (!msg)
3915 return -1;
3916
3917 ret = nl80211_put_mesh_config(msg, params);
3918 if (ret < 0) {
3919 nlmsg_free(msg);
3920 return ret;
3921 }
3922
3923 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3924 if (ret) {
3925 wpa_printf(MSG_ERROR,
3926 "nl80211: Mesh config set failed: %d (%s)",
3927 ret, strerror(-ret));
3928 return ret;
3929 }
3930 return 0;
3931}
3932#endif /* CONFIG_MESH */
3933
3934
d4f3003c
PK
3935static int nl80211_put_beacon_rate(struct nl_msg *msg, const u64 flags,
3936 struct wpa_driver_ap_params *params)
3937{
3938 struct nlattr *bands, *band;
3939 struct nl80211_txrate_vht vht_rate;
3940
3941 if (!params->freq ||
3942 (params->beacon_rate == 0 &&
3943 params->rate_type == BEACON_RATE_LEGACY))
3944 return 0;
3945
3946 bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
3947 if (!bands)
3948 return -1;
3949
3950 switch (params->freq->mode) {
3951 case HOSTAPD_MODE_IEEE80211B:
3952 case HOSTAPD_MODE_IEEE80211G:
3953 band = nla_nest_start(msg, NL80211_BAND_2GHZ);
3954 break;
3955 case HOSTAPD_MODE_IEEE80211A:
3956 band = nla_nest_start(msg, NL80211_BAND_5GHZ);
3957 break;
3958 case HOSTAPD_MODE_IEEE80211AD:
3959 band = nla_nest_start(msg, NL80211_BAND_60GHZ);
3960 break;
3961 default:
3962 return 0;
3963 }
3964
3965 if (!band)
3966 return -1;
3967
3968 os_memset(&vht_rate, 0, sizeof(vht_rate));
3969
3970 switch (params->rate_type) {
3971 case BEACON_RATE_LEGACY:
3972 if (!(flags & WPA_DRIVER_FLAGS_BEACON_RATE_LEGACY)) {
3973 wpa_printf(MSG_INFO,
3974 "nl80211: Driver does not support setting Beacon frame rate (legacy)");
3975 return -1;
3976 }
3977
3978 if (nla_put_u8(msg, NL80211_TXRATE_LEGACY,
3979 (u8) params->beacon_rate / 5) ||
3980 nla_put(msg, NL80211_TXRATE_HT, 0, NULL) ||
3981 (params->freq->vht_enabled &&
3982 nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
3983 &vht_rate)))
3984 return -1;
3985
3986 wpa_printf(MSG_DEBUG, " * beacon_rate = legacy:%u (* 100 kbps)",
3987 params->beacon_rate);
3988 break;
3989 case BEACON_RATE_HT:
3990 if (!(flags & WPA_DRIVER_FLAGS_BEACON_RATE_HT)) {
3991 wpa_printf(MSG_INFO,
3992 "nl80211: Driver does not support setting Beacon frame rate (HT)");
3993 return -1;
3994 }
3995 if (nla_put(msg, NL80211_TXRATE_LEGACY, 0, NULL) ||
3996 nla_put_u8(msg, NL80211_TXRATE_HT, params->beacon_rate) ||
3997 (params->freq->vht_enabled &&
3998 nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
3999 &vht_rate)))
4000 return -1;
4001 wpa_printf(MSG_DEBUG, " * beacon_rate = HT-MCS %u",
4002 params->beacon_rate);
4003 break;
4004 case BEACON_RATE_VHT:
4005 if (!(flags & WPA_DRIVER_FLAGS_BEACON_RATE_VHT)) {
4006 wpa_printf(MSG_INFO,
4007 "nl80211: Driver does not support setting Beacon frame rate (VHT)");
4008 return -1;
4009 }
4010 vht_rate.mcs[0] = BIT(params->beacon_rate);
4011 if (nla_put(msg, NL80211_TXRATE_LEGACY, 0, NULL))
4012 return -1;
4013 if (nla_put(msg, NL80211_TXRATE_HT, 0, NULL))
4014 return -1;
4015 if (nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
4016 &vht_rate))
4017 return -1;
4018 wpa_printf(MSG_DEBUG, " * beacon_rate = VHT-MCS %u",
4019 params->beacon_rate);
4020 break;
4021 }
4022
4023 nla_nest_end(msg, band);
4024 nla_nest_end(msg, bands);
4025
4026 return 0;
4027}
4028
4029
34f7c699
MB
4030static int nl80211_set_multicast_to_unicast(struct i802_bss *bss,
4031 int multicast_to_unicast)
4032{
4033 struct wpa_driver_nl80211_data *drv = bss->drv;
4034 struct nl_msg *msg;
4035 int ret;
4036
4037 msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_MULTICAST_TO_UNICAST);
4038 if (!msg ||
4039 (multicast_to_unicast &&
4040 nla_put_flag(msg, NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED))) {
4041 wpa_printf(MSG_ERROR,
4042 "nl80211: Failed to build NL80211_CMD_SET_MULTICAST_TO_UNICAST msg for %s",
4043 bss->ifname);
4044 nlmsg_free(msg);
4045 return -ENOBUFS;
4046 }
4047
4048 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4049
4050 switch (ret) {
4051 case 0:
4052 wpa_printf(MSG_DEBUG,
4053 "nl80211: multicast to unicast %s on interface %s",
4054 multicast_to_unicast ? "enabled" : "disabled",
4055 bss->ifname);
4056 break;
4057 case -EOPNOTSUPP:
4058 if (!multicast_to_unicast)
4059 break;
4060 wpa_printf(MSG_INFO,
4061 "nl80211: multicast to unicast not supported on interface %s",
4062 bss->ifname);
4063 break;
4064 default:
4065 wpa_printf(MSG_ERROR,
4066 "nl80211: %s multicast to unicast failed with %d (%s) on interface %s",
4067 multicast_to_unicast ? "enabling" : "disabling",
4068 ret, strerror(-ret), bss->ifname);
4069 break;
4070 }
4071
4072 return ret;
4073}
4074
4075
19c3b566
JM
4076static int wpa_driver_nl80211_set_ap(void *priv,
4077 struct wpa_driver_ap_params *params)
d2440ba0 4078{
a2e40bb6
FF
4079 struct i802_bss *bss = priv;
4080 struct wpa_driver_nl80211_data *drv = bss->drv;
d2440ba0
JM
4081 struct nl_msg *msg;
4082 u8 cmd = NL80211_CMD_NEW_BEACON;
5b82cdbe 4083 int ret = -ENOBUFS;
b4fd6fab 4084 int beacon_set;
b11d1d64 4085 int num_suites;
da1080d7 4086 int smps_mode;
de4ed4a8 4087 u32 suites[10], suite;
b11d1d64 4088 u32 ver;
052b8d38
MH
4089#ifdef CONFIG_MESH
4090 struct wpa_driver_mesh_bss_params mesh_params;
4091#endif /* CONFIG_MESH */
b4fd6fab 4092
f33c8606 4093 beacon_set = params->reenable ? 0 : bss->beacon_set;
d2440ba0 4094
d2440ba0 4095 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
b4fd6fab
JM
4096 beacon_set);
4097 if (beacon_set)
d2440ba0 4098 cmd = NL80211_CMD_SET_BEACON;
89fa633a
DL
4099 else if (!drv->device_ap_sme && !drv->use_monitor &&
4100 !nl80211_get_wiphy_data_ap(bss))
a70cd0db 4101 return -ENOBUFS;
d2440ba0 4102
b92e08fc
JM
4103 wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
4104 params->head, params->head_len);
b92e08fc
JM
4105 wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
4106 params->tail, params->tail_len);
13f83980 4107 wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", bss->ifindex);
b92e08fc 4108 wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
d4f3003c
PK
4109 wpa_printf(MSG_DEBUG, "nl80211: beacon_rate=%u", params->beacon_rate);
4110 wpa_printf(MSG_DEBUG, "nl80211: rate_type=%d", params->rate_type);
b92e08fc 4111 wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
21cd8f83
JM
4112 wpa_printf(MSG_DEBUG, "nl80211: ssid=%s",
4113 wpa_ssid_txt(params->ssid, params->ssid_len));
13f83980 4114 if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
a862e4a3
JM
4115 nla_put(msg, NL80211_ATTR_BEACON_HEAD, params->head_len,
4116 params->head) ||
4117 nla_put(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len,
4118 params->tail) ||
85e1fad8 4119 nl80211_put_beacon_int(msg, params->beacon_int) ||
d4f3003c 4120 nl80211_put_beacon_rate(msg, drv->capa.flags, params) ||
4ac2ea57 4121 nl80211_put_dtim_period(msg, params->dtim_period) ||
a862e4a3
JM
4122 nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
4123 goto fail;
b92e08fc
JM
4124 if (params->proberesp && params->proberesp_len) {
4125 wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
4126 params->proberesp, params->proberesp_len);
a862e4a3
JM
4127 if (nla_put(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
4128 params->proberesp))
4129 goto fail;
b92e08fc 4130 }
97a7a0b5
JM
4131 switch (params->hide_ssid) {
4132 case NO_SSID_HIDING:
b92e08fc 4133 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
a862e4a3
JM
4134 if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
4135 NL80211_HIDDEN_SSID_NOT_IN_USE))
4136 goto fail;
97a7a0b5
JM
4137 break;
4138 case HIDDEN_SSID_ZERO_LEN:
b92e08fc 4139 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
a862e4a3
JM
4140 if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
4141 NL80211_HIDDEN_SSID_ZERO_LEN))
4142 goto fail;
97a7a0b5
JM
4143 break;
4144 case HIDDEN_SSID_ZERO_CONTENTS:
b92e08fc 4145 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
a862e4a3
JM
4146 if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
4147 NL80211_HIDDEN_SSID_ZERO_CONTENTS))
4148 goto fail;
97a7a0b5
JM
4149 break;
4150 }
b92e08fc 4151 wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
a862e4a3
JM
4152 if (params->privacy &&
4153 nla_put_flag(msg, NL80211_ATTR_PRIVACY))
4154 goto fail;
b92e08fc 4155 wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
b11d1d64
JM
4156 if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
4157 (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
4158 /* Leave out the attribute */
a862e4a3
JM
4159 } else if (params->auth_algs & WPA_AUTH_ALG_SHARED) {
4160 if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE,
4161 NL80211_AUTHTYPE_SHARED_KEY))
4162 goto fail;
4163 } else {
4164 if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE,
4165 NL80211_AUTHTYPE_OPEN_SYSTEM))
4166 goto fail;
4167 }
b11d1d64 4168
b92e08fc 4169 wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
b11d1d64
JM
4170 ver = 0;
4171 if (params->wpa_version & WPA_PROTO_WPA)
4172 ver |= NL80211_WPA_VERSION_1;
4173 if (params->wpa_version & WPA_PROTO_RSN)
4174 ver |= NL80211_WPA_VERSION_2;
a862e4a3
JM
4175 if (ver &&
4176 nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
4177 goto fail;
b11d1d64 4178
b92e08fc
JM
4179 wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
4180 params->key_mgmt_suites);
b11d1d64
JM
4181 num_suites = 0;
4182 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
3aa24db9 4183 suites[num_suites++] = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
b11d1d64 4184 if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
3aa24db9 4185 suites[num_suites++] = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
a862e4a3
JM
4186 if (num_suites &&
4187 nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32),
4188 suites))
4189 goto fail;
b11d1d64 4190
533fe09b 4191 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
e3429c0b
JB
4192 (!params->pairwise_ciphers ||
4193 params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40)) &&
4194 (nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, ETH_P_PAE) ||
4195 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
a862e4a3 4196 goto fail;
9f12614b 4197
c8931afe
JM
4198 if (drv->device_ap_sme &&
4199 (params->key_mgmt_suites & WPA_KEY_MGMT_SAE) &&
4200 nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT))
4201 goto fail;
236e793e 4202
b92e08fc
JM
4203 wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
4204 params->pairwise_ciphers);
de4ed4a8
JM
4205 num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
4206 suites, ARRAY_SIZE(suites));
a862e4a3
JM
4207 if (num_suites &&
4208 nla_put(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
4209 num_suites * sizeof(u32), suites))
4210 goto fail;
b11d1d64 4211
b92e08fc
JM
4212 wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
4213 params->group_cipher);
de4ed4a8 4214 suite = wpa_cipher_to_cipher_suite(params->group_cipher);
a862e4a3
JM
4215 if (suite &&
4216 nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
4217 goto fail;
d2440ba0 4218
ee298f1b
JM
4219 if (params->ht_opmode != -1) {
4220 switch (params->smps_mode) {
4221 case HT_CAP_INFO_SMPS_DYNAMIC:
4222 wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - dynamic");
4223 smps_mode = NL80211_SMPS_DYNAMIC;
4224 break;
4225 case HT_CAP_INFO_SMPS_STATIC:
4226 wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - static");
4227 smps_mode = NL80211_SMPS_STATIC;
4228 break;
4229 default:
4230 /* invalid - fallback to smps off */
4231 case HT_CAP_INFO_SMPS_DISABLED:
4232 wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - off");
4233 smps_mode = NL80211_SMPS_OFF;
4234 break;
4235 }
a2426829 4236 if (nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, smps_mode))
ee298f1b 4237 goto fail;
da1080d7 4238 }
da1080d7 4239
fb91db56 4240 if (params->beacon_ies) {
b92e08fc
JM
4241 wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
4242 params->beacon_ies);
a862e4a3
JM
4243 if (nla_put(msg, NL80211_ATTR_IE,
4244 wpabuf_len(params->beacon_ies),
4245 wpabuf_head(params->beacon_ies)))
4246 goto fail;
fb91db56
JM
4247 }
4248 if (params->proberesp_ies) {
b92e08fc
JM
4249 wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
4250 params->proberesp_ies);
a862e4a3
JM
4251 if (nla_put(msg, NL80211_ATTR_IE_PROBE_RESP,
4252 wpabuf_len(params->proberesp_ies),
4253 wpabuf_head(params->proberesp_ies)))
4254 goto fail;
fb91db56
JM
4255 }
4256 if (params->assocresp_ies) {
b92e08fc
JM
4257 wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
4258 params->assocresp_ies);
a862e4a3
JM
4259 if (nla_put(msg, NL80211_ATTR_IE_ASSOC_RESP,
4260 wpabuf_len(params->assocresp_ies),
4261 wpabuf_head(params->assocresp_ies)))
4262 goto fail;
fb91db56
JM
4263 }
4264
a0133ee1 4265 if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER) {
b92e08fc
JM
4266 wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
4267 params->ap_max_inactivity);
a862e4a3
JM
4268 if (nla_put_u16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
4269 params->ap_max_inactivity))
4270 goto fail;
a0133ee1
VT
4271 }
4272
abb8d08b
EP
4273#ifdef CONFIG_P2P
4274 if (params->p2p_go_ctwindow > 0) {
4275 if (drv->p2p_go_ctwindow_supported) {
4276 wpa_printf(MSG_DEBUG, "nl80211: P2P GO ctwindow=%d",
4277 params->p2p_go_ctwindow);
4278 if (nla_put_u8(msg, NL80211_ATTR_P2P_CTWINDOW,
4279 params->p2p_go_ctwindow))
4280 goto fail;
4281 } else {
4282 wpa_printf(MSG_INFO,
4283 "nl80211: Driver does not support CTWindow configuration - ignore this parameter");
4284 }
4285 }
4286#endif /* CONFIG_P2P */
4287
86b5c400
LD
4288 if (params->pbss) {
4289 wpa_printf(MSG_DEBUG, "nl80211: PBSS");
4290 if (nla_put_flag(msg, NL80211_ATTR_PBSS))
4291 goto fail;
4292 }
4293
5b82cdbe
JB
4294 if (params->ftm_responder) {
4295 struct nlattr *ftm;
4296
4297 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_FTM_RESPONDER)) {
4298 ret = -ENOTSUP;
4299 goto fail;
4300 }
4301
4302 ftm = nla_nest_start(msg, NL80211_ATTR_FTM_RESPONDER);
4303 if (!ftm ||
4304 nla_put_flag(msg, NL80211_FTM_RESP_ATTR_ENABLED) ||
4305 (params->lci &&
4306 nla_put(msg, NL80211_FTM_RESP_ATTR_LCI,
4307 wpabuf_len(params->lci),
4308 wpabuf_head(params->lci))) ||
4309 (params->civic &&
4310 nla_put(msg, NL80211_FTM_RESP_ATTR_CIVICLOC,
4311 wpabuf_len(params->civic),
4312 wpabuf_head(params->civic))))
4313 goto fail;
4314 nla_nest_end(msg, ftm);
4315 }
4316
a84bf443
JC
4317#ifdef CONFIG_IEEE80211AX
4318 if (params->he_spr) {
4319 struct nlattr *spr;
4320
4321 spr = nla_nest_start(msg, NL80211_ATTR_HE_OBSS_PD);
4322 wpa_printf(MSG_DEBUG, "nl80211: he_spr=%d", params->he_spr);
4323
4324 if (nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET,
4325 params->he_spr_srg_obss_pd_min_offset) ||
4326 nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET,
4327 params->he_spr_srg_obss_pd_max_offset))
4328 goto fail;
4329
4330 nla_nest_end(msg, spr);
4331 }
4332#endif /* CONFIG_IEEE80211AX */
4333
d2440ba0
JM
4334 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4335 if (ret) {
4336 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
4337 ret, strerror(-ret));
b4fd6fab 4338 } else {
b4fd6fab 4339 bss->beacon_set = 1;
31357268 4340 nl80211_set_bss(bss, params->cts_protect, params->preamble,
d03e8d11 4341 params->short_slot_time, params->ht_opmode,
e5693c47 4342 params->isolate, params->basic_rates);
34f7c699
MB
4343 nl80211_set_multicast_to_unicast(bss,
4344 params->multicast_to_unicast);
e87ef751
PX
4345 if (beacon_set && params->freq &&
4346 params->freq->bandwidth != bss->bandwidth) {
4347 wpa_printf(MSG_DEBUG,
4348 "nl80211: Update BSS %s bandwidth: %d -> %d",
4349 bss->ifname, bss->bandwidth,
4350 params->freq->bandwidth);
4351 ret = nl80211_set_channel(bss, params->freq, 1);
4352 if (ret) {
4353 wpa_printf(MSG_DEBUG,
4354 "nl80211: Frequency set failed: %d (%s)",
4355 ret, strerror(-ret));
4356 } else {
4357 wpa_printf(MSG_DEBUG,
4358 "nl80211: Frequency set succeeded for ht2040 coex");
4359 bss->bandwidth = params->freq->bandwidth;
4360 }
f5728d0a 4361 } else if (!beacon_set && params->freq) {
e87ef751
PX
4362 /*
4363 * cfg80211 updates the driver on frequence change in AP
4364 * mode only at the point when beaconing is started, so
4365 * set the initial value here.
4366 */
4367 bss->bandwidth = params->freq->bandwidth;
4368 }
b4fd6fab 4369 }
052b8d38
MH
4370
4371#ifdef CONFIG_MESH
4372 if (is_mesh_interface(drv->nlmode) && params->ht_opmode != -1) {
4373 os_memset(&mesh_params, 0, sizeof(mesh_params));
4374 mesh_params.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
4375 mesh_params.ht_opmode = params->ht_opmode;
4376 ret = nl80211_set_mesh_config(priv, &mesh_params);
4377 if (ret < 0)
4378 return ret;
4379 }
4380#endif /* CONFIG_MESH */
4381
d2440ba0 4382 return ret;
a862e4a3 4383fail:
5883168a 4384 nlmsg_free(msg);
5b82cdbe 4385 return ret;
d2440ba0
JM
4386}
4387
4388
1c4ffa87 4389static int nl80211_put_freq_params(struct nl_msg *msg,
72b2605f 4390 const struct hostapd_freq_params *freq)
1581b38b 4391{
df4f9599
SE
4392 enum hostapd_hw_mode hw_mode;
4393 int is_24ghz;
4394 u8 channel;
4395
1fc4ab23 4396 wpa_printf(MSG_DEBUG, " * freq=%d", freq->freq);
a862e4a3
JM
4397 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq))
4398 return -ENOBUFS;
4399
ad9a1bfe 4400 wpa_printf(MSG_DEBUG, " * he_enabled=%d", freq->he_enabled);
1fc4ab23
JM
4401 wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled);
4402 wpa_printf(MSG_DEBUG, " * ht_enabled=%d", freq->ht_enabled);
4403
df4f9599
SE
4404 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
4405 is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
4406 hw_mode == HOSTAPD_MODE_IEEE80211B;
4407
4408 if (freq->vht_enabled || (freq->he_enabled && !is_24ghz)) {
a862e4a3
JM
4409 enum nl80211_chan_width cw;
4410
1fc4ab23 4411 wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth);
89b800d7
JB
4412 switch (freq->bandwidth) {
4413 case 20:
a862e4a3 4414 cw = NL80211_CHAN_WIDTH_20;
89b800d7
JB
4415 break;
4416 case 40:
a862e4a3 4417 cw = NL80211_CHAN_WIDTH_40;
89b800d7
JB
4418 break;
4419 case 80:
4420 if (freq->center_freq2)
a862e4a3 4421 cw = NL80211_CHAN_WIDTH_80P80;
89b800d7 4422 else
a862e4a3 4423 cw = NL80211_CHAN_WIDTH_80;
89b800d7
JB
4424 break;
4425 case 160:
a862e4a3 4426 cw = NL80211_CHAN_WIDTH_160;
89b800d7
JB
4427 break;
4428 default:
1c4ffa87 4429 return -EINVAL;
89b800d7 4430 }
a862e4a3 4431
1fc4ab23
JM
4432 wpa_printf(MSG_DEBUG, " * channel_width=%d", cw);
4433 wpa_printf(MSG_DEBUG, " * center_freq1=%d",
4434 freq->center_freq1);
4435 wpa_printf(MSG_DEBUG, " * center_freq2=%d",
4436 freq->center_freq2);
a862e4a3
JM
4437 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw) ||
4438 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1,
4439 freq->center_freq1) ||
4440 (freq->center_freq2 &&
4441 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2,
4442 freq->center_freq2)))
4443 return -ENOBUFS;
89b800d7 4444 } else if (freq->ht_enabled) {
a862e4a3
JM
4445 enum nl80211_channel_type ct;
4446
1fc4ab23
JM
4447 wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d",
4448 freq->sec_channel_offset);
89b800d7 4449 switch (freq->sec_channel_offset) {
f019981a 4450 case -1:
a862e4a3 4451 ct = NL80211_CHAN_HT40MINUS;
f019981a
JM
4452 break;
4453 case 1:
a862e4a3 4454 ct = NL80211_CHAN_HT40PLUS;
f019981a
JM
4455 break;
4456 default:
a862e4a3 4457 ct = NL80211_CHAN_HT20;
f019981a
JM
4458 break;
4459 }
a862e4a3 4460
1fc4ab23 4461 wpa_printf(MSG_DEBUG, " * channel_type=%d", ct);
a862e4a3
JM
4462 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ct))
4463 return -ENOBUFS;
dda5d9e3
AAL
4464 } else if (freq->edmg.channels && freq->edmg.bw_config) {
4465 wpa_printf(MSG_DEBUG,
4466 " * EDMG configuration: channels=0x%x bw_config=%d",
4467 freq->edmg.channels, freq->edmg.bw_config);
4468 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_CHANNELS,
4469 freq->edmg.channels) ||
4470 nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
4471 freq->edmg.bw_config))
4472 return -1;
3388e7b9
MH
4473 } else {
4474 wpa_printf(MSG_DEBUG, " * channel_type=%d",
4475 NL80211_CHAN_NO_HT);
4476 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
4477 NL80211_CHAN_NO_HT))
4478 return -ENOBUFS;
f019981a 4479 }
1c4ffa87 4480 return 0;
1c4ffa87
AO
4481}
4482
4483
e87ef751
PX
4484static int nl80211_set_channel(struct i802_bss *bss,
4485 struct hostapd_freq_params *freq, int set_chan)
1c4ffa87
AO
4486{
4487 struct wpa_driver_nl80211_data *drv = bss->drv;
4488 struct nl_msg *msg;
4489 int ret;
4490
4491 wpa_printf(MSG_DEBUG,
ad9a1bfe
JC
4492 "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
4493 freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled,
1c4ffa87 4494 freq->bandwidth, freq->center_freq1, freq->center_freq2);
1c4ffa87 4495
9725b784
JM
4496 msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
4497 NL80211_CMD_SET_WIPHY);
4498 if (!msg || nl80211_put_freq_params(msg, freq) < 0) {
a862e4a3
JM
4499 nlmsg_free(msg);
4500 return -1;
4501 }
1581b38b 4502
d2440ba0 4503 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
e4fb2167 4504 if (ret == 0) {
89b800d7 4505 bss->freq = freq->freq;
1581b38b 4506 return 0;
e4fb2167 4507 }
f019981a 4508 wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
89b800d7 4509 "%d (%s)", freq->freq, ret, strerror(-ret));
1581b38b
JM
4510 return -1;
4511}
4512
0f4e8b4f 4513
95ab6063
AN
4514static u32 sta_flags_nl80211(int flags)
4515{
4516 u32 f = 0;
4517
4518 if (flags & WPA_STA_AUTHORIZED)
4519 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
4520 if (flags & WPA_STA_WMM)
4521 f |= BIT(NL80211_STA_FLAG_WME);
4522 if (flags & WPA_STA_SHORT_PREAMBLE)
4523 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
4524 if (flags & WPA_STA_MFP)
4525 f |= BIT(NL80211_STA_FLAG_MFP);
45b722f1
AN
4526 if (flags & WPA_STA_TDLS_PEER)
4527 f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
7a228b5c
BC
4528 if (flags & WPA_STA_AUTHENTICATED)
4529 f |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
dc55b6b6
AB
4530 if (flags & WPA_STA_ASSOCIATED)
4531 f |= BIT(NL80211_STA_FLAG_ASSOCIATED);
95ab6063
AN
4532
4533 return f;
4534}
4535
4536
7c7e7877
BC
4537#ifdef CONFIG_MESH
4538static u32 sta_plink_state_nl80211(enum mesh_plink_state state)
4539{
4540 switch (state) {
d02e5498 4541 case PLINK_IDLE:
7c7e7877 4542 return NL80211_PLINK_LISTEN;
d02e5498 4543 case PLINK_OPN_SNT:
7c7e7877 4544 return NL80211_PLINK_OPN_SNT;
d02e5498 4545 case PLINK_OPN_RCVD:
7c7e7877
BC
4546 return NL80211_PLINK_OPN_RCVD;
4547 case PLINK_CNF_RCVD:
4548 return NL80211_PLINK_CNF_RCVD;
4549 case PLINK_ESTAB:
4550 return NL80211_PLINK_ESTAB;
4551 case PLINK_HOLDING:
4552 return NL80211_PLINK_HOLDING;
4553 case PLINK_BLOCKED:
4554 return NL80211_PLINK_BLOCKED;
4555 default:
4556 wpa_printf(MSG_ERROR, "nl80211: Invalid mesh plink state %d",
4557 state);
4558 }
4559 return -1;
4560}
4561#endif /* CONFIG_MESH */
4562
4563
62847751 4564static int wpa_driver_nl80211_sta_add(void *priv,
0f4e8b4f
JM
4565 struct hostapd_sta_add_params *params)
4566{
a2e40bb6
FF
4567 struct i802_bss *bss = priv;
4568 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8 4569 struct nl_msg *msg;
95ab6063 4570 struct nl80211_sta_flag_update upd;
0f4e8b4f
JM
4571 int ret = -ENOBUFS;
4572
45b722f1
AN
4573 if ((params->flags & WPA_STA_TDLS_PEER) &&
4574 !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
4575 return -EOPNOTSUPP;
4576
e4dea253
JM
4577 wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
4578 params->set ? "Set" : "Add", MAC2STR(params->addr));
13f83980
JM
4579 msg = nl80211_bss_msg(bss, 0, params->set ? NL80211_CMD_SET_STATION :
4580 NL80211_CMD_NEW_STATION);
4581 if (!msg || nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr))
a862e4a3 4582 goto fail;
5551bc9c 4583
dc55b6b6
AB
4584 /*
4585 * Set the below properties only in one of the following cases:
4586 * 1. New station is added, already associated.
4587 * 2. Set WPA_STA_TDLS_PEER station.
4588 * 3. Set an already added unassociated station, if driver supports
4589 * full AP client state. (Set these properties after station became
4590 * associated will be rejected by the driver).
4591 */
4592 if (!params->set || (params->flags & WPA_STA_TDLS_PEER) ||
4593 (params->set && FULL_AP_CLIENT_STATE_SUPP(drv->capa.flags) &&
4594 (params->flags & WPA_STA_ASSOCIATED))) {
5551bc9c
BC
4595 wpa_hexdump(MSG_DEBUG, " * supported rates",
4596 params->supp_rates, params->supp_rates_len);
a862e4a3
JM
4597 wpa_printf(MSG_DEBUG, " * capability=0x%x",
4598 params->capability);
4599 if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_RATES,
4600 params->supp_rates_len, params->supp_rates) ||
4601 nla_put_u16(msg, NL80211_ATTR_STA_CAPABILITY,
4602 params->capability))
4603 goto fail;
e503861f
JM
4604
4605 if (params->ht_capabilities) {
4606 wpa_hexdump(MSG_DEBUG, " * ht_capabilities",
4607 (u8 *) params->ht_capabilities,
4608 sizeof(*params->ht_capabilities));
a862e4a3
JM
4609 if (nla_put(msg, NL80211_ATTR_HT_CAPABILITY,
4610 sizeof(*params->ht_capabilities),
4611 params->ht_capabilities))
4612 goto fail;
e503861f
JM
4613 }
4614
4615 if (params->vht_capabilities) {
4616 wpa_hexdump(MSG_DEBUG, " * vht_capabilities",
4617 (u8 *) params->vht_capabilities,
4618 sizeof(*params->vht_capabilities));
a862e4a3
JM
4619 if (nla_put(msg, NL80211_ATTR_VHT_CAPABILITY,
4620 sizeof(*params->vht_capabilities),
4621 params->vht_capabilities))
4622 goto fail;
e503861f
JM
4623 }
4624
59d9c3a1
JC
4625 if (params->he_capab) {
4626 wpa_hexdump(MSG_DEBUG, " * he_capab",
4627 params->he_capab, params->he_capab_len);
4628 if (nla_put(msg, NL80211_ATTR_HE_CAPABILITY,
4629 params->he_capab_len, params->he_capab))
4630 goto fail;
4631 }
4632
e503861f
JM
4633 if (params->ext_capab) {
4634 wpa_hexdump(MSG_DEBUG, " * ext_capab",
4635 params->ext_capab, params->ext_capab_len);
a862e4a3
JM
4636 if (nla_put(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
4637 params->ext_capab_len, params->ext_capab))
4638 goto fail;
e503861f 4639 }
ae33239c
AB
4640
4641 if (is_ap_interface(drv->nlmode) &&
4642 nla_put_u8(msg, NL80211_ATTR_STA_SUPPORT_P2P_PS,
4643 params->support_p2p_ps ?
4644 NL80211_P2P_PS_SUPPORTED :
4645 NL80211_P2P_PS_UNSUPPORTED))
4646 goto fail;
5551bc9c 4647 }
45b722f1 4648 if (!params->set) {
f11b72c3
JM
4649 if (params->aid) {
4650 wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
a862e4a3
JM
4651 if (nla_put_u16(msg, NL80211_ATTR_STA_AID, params->aid))
4652 goto fail;
f11b72c3
JM
4653 } else {
4654 /*
4655 * cfg80211 validates that AID is non-zero, so we have
4656 * to make this a non-zero value for the TDLS case where
dc55b6b6
AB
4657 * a dummy STA entry is used for now and for a station
4658 * that is still not associated.
f11b72c3 4659 */
dc55b6b6
AB
4660 wpa_printf(MSG_DEBUG, " * aid=1 (%s workaround)",
4661 (params->flags & WPA_STA_TDLS_PEER) ?
4662 "TDLS" : "UNASSOC_STA");
a862e4a3
JM
4663 if (nla_put_u16(msg, NL80211_ATTR_STA_AID, 1))
4664 goto fail;
f11b72c3 4665 }
e4dea253
JM
4666 wpa_printf(MSG_DEBUG, " * listen_interval=%u",
4667 params->listen_interval);
a862e4a3
JM
4668 if (nla_put_u16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
4669 params->listen_interval))
4670 goto fail;
e112764e
JM
4671 } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
4672 wpa_printf(MSG_DEBUG, " * peer_aid=%u", params->aid);
a862e4a3
JM
4673 if (nla_put_u16(msg, NL80211_ATTR_PEER_AID, params->aid))
4674 goto fail;
dc55b6b6
AB
4675 } else if (FULL_AP_CLIENT_STATE_SUPP(drv->capa.flags) &&
4676 (params->flags & WPA_STA_ASSOCIATED)) {
4677 wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
4678 wpa_printf(MSG_DEBUG, " * listen_interval=%u",
4679 params->listen_interval);
4680 if (nla_put_u16(msg, NL80211_ATTR_STA_AID, params->aid) ||
4681 nla_put_u16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
4682 params->listen_interval))
4683 goto fail;
45b722f1 4684 }
05a8d422 4685
8a458116
MK
4686 if (params->vht_opmode_enabled) {
4687 wpa_printf(MSG_DEBUG, " * opmode=%u", params->vht_opmode);
a862e4a3
JM
4688 if (nla_put_u8(msg, NL80211_ATTR_OPMODE_NOTIF,
4689 params->vht_opmode))
4690 goto fail;
8a458116
MK
4691 }
4692
efc64886
SD
4693 if (params->supp_channels) {
4694 wpa_hexdump(MSG_DEBUG, " * supported channels",
4695 params->supp_channels, params->supp_channels_len);
a862e4a3
JM
4696 if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
4697 params->supp_channels_len, params->supp_channels))
4698 goto fail;
efc64886
SD
4699 }
4700
4701 if (params->supp_oper_classes) {
4702 wpa_hexdump(MSG_DEBUG, " * supported operating classes",
4703 params->supp_oper_classes,
4704 params->supp_oper_classes_len);
a862e4a3
JM
4705 if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
4706 params->supp_oper_classes_len,
4707 params->supp_oper_classes))
4708 goto fail;
efc64886
SD
4709 }
4710
95ab6063 4711 os_memset(&upd, 0, sizeof(upd));
7e31703e
BC
4712 upd.set = sta_flags_nl80211(params->flags);
4713 upd.mask = upd.set | sta_flags_nl80211(params->flags_mask);
dc55b6b6
AB
4714
4715 /*
4716 * If the driver doesn't support full AP client state, ignore ASSOC/AUTH
4717 * flags, as nl80211 driver moves a new station, by default, into
4718 * associated state.
4719 *
4720 * On the other hand, if the driver supports that feature and the
4721 * station is added in unauthenticated state, set the
4722 * authenticated/associated bits in the mask to prevent moving this
4723 * station to associated state before it is actually associated.
4724 *
4725 * This is irrelevant for mesh mode where the station is added to the
4726 * driver as authenticated already, and ASSOCIATED isn't part of the
4727 * nl80211 API.
4728 */
4729 if (!is_mesh_interface(drv->nlmode)) {
4730 if (!FULL_AP_CLIENT_STATE_SUPP(drv->capa.flags)) {
4731 wpa_printf(MSG_DEBUG,
4732 "nl80211: Ignore ASSOC/AUTH flags since driver doesn't support full AP client state");
4733 upd.mask &= ~(BIT(NL80211_STA_FLAG_ASSOCIATED) |
4734 BIT(NL80211_STA_FLAG_AUTHENTICATED));
4735 } else if (!params->set &&
4736 !(params->flags & WPA_STA_TDLS_PEER)) {
4737 if (!(params->flags & WPA_STA_AUTHENTICATED))
4738 upd.mask |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
4739 if (!(params->flags & WPA_STA_ASSOCIATED))
4740 upd.mask |= BIT(NL80211_STA_FLAG_ASSOCIATED);
4741 }
e347cafe
MH
4742#ifdef CONFIG_MESH
4743 } else {
4744 if (params->plink_state == PLINK_ESTAB && params->peer_aid) {
4745 ret = nla_put_u16(msg, NL80211_ATTR_MESH_PEER_AID,
4746 params->peer_aid);
4747 if (ret)
4748 goto fail;
4749 }
4750#endif /* CONFIG_MESH */
dc55b6b6
AB
4751 }
4752
e4dea253
JM
4753 wpa_printf(MSG_DEBUG, " * flags set=0x%x mask=0x%x",
4754 upd.set, upd.mask);
a862e4a3
JM
4755 if (nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd))
4756 goto fail;
95ab6063 4757
7c7e7877 4758#ifdef CONFIG_MESH
a862e4a3
JM
4759 if (params->plink_state &&
4760 nla_put_u8(msg, NL80211_ATTR_STA_PLINK_STATE,
4761 sta_plink_state_nl80211(params->plink_state)))
4762 goto fail;
7c7e7877
BC
4763#endif /* CONFIG_MESH */
4764
968520da
SD
4765 if ((!params->set || (params->flags & WPA_STA_TDLS_PEER) ||
4766 FULL_AP_CLIENT_STATE_SUPP(drv->capa.flags)) &&
4767 (params->flags & WPA_STA_WMM)) {
8970bae8
JB
4768 struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
4769
e4dea253 4770 wpa_printf(MSG_DEBUG, " * qosinfo=0x%x", params->qosinfo);
a862e4a3
JM
4771 if (!wme ||
4772 nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
4773 params->qosinfo & WMM_QOSINFO_STA_AC_MASK) ||
4774 nla_put_u8(msg, NL80211_STA_WME_MAX_SP,
4775 (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
4776 WMM_QOSINFO_STA_SP_MASK))
4777 goto fail;
8970bae8 4778 nla_nest_end(msg, wme);
774bfa62
EP
4779 }
4780
0f4e8b4f 4781 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 4782 msg = NULL;
0f4e8b4f 4783 if (ret)
45b722f1
AN
4784 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
4785 "result: %d (%s)", params->set ? "SET" : "NEW", ret,
4786 strerror(-ret));
0f4e8b4f
JM
4787 if (ret == -EEXIST)
4788 ret = 0;
a862e4a3 4789fail:
5883168a 4790 nlmsg_free(msg);
0f4e8b4f
JM
4791 return ret;
4792}
4793
4794
97ed9a06
KP
4795static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
4796{
4797#ifdef CONFIG_LIBNL3_ROUTE
4798 struct wpa_driver_nl80211_data *drv = bss->drv;
4799 struct rtnl_neigh *rn;
4800 struct nl_addr *nl_addr;
4801 int err;
4802
4803 rn = rtnl_neigh_alloc();
4804 if (!rn)
4805 return;
4806
4807 rtnl_neigh_set_family(rn, AF_BRIDGE);
4808 rtnl_neigh_set_ifindex(rn, bss->ifindex);
4809 nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
4810 if (!nl_addr) {
4811 rtnl_neigh_put(rn);
4812 return;
4813 }
4814 rtnl_neigh_set_lladdr(rn, nl_addr);
4815
4816 err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
4817 if (err < 0) {
4818 wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
4819 MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
4820 bss->ifindex, nl_geterror(err));
4821 } else {
4822 wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry for "
4823 MACSTR, MAC2STR(addr));
4824 }
4825
4826 nl_addr_put(nl_addr);
4827 rtnl_neigh_put(rn);
4828#endif /* CONFIG_LIBNL3_ROUTE */
4829}
4830
4831
59d7148a
JM
4832static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr,
4833 int deauth, u16 reason_code)
0f4e8b4f 4834{
a2e40bb6 4835 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f
JM
4836 struct nl_msg *msg;
4837 int ret;
4838
13f83980 4839 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION)) ||
a862e4a3
JM
4840 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
4841 (deauth == 0 &&
4842 nla_put_u8(msg, NL80211_ATTR_MGMT_SUBTYPE,
4843 WLAN_FC_STYPE_DISASSOC)) ||
4844 (deauth == 1 &&
4845 nla_put_u8(msg, NL80211_ATTR_MGMT_SUBTYPE,
4846 WLAN_FC_STYPE_DEAUTH)) ||
4847 (reason_code &&
4848 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) {
4849 nlmsg_free(msg);
4850 return -ENOBUFS;
4851 }
0f4e8b4f
JM
4852
4853 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
83e7bb0e
JM
4854 wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
4855 " --> %d (%s)",
4856 bss->ifname, MAC2STR(addr), ret, strerror(-ret));
97ed9a06
KP
4857
4858 if (drv->rtnl_sk)
4859 rtnl_neigh_delete_fdb_entry(bss, addr);
4860
0f4e8b4f
JM
4861 if (ret == -ENOENT)
4862 return 0;
4863 return ret;
0f4e8b4f
JM
4864}
4865
1581b38b 4866
f3407c66 4867void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx)
0915d02c
JM
4868{
4869 struct nl_msg *msg;
de884303 4870 struct wpa_driver_nl80211_data *drv2;
0915d02c 4871
c6e8e8e4
JM
4872 wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
4873
2135f224 4874 /* stop listening for EAPOL on this interface */
de884303
JM
4875 dl_list_for_each(drv2, &drv->global->interfaces,
4876 struct wpa_driver_nl80211_data, list)
732b1d20
MB
4877 {
4878 del_ifidx(drv2, ifidx, IFIDX_ANY);
4879 /* Remove all bridges learned for this iface */
4880 del_ifidx(drv2, IFIDX_ANY, ifidx);
4881 }
2135f224 4882
95376e1a 4883 msg = nl80211_ifindex_msg(drv, ifidx, 0, NL80211_CMD_DEL_INTERFACE);
0915d02c
JM
4884 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
4885 return;
e748062b 4886 wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
0915d02c
JM
4887}
4888
4889
cc9a2575 4890const char * nl80211_iftype_str(enum nl80211_iftype mode)
a1922f93
JM
4891{
4892 switch (mode) {
4893 case NL80211_IFTYPE_ADHOC:
4894 return "ADHOC";
4895 case NL80211_IFTYPE_STATION:
4896 return "STATION";
4897 case NL80211_IFTYPE_AP:
4898 return "AP";
1045ec36
JM
4899 case NL80211_IFTYPE_AP_VLAN:
4900 return "AP_VLAN";
4901 case NL80211_IFTYPE_WDS:
4902 return "WDS";
a1922f93
JM
4903 case NL80211_IFTYPE_MONITOR:
4904 return "MONITOR";
1045ec36
JM
4905 case NL80211_IFTYPE_MESH_POINT:
4906 return "MESH_POINT";
a1922f93
JM
4907 case NL80211_IFTYPE_P2P_CLIENT:
4908 return "P2P_CLIENT";
4909 case NL80211_IFTYPE_P2P_GO:
4910 return "P2P_GO";
7aad838c
NS
4911 case NL80211_IFTYPE_P2P_DEVICE:
4912 return "P2P_DEVICE";
a1922f93
JM
4913 default:
4914 return "unknown";
4915 }
4916}
4917
4918
a35187e7
KH
4919static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
4920 const char *ifname,
4921 enum nl80211_iftype iftype,
d6dcfcda
DS
4922 const u8 *addr, int wds,
4923 int (*handler)(struct nl_msg *, void *),
4924 void *arg)
0915d02c 4925{
8970bae8 4926 struct nl_msg *msg;
0915d02c
JM
4927 int ifidx;
4928 int ret = -ENOBUFS;
4929
a1922f93
JM
4930 wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
4931 iftype, nl80211_iftype_str(iftype));
4932
56f77852
JM
4933 msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_NEW_INTERFACE);
4934 if (!msg ||
a862e4a3
JM
4935 nla_put_string(msg, NL80211_ATTR_IFNAME, ifname) ||
4936 nla_put_u32(msg, NL80211_ATTR_IFTYPE, iftype))
4937 goto fail;
0915d02c
JM
4938
4939 if (iftype == NL80211_IFTYPE_MONITOR) {
8970bae8 4940 struct nlattr *flags;
0915d02c 4941
8970bae8 4942 flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
a862e4a3
JM
4943 if (!flags ||
4944 nla_put_flag(msg, NL80211_MNTR_FLAG_COOK_FRAMES))
4945 goto fail;
0915d02c 4946
8970bae8 4947 nla_nest_end(msg, flags);
fbbfcbac 4948 } else if (wds) {
a862e4a3
JM
4949 if (nla_put_u8(msg, NL80211_ATTR_4ADDR, wds))
4950 goto fail;
0915d02c
JM
4951 }
4952
52f5877a
IP
4953 /*
4954 * Tell cfg80211 that the interface belongs to the socket that created
4955 * it, and the interface should be deleted when the socket is closed.
4956 */
a862e4a3
JM
4957 if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
4958 goto fail;
52f5877a 4959
d6dcfcda 4960 ret = send_and_recv_msgs(drv, msg, handler, arg);
5883168a 4961 msg = NULL;
0915d02c 4962 if (ret) {
a862e4a3 4963 fail:
5883168a 4964 nlmsg_free(msg);
a35187e7
KH
4965 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
4966 ifname, ret, strerror(-ret));
0915d02c
JM
4967 return ret;
4968 }
4969
f632e483 4970 if (iftype == NL80211_IFTYPE_P2P_DEVICE)
6bae92e0 4971 return 0;
6bae92e0 4972
0915d02c 4973 ifidx = if_nametoindex(ifname);
c6e8e8e4
JM
4974 wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
4975 ifname, ifidx);
0915d02c
JM
4976
4977 if (ifidx <= 0)
4978 return -1;
4979
147848ec
JM
4980 /*
4981 * Some virtual interfaces need to process EAPOL packets and events on
4982 * the parent interface. This is used mainly with hostapd.
4983 */
4984 if (drv->hostapd ||
4985 iftype == NL80211_IFTYPE_AP_VLAN ||
4986 iftype == NL80211_IFTYPE_WDS ||
4987 iftype == NL80211_IFTYPE_MONITOR) {
4988 /* start listening for EAPOL on this interface */
732b1d20 4989 add_ifidx(drv, ifidx, IFIDX_ANY);
147848ec 4990 }
2135f224 4991
7bfc47c3 4992 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
c81eff1a 4993 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
41d931ee
JM
4994 nl80211_remove_iface(drv, ifidx);
4995 return -1;
2135f224 4996 }
2135f224 4997
0915d02c
JM
4998 return ifidx;
4999}
22a7c9d7
JM
5000
5001
f3407c66
JM
5002int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
5003 const char *ifname, enum nl80211_iftype iftype,
5004 const u8 *addr, int wds,
5005 int (*handler)(struct nl_msg *, void *),
5006 void *arg, int use_existing)
a35187e7
KH
5007{
5008 int ret;
5009
d6dcfcda
DS
5010 ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
5011 arg);
a35187e7 5012
ffbf1eaa 5013 /* if error occurred and interface exists already */
a35187e7 5014 if (ret == -ENFILE && if_nametoindex(ifname)) {
2aec4f3c
JM
5015 if (use_existing) {
5016 wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
5017 ifname);
6997f8ba
JM
5018 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
5019 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
5020 addr) < 0 &&
5021 (linux_set_iface_flags(drv->global->ioctl_sock,
5022 ifname, 0) < 0 ||
5023 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
5024 addr) < 0 ||
5025 linux_set_iface_flags(drv->global->ioctl_sock,
5026 ifname, 1) < 0))
5027 return -1;
2aec4f3c
JM
5028 return -ENFILE;
5029 }
a35187e7
KH
5030 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
5031
5032 /* Try to remove the interface that was already there. */
5033 nl80211_remove_iface(drv, if_nametoindex(ifname));
5034
5035 /* Try to create the interface again */
fbbfcbac 5036 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
d6dcfcda 5037 wds, handler, arg);
a35187e7
KH
5038 }
5039
3e208481
JM
5040 if (ret >= 0 && is_p2p_net_interface(iftype)) {
5041 wpa_printf(MSG_DEBUG,
5042 "nl80211: Interface %s created for P2P - disable 11b rates",
5043 ifname);
4e5cb1a3 5044 nl80211_disable_11b_rates(drv, ret, 1);
3e208481 5045 }
4e5cb1a3 5046
a35187e7
KH
5047 return ret;
5048}
0915d02c 5049
2135f224 5050
3fd1cefb
JB
5051static int nl80211_setup_ap(struct i802_bss *bss)
5052{
5053 struct wpa_driver_nl80211_data *drv = bss->drv;
5054
748c0ac0
JM
5055 wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
5056 bss->ifname, drv->device_ap_sme, drv->use_monitor);
36488c05 5057
a11241fa
JB
5058 /*
5059 * Disable Probe Request reporting unless we need it in this way for
5060 * devices that include the AP SME, in the other case (unless using
5061 * monitor iface) we'll get it through the nl_mgmt socket instead.
5062 */
5063 if (!drv->device_ap_sme)
5064 wpa_driver_nl80211_probe_req_report(bss, 0);
5065
5066 if (!drv->device_ap_sme && !drv->use_monitor)
5067 if (nl80211_mgmt_subscribe_ap(bss))
5068 return -1;
5069
a6cc0602
JM
5070 if (drv->device_ap_sme && !drv->use_monitor)
5071 if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
f4830bed
RM
5072 wpa_printf(MSG_DEBUG,
5073 "nl80211: Failed to subscribe for mgmt frames from SME driver - trying to run without it");
a6cc0602 5074
a11241fa 5075 if (!drv->device_ap_sme && drv->use_monitor &&
ea19b39f
RM
5076 nl80211_create_monitor_interface(drv) &&
5077 !drv->device_ap_sme)
3fd1cefb
JB
5078 return -1;
5079
5080 if (drv->device_ap_sme &&
5081 wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
5082 wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
5083 "Probe Request frame reporting in AP mode");
5084 /* Try to survive without this */
5085 }
5086
5087 return 0;
5088}
5089
5090
5091static void nl80211_teardown_ap(struct i802_bss *bss)
5092{
5093 struct wpa_driver_nl80211_data *drv = bss->drv;
5094
748c0ac0
JM
5095 wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
5096 bss->ifname, drv->device_ap_sme, drv->use_monitor);
a6cc0602 5097 if (drv->device_ap_sme) {
3fd1cefb 5098 wpa_driver_nl80211_probe_req_report(bss, 0);
a6cc0602
JM
5099 if (!drv->use_monitor)
5100 nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
5101 } else if (drv->use_monitor)
3fd1cefb 5102 nl80211_remove_monitor_interface(drv);
a11241fa 5103 else
36488c05 5104 nl80211_mgmt_unsubscribe(bss, "AP teardown");
a11241fa 5105
a70cd0db 5106 nl80211_put_wiphy_data_ap(bss);
3fd1cefb
JB
5107 bss->beacon_set = 0;
5108}
5109
5110
f10bfc9a
JM
5111static int nl80211_send_eapol_data(struct i802_bss *bss,
5112 const u8 *addr, const u8 *data,
d12dab4c 5113 size_t data_len)
f10bfc9a 5114{
d12dab4c
JB
5115 struct sockaddr_ll ll;
5116 int ret;
5117
5118 if (bss->drv->eapol_tx_sock < 0) {
5119 wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
f10bfc9a
JM
5120 return -1;
5121 }
5122
d12dab4c
JB
5123 os_memset(&ll, 0, sizeof(ll));
5124 ll.sll_family = AF_PACKET;
5125 ll.sll_ifindex = bss->ifindex;
5126 ll.sll_protocol = htons(ETH_P_PAE);
5127 ll.sll_halen = ETH_ALEN;
5128 os_memcpy(ll.sll_addr, addr, ETH_ALEN);
5129 ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
5130 (struct sockaddr *) &ll, sizeof(ll));
5131 if (ret < 0)
5132 wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
5133 strerror(errno));
5134
5135 return ret;
f10bfc9a 5136}
5fb1a232 5137
f10bfc9a 5138
db149ac9
JM
5139static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
5140
5141static int wpa_driver_nl80211_hapd_send_eapol(
5142 void *priv, const u8 *addr, const u8 *data,
4378fc14 5143 size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
db149ac9 5144{
a2e40bb6
FF
5145 struct i802_bss *bss = priv;
5146 struct wpa_driver_nl80211_data *drv = bss->drv;
db149ac9
JM
5147 struct ieee80211_hdr *hdr;
5148 size_t len;
5149 u8 *pos;
5150 int res;
4378fc14 5151 int qos = flags & WPA_STA_WMM;
db149ac9 5152
a11241fa 5153 if (drv->device_ap_sme || !drv->use_monitor)
d12dab4c 5154 return nl80211_send_eapol_data(bss, addr, data, data_len);
f10bfc9a 5155
db149ac9
JM
5156 len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
5157 data_len;
5158 hdr = os_zalloc(len);
5159 if (hdr == NULL) {
7ac3616d
JM
5160 wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
5161 (unsigned long) len);
db149ac9
JM
5162 return -1;
5163 }
5164
5165 hdr->frame_control =
5166 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
5167 hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
5168 if (encrypt)
5169 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
db149ac9
JM
5170 if (qos) {
5171 hdr->frame_control |=
5172 host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
5173 }
db149ac9
JM
5174
5175 memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
5176 memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
5177 memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
5178 pos = (u8 *) (hdr + 1);
5179
db149ac9 5180 if (qos) {
92d521d8
FF
5181 /* Set highest priority in QoS header */
5182 pos[0] = 7;
db149ac9
JM
5183 pos[1] = 0;
5184 pos += 2;
5185 }
db149ac9
JM
5186
5187 memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
5188 pos += sizeof(rfc1042_header);
5189 WPA_PUT_BE16(pos, ETH_P_PAE);
5190 pos += 2;
5191 memcpy(pos, data, data_len);
5192
14cc3d10 5193 res = nl80211_send_monitor(drv, hdr, len, encrypt, 0);
db149ac9
JM
5194 if (res < 0) {
5195 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
5196 "failed: %d (%s)",
3ea58a05 5197 (unsigned long) len, res, strerror(res));
db149ac9 5198 }
7bf12757 5199 os_free(hdr);
db149ac9
JM
5200
5201 return res;
5202}
5203
a8d6ffa4 5204
3234cba4 5205static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
f97e3ce4
JM
5206 unsigned int total_flags,
5207 unsigned int flags_or,
5208 unsigned int flags_and)
a8d6ffa4 5209{
a2e40bb6 5210 struct i802_bss *bss = priv;
8970bae8
JB
5211 struct nl_msg *msg;
5212 struct nlattr *flags;
7e76ee9c 5213 struct nl80211_sta_flag_update upd;
a8d6ffa4 5214
0cd9846c
JM
5215 wpa_printf(MSG_DEBUG, "nl80211: Set STA flags - ifname=%s addr=" MACSTR
5216 " total_flags=0x%x flags_or=0x%x flags_and=0x%x authorized=%d",
5217 bss->ifname, MAC2STR(addr), total_flags, flags_or, flags_and,
5218 !!(total_flags & WPA_STA_AUTHORIZED));
5219
13f83980 5220 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
a862e4a3
JM
5221 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
5222 goto fail;
a8d6ffa4 5223
7e76ee9c
JM
5224 /*
5225 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
5226 * can be removed eventually.
5227 */
8970bae8 5228 flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
a862e4a3
JM
5229 if (!flags ||
5230 ((total_flags & WPA_STA_AUTHORIZED) &&
5231 nla_put_flag(msg, NL80211_STA_FLAG_AUTHORIZED)) ||
5232 ((total_flags & WPA_STA_WMM) &&
5233 nla_put_flag(msg, NL80211_STA_FLAG_WME)) ||
5234 ((total_flags & WPA_STA_SHORT_PREAMBLE) &&
5235 nla_put_flag(msg, NL80211_STA_FLAG_SHORT_PREAMBLE)) ||
5236 ((total_flags & WPA_STA_MFP) &&
5237 nla_put_flag(msg, NL80211_STA_FLAG_MFP)) ||
5238 ((total_flags & WPA_STA_TDLS_PEER) &&
5239 nla_put_flag(msg, NL80211_STA_FLAG_TDLS_PEER)))
5240 goto fail;
45b722f1 5241
8970bae8 5242 nla_nest_end(msg, flags);
a8d6ffa4 5243
7e76ee9c
JM
5244 os_memset(&upd, 0, sizeof(upd));
5245 upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
5246 upd.set = sta_flags_nl80211(flags_or);
a862e4a3
JM
5247 if (nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd))
5248 goto fail;
7e76ee9c 5249
13f83980 5250 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
a862e4a3 5251fail:
5883168a 5252 nlmsg_free(msg);
a8d6ffa4
JM
5253 return -ENOBUFS;
5254}
5255
0915d02c 5256
6720b948
THJ
5257static int driver_nl80211_sta_set_airtime_weight(void *priv, const u8 *addr,
5258 unsigned int weight)
5259{
5260 struct i802_bss *bss = priv;
5261 struct nl_msg *msg;
5262
5263 wpa_printf(MSG_DEBUG,
5264 "nl80211: Set STA airtime weight - ifname=%s addr=" MACSTR
5265 " weight=%u", bss->ifname, MAC2STR(addr), weight);
5266
5267 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
5268 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
5269 nla_put_u16(msg, NL80211_ATTR_AIRTIME_WEIGHT, weight))
5270 goto fail;
5271
5272 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
5273fail:
5274 nlmsg_free(msg);
5275 return -ENOBUFS;
5276}
5277
5278
1581b38b
JM
5279static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
5280 struct wpa_driver_associate_params *params)
5281{
708bc8e0 5282 enum nl80211_iftype nlmode, old_mode;
b1f625e0
EP
5283
5284 if (params->p2p) {
046b26a2
JM
5285 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
5286 "group (GO)");
b1f625e0
EP
5287 nlmode = NL80211_IFTYPE_P2P_GO;
5288 } else
5289 nlmode = NL80211_IFTYPE_AP;
5290
708bc8e0 5291 old_mode = drv->nlmode;
834ee56f 5292 if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
708bc8e0
JM
5293 nl80211_remove_monitor_interface(drv);
5294 return -1;
5295 }
5296
6e9023ea
JM
5297 if (params->freq.freq &&
5298 nl80211_set_channel(drv->first_bss, &params->freq, 0)) {
708bc8e0 5299 if (old_mode != nlmode)
834ee56f 5300 wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
460456f8 5301 nl80211_remove_monitor_interface(drv);
1581b38b 5302 return -1;
0915d02c 5303 }
1581b38b 5304
1581b38b
JM
5305 return 0;
5306}
1581b38b
JM
5307
5308
666e508c
JM
5309static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
5310 int reset_mode)
5cc4d64b
JM
5311{
5312 struct nl_msg *msg;
9725b784 5313 int ret;
a862e4a3 5314
9725b784 5315 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_IBSS);
5cc4d64b 5316 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5cc4d64b
JM
5317 if (ret) {
5318 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
5319 "(%s)", ret, strerror(-ret));
9725b784
JM
5320 } else {
5321 wpa_printf(MSG_DEBUG,
5322 "nl80211: Leave IBSS request sent successfully");
5cc4d64b
JM
5323 }
5324
666e508c
JM
5325 if (reset_mode &&
5326 wpa_driver_nl80211_set_mode(drv->first_bss,
5d4c78fb
JM
5327 NL80211_IFTYPE_STATION)) {
5328 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
5329 "station mode");
5330 }
5331
5cc4d64b
JM
5332 return ret;
5333}
5334
5335
95ff3069
JD
5336static int nl80211_ht_vht_overrides(struct nl_msg *msg,
5337 struct wpa_driver_associate_params *params)
5338{
5339 if (params->disable_ht && nla_put_flag(msg, NL80211_ATTR_DISABLE_HT))
5340 return -1;
5341
5342 if (params->htcaps && params->htcaps_mask) {
5343 int sz = sizeof(struct ieee80211_ht_capabilities);
5344 wpa_hexdump(MSG_DEBUG, " * htcaps", params->htcaps, sz);
5345 wpa_hexdump(MSG_DEBUG, " * htcaps_mask",
5346 params->htcaps_mask, sz);
5347 if (nla_put(msg, NL80211_ATTR_HT_CAPABILITY, sz,
5348 params->htcaps) ||
5349 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
5350 params->htcaps_mask))
5351 return -1;
5352 }
5353
5354#ifdef CONFIG_VHT_OVERRIDES
5355 if (params->disable_vht) {
5356 wpa_printf(MSG_DEBUG, " * VHT disabled");
5357 if (nla_put_flag(msg, NL80211_ATTR_DISABLE_VHT))
5358 return -1;
5359 }
5360
5361 if (params->vhtcaps && params->vhtcaps_mask) {
5362 int sz = sizeof(struct ieee80211_vht_capabilities);
5363 wpa_hexdump(MSG_DEBUG, " * vhtcaps", params->vhtcaps, sz);
5364 wpa_hexdump(MSG_DEBUG, " * vhtcaps_mask",
5365 params->vhtcaps_mask, sz);
5366 if (nla_put(msg, NL80211_ATTR_VHT_CAPABILITY, sz,
5367 params->vhtcaps) ||
5368 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
5369 params->vhtcaps_mask))
5370 return -1;
5371 }
5372#endif /* CONFIG_VHT_OVERRIDES */
5373
5374 return 0;
5375}
5376
5377
5cc4d64b
JM
5378static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
5379 struct wpa_driver_associate_params *params)
5380{
5381 struct nl_msg *msg;
5382 int ret = -1;
5383 int count = 0;
5384
5385 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
5386
4ec68377 5387 if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, &params->freq)) {
5cc4d64b
JM
5388 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
5389 "IBSS mode");
5390 return -1;
5391 }
5392
5393retry:
9725b784 5394 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_IBSS)) ||
a862e4a3
JM
5395 params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
5396 goto fail;
5cc4d64b 5397
21cd8f83
JM
5398 wpa_printf(MSG_DEBUG, " * SSID=%s",
5399 wpa_ssid_txt(params->ssid, params->ssid_len));
a862e4a3
JM
5400 if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
5401 goto fail;
5cc4d64b
JM
5402 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
5403 drv->ssid_len = params->ssid_len;
5404
85e1fad8
JM
5405 if (nl80211_put_freq_params(msg, &params->freq) < 0 ||
5406 nl80211_put_beacon_int(msg, params->beacon_int))
a862e4a3 5407 goto fail;
5cc4d64b
JM
5408
5409 ret = nl80211_set_conn_keys(params, msg);
5410 if (ret)
a862e4a3 5411 goto fail;
5cc4d64b 5412
913e3cf7
NC
5413 if (params->bssid && params->fixed_bssid) {
5414 wpa_printf(MSG_DEBUG, " * BSSID=" MACSTR,
5415 MAC2STR(params->bssid));
a862e4a3
JM
5416 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
5417 goto fail;
913e3cf7
NC
5418 }
5419
4d9e6fba
JD
5420 if (params->fixed_freq) {
5421 wpa_printf(MSG_DEBUG, " * fixed_freq");
5422 if (nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED))
5423 goto fail;
5424 }
5425
4848a38d
JM
5426 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
5427 params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
5428 params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
5429 params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
e640888c 5430 wpa_printf(MSG_DEBUG, " * control port");
a862e4a3
JM
5431 if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT))
5432 goto fail;
e640888c
AQ
5433 }
5434
a95795ad
JM
5435 if (params->wpa_ie) {
5436 wpa_hexdump(MSG_DEBUG,
5437 " * Extra IEs for Beacon/Probe Response frames",
5438 params->wpa_ie, params->wpa_ie_len);
a862e4a3
JM
5439 if (nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len,
5440 params->wpa_ie))
5441 goto fail;
a95795ad
JM
5442 }
5443
e15dcf6d
PK
5444 ret = nl80211_ht_vht_overrides(msg, params);
5445 if (ret < 0)
5446 goto fail;
95ff3069 5447
5cc4d64b
JM
5448 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5449 msg = NULL;
5450 if (ret) {
5451 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
5452 ret, strerror(-ret));
5453 count++;
5454 if (ret == -EALREADY && count == 1) {
5455 wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
5456 "forced leave");
666e508c 5457 nl80211_leave_ibss(drv, 0);
5cc4d64b
JM
5458 nlmsg_free(msg);
5459 goto retry;
5460 }
a862e4a3
JM
5461 } else {
5462 wpa_printf(MSG_DEBUG,
5463 "nl80211: Join IBSS request sent successfully");
5cc4d64b 5464 }
5cc4d64b 5465
a862e4a3 5466fail:
5cc4d64b
JM
5467 nlmsg_free(msg);
5468 return ret;
5469}
5470
5471
ad295f3b
VK
5472static int nl80211_put_fils_connect_params(struct wpa_driver_nl80211_data *drv,
5473 struct wpa_driver_associate_params *params,
5474 struct nl_msg *msg)
5475{
5476 if (params->fils_erp_username_len) {
5477 wpa_hexdump_ascii(MSG_DEBUG, " * FILS ERP EMSKname/username",
5478 params->fils_erp_username,
5479 params->fils_erp_username_len);
5480 if (nla_put(msg, NL80211_ATTR_FILS_ERP_USERNAME,
5481 params->fils_erp_username_len,
5482 params->fils_erp_username))
5483 return -1;
5484 }
5485
5486 if (params->fils_erp_realm_len) {
5487 wpa_hexdump_ascii(MSG_DEBUG, " * FILS ERP Realm",
5488 params->fils_erp_realm,
5489 params->fils_erp_realm_len);
5490 if (nla_put(msg, NL80211_ATTR_FILS_ERP_REALM,
5491 params->fils_erp_realm_len, params->fils_erp_realm))
5492 return -1;
5493 }
5494
5495 wpa_printf(MSG_DEBUG, " * FILS ERP next seq %u",
5496 params->fils_erp_next_seq_num);
5497 if (nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
5498 params->fils_erp_next_seq_num))
5499 return -1;
5500
5501 if (params->fils_erp_rrk_len) {
5502 wpa_printf(MSG_DEBUG, " * FILS ERP rRK (len=%lu)",
5503 (unsigned long) params->fils_erp_rrk_len);
5504 if (nla_put(msg, NL80211_ATTR_FILS_ERP_RRK,
5505 params->fils_erp_rrk_len, params->fils_erp_rrk))
5506 return -1;
5507 }
5508
5509 return 0;
5510}
5511
5512
a0bdd191
JM
5513static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
5514 struct wpa_driver_associate_params *params,
5515 struct nl_msg *msg)
cfaab580 5516{
c85dfc6f
JM
5517 if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
5518 return -1;
5519
cfaab580
ZY
5520 if (params->bssid) {
5521 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
5522 MAC2STR(params->bssid));
a862e4a3
JM
5523 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
5524 return -1;
cfaab580 5525 }
a0bdd191 5526
7ac7fd43
DS
5527 if (params->bssid_hint) {
5528 wpa_printf(MSG_DEBUG, " * bssid_hint=" MACSTR,
5529 MAC2STR(params->bssid_hint));
a862e4a3
JM
5530 if (nla_put(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
5531 params->bssid_hint))
5532 return -1;
7ac7fd43
DS
5533 }
5534
4ec68377
JD
5535 if (params->freq.freq) {
5536 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq);
a862e4a3
JM
5537 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
5538 params->freq.freq))
5539 return -1;
4ec68377 5540 drv->assoc_freq = params->freq.freq;
30158a0d
SD
5541 } else
5542 drv->assoc_freq = 0;
a0bdd191 5543
7ac7fd43
DS
5544 if (params->freq_hint) {
5545 wpa_printf(MSG_DEBUG, " * freq_hint=%d", params->freq_hint);
a862e4a3
JM
5546 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
5547 params->freq_hint))
5548 return -1;
7ac7fd43
DS
5549 }
5550
dda5d9e3
AAL
5551 if (params->freq.edmg.channels && params->freq.edmg.bw_config) {
5552 wpa_printf(MSG_DEBUG,
5553 " * EDMG configuration: channels=0x%x bw_config=%d",
5554 params->freq.edmg.channels,
5555 params->freq.edmg.bw_config);
5556 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_CHANNELS,
5557 params->freq.edmg.channels) ||
5558 nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
5559 params->freq.edmg.bw_config))
5560 return -1;
5561 }
5562
1f6c0ab8
BS
5563 if (params->bg_scan_period >= 0) {
5564 wpa_printf(MSG_DEBUG, " * bg scan period=%d",
5565 params->bg_scan_period);
a862e4a3
JM
5566 if (nla_put_u16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
5567 params->bg_scan_period))
5568 return -1;
1f6c0ab8 5569 }
a0bdd191 5570
cfaab580 5571 if (params->ssid) {
21cd8f83
JM
5572 wpa_printf(MSG_DEBUG, " * SSID=%s",
5573 wpa_ssid_txt(params->ssid, params->ssid_len));
a862e4a3
JM
5574 if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
5575 params->ssid))
5576 return -1;
cfaab580 5577 if (params->ssid_len > sizeof(drv->ssid))
a862e4a3 5578 return -1;
cfaab580
ZY
5579 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
5580 drv->ssid_len = params->ssid_len;
5581 }
a0bdd191 5582
cfaab580 5583 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
a862e4a3
JM
5584 if (params->wpa_ie &&
5585 nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len, params->wpa_ie))
5586 return -1;
cfaab580 5587
64fa840a
JM
5588 if (params->wpa_proto) {
5589 enum nl80211_wpa_versions ver = 0;
cfaab580 5590
64fa840a
JM
5591 if (params->wpa_proto & WPA_PROTO_WPA)
5592 ver |= NL80211_WPA_VERSION_1;
5593 if (params->wpa_proto & WPA_PROTO_RSN)
5594 ver |= NL80211_WPA_VERSION_2;
cfaab580 5595
64fa840a 5596 wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
a862e4a3
JM
5597 if (nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
5598 return -1;
cfaab580
ZY
5599 }
5600
4848a38d 5601 if (params->pairwise_suite != WPA_CIPHER_NONE) {
a0bdd191
JM
5602 u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
5603 wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
a862e4a3
JM
5604 if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
5605 cipher))
5606 return -1;
cfaab580
ZY
5607 }
5608
ae6f9272
JM
5609 if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
5610 !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
5611 /*
5612 * This is likely to work even though many drivers do not
5613 * advertise support for operations without GTK.
5614 */
5615 wpa_printf(MSG_DEBUG, " * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
5616 } else if (params->group_suite != WPA_CIPHER_NONE) {
a0bdd191
JM
5617 u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
5618 wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
a862e4a3
JM
5619 if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher))
5620 return -1;
cfaab580
ZY
5621 }
5622
4848a38d
JM
5623 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
5624 params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
5625 params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
5626 params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
163f801e 5627 params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
8802326f
JJ
5628 params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
5629 params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
666497c8 5630 params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
005585d6
AB
5631 params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
5632 params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE ||
5e3b5197 5633 params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
ad295f3b 5634 params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 ||
005585d6 5635 params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X_SHA384 ||
ad295f3b
VK
5636 params->key_mgmt_suite == WPA_KEY_MGMT_FILS_SHA256 ||
5637 params->key_mgmt_suite == WPA_KEY_MGMT_FILS_SHA384 ||
5638 params->key_mgmt_suite == WPA_KEY_MGMT_FT_FILS_SHA256 ||
e005725a
SD
5639 params->key_mgmt_suite == WPA_KEY_MGMT_FT_FILS_SHA384 ||
5640 params->key_mgmt_suite == WPA_KEY_MGMT_OWE ||
5641 params->key_mgmt_suite == WPA_KEY_MGMT_DPP) {
3aa24db9 5642 int mgmt = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
cfaab580
ZY
5643
5644 switch (params->key_mgmt_suite) {
4848a38d 5645 case WPA_KEY_MGMT_CCKM:
3aa24db9 5646 mgmt = RSN_AUTH_KEY_MGMT_CCKM;
369c8d7b 5647 break;
4848a38d 5648 case WPA_KEY_MGMT_IEEE8021X:
3aa24db9 5649 mgmt = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
cfaab580 5650 break;
4848a38d 5651 case WPA_KEY_MGMT_FT_IEEE8021X:
3aa24db9 5652 mgmt = RSN_AUTH_KEY_MGMT_FT_802_1X;
6a1ce395 5653 break;
4848a38d 5654 case WPA_KEY_MGMT_FT_PSK:
3aa24db9 5655 mgmt = RSN_AUTH_KEY_MGMT_FT_PSK;
6a1ce395 5656 break;
8802326f 5657 case WPA_KEY_MGMT_IEEE8021X_SHA256:
3aa24db9 5658 mgmt = RSN_AUTH_KEY_MGMT_802_1X_SHA256;
8802326f
JJ
5659 break;
5660 case WPA_KEY_MGMT_PSK_SHA256:
3aa24db9 5661 mgmt = RSN_AUTH_KEY_MGMT_PSK_SHA256;
8802326f 5662 break;
163f801e 5663 case WPA_KEY_MGMT_OSEN:
3aa24db9 5664 mgmt = RSN_AUTH_KEY_MGMT_OSEN;
163f801e 5665 break;
005585d6
AB
5666 case WPA_KEY_MGMT_SAE:
5667 mgmt = RSN_AUTH_KEY_MGMT_SAE;
5668 break;
5669 case WPA_KEY_MGMT_FT_SAE:
5670 mgmt = RSN_AUTH_KEY_MGMT_FT_SAE;
5671 break;
666497c8 5672 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
3aa24db9 5673 mgmt = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
666497c8 5674 break;
5e3b5197 5675 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
3aa24db9 5676 mgmt = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
5e3b5197 5677 break;
005585d6
AB
5678 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
5679 mgmt = RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384;
5680 break;
ad295f3b
VK
5681 case WPA_KEY_MGMT_FILS_SHA256:
5682 mgmt = RSN_AUTH_KEY_MGMT_FILS_SHA256;
5683 break;
5684 case WPA_KEY_MGMT_FILS_SHA384:
5685 mgmt = RSN_AUTH_KEY_MGMT_FILS_SHA384;
5686 break;
5687 case WPA_KEY_MGMT_FT_FILS_SHA256:
5688 mgmt = RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
5689 break;
5690 case WPA_KEY_MGMT_FT_FILS_SHA384:
5691 mgmt = RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
5692 break;
e005725a
SD
5693 case WPA_KEY_MGMT_OWE:
5694 mgmt = RSN_AUTH_KEY_MGMT_OWE;
5695 break;
5696 case WPA_KEY_MGMT_DPP:
5697 mgmt = RSN_AUTH_KEY_MGMT_DPP;
5698 break;
4848a38d 5699 case WPA_KEY_MGMT_PSK:
cfaab580 5700 default:
3aa24db9 5701 mgmt = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
cfaab580
ZY
5702 break;
5703 }
163f801e 5704 wpa_printf(MSG_DEBUG, " * akm=0x%x", mgmt);
a862e4a3
JM
5705 if (nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, mgmt))
5706 return -1;
cfaab580
ZY
5707 }
5708
cb28bd52 5709 if (params->req_handshake_offload &&
d896874f
AS
5710 (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) {
5711 wpa_printf(MSG_DEBUG, " * WANT_1X_4WAY_HS");
5712 if (nla_put_flag(msg, NL80211_ATTR_WANT_1X_4WAY_HS))
5713 return -1;
5714 }
5715
730c5a1d
EP
5716 /* Add PSK in case of 4-way handshake offload */
5717 if (params->psk &&
436ee2fd 5718 (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK)) {
730c5a1d
EP
5719 wpa_hexdump_key(MSG_DEBUG, " * PSK", params->psk, 32);
5720 if (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk))
5721 return -1;
5722 }
5723
a862e4a3
JM
5724 if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT))
5725 return -1;
a0bdd191 5726
e3429c0b
JB
5727 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
5728 (params->pairwise_suite == WPA_CIPHER_NONE ||
5729 params->pairwise_suite == WPA_CIPHER_WEP104 ||
5730 params->pairwise_suite == WPA_CIPHER_WEP40) &&
5731 (nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, ETH_P_PAE) ||
5732 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
5733 return -1;
5734
58162adf
AK
5735 if (params->rrm_used) {
5736 u32 drv_rrm_flags = drv->capa.rrm_flags;
b5d172e5
BL
5737 if ((!((drv_rrm_flags &
5738 WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) &&
5739 (drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET)) &&
5740 !(drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_RRM)) ||
a862e4a3
JM
5741 nla_put_flag(msg, NL80211_ATTR_USE_RRM))
5742 return -1;
58162adf
AK
5743 }
5744
95ff3069 5745 if (nl80211_ht_vht_overrides(msg, params) < 0)
a862e4a3 5746 return -1;
80e8a5ee 5747
a0bdd191
JM
5748 if (params->p2p)
5749 wpa_printf(MSG_DEBUG, " * P2P group");
5750
86b5c400
LD
5751 if (params->pbss) {
5752 wpa_printf(MSG_DEBUG, " * PBSS");
5753 if (nla_put_flag(msg, NL80211_ATTR_PBSS))
5754 return -1;
5755 }
5756
1126c078 5757 drv->connect_reassoc = 0;
00c3c4ac
JM
5758 if (params->prev_bssid) {
5759 wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
5760 MAC2STR(params->prev_bssid));
5761 if (nla_put(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
5762 params->prev_bssid))
5763 return -1;
1126c078 5764 drv->connect_reassoc = 1;
00c3c4ac
JM
5765 }
5766
ad295f3b
VK
5767 if ((params->auth_alg & WPA_AUTH_ALG_FILS) &&
5768 nl80211_put_fils_connect_params(drv, params, msg) != 0)
5769 return -1;
5770
1317ea2c
SD
5771 if ((params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
5772 params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE) &&
ba71cb82
SD
5773 (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) &&
5774 nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT))
5775 return -1;
5776
a0bdd191 5777 return 0;
a0bdd191
JM
5778}
5779
5780
5781static int wpa_driver_nl80211_try_connect(
5782 struct wpa_driver_nl80211_data *drv,
40a68f33 5783 struct wpa_driver_associate_params *params,
25ebd538 5784 struct nl_sock *nl_connect)
a0bdd191
JM
5785{
5786 struct nl_msg *msg;
5787 enum nl80211_auth_type type;
5788 int ret;
5789 int algs;
5790
b658547d 5791#ifdef CONFIG_DRIVER_NL80211_QCA
b41f2684
CL
5792 if (params->req_key_mgmt_offload && params->psk &&
5793 (params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
5794 params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
5795 params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
5796 wpa_printf(MSG_DEBUG, "nl80211: Key management set PSK");
5797 ret = issue_key_mgmt_set_key(drv, params->psk, 32);
5798 if (ret)
5799 return ret;
5800 }
b658547d 5801#endif /* CONFIG_DRIVER_NL80211_QCA */
b41f2684 5802
9725b784
JM
5803 wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
5804 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT);
a0bdd191
JM
5805 if (!msg)
5806 return -1;
5807
a0bdd191
JM
5808 ret = nl80211_connect_common(drv, params, msg);
5809 if (ret)
a862e4a3 5810 goto fail;
a0bdd191 5811
299d21e8
EG
5812 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED &&
5813 nla_put_u32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED))
5814 goto fail;
5815
5816 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_OPTIONAL &&
5817 (drv->capa.flags & WPA_DRIVER_FLAGS_MFP_OPTIONAL) &&
5818 nla_put_u32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_OPTIONAL))
5819 goto fail;
5820
a0bdd191
JM
5821 algs = 0;
5822 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
5823 algs++;
5824 if (params->auth_alg & WPA_AUTH_ALG_SHARED)
5825 algs++;
5826 if (params->auth_alg & WPA_AUTH_ALG_LEAP)
5827 algs++;
64a0a75b
JM
5828 if (params->auth_alg & WPA_AUTH_ALG_FILS)
5829 algs++;
86c998d3
AM
5830 if (params->auth_alg & WPA_AUTH_ALG_FT)
5831 algs++;
a0bdd191
JM
5832 if (algs > 1) {
5833 wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic "
5834 "selection");
5835 goto skip_auth_type;
5836 }
5837
3c67e977 5838 type = get_nl_auth_type(params->auth_alg);
a0bdd191 5839 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
3c67e977
VK
5840 if (type == NL80211_AUTHTYPE_MAX ||
5841 nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
a862e4a3 5842 goto fail;
a0bdd191
JM
5843
5844skip_auth_type:
cfaab580
ZY
5845 ret = nl80211_set_conn_keys(params, msg);
5846 if (ret)
a862e4a3 5847 goto fail;
cfaab580 5848
40a68f33 5849 if (nl_connect)
0fa33e05
JM
5850 ret = send_and_recv(drv->global, nl_connect, msg,
5851 NULL, (void *) -1);
40a68f33 5852 else
0fa33e05 5853 ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
40a68f33 5854
cfaab580
ZY
5855 msg = NULL;
5856 if (ret) {
5857 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
5858 "(%s)", ret, strerror(-ret));
a862e4a3
JM
5859 } else {
5860 wpa_printf(MSG_DEBUG,
5861 "nl80211: Connect request send successfully");
cfaab580 5862 }
cfaab580 5863
a862e4a3 5864fail:
0fa33e05 5865 nl80211_nlmsg_clear(msg);
cfaab580
ZY
5866 nlmsg_free(msg);
5867 return ret;
5868
5869}
5870
5871
a8c5b43a
CW
5872static int wpa_driver_nl80211_connect(
5873 struct wpa_driver_nl80211_data *drv,
40a68f33 5874 struct wpa_driver_associate_params *params,
25ebd538 5875 struct nl_sock *nl_connect)
a8c5b43a 5876{
0d4e3d1d
JJ
5877 int ret;
5878
5879 /* Store the connection attempted bssid for future use */
5880 if (params->bssid)
5881 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
5882 else
5883 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
5884
40a68f33 5885 ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
a8c5b43a
CW
5886 if (ret == -EALREADY) {
5887 /*
5888 * cfg80211 does not currently accept new connections if
5889 * we are already connected. As a workaround, force
5890 * disconnection and try again.
5891 */
5892 wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
5893 "disconnecting before reassociation "
5894 "attempt");
5895 if (wpa_driver_nl80211_disconnect(
10d32e2c 5896 drv, WLAN_REASON_PREV_AUTH_NOT_VALID, nl_connect))
a8c5b43a 5897 return -1;
40a68f33 5898 ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
a8c5b43a
CW
5899 }
5900 return ret;
5901}
5902
5903
c2a04078
JM
5904static int wpa_driver_nl80211_associate(
5905 void *priv, struct wpa_driver_associate_params *params)
5906{
a2e40bb6
FF
5907 struct i802_bss *bss = priv;
5908 struct wpa_driver_nl80211_data *drv = bss->drv;
a862e4a3 5909 int ret = -1;
c2a04078
JM
5910 struct nl_msg *msg;
5911
4bd71954
JM
5912 nl80211_unmask_11b_rates(bss);
5913
5cc4d64b 5914 if (params->mode == IEEE80211_MODE_AP)
1581b38b 5915 return wpa_driver_nl80211_ap(drv, params);
1581b38b 5916
5cc4d64b
JM
5917 if (params->mode == IEEE80211_MODE_IBSS)
5918 return wpa_driver_nl80211_ibss(drv, params);
5919
4a867032 5920 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
b1f625e0
EP
5921 enum nl80211_iftype nlmode = params->p2p ?
5922 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
25ebd538 5923 struct nl_sock *nl_connect = NULL;
b1f625e0
EP
5924
5925 if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
4a867032 5926 return -1;
1317ea2c
SD
5927 if (params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
5928 params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE) {
40a68f33 5929 nl_connect = bss->nl_connect;
10d32e2c
CI
5930 bss->use_nl_connect = 1;
5931 } else {
5932 bss->use_nl_connect = 0;
5933 }
5934
40a68f33 5935 return wpa_driver_nl80211_connect(drv, params, nl_connect);
4a867032 5936 }
cfaab580 5937
add9b7a4 5938 nl80211_mark_disconnected(drv);
c2a04078 5939
c2a04078
JM
5940 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
5941 drv->ifindex);
9725b784
JM
5942 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_ASSOCIATE);
5943 if (!msg)
5944 return -1;
c2a04078 5945
a0bdd191
JM
5946 ret = nl80211_connect_common(drv, params, msg);
5947 if (ret)
a862e4a3 5948 goto fail;
01652550 5949
299d21e8
EG
5950 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED &&
5951 nla_put_u32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED))
5952 goto fail;
5953
40a45727
JM
5954 if (params->fils_kek) {
5955 wpa_printf(MSG_DEBUG, " * FILS KEK (len=%u)",
5956 (unsigned int) params->fils_kek_len);
5957 if (nla_put(msg, NL80211_ATTR_FILS_KEK, params->fils_kek_len,
5958 params->fils_kek))
5959 goto fail;
5960 }
5961 if (params->fils_nonces) {
5962 wpa_hexdump(MSG_DEBUG, " * FILS nonces (for AAD)",
5963 params->fils_nonces,
5964 params->fils_nonces_len);
5965 if (nla_put(msg, NL80211_ATTR_FILS_NONCES,
5966 params->fils_nonces_len, params->fils_nonces))
5967 goto fail;
5968 }
5969
c2a04078
JM
5970 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5971 msg = NULL;
5972 if (ret) {
3b7ea880
BG
5973 wpa_dbg(drv->ctx, MSG_DEBUG,
5974 "nl80211: MLME command failed (assoc): ret=%d (%s)",
5975 ret, strerror(-ret));
8856462d 5976 nl80211_dump_scan(drv);
a862e4a3
JM
5977 } else {
5978 wpa_printf(MSG_DEBUG,
5979 "nl80211: Association request send successfully");
c2a04078 5980 }
c2a04078 5981
a862e4a3 5982fail:
c2a04078
JM
5983 nlmsg_free(msg);
5984 return ret;
5985}
3f5285e8
JM
5986
5987
ad1e68e6 5988static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
a1922f93 5989 int ifindex, enum nl80211_iftype mode)
3f5285e8 5990{
3f5285e8 5991 struct nl_msg *msg;
ad1e68e6
JM
5992 int ret = -ENOBUFS;
5993
a1922f93
JM
5994 wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
5995 ifindex, mode, nl80211_iftype_str(mode));
5996
56f77852
JM
5997 msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
5998 if (!msg || nla_put_u32(msg, NL80211_ATTR_IFTYPE, mode))
a862e4a3 5999 goto fail;
ad1e68e6
JM
6000
6001 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 6002 msg = NULL;
ad1e68e6
JM
6003 if (!ret)
6004 return 0;
a862e4a3 6005fail:
5883168a 6006 nlmsg_free(msg);
ad1e68e6
JM
6007 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
6008 " %d (%s)", ifindex, mode, ret, strerror(-ret));
6009 return ret;
6010}
6011
6012
3c5d34e3
CW
6013static int wpa_driver_nl80211_set_mode_impl(
6014 struct i802_bss *bss,
6015 enum nl80211_iftype nlmode,
6016 struct hostapd_freq_params *desired_freq_params)
ad1e68e6 6017{
a2e40bb6 6018 struct wpa_driver_nl80211_data *drv = bss->drv;
ad1e68e6 6019 int ret = -1;
26af9dca 6020 int i;
86957e62 6021 int was_ap = is_ap_interface(drv->nlmode);
671a5039 6022 int res;
ebffdbc4 6023 int mode_switch_res;
1581b38b 6024
a5a187b0
JM
6025 if (TEST_FAIL())
6026 return -1;
6027
ebffdbc4
CW
6028 mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
6029 if (mode_switch_res && nlmode == nl80211_get_ifmode(bss))
6030 mode_switch_res = 0;
8e12685c 6031
ebffdbc4 6032 if (mode_switch_res == 0) {
ad1e68e6 6033 drv->nlmode = nlmode;
460456f8
JM
6034 ret = 0;
6035 goto done;
ad1e68e6 6036 }
3f5285e8 6037
ebffdbc4 6038 if (mode_switch_res == -ENODEV)
671a5039
JM
6039 return -1;
6040
460456f8 6041 if (nlmode == drv->nlmode) {
c6e8e8e4
JM
6042 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
6043 "requested mode - ignore error");
460456f8
JM
6044 ret = 0;
6045 goto done; /* Already in the requested mode */
6046 }
3f5285e8 6047
3f5285e8
JM
6048 /* mac80211 doesn't allow mode changes while the device is up, so
6049 * take the device down, try to set the mode again, and bring the
6050 * device back up.
6051 */
26af9dca
JM
6052 wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
6053 "interface down");
6054 for (i = 0; i < 10; i++) {
91724d6f 6055 res = i802_set_iface_flags(bss, 0);
6e8183d7
JM
6056 if (res == -EACCES || res == -ENODEV)
6057 break;
ebffdbc4 6058 if (res != 0) {
26af9dca
JM
6059 wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
6060 "interface down");
ebffdbc4
CW
6061 os_sleep(0, 100000);
6062 continue;
6063 }
3c5d34e3
CW
6064
6065 /*
6066 * Setting the mode will fail for some drivers if the phy is
6067 * on a frequency that the mode is disallowed in.
6068 */
6069 if (desired_freq_params) {
bdf5ccb2 6070 res = nl80211_set_channel(bss, desired_freq_params, 0);
3c5d34e3
CW
6071 if (res) {
6072 wpa_printf(MSG_DEBUG,
6073 "nl80211: Failed to set frequency on interface");
6074 }
6075 }
6076
ebffdbc4
CW
6077 /* Try to set the mode again while the interface is down */
6078 mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
6079 if (mode_switch_res == -EBUSY) {
6080 wpa_printf(MSG_DEBUG,
6081 "nl80211: Delaying mode set while interface going down");
6082 os_sleep(0, 100000);
6083 continue;
6084 }
6085 ret = mode_switch_res;
6086 break;
3f5285e8
JM
6087 }
6088
c6e8e8e4
JM
6089 if (!ret) {
6090 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
6091 "interface is down");
ad1e68e6 6092 drv->nlmode = nlmode;
7d9c3698 6093 drv->ignore_if_down_event = 1;
c6e8e8e4 6094 }
ad1e68e6 6095
ebffdbc4
CW
6096 /* Bring the interface back up */
6097 res = linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
6098 if (res != 0) {
6099 wpa_printf(MSG_DEBUG,
6100 "nl80211: Failed to set interface up after switching mode");
6101 ret = -1;
6102 }
6103
460456f8 6104done:
3fd1cefb
JB
6105 if (ret) {
6106 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
6107 "from %d failed", nlmode, drv->nlmode);
6108 return ret;
6109 }
6110
3e208481
JM
6111 if (is_p2p_net_interface(nlmode)) {
6112 wpa_printf(MSG_DEBUG,
6113 "nl80211: Interface %s mode change to P2P - disable 11b rates",
6114 bss->ifname);
edb9bfba 6115 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
3e208481
JM
6116 } else if (drv->disabled_11b_rates) {
6117 wpa_printf(MSG_DEBUG,
6118 "nl80211: Interface %s mode changed to non-P2P - re-enable 11b rates",
6119 bss->ifname);
1d0c6fb1 6120 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
3e208481 6121 }
edb9bfba 6122
3fd1cefb 6123 if (is_ap_interface(nlmode)) {
36488c05 6124 nl80211_mgmt_unsubscribe(bss, "start AP");
460456f8 6125 /* Setup additional AP mode functionality if needed */
3fd1cefb 6126 if (nl80211_setup_ap(bss))
460456f8 6127 return -1;
3fd1cefb 6128 } else if (was_ap) {
460456f8 6129 /* Remove additional AP mode functionality */
3fd1cefb 6130 nl80211_teardown_ap(bss);
a11241fa 6131 } else {
36488c05 6132 nl80211_mgmt_unsubscribe(bss, "mode change");
460456f8 6133 }
460456f8 6134
afb0550a
BC
6135 if (is_mesh_interface(nlmode) &&
6136 nl80211_mgmt_subscribe_mesh(bss))
6137 return -1;
6138
873d0fcf 6139 if (!bss->in_deinit && !is_ap_interface(nlmode) &&
afb0550a 6140 !is_mesh_interface(nlmode) &&
a11241fa
JB
6141 nl80211_mgmt_subscribe_non_ap(bss) < 0)
6142 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
6143 "frame processing - ignore for now");
08359050 6144
3fd1cefb 6145 return 0;
3f5285e8
JM
6146}
6147
6148
f3407c66
JM
6149int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
6150 enum nl80211_iftype nlmode)
3c5d34e3
CW
6151{
6152 return wpa_driver_nl80211_set_mode_impl(bss, nlmode, NULL);
6153}
6154
6155
4ec68377
JD
6156static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
6157 struct hostapd_freq_params *freq)
3c5d34e3 6158{
3c5d34e3 6159 return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
4ec68377 6160 freq);
3c5d34e3 6161}
65d645ce
AS
6162
6163
3f5285e8
JM
6164static int wpa_driver_nl80211_get_capa(void *priv,
6165 struct wpa_driver_capa *capa)
6166{
a2e40bb6
FF
6167 struct i802_bss *bss = priv;
6168 struct wpa_driver_nl80211_data *drv = bss->drv;
65d645ce 6169
3f5285e8
JM
6170 if (!drv->has_capability)
6171 return -1;
6172 os_memcpy(capa, &drv->capa, sizeof(*capa));
8cd6b7bc
JB
6173 if (drv->extended_capa && drv->extended_capa_mask) {
6174 capa->extended_capa = drv->extended_capa;
6175 capa->extended_capa_mask = drv->extended_capa_mask;
6176 capa->extended_capa_len = drv->extended_capa_len;
6177 }
851b0c55 6178
906bc4c7 6179 return 0;
3f5285e8
JM
6180}
6181
6182
6183static int wpa_driver_nl80211_set_operstate(void *priv, int state)
6184{
a2e40bb6
FF
6185 struct i802_bss *bss = priv;
6186 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 6187
90a545cc
JM
6188 wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
6189 bss->ifname, drv->operstate, state,
6190 state ? "UP" : "DORMANT");
3f5285e8 6191 drv->operstate = state;
36d84860 6192 return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
e2d02c29 6193 state ? IF_OPER_UP : IF_OPER_DORMANT);
3f5285e8
JM
6194}
6195
01652550
JM
6196
6197static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
6198{
a2e40bb6
FF
6199 struct i802_bss *bss = priv;
6200 struct wpa_driver_nl80211_data *drv = bss->drv;
01652550
JM
6201 struct nl_msg *msg;
6202 struct nl80211_sta_flag_update upd;
a862e4a3 6203 int ret;
2eef5177
JM
6204
6205 if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
6206 wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
6207 return 0;
6208 }
01652550 6209
1ba51ec0
JM
6210 wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
6211 MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
6212
01652550
JM
6213 os_memset(&upd, 0, sizeof(upd));
6214 upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
6215 if (authorized)
6216 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
a862e4a3 6217
13f83980 6218 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
a862e4a3
JM
6219 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid) ||
6220 nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd)) {
6221 nlmsg_free(msg);
6222 return -ENOBUFS;
6223 }
01652550 6224
2eef5177 6225 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2eef5177
JM
6226 if (!ret)
6227 return 0;
2eef5177
JM
6228 wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
6229 ret, strerror(-ret));
6230 return ret;
01652550
JM
6231}
6232
3f5285e8 6233
f07ead6a
JM
6234/* Set kernel driver on given frequency (MHz) */
6235static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
c5121837 6236{
f07ead6a 6237 struct i802_bss *bss = priv;
13a524a3 6238 return nl80211_set_channel(bss, freq, 0);
c5121837
JM
6239}
6240
f7b3920c 6241
c5121837
JM
6242static inline int min_int(int a, int b)
6243{
6244 if (a < b)
6245 return a;
6246 return b;
6247}
6248
6249
6250static int get_key_handler(struct nl_msg *msg, void *arg)
6251{
6252 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6253 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6254
6255 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6256 genlmsg_attrlen(gnlh, 0), NULL);
6257
6258 /*
6259 * TODO: validate the key index and mac address!
6260 * Otherwise, there's a race condition as soon as
6261 * the kernel starts sending key notifications.
6262 */
6263
6264 if (tb[NL80211_ATTR_KEY_SEQ])
6265 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
6266 min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
4efade31 6267 nl80211_nlmsg_clear(msg);
c5121837
JM
6268 return NL_SKIP;
6269}
6270
6271
6272static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
6273 int idx, u8 *seq)
6274{
a2e40bb6
FF
6275 struct i802_bss *bss = priv;
6276 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6277 struct nl_msg *msg;
6278
95376e1a
JM
6279 msg = nl80211_ifindex_msg(drv, if_nametoindex(iface), 0,
6280 NL80211_CMD_GET_KEY);
6281 if (!msg ||
a862e4a3 6282 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
95376e1a 6283 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, idx)) {
a862e4a3
JM
6284 nlmsg_free(msg);
6285 return -ENOBUFS;
6286 }
c5121837
JM
6287
6288 memset(seq, 0, 6);
6289
6290 return send_and_recv_msgs(drv, msg, get_key_handler, seq);
c5121837
JM
6291}
6292
6293
c5121837
JM
6294static int i802_set_rts(void *priv, int rts)
6295{
a2e40bb6
FF
6296 struct i802_bss *bss = priv;
6297 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451 6298 struct nl_msg *msg;
a862e4a3 6299 int ret;
ad649451 6300 u32 val;
c5121837 6301
bf0021ed 6302 if (rts >= 2347 || rts == -1)
ad649451
JM
6303 val = (u32) -1;
6304 else
6305 val = rts;
c5121837 6306
9725b784 6307 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
a862e4a3
JM
6308 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6309 nlmsg_free(msg);
6310 return -ENOBUFS;
6311 }
ad649451
JM
6312
6313 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6314 if (!ret)
6315 return 0;
ad649451
JM
6316 wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
6317 "%d (%s)", rts, ret, strerror(-ret));
6318 return ret;
c5121837
JM
6319}
6320
6321
6322static int i802_set_frag(void *priv, int frag)
6323{
a2e40bb6
FF
6324 struct i802_bss *bss = priv;
6325 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451 6326 struct nl_msg *msg;
a862e4a3 6327 int ret;
ad649451 6328 u32 val;
c5121837 6329
bf0021ed 6330 if (frag >= 2346 || frag == -1)
ad649451
JM
6331 val = (u32) -1;
6332 else
6333 val = frag;
c5121837 6334
9725b784 6335 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
a862e4a3
JM
6336 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val)) {
6337 nlmsg_free(msg);
6338 return -ENOBUFS;
6339 }
ad649451
JM
6340
6341 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6342 if (!ret)
6343 return 0;
ad649451
JM
6344 wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
6345 "%d: %d (%s)", frag, ret, strerror(-ret));
6346 return ret;
c5121837
JM
6347}
6348
6349
c5121837
JM
6350static int i802_flush(void *priv)
6351{
a2e40bb6 6352 struct i802_bss *bss = priv;
c5121837 6353 struct nl_msg *msg;
82554b10 6354 int res;
c5121837 6355
83e7bb0e
JM
6356 wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
6357 bss->ifname);
c5121837
JM
6358
6359 /*
6360 * XXX: FIX! this needs to flush all VLANs too
6361 */
13f83980
JM
6362 msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION);
6363 res = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
82554b10
JM
6364 if (res) {
6365 wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
6366 "(%s)", res, strerror(-res));
6367 }
6368 return res;
c5121837
JM
6369}
6370
6371
1d6f6385
THJ
6372static void get_sta_tid_stats(struct hostap_sta_driver_data *data,
6373 struct nlattr *attr)
6374{
6375 struct nlattr *tid_stats[NL80211_TID_STATS_MAX + 1], *tidattr;
6376 struct nlattr *txq_stats[NL80211_TXQ_STATS_MAX + 1];
6377 static struct nla_policy txq_stats_policy[NL80211_TXQ_STATS_MAX + 1] = {
6378 [NL80211_TXQ_STATS_BACKLOG_BYTES] = { .type = NLA_U32 },
6379 [NL80211_TXQ_STATS_BACKLOG_PACKETS] = { .type = NLA_U32 },
6380 };
6381 int rem;
6382
6383 nla_for_each_nested(tidattr, attr, rem) {
6384 if (nla_parse_nested(tid_stats, NL80211_TID_STATS_MAX,
6385 tidattr, NULL) != 0 ||
6386 !tid_stats[NL80211_TID_STATS_TXQ_STATS] ||
6387 nla_parse_nested(txq_stats, NL80211_TXQ_STATS_MAX,
6388 tid_stats[NL80211_TID_STATS_TXQ_STATS],
6389 txq_stats_policy) != 0)
6390 continue;
6391 /* sum the backlogs over all TIDs for station */
6392 if (txq_stats[NL80211_TXQ_STATS_BACKLOG_BYTES])
6393 data->backlog_bytes += nla_get_u32(
6394 txq_stats[NL80211_TXQ_STATS_BACKLOG_BYTES]);
6395 if (txq_stats[NL80211_TXQ_STATS_BACKLOG_PACKETS])
6396 data->backlog_bytes += nla_get_u32(
6397 txq_stats[NL80211_TXQ_STATS_BACKLOG_PACKETS]);
6398 }
6399}
6400
6401
c5121837
JM
6402static int get_sta_handler(struct nl_msg *msg, void *arg)
6403{
6404 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6405 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6406 struct hostap_sta_driver_data *data = arg;
6407 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
6408 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
6409 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
6410 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
6411 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
6412 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
6413 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
dc7785f8 6414 [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
43022abd
NL
6415 [NL80211_STA_INFO_RX_BYTES64] = { .type = NLA_U64 },
6416 [NL80211_STA_INFO_TX_BYTES64] = { .type = NLA_U64 },
3567641e 6417 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
72123a84 6418 [NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 },
58d4c236
THJ
6419 [NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 },
6420 [NL80211_STA_INFO_TX_DURATION] = { .type = NLA_U64 },
3567641e 6421 };
6422 struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
6423 static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
6424 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
6425 [NL80211_RATE_INFO_BITRATE32] = { .type = NLA_U32 },
6426 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
6427 [NL80211_RATE_INFO_VHT_MCS] = { .type = NLA_U8 },
6428 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
6429 [NL80211_RATE_INFO_VHT_NSS] = { .type = NLA_U8 },
c5121837
JM
6430 };
6431
6432 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6433 genlmsg_attrlen(gnlh, 0), NULL);
6434
6435 /*
6436 * TODO: validate the interface and mac address!
6437 * Otherwise, there's a race condition as soon as
6438 * the kernel starts sending station notifications.
6439 */
6440
6441 if (!tb[NL80211_ATTR_STA_INFO]) {
6442 wpa_printf(MSG_DEBUG, "sta stats missing!");
6443 return NL_SKIP;
6444 }
6445 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
6446 tb[NL80211_ATTR_STA_INFO],
6447 stats_policy)) {
6448 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
6449 return NL_SKIP;
6450 }
6451
6452 if (stats[NL80211_STA_INFO_INACTIVE_TIME])
6453 data->inactive_msec =
6454 nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
43022abd 6455 /* For backwards compatibility, fetch the 32-bit counters first. */
c5121837
JM
6456 if (stats[NL80211_STA_INFO_RX_BYTES])
6457 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
6458 if (stats[NL80211_STA_INFO_TX_BYTES])
6459 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
43022abd
NL
6460 if (stats[NL80211_STA_INFO_RX_BYTES64] &&
6461 stats[NL80211_STA_INFO_TX_BYTES64]) {
6462 /*
6463 * The driver supports 64-bit counters, so use them to override
6464 * the 32-bit values.
6465 */
6466 data->rx_bytes =
6467 nla_get_u64(stats[NL80211_STA_INFO_RX_BYTES64]);
6468 data->tx_bytes =
6469 nla_get_u64(stats[NL80211_STA_INFO_TX_BYTES64]);
6470 data->bytes_64bit = 1;
6471 }
c5121837
JM
6472 if (stats[NL80211_STA_INFO_RX_PACKETS])
6473 data->rx_packets =
6474 nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
6475 if (stats[NL80211_STA_INFO_TX_PACKETS])
6476 data->tx_packets =
6477 nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
58d4c236
THJ
6478 if (stats[NL80211_STA_INFO_RX_DURATION])
6479 data->rx_airtime =
6480 nla_get_u64(stats[NL80211_STA_INFO_RX_DURATION]);
6481 if (stats[NL80211_STA_INFO_TX_DURATION])
6482 data->tx_airtime =
6483 nla_get_u64(stats[NL80211_STA_INFO_TX_DURATION]);
dc7785f8
YZ
6484 if (stats[NL80211_STA_INFO_TX_FAILED])
6485 data->tx_retry_failed =
6486 nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
3567641e 6487 if (stats[NL80211_STA_INFO_SIGNAL])
6488 data->signal = nla_get_u8(stats[NL80211_STA_INFO_SIGNAL]);
72123a84
BP
6489 if (stats[NL80211_STA_INFO_ACK_SIGNAL]) {
6490 data->last_ack_rssi =
6491 nla_get_u8(stats[NL80211_STA_INFO_ACK_SIGNAL]);
6492 data->flags |= STA_DRV_DATA_LAST_ACK_RSSI;
6493 }
3567641e 6494
6495 if (stats[NL80211_STA_INFO_TX_BITRATE] &&
6496 nla_parse_nested(rate, NL80211_RATE_INFO_MAX,
6497 stats[NL80211_STA_INFO_TX_BITRATE],
6498 rate_policy) == 0) {
6499 if (rate[NL80211_RATE_INFO_BITRATE32])
6500 data->current_tx_rate =
6501 nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
6502 else if (rate[NL80211_RATE_INFO_BITRATE])
6503 data->current_tx_rate =
6504 nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
6505
6506 if (rate[NL80211_RATE_INFO_MCS]) {
6507 data->tx_mcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
6508 data->flags |= STA_DRV_DATA_TX_MCS;
6509 }
6510 if (rate[NL80211_RATE_INFO_VHT_MCS]) {
6511 data->tx_vhtmcs =
6512 nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
6513 data->flags |= STA_DRV_DATA_TX_VHT_MCS;
6514 }
6515 if (rate[NL80211_RATE_INFO_SHORT_GI])
6516 data->flags |= STA_DRV_DATA_TX_SHORT_GI;
6517 if (rate[NL80211_RATE_INFO_VHT_NSS]) {
6518 data->tx_vht_nss =
6519 nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
6520 data->flags |= STA_DRV_DATA_TX_VHT_NSS;
6521 }
6522 }
6523
6524 if (stats[NL80211_STA_INFO_RX_BITRATE] &&
6525 nla_parse_nested(rate, NL80211_RATE_INFO_MAX,
6526 stats[NL80211_STA_INFO_RX_BITRATE],
6527 rate_policy) == 0) {
6528 if (rate[NL80211_RATE_INFO_BITRATE32])
6529 data->current_rx_rate =
6530 nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
6531 else if (rate[NL80211_RATE_INFO_BITRATE])
6532 data->current_rx_rate =
6533 nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
6534
6535 if (rate[NL80211_RATE_INFO_MCS]) {
6536 data->rx_mcs =
6537 nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
6538 data->flags |= STA_DRV_DATA_RX_MCS;
6539 }
6540 if (rate[NL80211_RATE_INFO_VHT_MCS]) {
6541 data->rx_vhtmcs =
6542 nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
6543 data->flags |= STA_DRV_DATA_RX_VHT_MCS;
6544 }
6545 if (rate[NL80211_RATE_INFO_SHORT_GI])
6546 data->flags |= STA_DRV_DATA_RX_SHORT_GI;
6547 if (rate[NL80211_RATE_INFO_VHT_NSS]) {
6548 data->rx_vht_nss =
6549 nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
6550 data->flags |= STA_DRV_DATA_RX_VHT_NSS;
6551 }
6552 }
c5121837 6553
1d6f6385
THJ
6554 if (stats[NL80211_STA_INFO_TID_STATS])
6555 get_sta_tid_stats(data, stats[NL80211_STA_INFO_TID_STATS]);
6556
c5121837
JM
6557 return NL_SKIP;
6558}
6559
9ebce9c5
JM
6560static int i802_read_sta_data(struct i802_bss *bss,
6561 struct hostap_sta_driver_data *data,
c5121837
JM
6562 const u8 *addr)
6563{
c5121837
JM
6564 struct nl_msg *msg;
6565
13f83980
JM
6566 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_GET_STATION)) ||
6567 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
a862e4a3
JM
6568 nlmsg_free(msg);
6569 return -ENOBUFS;
6570 }
c5121837 6571
13f83980 6572 return send_and_recv_msgs(bss->drv, msg, get_sta_handler, data);
c5121837
JM
6573}
6574
6575
c5121837
JM
6576static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
6577 int cw_min, int cw_max, int burst_time)
6578{
a2e40bb6
FF
6579 struct i802_bss *bss = priv;
6580 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6581 struct nl_msg *msg;
6582 struct nlattr *txq, *params;
bd512469 6583 int res;
c5121837 6584
13f83980 6585 msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_WIPHY);
c5121837
JM
6586 if (!msg)
6587 return -1;
6588
c5121837
JM
6589 txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
6590 if (!txq)
a862e4a3 6591 goto fail;
c5121837
JM
6592
6593 /* We are only sending parameters for a single TXQ at a time */
6594 params = nla_nest_start(msg, 1);
6595 if (!params)
a862e4a3 6596 goto fail;
c5121837 6597
7e3c1781
JM
6598 switch (queue) {
6599 case 0:
a862e4a3
JM
6600 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO))
6601 goto fail;
7e3c1781
JM
6602 break;
6603 case 1:
a862e4a3
JM
6604 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI))
6605 goto fail;
7e3c1781
JM
6606 break;
6607 case 2:
a862e4a3
JM
6608 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE))
6609 goto fail;
7e3c1781
JM
6610 break;
6611 case 3:
a862e4a3
JM
6612 if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK))
6613 goto fail;
7e3c1781
JM
6614 break;
6615 }
c5121837
JM
6616 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
6617 * 32 usec, so need to convert the value here. */
a862e4a3
JM
6618 if (nla_put_u16(msg, NL80211_TXQ_ATTR_TXOP,
6619 (burst_time * 100 + 16) / 32) ||
6620 nla_put_u16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min) ||
6621 nla_put_u16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max) ||
6622 nla_put_u8(msg, NL80211_TXQ_ATTR_AIFS, aifs))
6623 goto fail;
c5121837
JM
6624
6625 nla_nest_end(msg, params);
6626
6627 nla_nest_end(msg, txq);
6628
bd512469
JM
6629 res = send_and_recv_msgs(drv, msg, NULL, NULL);
6630 wpa_printf(MSG_DEBUG,
6631 "nl80211: TX queue param set: queue=%d aifs=%d cw_min=%d cw_max=%d burst_time=%d --> res=%d",
6632 queue, aifs, cw_min, cw_max, burst_time, res);
6633 if (res == 0)
c5121837 6634 return 0;
9e088e74 6635 msg = NULL;
a862e4a3 6636fail:
9e088e74 6637 nlmsg_free(msg);
c5121837
JM
6638 return -1;
6639}
6640
6641
9ebce9c5 6642static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
c5121837
JM
6643 const char *ifname, int vlan_id)
6644{
a2e40bb6 6645 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 6646 struct nl_msg *msg;
a862e4a3 6647 int ret;
c5121837 6648
bbc706a3
JM
6649 wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
6650 ", ifname=%s[%d], vlan_id=%d)",
6651 bss->ifname, if_nametoindex(bss->ifname),
6652 MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
13f83980 6653 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
a862e4a3
JM
6654 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
6655 nla_put_u32(msg, NL80211_ATTR_STA_VLAN, if_nametoindex(ifname))) {
6656 nlmsg_free(msg);
6657 return -ENOBUFS;
6658 }
c5121837 6659
cd1d72c1
JM
6660 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6661 if (ret < 0) {
6662 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
6663 MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
6664 MAC2STR(addr), ifname, vlan_id, ret,
6665 strerror(-ret));
6666 }
cd1d72c1 6667 return ret;
c5121837
JM
6668}
6669
fbbfcbac 6670
c5121837
JM
6671static int i802_get_inact_sec(void *priv, const u8 *addr)
6672{
6673 struct hostap_sta_driver_data data;
6674 int ret;
6675
7824bf77 6676 os_memset(&data, 0, sizeof(data));
c5121837
JM
6677 data.inactive_msec = (unsigned long) -1;
6678 ret = i802_read_sta_data(priv, &data, addr);
b9749bac
MH
6679 if (ret == -ENOENT)
6680 return -ENOENT;
c5121837
JM
6681 if (ret || data.inactive_msec == (unsigned long) -1)
6682 return -1;
6683 return data.inactive_msec / 1000;
6684}
6685
6686
6687static int i802_sta_clear_stats(void *priv, const u8 *addr)
6688{
6689#if 0
6690 /* TODO */
6691#endif
6692 return 0;
6693}
6694
6695
731723a5 6696static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
4be17ffb 6697 u16 reason)
c5121837 6698{
a2e40bb6 6699 struct i802_bss *bss = priv;
e1bd4e19 6700 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 6701 struct ieee80211_mgmt mgmt;
05e5e615
DL
6702 u8 channel;
6703
6704 if (ieee80211_freq_to_chan(bss->freq, &channel) ==
6705 HOSTAPD_MODE_IEEE80211AD) {
6706 /* Deauthentication is not used in DMG/IEEE 802.11ad;
6707 * disassociate the STA instead. */
6708 return i802_sta_disassoc(priv, own_addr, addr, reason);
6709 }
c5121837 6710
0d391b03
BC
6711 if (is_mesh_interface(drv->nlmode))
6712 return -1;
6713
e1bd4e19 6714 if (drv->device_ap_sme)
59d7148a 6715 return wpa_driver_nl80211_sta_remove(bss, addr, 1, reason);
e1bd4e19 6716
c5121837
JM
6717 memset(&mgmt, 0, sizeof(mgmt));
6718 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
6719 WLAN_FC_STYPE_DEAUTH);
6720 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
6721 memcpy(mgmt.sa, own_addr, ETH_ALEN);
6722 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 6723 mgmt.u.deauth.reason_code = host_to_le16(reason);
a2e40bb6 6724 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 6725 IEEE80211_HDRLEN +
9ebce9c5 6726 sizeof(mgmt.u.deauth), 0, 0, 0, 0,
27cc06d0 6727 0, NULL, 0, 0);
c5121837
JM
6728}
6729
6730
731723a5 6731static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
4be17ffb 6732 u16 reason)
c5121837 6733{
a2e40bb6 6734 struct i802_bss *bss = priv;
e1bd4e19 6735 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6736 struct ieee80211_mgmt mgmt;
6737
0d391b03
BC
6738 if (is_mesh_interface(drv->nlmode))
6739 return -1;
6740
e1bd4e19 6741 if (drv->device_ap_sme)
59d7148a 6742 return wpa_driver_nl80211_sta_remove(bss, addr, 0, reason);
e1bd4e19 6743
c5121837
JM
6744 memset(&mgmt, 0, sizeof(mgmt));
6745 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
6746 WLAN_FC_STYPE_DISASSOC);
6747 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
6748 memcpy(mgmt.sa, own_addr, ETH_ALEN);
6749 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 6750 mgmt.u.disassoc.reason_code = host_to_le16(reason);
a2e40bb6 6751 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 6752 IEEE80211_HDRLEN +
9ebce9c5 6753 sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
27cc06d0 6754 0, NULL, 0, 0);
c5121837
JM
6755}
6756
6757
9b4d9c8b
JM
6758static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
6759{
6760 char buf[200], *pos, *end;
6761 int i, res;
6762
6763 pos = buf;
6764 end = pos + sizeof(buf);
6765
6766 for (i = 0; i < drv->num_if_indices; i++) {
099224c1 6767 if (!drv->if_indices[i].ifindex)
9b4d9c8b 6768 continue;
732b1d20 6769 res = os_snprintf(pos, end - pos, " %d(%d)",
099224c1
JM
6770 drv->if_indices[i].ifindex,
6771 drv->if_indices[i].reason);
d85e1fc8 6772 if (os_snprintf_error(end - pos, res))
9b4d9c8b
JM
6773 break;
6774 pos += res;
6775 }
6776 *pos = '\0';
6777
6778 wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
6779 drv->num_if_indices, buf);
6780}
6781
6782
732b1d20
MB
6783static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
6784 int ifidx_reason)
f07ead6a
JM
6785{
6786 int i;
099224c1 6787 struct drv_nl80211_if_info *old;
f07ead6a 6788
732b1d20
MB
6789 wpa_printf(MSG_DEBUG,
6790 "nl80211: Add own interface ifindex %d (ifidx_reason %d)",
6791 ifidx, ifidx_reason);
6792 if (have_ifidx(drv, ifidx, ifidx_reason)) {
b36935be
MB
6793 wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
6794 ifidx);
6795 return;
6796 }
f07ead6a 6797 for (i = 0; i < drv->num_if_indices; i++) {
099224c1
JM
6798 if (drv->if_indices[i].ifindex == 0) {
6799 drv->if_indices[i].ifindex = ifidx;
6800 drv->if_indices[i].reason = ifidx_reason;
9b4d9c8b 6801 dump_ifidx(drv);
f07ead6a
JM
6802 return;
6803 }
6804 }
6805
6806 if (drv->if_indices != drv->default_if_indices)
6807 old = drv->if_indices;
6808 else
6809 old = NULL;
6810
067ffa26 6811 drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
099224c1 6812 sizeof(*old));
f07ead6a
JM
6813 if (!drv->if_indices) {
6814 if (!old)
6815 drv->if_indices = drv->default_if_indices;
6816 else
6817 drv->if_indices = old;
6818 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
6819 "interfaces");
6820 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
6821 return;
732b1d20
MB
6822 }
6823 if (!old)
f07ead6a
JM
6824 os_memcpy(drv->if_indices, drv->default_if_indices,
6825 sizeof(drv->default_if_indices));
099224c1
JM
6826 drv->if_indices[drv->num_if_indices].ifindex = ifidx;
6827 drv->if_indices[drv->num_if_indices].reason = ifidx_reason;
f07ead6a 6828 drv->num_if_indices++;
9b4d9c8b 6829 dump_ifidx(drv);
f07ead6a
JM
6830}
6831
6832
732b1d20
MB
6833static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
6834 int ifidx_reason)
f07ead6a
JM
6835{
6836 int i;
6837
6838 for (i = 0; i < drv->num_if_indices; i++) {
099224c1
JM
6839 if ((drv->if_indices[i].ifindex == ifidx ||
6840 ifidx == IFIDX_ANY) &&
6841 (drv->if_indices[i].reason == ifidx_reason ||
732b1d20 6842 ifidx_reason == IFIDX_ANY)) {
099224c1
JM
6843 drv->if_indices[i].ifindex = 0;
6844 drv->if_indices[i].reason = 0;
f07ead6a
JM
6845 break;
6846 }
6847 }
9b4d9c8b 6848 dump_ifidx(drv);
f07ead6a
JM
6849}
6850
6851
732b1d20
MB
6852static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
6853 int ifidx_reason)
f07ead6a
JM
6854{
6855 int i;
6856
6857 for (i = 0; i < drv->num_if_indices; i++)
099224c1
JM
6858 if (drv->if_indices[i].ifindex == ifidx &&
6859 (drv->if_indices[i].reason == ifidx_reason ||
732b1d20 6860 ifidx_reason == IFIDX_ANY))
f07ead6a
JM
6861 return 1;
6862
6863 return 0;
6864}
6865
6866
6867static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
0e80ea2c 6868 const char *bridge_ifname, char *ifname_wds)
f07ead6a
JM
6869{
6870 struct i802_bss *bss = priv;
6871 struct wpa_driver_nl80211_data *drv = bss->drv;
6872 char name[IFNAMSIZ + 1];
1952b626 6873 union wpa_event_data event;
d577f7f3
AO
6874 int ret;
6875
6876 ret = os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
6877 if (ret >= (int) sizeof(name))
6878 wpa_printf(MSG_WARNING,
6879 "nl80211: WDS interface name was truncated");
6880 else if (ret < 0)
6881 return ret;
f07ead6a 6882
69dd2967
SM
6883 if (ifname_wds)
6884 os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
6885
f07ead6a
JM
6886 wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
6887 " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
6888 if (val) {
6889 if (!if_nametoindex(name)) {
6890 if (nl80211_create_iface(drv, name,
6891 NL80211_IFTYPE_AP_VLAN,
2aec4f3c
JM
6892 bss->addr, 1, NULL, NULL, 0) <
6893 0)
f07ead6a
JM
6894 return -1;
6895 if (bridge_ifname &&
c81eff1a
BG
6896 linux_br_add_if(drv->global->ioctl_sock,
6897 bridge_ifname, name) < 0)
f07ead6a 6898 return -1;
1952b626
BP
6899
6900 os_memset(&event, 0, sizeof(event));
6901 event.wds_sta_interface.sta_addr = addr;
6902 event.wds_sta_interface.ifname = name;
6903 event.wds_sta_interface.istatus = INTERFACE_ADDED;
8bfbb295 6904 wpa_supplicant_event(bss->ctx,
1952b626
BP
6905 EVENT_WDS_STA_INTERFACE_STATUS,
6906 &event);
f07ead6a 6907 }
75227f3a
JM
6908 if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
6909 wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
6910 "interface %s up", name);
6911 }
f07ead6a
JM
6912 return i802_set_sta_vlan(priv, addr, name, 0);
6913 } else {
f9052d6e
JM
6914 if (bridge_ifname &&
6915 linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
6916 name) < 0)
6917 wpa_printf(MSG_INFO,
6918 "nl80211: Failed to remove interface %s from bridge %s: %s",
6919 name, bridge_ifname, strerror(errno));
c34e618d 6920
f07ead6a 6921 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
d0595b25 6922 nl80211_remove_iface(drv, if_nametoindex(name));
1952b626
BP
6923 os_memset(&event, 0, sizeof(event));
6924 event.wds_sta_interface.sta_addr = addr;
6925 event.wds_sta_interface.ifname = name;
6926 event.wds_sta_interface.istatus = INTERFACE_REMOVED;
8bfbb295 6927 wpa_supplicant_event(bss->ctx, EVENT_WDS_STA_INTERFACE_STATUS,
1952b626 6928 &event);
d0595b25 6929 return 0;
f07ead6a
JM
6930 }
6931}
6932
6933
6934static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
6935{
6936 struct wpa_driver_nl80211_data *drv = eloop_ctx;
6937 struct sockaddr_ll lladdr;
6938 unsigned char buf[3000];
6939 int len;
6940 socklen_t fromlen = sizeof(lladdr);
6941
6942 len = recvfrom(sock, buf, sizeof(buf), 0,
6943 (struct sockaddr *)&lladdr, &fromlen);
6944 if (len < 0) {
7ac3616d
JM
6945 wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
6946 strerror(errno));
f07ead6a
JM
6947 return;
6948 }
6949
732b1d20 6950 if (have_ifidx(drv, lladdr.sll_ifindex, IFIDX_ANY))
f07ead6a
JM
6951 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
6952}
6953
6954
94627f6c 6955static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
e17a2477 6956 struct i802_bss *bss,
94627f6c
JM
6957 const char *brname, const char *ifname)
6958{
6c6678e7 6959 int br_ifindex;
94627f6c
JM
6960 char in_br[IFNAMSIZ];
6961
e17a2477 6962 os_strlcpy(bss->brname, brname, IFNAMSIZ);
6c6678e7 6963 br_ifindex = if_nametoindex(brname);
6c6678e7 6964 if (br_ifindex == 0) {
94627f6c
JM
6965 /*
6966 * Bridge was configured, but the bridge device does
6967 * not exist. Try to add it now.
6968 */
c81eff1a 6969 if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
94627f6c
JM
6970 wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
6971 "bridge interface %s: %s",
6972 brname, strerror(errno));
6973 return -1;
6974 }
e17a2477 6975 bss->added_bridge = 1;
8997613c 6976 br_ifindex = if_nametoindex(brname);
732b1d20 6977 add_ifidx(drv, br_ifindex, drv->ifindex);
94627f6c 6978 }
8997613c 6979 bss->br_ifindex = br_ifindex;
94627f6c
JM
6980
6981 if (linux_br_get(in_br, ifname) == 0) {
c809756f
SM
6982 if (os_strcmp(in_br, brname) == 0) {
6983 bss->already_in_bridge = 1;
94627f6c 6984 return 0; /* already in the bridge */
c809756f 6985 }
94627f6c
JM
6986
6987 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
6988 "bridge %s", ifname, in_br);
c81eff1a
BG
6989 if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
6990 0) {
94627f6c
JM
6991 wpa_printf(MSG_ERROR, "nl80211: Failed to "
6992 "remove interface %s from bridge "
6993 "%s: %s",
fdbfb63e 6994 ifname, in_br, strerror(errno));
94627f6c
JM
6995 return -1;
6996 }
6997 }
6998
6999 wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
7000 ifname, brname);
c81eff1a 7001 if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
8e111157
MK
7002 wpa_printf(MSG_WARNING,
7003 "nl80211: Failed to add interface %s into bridge %s: %s",
94627f6c 7004 ifname, brname, strerror(errno));
8e111157
MK
7005 /* Try to continue without the interface being in a bridge. This
7006 * may be needed for some cases, e.g., with Open vSwitch, where
7007 * an external component will need to handle bridge
7008 * configuration. */
7009 return 0;
94627f6c 7010 }
e17a2477 7011 bss->added_if_into_bridge = 1;
94627f6c
JM
7012
7013 return 0;
7014}
7015
7016
92f475b4
JM
7017static void *i802_init(struct hostapd_data *hapd,
7018 struct wpa_init_params *params)
c5121837
JM
7019{
7020 struct wpa_driver_nl80211_data *drv;
a2e40bb6 7021 struct i802_bss *bss;
c5121837 7022 size_t i;
cb05808c
AN
7023 char master_ifname[IFNAMSIZ];
7024 int ifindex, br_ifindex = 0;
94627f6c 7025 int br_added = 0;
c5121837 7026
0d547d5f
JM
7027 bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
7028 params->global_priv, 1,
0ecff8d7 7029 params->bssid, params->driver_params);
a2e40bb6 7030 if (bss == NULL)
c5121837 7031 return NULL;
c5121837 7032
a2e40bb6 7033 drv = bss->drv;
7635bfb0 7034
cb05808c 7035 if (linux_br_get(master_ifname, params->ifname) == 0) {
94627f6c 7036 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
cb05808c
AN
7037 params->ifname, master_ifname);
7038 br_ifindex = if_nametoindex(master_ifname);
7039 os_strlcpy(bss->brname, master_ifname, IFNAMSIZ);
7040 } else if ((params->num_bridge == 0 || !params->bridge[0]) &&
7041 linux_master_get(master_ifname, params->ifname) == 0) {
7042 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in master %s",
7043 params->ifname, master_ifname);
7044 /* start listening for EAPOL on the master interface */
732b1d20 7045 add_ifidx(drv, if_nametoindex(master_ifname), drv->ifindex);
f2d6c17a
DL
7046
7047 /* check if master itself is under bridge */
7048 if (linux_br_get(master_ifname, master_ifname) == 0) {
7049 wpa_printf(MSG_DEBUG, "nl80211: which is in bridge %s",
7050 master_ifname);
7051 br_ifindex = if_nametoindex(master_ifname);
7052 os_strlcpy(bss->brname, master_ifname, IFNAMSIZ);
7053 }
94627f6c 7054 } else {
cb05808c 7055 master_ifname[0] = '\0';
94627f6c 7056 }
cb05808c 7057
6c6678e7 7058 bss->br_ifindex = br_ifindex;
94627f6c 7059
92f475b4 7060 for (i = 0; i < params->num_bridge; i++) {
94627f6c
JM
7061 if (params->bridge[i]) {
7062 ifindex = if_nametoindex(params->bridge[i]);
7063 if (ifindex)
732b1d20 7064 add_ifidx(drv, ifindex, drv->ifindex);
94627f6c
JM
7065 if (ifindex == br_ifindex)
7066 br_added = 1;
7067 }
c5121837 7068 }
c5121837 7069
ad1e68e6 7070 /* start listening for EAPOL on the default AP interface */
732b1d20 7071 add_ifidx(drv, drv->ifindex, IFIDX_ANY);
ad1e68e6 7072
5ef8e39f
JM
7073 if (params->num_bridge && params->bridge[0]) {
7074 if (i802_check_bridge(drv, bss, params->bridge[0],
7075 params->ifname) < 0)
7076 goto failed;
cb05808c 7077 if (os_strcmp(params->bridge[0], master_ifname) != 0)
5ef8e39f
JM
7078 br_added = 1;
7079 }
7080
7081 if (!br_added && br_ifindex &&
7082 (params->num_bridge == 0 || !params->bridge[0]))
732b1d20 7083 add_ifidx(drv, br_ifindex, drv->ifindex);
94627f6c 7084
97ed9a06 7085#ifdef CONFIG_LIBNL3_ROUTE
c809756f 7086 if (bss->added_if_into_bridge || bss->already_in_bridge) {
3ea58a05
JM
7087 int err;
7088
97ed9a06
KP
7089 drv->rtnl_sk = nl_socket_alloc();
7090 if (drv->rtnl_sk == NULL) {
7091 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
7092 goto failed;
7093 }
7094
3ea58a05
JM
7095 err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
7096 if (err) {
97ed9a06 7097 wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
3ea58a05 7098 nl_geterror(err));
97ed9a06
KP
7099 goto failed;
7100 }
7101 }
7102#endif /* CONFIG_LIBNL3_ROUTE */
7103
ad1e68e6
JM
7104 drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
7105 if (drv->eapol_sock < 0) {
7ac3616d
JM
7106 wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
7107 strerror(errno));
bbaf0837 7108 goto failed;
ad1e68e6
JM
7109 }
7110
7111 if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
7112 {
7ac3616d 7113 wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
c5121837 7114 goto failed;
ad1e68e6
JM
7115 }
7116
c81eff1a
BG
7117 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
7118 params->own_addr))
bbaf0837 7119 goto failed;
fee354c7 7120 os_memcpy(drv->perm_addr, params->own_addr, ETH_ALEN);
c5121837 7121
341eebee
JB
7122 memcpy(bss->addr, params->own_addr, ETH_ALEN);
7123
a2e40bb6 7124 return bss;
c5121837
JM
7125
7126failed:
7635bfb0 7127 wpa_driver_nl80211_deinit(bss);
bbaf0837
JM
7128 return NULL;
7129}
c5121837 7130
c5121837 7131
bbaf0837
JM
7132static void i802_deinit(void *priv)
7133{
9ebce9c5
JM
7134 struct i802_bss *bss = priv;
7135 wpa_driver_nl80211_deinit(bss);
c5121837
JM
7136}
7137
c5121837 7138
22a7c9d7
JM
7139static enum nl80211_iftype wpa_driver_nl80211_if_type(
7140 enum wpa_driver_if_type type)
7141{
7142 switch (type) {
7143 case WPA_IF_STATION:
9f51b113 7144 return NL80211_IFTYPE_STATION;
75bde05d
JM
7145 case WPA_IF_P2P_CLIENT:
7146 case WPA_IF_P2P_GROUP:
9f51b113 7147 return NL80211_IFTYPE_P2P_CLIENT;
22a7c9d7
JM
7148 case WPA_IF_AP_VLAN:
7149 return NL80211_IFTYPE_AP_VLAN;
7150 case WPA_IF_AP_BSS:
7151 return NL80211_IFTYPE_AP;
9f51b113
JB
7152 case WPA_IF_P2P_GO:
7153 return NL80211_IFTYPE_P2P_GO;
7aad838c
NS
7154 case WPA_IF_P2P_DEVICE:
7155 return NL80211_IFTYPE_P2P_DEVICE;
5b78493f
MH
7156 case WPA_IF_MESH:
7157 return NL80211_IFTYPE_MESH_POINT;
98342208
AK
7158 default:
7159 return -1;
22a7c9d7 7160 }
22a7c9d7
JM
7161}
7162
7163
f2ed8023
JM
7164static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
7165{
7166 struct wpa_driver_nl80211_data *drv;
7167 dl_list_for_each(drv, &global->interfaces,
7168 struct wpa_driver_nl80211_data, list) {
834ee56f 7169 if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
f2ed8023
JM
7170 return 1;
7171 }
7172 return 0;
7173}
7174
7175
5b78493f 7176static int nl80211_vif_addr(struct wpa_driver_nl80211_data *drv, u8 *new_addr)
f2ed8023
JM
7177{
7178 unsigned int idx;
7179
7180 if (!drv->global)
7181 return -1;
7182
834ee56f 7183 os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
f2ed8023 7184 for (idx = 0; idx < 64; idx++) {
834ee56f 7185 new_addr[0] = drv->first_bss->addr[0] | 0x02;
f2ed8023
JM
7186 new_addr[0] ^= idx << 2;
7187 if (!nl80211_addr_in_use(drv->global, new_addr))
7188 break;
7189 }
7190 if (idx == 64)
7191 return -1;
7192
5b78493f 7193 wpa_printf(MSG_DEBUG, "nl80211: Assigned new virtual interface address "
f2ed8023
JM
7194 MACSTR, MAC2STR(new_addr));
7195
7196 return 0;
7197}
7198
7199
f632e483
AS
7200struct wdev_info {
7201 u64 wdev_id;
7202 int wdev_id_set;
7203 u8 macaddr[ETH_ALEN];
7204};
7205
7206static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
e472e1b4
AS
7207{
7208 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7209 struct nlattr *tb[NL80211_ATTR_MAX + 1];
f632e483 7210 struct wdev_info *wi = arg;
e472e1b4
AS
7211
7212 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7213 genlmsg_attrlen(gnlh, 0), NULL);
7214 if (tb[NL80211_ATTR_WDEV]) {
f632e483
AS
7215 wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
7216 wi->wdev_id_set = 1;
e472e1b4
AS
7217 }
7218
7219 if (tb[NL80211_ATTR_MAC])
f632e483 7220 os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
e472e1b4
AS
7221 ETH_ALEN);
7222
7223 return NL_SKIP;
7224}
7225
7226
7ab68865 7227static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
8043e725 7228 const char *ifname, const u8 *addr,
f3585c8a 7229 void *bss_ctx, void **drv_priv,
e17a2477 7230 char *force_ifname, u8 *if_addr,
d8a3b66d
AS
7231 const char *bridge, int use_existing,
7232 int setup_ap)
22a7c9d7 7233{
e472e1b4 7234 enum nl80211_iftype nlmode;
a2e40bb6
FF
7235 struct i802_bss *bss = priv;
7236 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7 7237 int ifidx;
2aec4f3c 7238 int added = 1;
22a7c9d7 7239
f3585c8a
JM
7240 if (addr)
7241 os_memcpy(if_addr, addr, ETH_ALEN);
e472e1b4
AS
7242 nlmode = wpa_driver_nl80211_if_type(type);
7243 if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
f632e483
AS
7244 struct wdev_info p2pdev_info;
7245
7246 os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
e472e1b4 7247 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
f632e483 7248 0, nl80211_wdev_handler,
2aec4f3c 7249 &p2pdev_info, use_existing);
f632e483 7250 if (!p2pdev_info.wdev_id_set || ifidx != 0) {
e472e1b4
AS
7251 wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
7252 ifname);
e472e1b4
AS
7253 return -1;
7254 }
f632e483
AS
7255
7256 drv->global->if_add_wdevid = p2pdev_info.wdev_id;
7257 drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
7258 if (!is_zero_ether_addr(p2pdev_info.macaddr))
7259 os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
7260 wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
7261 ifname,
7262 (long long unsigned int) p2pdev_info.wdev_id);
e472e1b4
AS
7263 } else {
7264 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
2aec4f3c
JM
7265 0, NULL, NULL, use_existing);
7266 if (use_existing && ifidx == -ENFILE) {
7267 added = 0;
7268 ifidx = if_nametoindex(ifname);
7269 } else if (ifidx < 0) {
e472e1b4
AS
7270 return -1;
7271 }
22a7c9d7
JM
7272 }
7273
ab7a1add 7274 if (!addr) {
8ea8a89c 7275 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
ab7a1add
AS
7276 os_memcpy(if_addr, bss->addr, ETH_ALEN);
7277 else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
8ea8a89c 7278 ifname, if_addr) < 0) {
2aec4f3c
JM
7279 if (added)
7280 nl80211_remove_iface(drv, ifidx);
ab7a1add
AS
7281 return -1;
7282 }
c55f774d
JM
7283 }
7284
c55f774d
JM
7285 if (!addr &&
7286 (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
8ea8a89c
JM
7287 type == WPA_IF_P2P_GO || type == WPA_IF_MESH ||
7288 type == WPA_IF_STATION)) {
7289 /* Enforce unique address */
ab7a1add 7290 u8 new_addr[ETH_ALEN];
c55f774d 7291
ab7a1add 7292 if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
c81eff1a 7293 new_addr) < 0) {
ea39367c
MK
7294 if (added)
7295 nl80211_remove_iface(drv, ifidx);
c55f774d
JM
7296 return -1;
7297 }
f608081c 7298 if (nl80211_addr_in_use(drv->global, new_addr)) {
c55f774d 7299 wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
8ea8a89c 7300 "for interface %s type %d", ifname, type);
5b78493f 7301 if (nl80211_vif_addr(drv, new_addr) < 0) {
ea39367c
MK
7302 if (added)
7303 nl80211_remove_iface(drv, ifidx);
c55f774d
JM
7304 return -1;
7305 }
c81eff1a 7306 if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
c55f774d 7307 new_addr) < 0) {
ea39367c
MK
7308 if (added)
7309 nl80211_remove_iface(drv, ifidx);
c55f774d
JM
7310 return -1;
7311 }
c55f774d 7312 }
f67eeb5c 7313 os_memcpy(if_addr, new_addr, ETH_ALEN);
c55f774d 7314 }
f3585c8a 7315
d8a3b66d 7316 if (type == WPA_IF_AP_BSS && setup_ap) {
f5eb9da3
JM
7317 struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
7318 if (new_bss == NULL) {
2aec4f3c
JM
7319 if (added)
7320 nl80211_remove_iface(drv, ifidx);
f5eb9da3
JM
7321 return -1;
7322 }
7323
7324 if (bridge &&
7325 i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
7326 wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
7327 "interface %s to a bridge %s",
7328 ifname, bridge);
2aec4f3c
JM
7329 if (added)
7330 nl80211_remove_iface(drv, ifidx);
f5eb9da3
JM
7331 os_free(new_bss);
7332 return -1;
7333 }
7334
c81eff1a
BG
7335 if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
7336 {
ea39367c
MK
7337 if (added)
7338 nl80211_remove_iface(drv, ifidx);
07179987 7339 os_free(new_bss);
22a7c9d7
JM
7340 return -1;
7341 }
a2e40bb6 7342 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
341eebee 7343 os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
a2e40bb6
FF
7344 new_bss->ifindex = ifidx;
7345 new_bss->drv = drv;
834ee56f
KP
7346 new_bss->next = drv->first_bss->next;
7347 new_bss->freq = drv->first_bss->freq;
a5e1eb20 7348 new_bss->ctx = bss_ctx;
2aec4f3c 7349 new_bss->added_if = added;
834ee56f 7350 drv->first_bss->next = new_bss;
a2e40bb6
FF
7351 if (drv_priv)
7352 *drv_priv = new_bss;
cc7a48d1 7353 nl80211_init_bss(new_bss);
3dd1d890
YAP
7354
7355 /* Subscribe management frames for this WPA_IF_AP_BSS */
7356 if (nl80211_setup_ap(new_bss))
7357 return -1;
22a7c9d7 7358 }
22a7c9d7 7359
ff6a158b
JM
7360 if (drv->global)
7361 drv->global->if_add_ifindex = ifidx;
7362
d1bb7aed
JJ
7363 /*
7364 * Some virtual interfaces need to process EAPOL packets and events on
7365 * the parent interface. This is used mainly with hostapd.
7366 */
7367 if (ifidx > 0 &&
7368 (drv->hostapd ||
7369 nlmode == NL80211_IFTYPE_AP_VLAN ||
7370 nlmode == NL80211_IFTYPE_WDS ||
7371 nlmode == NL80211_IFTYPE_MONITOR))
732b1d20 7372 add_ifidx(drv, ifidx, IFIDX_ANY);
b36935be 7373
22a7c9d7
JM
7374 return 0;
7375}
7376
7377
9ebce9c5 7378static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
22a7c9d7
JM
7379 enum wpa_driver_if_type type,
7380 const char *ifname)
7381{
a2e40bb6 7382 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
7383 int ifindex = if_nametoindex(ifname);
7384
2aec4f3c
JM
7385 wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
7386 __func__, type, ifname, ifindex, bss->added_if);
158b090c 7387 if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
2b72df63 7388 nl80211_remove_iface(drv, ifindex);
de884303
JM
7389 else if (ifindex > 0 && !bss->added_if) {
7390 struct wpa_driver_nl80211_data *drv2;
7391 dl_list_for_each(drv2, &drv->global->interfaces,
732b1d20
MB
7392 struct wpa_driver_nl80211_data, list) {
7393 del_ifidx(drv2, ifindex, IFIDX_ANY);
7394 del_ifidx(drv2, IFIDX_ANY, ifindex);
7395 }
de884303 7396 }
c34e618d 7397
c34e618d
FF
7398 if (type != WPA_IF_AP_BSS)
7399 return 0;
7400
e17a2477 7401 if (bss->added_if_into_bridge) {
c81eff1a
BG
7402 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
7403 bss->ifname) < 0)
e17a2477
JM
7404 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
7405 "interface %s from bridge %s: %s",
7406 bss->ifname, bss->brname, strerror(errno));
7407 }
7408 if (bss->added_bridge) {
c81eff1a 7409 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
e17a2477
JM
7410 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
7411 "bridge %s: %s",
7412 bss->brname, strerror(errno));
7413 }
a2e40bb6 7414
834ee56f 7415 if (bss != drv->first_bss) {
8546ea19 7416 struct i802_bss *tbss;
a2e40bb6 7417
2aec4f3c 7418 wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
834ee56f 7419 for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
8546ea19
JM
7420 if (tbss->next == bss) {
7421 tbss->next = bss->next;
3dd1d890
YAP
7422 /* Unsubscribe management frames */
7423 nl80211_teardown_ap(bss);
cc7a48d1 7424 nl80211_destroy_bss(bss);
5c9da160
MB
7425 if (!bss->added_if)
7426 i802_set_iface_flags(bss, 0);
8546ea19
JM
7427 os_free(bss);
7428 bss = NULL;
7429 break;
7430 }
22a7c9d7 7431 }
8546ea19
JM
7432 if (bss)
7433 wpa_printf(MSG_INFO, "nl80211: %s - could not find "
7434 "BSS %p in the list", __func__, bss);
390e489c 7435 } else {
2aec4f3c 7436 wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
390e489c 7437 nl80211_teardown_ap(bss);
2aec4f3c 7438 if (!bss->added_if && !drv->first_bss->next)
a70cd0db 7439 wpa_driver_nl80211_del_beacon(bss);
390e489c 7440 nl80211_destroy_bss(bss);
2aec4f3c
JM
7441 if (!bss->added_if)
7442 i802_set_iface_flags(bss, 0);
390e489c
KP
7443 if (drv->first_bss->next) {
7444 drv->first_bss = drv->first_bss->next;
7445 drv->ctx = drv->first_bss->ctx;
7446 os_free(bss);
7447 } else {
7448 wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
7449 }
22a7c9d7 7450 }
22a7c9d7
JM
7451
7452 return 0;
7453}
7454
7455
55777702
JM
7456static int cookie_handler(struct nl_msg *msg, void *arg)
7457{
7458 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7459 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7460 u64 *cookie = arg;
7461 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7462 genlmsg_attrlen(gnlh, 0), NULL);
7463 if (tb[NL80211_ATTR_COOKIE])
7464 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
7465 return NL_SKIP;
7466}
7467
7468
88df0ef7 7469static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f
JB
7470 unsigned int freq, unsigned int wait,
7471 const u8 *buf, size_t buf_len,
88df0ef7 7472 u64 *cookie_out, int no_cck, int no_ack,
2d3943ce
AO
7473 int offchanok, const u16 *csa_offs,
7474 size_t csa_offs_len)
9884f9cc 7475{
88df0ef7 7476 struct wpa_driver_nl80211_data *drv = bss->drv;
9884f9cc
JB
7477 struct nl_msg *msg;
7478 u64 cookie;
7479 int ret = -1;
7480
cc2ada86 7481 wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
2e3e4566
JM
7482 "no_ack=%d offchanok=%d",
7483 freq, wait, no_cck, no_ack, offchanok);
c91f796f 7484 wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
9884f9cc 7485
56f77852 7486 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME)) ||
a862e4a3
JM
7487 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
7488 (wait && nla_put_u32(msg, NL80211_ATTR_DURATION, wait)) ||
7489 (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
7490 drv->test_use_roc_tx) &&
7491 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) ||
7492 (no_cck && nla_put_flag(msg, NL80211_ATTR_TX_NO_CCK_RATE)) ||
7493 (no_ack && nla_put_flag(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK)) ||
2d3943ce
AO
7494 (csa_offs && nla_put(msg, NL80211_ATTR_CSA_C_OFFSETS_TX,
7495 csa_offs_len * sizeof(u16), csa_offs)) ||
a862e4a3
JM
7496 nla_put(msg, NL80211_ATTR_FRAME, buf_len, buf))
7497 goto fail;
9884f9cc
JB
7498
7499 cookie = 0;
7500 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
7501 msg = NULL;
7502 if (ret) {
7503 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
a05225c8
JM
7504 "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
7505 freq, wait);
a862e4a3
JM
7506 } else {
7507 wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
7508 "cookie 0x%llx", no_ack ? " (no ACK)" : "",
7509 (long long unsigned int) cookie);
9884f9cc 7510
a862e4a3
JM
7511 if (cookie_out)
7512 *cookie_out = no_ack ? (u64) -1 : cookie;
759a8a3a
JM
7513
7514 if (drv->num_send_action_cookies == MAX_SEND_ACTION_COOKIES) {
7515 wpa_printf(MSG_DEBUG,
7516 "nl80211: Drop oldest pending send action cookie 0x%llx",
7517 (long long unsigned int)
7518 drv->send_action_cookies[0]);
7519 os_memmove(&drv->send_action_cookies[0],
7520 &drv->send_action_cookies[1],
7521 (MAX_SEND_ACTION_COOKIES - 1) *
7522 sizeof(u64));
7523 drv->num_send_action_cookies--;
7524 }
7525 drv->send_action_cookies[drv->num_send_action_cookies] = cookie;
7526 drv->num_send_action_cookies++;
a862e4a3 7527 }
9884f9cc 7528
a862e4a3 7529fail:
9884f9cc
JB
7530 nlmsg_free(msg);
7531 return ret;
7532}
7533
7534
9ebce9c5
JM
7535static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
7536 unsigned int freq,
190b9062 7537 unsigned int wait_time,
58f6fbe0
JM
7538 const u8 *dst, const u8 *src,
7539 const u8 *bssid,
b106173a
JM
7540 const u8 *data, size_t data_len,
7541 int no_cck)
58f6fbe0 7542{
a2e40bb6 7543 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0 7544 int ret = -1;
58f6fbe0
JM
7545 u8 *buf;
7546 struct ieee80211_hdr *hdr;
58f6fbe0 7547
5dfca53f 7548 wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
55231068
JM
7549 "freq=%u MHz wait=%d ms no_cck=%d)",
7550 drv->ifindex, freq, wait_time, no_cck);
58f6fbe0
JM
7551
7552 buf = os_zalloc(24 + data_len);
7553 if (buf == NULL)
7554 return ret;
7555 os_memcpy(buf + 24, data, data_len);
7556 hdr = (struct ieee80211_hdr *) buf;
7557 hdr->frame_control =
7558 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
7559 os_memcpy(hdr->addr1, dst, ETH_ALEN);
7560 os_memcpy(hdr->addr2, src, ETH_ALEN);
7561 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
7562
8331c9b3
VK
7563 if (os_memcmp(bss->addr, src, ETH_ALEN) != 0) {
7564 wpa_printf(MSG_DEBUG, "nl80211: Use random TA " MACSTR,
7565 MAC2STR(src));
7566 os_memcpy(bss->rand_addr, src, ETH_ALEN);
7567 } else {
7568 os_memset(bss->rand_addr, 0, ETH_ALEN);
7569 }
7570
f78f2785
JM
7571 if (is_ap_interface(drv->nlmode) &&
7572 (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
7573 (int) freq == bss->freq || drv->device_ap_sme ||
7574 !drv->use_monitor))
9ebce9c5
JM
7575 ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
7576 0, freq, no_cck, 1,
27cc06d0 7577 wait_time, NULL, 0, 0);
9884f9cc 7578 else
88df0ef7 7579 ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
5dfca53f 7580 24 + data_len,
b106173a 7581 &drv->send_action_cookie,
2d3943ce 7582 no_cck, 0, 1, NULL, 0);
58f6fbe0 7583
f8bf1421 7584 os_free(buf);
58f6fbe0
JM
7585 return ret;
7586}
7587
7588
759a8a3a 7589static void nl80211_frame_wait_cancel(struct i802_bss *bss, u64 cookie)
5dfca53f 7590{
5dfca53f
JB
7591 struct wpa_driver_nl80211_data *drv = bss->drv;
7592 struct nl_msg *msg;
7593 int ret;
7594
316a9e4d 7595 wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
759a8a3a 7596 (long long unsigned int) cookie);
56f77852 7597 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME_WAIT_CANCEL)) ||
759a8a3a 7598 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) {
a862e4a3
JM
7599 nlmsg_free(msg);
7600 return;
7601 }
5dfca53f
JB
7602
7603 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5dfca53f
JB
7604 if (ret)
7605 wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
7606 "(%s)", ret, strerror(-ret));
5dfca53f
JB
7607}
7608
7609
759a8a3a
JM
7610static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
7611{
7612 struct i802_bss *bss = priv;
7613 struct wpa_driver_nl80211_data *drv = bss->drv;
7614 unsigned int i;
7615 u64 cookie;
7616
7617 /* Cancel the last pending TX cookie */
7618 nl80211_frame_wait_cancel(bss, drv->send_action_cookie);
7619
7620 /*
7621 * Cancel the other pending TX cookies, if any. This is needed since
7622 * the driver may keep a list of all pending offchannel TX operations
7623 * and free up the radio only once they have expired or cancelled.
7624 */
7625 for (i = drv->num_send_action_cookies; i > 0; i--) {
7626 cookie = drv->send_action_cookies[i - 1];
7627 if (cookie != drv->send_action_cookie)
7628 nl80211_frame_wait_cancel(bss, cookie);
7629 }
7630 drv->num_send_action_cookies = 0;
7631}
7632
7633
55777702
JM
7634static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
7635 unsigned int duration)
7636{
a2e40bb6
FF
7637 struct i802_bss *bss = priv;
7638 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
7639 struct nl_msg *msg;
7640 int ret;
7641 u64 cookie;
7642
56f77852 7643 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REMAIN_ON_CHANNEL)) ||
a862e4a3
JM
7644 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
7645 nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) {
7646 nlmsg_free(msg);
7647 return -1;
7648 }
55777702
JM
7649
7650 cookie = 0;
7651 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
7652 if (ret == 0) {
7653 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
7654 "0x%llx for freq=%u MHz duration=%u",
7655 (long long unsigned int) cookie, freq, duration);
7656 drv->remain_on_chan_cookie = cookie;
531f0331 7657 drv->pending_remain_on_chan = 1;
55777702
JM
7658 return 0;
7659 }
7660 wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
15ed5535
JM
7661 "(freq=%d duration=%u): %d (%s)",
7662 freq, duration, ret, strerror(-ret));
55777702
JM
7663 return -1;
7664}
7665
7666
7667static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
7668{
a2e40bb6
FF
7669 struct i802_bss *bss = priv;
7670 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
7671 struct nl_msg *msg;
7672 int ret;
7673
7674 if (!drv->pending_remain_on_chan) {
7675 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
7676 "to cancel");
7677 return -1;
7678 }
7679
7680 wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
7681 "0x%llx",
7682 (long long unsigned int) drv->remain_on_chan_cookie);
7683
56f77852
JM
7684 msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
7685 if (!msg ||
a862e4a3
JM
7686 nla_put_u64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie)) {
7687 nlmsg_free(msg);
7688 return -1;
7689 }
55777702
JM
7690
7691 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7692 if (ret == 0)
7693 return 0;
7694 wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
7695 "%d (%s)", ret, strerror(-ret));
55777702
JM
7696 return -1;
7697}
7698
7699
9ebce9c5 7700static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
504e905c 7701{
a2e40bb6 7702 struct wpa_driver_nl80211_data *drv = bss->drv;
504e905c 7703
5582a5d1 7704 if (!report) {
0d891981 7705 if (bss->nl_preq && drv->device_ap_sme &&
b8d87ed2
AP
7706 is_ap_interface(drv->nlmode) && !bss->in_deinit &&
7707 !bss->static_ap) {
0d891981
JM
7708 /*
7709 * Do not disable Probe Request reporting that was
7710 * enabled in nl80211_setup_ap().
7711 */
7712 wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
7713 "Probe Request reporting nl_preq=%p while "
7714 "in AP mode", bss->nl_preq);
7715 } else if (bss->nl_preq) {
36488c05
JM
7716 wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
7717 "reporting nl_preq=%p", bss->nl_preq);
40a68f33 7718 nl80211_destroy_eloop_handle(&bss->nl_preq, 0);
5582a5d1
JB
7719 }
7720 return 0;
7721 }
7722
481234cf 7723 if (bss->nl_preq) {
5582a5d1 7724 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
36488c05 7725 "already on! nl_preq=%p", bss->nl_preq);
5582a5d1
JB
7726 return 0;
7727 }
7728
481234cf
JM
7729 bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
7730 if (bss->nl_preq == NULL)
5582a5d1 7731 return -1;
36488c05
JM
7732 wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
7733 "reporting nl_preq=%p", bss->nl_preq);
5582a5d1 7734
481234cf 7735 if (nl80211_register_frame(bss, bss->nl_preq,
5582a5d1
JB
7736 (WLAN_FC_TYPE_MGMT << 2) |
7737 (WLAN_FC_STYPE_PROBE_REQ << 4),
a92dfde8
JB
7738 NULL, 0) < 0)
7739 goto out_err;
5582a5d1 7740
5f65e9f7
JB
7741 nl80211_register_eloop_read(&bss->nl_preq,
7742 wpa_driver_nl80211_event_receive,
40a68f33 7743 bss->nl_cb, 0);
5582a5d1 7744
504e905c 7745 return 0;
5582a5d1 7746
a92dfde8 7747 out_err:
221a59c9 7748 nl_destroy_handles(&bss->nl_preq);
5582a5d1 7749 return -1;
504e905c
JM
7750}
7751
7752
4e5cb1a3
JM
7753static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
7754 int ifindex, int disabled)
7755{
7756 struct nl_msg *msg;
7757 struct nlattr *bands, *band;
7758 int ret;
7759
3e208481
JM
7760 wpa_printf(MSG_DEBUG,
7761 "nl80211: NL80211_CMD_SET_TX_BITRATE_MASK (ifindex=%d %s)",
7762 ifindex, disabled ? "NL80211_TXRATE_LEGACY=OFDM-only" :
7763 "no NL80211_TXRATE_LEGACY constraint");
7764
95376e1a
JM
7765 msg = nl80211_ifindex_msg(drv, ifindex, 0,
7766 NL80211_CMD_SET_TX_BITRATE_MASK);
4e5cb1a3
JM
7767 if (!msg)
7768 return -1;
7769
4e5cb1a3
JM
7770 bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
7771 if (!bands)
a862e4a3 7772 goto fail;
4e5cb1a3
JM
7773
7774 /*
7775 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
7776 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
7777 * rates. All 5 GHz rates are left enabled.
7778 */
7779 band = nla_nest_start(msg, NL80211_BAND_2GHZ);
a862e4a3
JM
7780 if (!band ||
7781 (disabled && nla_put(msg, NL80211_TXRATE_LEGACY, 8,
7782 "\x0c\x12\x18\x24\x30\x48\x60\x6c")))
7783 goto fail;
4e5cb1a3
JM
7784 nla_nest_end(msg, band);
7785
7786 nla_nest_end(msg, bands);
7787
7788 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4e5cb1a3
JM
7789 if (ret) {
7790 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
7791 "(%s)", ret, strerror(-ret));
1d0c6fb1
JM
7792 } else
7793 drv->disabled_11b_rates = disabled;
4e5cb1a3
JM
7794
7795 return ret;
7796
a862e4a3 7797fail:
4e5cb1a3
JM
7798 nlmsg_free(msg);
7799 return -1;
7800}
7801
7802
af473088
JM
7803static int wpa_driver_nl80211_deinit_ap(void *priv)
7804{
a2e40bb6
FF
7805 struct i802_bss *bss = priv;
7806 struct wpa_driver_nl80211_data *drv = bss->drv;
b1f625e0 7807 if (!is_ap_interface(drv->nlmode))
af473088 7808 return -1;
a70cd0db 7809 wpa_driver_nl80211_del_beacon(bss);
9bc5cfa3 7810 bss->beacon_set = 0;
60b13c20
IP
7811
7812 /*
7813 * If the P2P GO interface was dynamically added, then it is
7814 * possible that the interface change to station is not possible.
7815 */
7816 if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
7817 return 0;
7818
b1f625e0 7819 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
af473088
JM
7820}
7821
7822
695c7038
SW
7823static int wpa_driver_nl80211_stop_ap(void *priv)
7824{
7825 struct i802_bss *bss = priv;
7826 struct wpa_driver_nl80211_data *drv = bss->drv;
7827 if (!is_ap_interface(drv->nlmode))
7828 return -1;
a70cd0db 7829 wpa_driver_nl80211_del_beacon(bss);
695c7038
SW
7830 bss->beacon_set = 0;
7831 return 0;
7832}
7833
7834
3c29244e
EP
7835static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
7836{
7837 struct i802_bss *bss = priv;
7838 struct wpa_driver_nl80211_data *drv = bss->drv;
7839 if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
7840 return -1;
60b13c20
IP
7841
7842 /*
7843 * If the P2P Client interface was dynamically added, then it is
7844 * possible that the interface change to station is not possible.
7845 */
7846 if (bss->if_dynamic)
7847 return 0;
7848
3c29244e
EP
7849 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
7850}
7851
7852
207ef3fb
JM
7853static void wpa_driver_nl80211_resume(void *priv)
7854{
a2e40bb6 7855 struct i802_bss *bss = priv;
e8dc205f 7856 enum nl80211_iftype nlmode = nl80211_get_ifmode(bss);
91724d6f
AS
7857
7858 if (i802_set_iface_flags(bss, 1))
7859 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
e8dc205f
AO
7860
7861 if (is_p2p_net_interface(nlmode))
7862 nl80211_disable_11b_rates(bss->drv, bss->drv->ifindex, 1);
207ef3fb
JM
7863}
7864
7865
b625473c
JM
7866static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
7867{
7868 struct i802_bss *bss = priv;
7869 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8
JB
7870 struct nl_msg *msg;
7871 struct nlattr *cqm;
b625473c
JM
7872
7873 wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
7874 "hysteresis=%d", threshold, hysteresis);
7875
13f83980 7876 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_CQM)) ||
a862e4a3
JM
7877 !(cqm = nla_nest_start(msg, NL80211_ATTR_CQM)) ||
7878 nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold) ||
7879 nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis)) {
7880 nlmsg_free(msg);
7881 return -1;
7882 }
8970bae8 7883 nla_nest_end(msg, cqm);
21270bb4 7884
a862e4a3 7885 return send_and_recv_msgs(drv, msg, NULL, NULL);
b625473c
JM
7886}
7887
7888
2cc8d8f4
AO
7889static int get_channel_width(struct nl_msg *msg, void *arg)
7890{
7891 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7892 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7893 struct wpa_signal_info *sig_change = arg;
7894
7895 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7896 genlmsg_attrlen(gnlh, 0), NULL);
7897
7898 sig_change->center_frq1 = -1;
7899 sig_change->center_frq2 = -1;
7900 sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
7901
7902 if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
7903 sig_change->chanwidth = convert2width(
7904 nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
7905 if (tb[NL80211_ATTR_CENTER_FREQ1])
7906 sig_change->center_frq1 =
7907 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
7908 if (tb[NL80211_ATTR_CENTER_FREQ2])
7909 sig_change->center_frq2 =
7910 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
7911 }
7912
7913 return NL_SKIP;
7914}
7915
7916
7917static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
7918 struct wpa_signal_info *sig)
7919{
7920 struct nl_msg *msg;
7921
9725b784 7922 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_INTERFACE);
2cc8d8f4 7923 return send_and_recv_msgs(drv, msg, get_channel_width, sig);
2cc8d8f4
AO
7924}
7925
7926
1c5c7273
PS
7927static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
7928{
7929 struct i802_bss *bss = priv;
7930 struct wpa_driver_nl80211_data *drv = bss->drv;
7931 int res;
7932
7933 os_memset(si, 0, sizeof(*si));
7934 res = nl80211_get_link_signal(drv, si);
1d6955e6
JM
7935 if (res) {
7936 if (drv->nlmode != NL80211_IFTYPE_ADHOC &&
7937 drv->nlmode != NL80211_IFTYPE_MESH_POINT)
7938 return res;
7939 si->current_signal = 0;
7940 }
1c5c7273 7941
2cc8d8f4
AO
7942 res = nl80211_get_channel_width(drv, si);
7943 if (res != 0)
7944 return res;
7945
1c5c7273
PS
7946 return nl80211_get_link_noise(drv, si);
7947}
7948
7949
c55f774d
JM
7950static int nl80211_set_param(void *priv, const char *param)
7951{
ef24ad3e
JM
7952 struct i802_bss *bss = priv;
7953 struct wpa_driver_nl80211_data *drv = bss->drv;
7954
c55f774d
JM
7955 if (param == NULL)
7956 return 0;
99a94f55 7957 wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
c55f774d
JM
7958
7959#ifdef CONFIG_P2P
7960 if (os_strstr(param, "use_p2p_group_interface=1")) {
7961 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
7962 "interface");
7963 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
7964 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
7965 }
7966#endif /* CONFIG_P2P */
7967
ef24ad3e 7968 if (os_strstr(param, "use_monitor=1"))
327b01d3 7969 drv->use_monitor = 1;
327b01d3
JM
7970
7971 if (os_strstr(param, "force_connect_cmd=1")) {
327b01d3 7972 drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
b497a212 7973 drv->force_connect_cmd = 1;
327b01d3
JM
7974 }
7975
ef24ad3e 7976 if (os_strstr(param, "force_bss_selection=1"))
4d584d8c 7977 drv->capa.flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
4d584d8c 7978
64abb725 7979 if (os_strstr(param, "no_offchannel_tx=1")) {
64abb725
JM
7980 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
7981 drv->test_use_roc_tx = 1;
7982 }
7983
c55f774d
JM
7984 return 0;
7985}
7986
7987
45e3fc72 7988static void * nl80211_global_init(void *ctx)
f2ed8023
JM
7989{
7990 struct nl80211_global *global;
36d84860
BG
7991 struct netlink_config *cfg;
7992
f2ed8023
JM
7993 global = os_zalloc(sizeof(*global));
7994 if (global == NULL)
7995 return NULL;
45e3fc72 7996 global->ctx = ctx;
c81eff1a 7997 global->ioctl_sock = -1;
f2ed8023 7998 dl_list_init(&global->interfaces);
ff6a158b 7999 global->if_add_ifindex = -1;
36d84860
BG
8000
8001 cfg = os_zalloc(sizeof(*cfg));
8002 if (cfg == NULL)
8003 goto err;
8004
8005 cfg->ctx = global;
8006 cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
8007 cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
8008 global->netlink = netlink_init(cfg);
8009 if (global->netlink == NULL) {
8010 os_free(cfg);
8011 goto err;
8012 }
8013
2a7b66f5
BG
8014 if (wpa_driver_nl80211_init_nl_global(global) < 0)
8015 goto err;
8016
c81eff1a
BG
8017 global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
8018 if (global->ioctl_sock < 0) {
7ac3616d
JM
8019 wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
8020 strerror(errno));
c81eff1a
BG
8021 goto err;
8022 }
8023
f2ed8023 8024 return global;
36d84860
BG
8025
8026err:
8027 nl80211_global_deinit(global);
8028 return NULL;
f2ed8023
JM
8029}
8030
8031
8032static void nl80211_global_deinit(void *priv)
8033{
8034 struct nl80211_global *global = priv;
8035 if (global == NULL)
8036 return;
8037 if (!dl_list_empty(&global->interfaces)) {
8038 wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
8039 "nl80211_global_deinit",
8040 dl_list_len(&global->interfaces));
8041 }
36d84860
BG
8042
8043 if (global->netlink)
8044 netlink_deinit(global->netlink);
8045
276e2d67
BG
8046 nl_destroy_handles(&global->nl);
8047
5f65e9f7 8048 if (global->nl_event)
40a68f33 8049 nl80211_destroy_eloop_handle(&global->nl_event, 0);
d6c9aab8
JB
8050
8051 nl_cb_put(global->nl_cb);
2a7b66f5 8052
c81eff1a
BG
8053 if (global->ioctl_sock >= 0)
8054 close(global->ioctl_sock);
8055
f2ed8023
JM
8056 os_free(global);
8057}
8058
8059
6859f1cb
BG
8060static const char * nl80211_get_radio_name(void *priv)
8061{
8062 struct i802_bss *bss = priv;
8063 struct wpa_driver_nl80211_data *drv = bss->drv;
8064 return drv->phyname;
8065}
8066
8067
061a3d3d
VK
8068static int nl80211_pmkid(struct i802_bss *bss, int cmd,
8069 struct wpa_pmkid_params *params)
a6efc65d
JM
8070{
8071 struct nl_msg *msg;
0887215d 8072 const size_t PMK_MAX_LEN = 48; /* current cfg80211 limit */
a6efc65d 8073
13f83980 8074 if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
061a3d3d
VK
8075 (params->pmkid &&
8076 nla_put(msg, NL80211_ATTR_PMKID, 16, params->pmkid)) ||
8077 (params->bssid &&
8078 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid)) ||
8079 (params->ssid_len &&
8080 nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid)) ||
8081 (params->fils_cache_id &&
8082 nla_put(msg, NL80211_ATTR_FILS_CACHE_ID, 2,
8083 params->fils_cache_id)) ||
c6ec9759 8084 (cmd != NL80211_CMD_DEL_PMKSA &&
8085 params->pmk_len && params->pmk_len <= PMK_MAX_LEN &&
061a3d3d 8086 nla_put(msg, NL80211_ATTR_PMK, params->pmk_len, params->pmk))) {
6110753b 8087 nl80211_nlmsg_clear(msg);
a862e4a3
JM
8088 nlmsg_free(msg);
8089 return -ENOBUFS;
8090 }
a6efc65d 8091
6110753b 8092 return send_and_recv_msgs(bss->drv, msg, NULL, (void *) -1);
a6efc65d
JM
8093}
8094
8095
6fbb5414 8096static int nl80211_add_pmkid(void *priv, struct wpa_pmkid_params *params)
a6efc65d
JM
8097{
8098 struct i802_bss *bss = priv;
e7f6e6ee 8099 int ret;
061a3d3d
VK
8100
8101 if (params->bssid)
8102 wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR,
8103 MAC2STR(params->bssid));
8104 else if (params->fils_cache_id && params->ssid_len) {
8105 wpa_printf(MSG_DEBUG,
8106 "nl80211: Add PMKSA for cache id %02x%02x SSID %s",
8107 params->fils_cache_id[0], params->fils_cache_id[1],
8108 wpa_ssid_txt(params->ssid, params->ssid_len));
8109 }
8110
e7f6e6ee
JM
8111 ret = nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, params);
8112 if (ret < 0) {
8113 wpa_printf(MSG_DEBUG,
8114 "nl80211: NL80211_CMD_SET_PMKSA failed: %d (%s)",
8115 ret, strerror(-ret));
8116 }
8117
8118 return ret;
a6efc65d
JM
8119}
8120
8121
6fbb5414 8122static int nl80211_remove_pmkid(void *priv, struct wpa_pmkid_params *params)
a6efc65d
JM
8123{
8124 struct i802_bss *bss = priv;
e7f6e6ee 8125 int ret;
061a3d3d
VK
8126
8127 if (params->bssid)
8128 wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
8129 MAC2STR(params->bssid));
8130 else if (params->fils_cache_id && params->ssid_len) {
8131 wpa_printf(MSG_DEBUG,
8132 "nl80211: Delete PMKSA for cache id %02x%02x SSID %s",
8133 params->fils_cache_id[0], params->fils_cache_id[1],
8134 wpa_ssid_txt(params->ssid, params->ssid_len));
8135 }
8136
e7f6e6ee
JM
8137 ret = nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, params);
8138 if (ret < 0) {
8139 wpa_printf(MSG_DEBUG,
8140 "nl80211: NL80211_CMD_DEL_PMKSA failed: %d (%s)",
8141 ret, strerror(-ret));
8142 }
8143
8144 return ret;
a6efc65d
JM
8145}
8146
8147
8148static int nl80211_flush_pmkid(void *priv)
8149{
8150 struct i802_bss *bss = priv;
061a3d3d
VK
8151 struct nl_msg *msg;
8152
a6efc65d 8153 wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
061a3d3d
VK
8154 msg = nl80211_bss_msg(bss, 0, NL80211_CMD_FLUSH_PMKSA);
8155 if (!msg)
8156 return -ENOBUFS;
8157 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
a6efc65d
JM
8158}
8159
8160
0185007c
MK
8161static void clean_survey_results(struct survey_results *survey_results)
8162{
8163 struct freq_survey *survey, *tmp;
8164
8165 if (dl_list_empty(&survey_results->survey_list))
8166 return;
8167
8168 dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
8169 struct freq_survey, list) {
8170 dl_list_del(&survey->list);
8171 os_free(survey);
8172 }
8173}
8174
8175
8176static void add_survey(struct nlattr **sinfo, u32 ifidx,
8177 struct dl_list *survey_list)
8178{
8179 struct freq_survey *survey;
8180
8181 survey = os_zalloc(sizeof(struct freq_survey));
8182 if (!survey)
8183 return;
8184
8185 survey->ifidx = ifidx;
8186 survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
8187 survey->filled = 0;
8188
8189 if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
8190 survey->nf = (int8_t)
8191 nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
8192 survey->filled |= SURVEY_HAS_NF;
8193 }
8194
8195 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
8196 survey->channel_time =
8197 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
8198 survey->filled |= SURVEY_HAS_CHAN_TIME;
8199 }
8200
8201 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
8202 survey->channel_time_busy =
8203 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
8204 survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
8205 }
8206
8207 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
8208 survey->channel_time_rx =
8209 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
8210 survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
8211 }
8212
8213 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
8214 survey->channel_time_tx =
8215 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
8216 survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
8217 }
8218
8219 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)",
8220 survey->freq,
8221 survey->nf,
8222 (unsigned long int) survey->channel_time,
8223 (unsigned long int) survey->channel_time_busy,
8224 (unsigned long int) survey->channel_time_tx,
8225 (unsigned long int) survey->channel_time_rx,
8226 survey->filled);
8227
8228 dl_list_add_tail(survey_list, &survey->list);
8229}
8230
8231
8232static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
8233 unsigned int freq_filter)
8234{
8235 if (!freq_filter)
8236 return 1;
8237
8238 return freq_filter == surveyed_freq;
8239}
8240
8241
8242static int survey_handler(struct nl_msg *msg, void *arg)
8243{
8244 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8245 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8246 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
8247 struct survey_results *survey_results;
8248 u32 surveyed_freq = 0;
8249 u32 ifidx;
8250
8251 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
8252 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
8253 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
8254 };
8255
8256 survey_results = (struct survey_results *) arg;
8257
8258 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8259 genlmsg_attrlen(gnlh, 0), NULL);
8260
e28f39b7
SJ
8261 if (!tb[NL80211_ATTR_IFINDEX])
8262 return NL_SKIP;
8263
0185007c
MK
8264 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
8265
8266 if (!tb[NL80211_ATTR_SURVEY_INFO])
8267 return NL_SKIP;
8268
8269 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
8270 tb[NL80211_ATTR_SURVEY_INFO],
8271 survey_policy))
8272 return NL_SKIP;
8273
8274 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
8275 wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
8276 return NL_SKIP;
8277 }
8278
8279 surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
8280
8281 if (!check_survey_ok(sinfo, surveyed_freq,
8282 survey_results->freq_filter))
8283 return NL_SKIP;
8284
8285 if (survey_results->freq_filter &&
8286 survey_results->freq_filter != surveyed_freq) {
8287 wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
8288 surveyed_freq);
8289 return NL_SKIP;
8290 }
8291
8292 add_survey(sinfo, ifidx, &survey_results->survey_list);
8293
8294 return NL_SKIP;
8295}
8296
8297
8298static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
8299{
8300 struct i802_bss *bss = priv;
8301 struct wpa_driver_nl80211_data *drv = bss->drv;
8302 struct nl_msg *msg;
9725b784 8303 int err;
0185007c
MK
8304 union wpa_event_data data;
8305 struct survey_results *survey_results;
8306
8307 os_memset(&data, 0, sizeof(data));
8308 survey_results = &data.survey_results;
8309
8310 dl_list_init(&survey_results->survey_list);
8311
9725b784 8312 msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
0185007c 8313 if (!msg)
a862e4a3 8314 return -ENOBUFS;
0185007c 8315
0185007c
MK
8316 if (freq)
8317 data.survey_results.freq_filter = freq;
8318
8319 do {
8320 wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
8321 err = send_and_recv_msgs(drv, msg, survey_handler,
8322 survey_results);
8323 } while (err > 0);
8324
a862e4a3 8325 if (err)
0185007c 8326 wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
a862e4a3
JM
8327 else
8328 wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
0185007c 8329
0185007c 8330 clean_survey_results(survey_results);
0185007c
MK
8331 return err;
8332}
8333
8334
98cd3d1c
JM
8335static void nl80211_set_rekey_info(void *priv, const u8 *kek, size_t kek_len,
8336 const u8 *kck, size_t kck_len,
b14a210c
JB
8337 const u8 *replay_ctr)
8338{
8339 struct i802_bss *bss = priv;
8340 struct wpa_driver_nl80211_data *drv = bss->drv;
8341 struct nlattr *replay_nested;
8342 struct nl_msg *msg;
64ae2447 8343 int ret;
b14a210c 8344
64ae2447
JM
8345 if (!drv->set_rekey_offload)
8346 return;
8347
8348 wpa_printf(MSG_DEBUG, "nl80211: Set rekey offload");
13f83980 8349 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_REKEY_OFFLOAD)) ||
a862e4a3 8350 !(replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA)) ||
98cd3d1c 8351 nla_put(msg, NL80211_REKEY_DATA_KEK, kek_len, kek) ||
b6ea7642 8352 (kck_len && nla_put(msg, NL80211_REKEY_DATA_KCK, kck_len, kck)) ||
a862e4a3
JM
8353 nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
8354 replay_ctr)) {
bbd89bfc 8355 nl80211_nlmsg_clear(msg);
a862e4a3
JM
8356 nlmsg_free(msg);
8357 return;
8358 }
b14a210c
JB
8359
8360 nla_nest_end(msg, replay_nested);
8361
64ae2447
JM
8362 ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
8363 if (ret == -EOPNOTSUPP) {
8364 wpa_printf(MSG_DEBUG,
8365 "nl80211: Driver does not support rekey offload");
8366 drv->set_rekey_offload = 0;
8367 }
b14a210c
JB
8368}
8369
8370
39718852
JB
8371static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
8372 const u8 *addr, int qos)
bcf24348 8373{
39718852
JB
8374 /* send data frame to poll STA and check whether
8375 * this frame is ACKed */
bcf24348
JB
8376 struct {
8377 struct ieee80211_hdr hdr;
8378 u16 qos_ctl;
8379 } STRUCT_PACKED nulldata;
8380 size_t size;
8381
8382 /* Send data frame to poll STA and check whether this frame is ACKed */
8383
8384 os_memset(&nulldata, 0, sizeof(nulldata));
8385
8386 if (qos) {
8387 nulldata.hdr.frame_control =
8388 IEEE80211_FC(WLAN_FC_TYPE_DATA,
8389 WLAN_FC_STYPE_QOS_NULL);
8390 size = sizeof(nulldata);
8391 } else {
8392 nulldata.hdr.frame_control =
8393 IEEE80211_FC(WLAN_FC_TYPE_DATA,
8394 WLAN_FC_STYPE_NULLFUNC);
8395 size = sizeof(struct ieee80211_hdr);
8396 }
8397
8398 nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
8399 os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
8400 os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
8401 os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
8402
9ebce9c5 8403 if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
27cc06d0 8404 0, 0, NULL, 0, 0) < 0)
bcf24348
JB
8405 wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
8406 "send poll frame");
8407}
8408
39718852
JB
8409static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
8410 int qos)
8411{
8412 struct i802_bss *bss = priv;
8413 struct wpa_driver_nl80211_data *drv = bss->drv;
8414 struct nl_msg *msg;
323a51cc 8415 u64 cookie;
fc99fab7 8416 int ret;
39718852
JB
8417
8418 if (!drv->poll_command_supported) {
8419 nl80211_send_null_frame(bss, own_addr, addr, qos);
8420 return;
8421 }
8422
13f83980 8423 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_PROBE_CLIENT)) ||
a862e4a3
JM
8424 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
8425 nlmsg_free(msg);
8426 return;
8427 }
39718852 8428
323a51cc 8429 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
fc99fab7
JM
8430 if (ret < 0) {
8431 wpa_printf(MSG_DEBUG, "nl80211: Client probe request for "
8432 MACSTR " failed: ret=%d (%s)",
8433 MAC2STR(addr), ret, strerror(-ret));
323a51cc
IP
8434 } else {
8435 wpa_printf(MSG_DEBUG,
8436 "nl80211: Client probe request addr=" MACSTR
8437 " cookie=%llu", MAC2STR(addr),
8438 (long long unsigned int) cookie);
fc99fab7 8439 }
39718852
JB
8440}
8441
bcf24348 8442
29f338af
JM
8443static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
8444{
8445 struct nl_msg *msg;
1baa130b 8446 int ret;
29f338af 8447
13f83980 8448 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_POWER_SAVE)) ||
a862e4a3
JM
8449 nla_put_u32(msg, NL80211_ATTR_PS_STATE,
8450 enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED)) {
8451 nlmsg_free(msg);
8452 return -ENOBUFS;
8453 }
1baa130b
JM
8454
8455 ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
8456 if (ret < 0) {
8457 wpa_printf(MSG_DEBUG,
8458 "nl80211: Setting PS state %s failed: %d (%s)",
8459 enabled ? "enabled" : "disabled",
8460 ret, strerror(-ret));
8461 }
8462 return ret;
29f338af
JM
8463}
8464
8465
8466static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
8467 int ctwindow)
8468{
8469 struct i802_bss *bss = priv;
8470
8471 wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
8472 "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
8473
0de38036
JM
8474 if (opp_ps != -1 || ctwindow != -1) {
8475#ifdef ANDROID_P2P
8476 wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
8477#else /* ANDROID_P2P */
29f338af 8478 return -1; /* Not yet supported */
0de38036
JM
8479#endif /* ANDROID_P2P */
8480 }
29f338af
JM
8481
8482 if (legacy_ps == -1)
8483 return 0;
8484 if (legacy_ps != 0 && legacy_ps != 1)
8485 return -1; /* Not yet supported */
8486
8487 return nl80211_set_power_save(bss, legacy_ps);
8488}
8489
8490
04e8003c
JD
8491static int nl80211_start_radar_detection(void *priv,
8492 struct hostapd_freq_params *freq)
f90e9c1c
SW
8493{
8494 struct i802_bss *bss = priv;
8495 struct wpa_driver_nl80211_data *drv = bss->drv;
8496 struct nl_msg *msg;
8497 int ret;
8498
ad9a1bfe
JC
8499 wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC) %d MHz (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
8500 freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled,
04e8003c
JD
8501 freq->bandwidth, freq->center_freq1, freq->center_freq2);
8502
f90e9c1c
SW
8503 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
8504 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
8505 "detection");
8506 return -1;
8507 }
8508
9725b784 8509 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_RADAR_DETECT)) ||
a862e4a3
JM
8510 nl80211_put_freq_params(msg, freq) < 0) {
8511 nlmsg_free(msg);
8512 return -1;
8513 }
f90e9c1c
SW
8514
8515 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8516 if (ret == 0)
8517 return 0;
8518 wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
8519 "%d (%s)", ret, strerror(-ret));
f90e9c1c
SW
8520 return -1;
8521}
8522
03ea1786
AN
8523#ifdef CONFIG_TDLS
8524
8525static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
8526 u8 dialog_token, u16 status_code,
984dadc2
AN
8527 u32 peer_capab, int initiator, const u8 *buf,
8528 size_t len)
03ea1786
AN
8529{
8530 struct i802_bss *bss = priv;
8531 struct wpa_driver_nl80211_data *drv = bss->drv;
8532 struct nl_msg *msg;
8533
8534 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
8535 return -EOPNOTSUPP;
8536
8537 if (!dst)
8538 return -EINVAL;
8539
9725b784 8540 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_TDLS_MGMT)) ||
a862e4a3
JM
8541 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
8542 nla_put_u8(msg, NL80211_ATTR_TDLS_ACTION, action_code) ||
8543 nla_put_u8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token) ||
8544 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status_code))
8545 goto fail;
96ecea5e
SD
8546 if (peer_capab) {
8547 /*
8548 * The internal enum tdls_peer_capability definition is
8549 * currently identical with the nl80211 enum
8550 * nl80211_tdls_peer_capability, so no conversion is needed
8551 * here.
8552 */
a862e4a3
JM
8553 if (nla_put_u32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY,
8554 peer_capab))
8555 goto fail;
96ecea5e 8556 }
a862e4a3
JM
8557 if ((initiator &&
8558 nla_put_flag(msg, NL80211_ATTR_TDLS_INITIATOR)) ||
8559 nla_put(msg, NL80211_ATTR_IE, len, buf))
8560 goto fail;
03ea1786
AN
8561
8562 return send_and_recv_msgs(drv, msg, NULL, NULL);
8563
a862e4a3 8564fail:
03ea1786
AN
8565 nlmsg_free(msg);
8566 return -ENOBUFS;
8567}
8568
8569
8570static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
8571{
8572 struct i802_bss *bss = priv;
8573 struct wpa_driver_nl80211_data *drv = bss->drv;
8574 struct nl_msg *msg;
8575 enum nl80211_tdls_operation nl80211_oper;
b2442f25 8576 int res;
03ea1786
AN
8577
8578 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
8579 return -EOPNOTSUPP;
8580
8581 switch (oper) {
8582 case TDLS_DISCOVERY_REQ:
8583 nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
8584 break;
8585 case TDLS_SETUP:
8586 nl80211_oper = NL80211_TDLS_SETUP;
8587 break;
8588 case TDLS_TEARDOWN:
8589 nl80211_oper = NL80211_TDLS_TEARDOWN;
8590 break;
8591 case TDLS_ENABLE_LINK:
8592 nl80211_oper = NL80211_TDLS_ENABLE_LINK;
8593 break;
8594 case TDLS_DISABLE_LINK:
8595 nl80211_oper = NL80211_TDLS_DISABLE_LINK;
8596 break;
8597 case TDLS_ENABLE:
8598 return 0;
8599 case TDLS_DISABLE:
8600 return 0;
8601 default:
8602 return -EINVAL;
8603 }
8604
9725b784 8605 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_TDLS_OPER)) ||
a862e4a3 8606 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper) ||
a862e4a3
JM
8607 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) {
8608 nlmsg_free(msg);
8609 return -ENOBUFS;
8610 }
03ea1786 8611
b2442f25
JM
8612 res = send_and_recv_msgs(drv, msg, NULL, NULL);
8613 wpa_printf(MSG_DEBUG, "nl80211: TDLS_OPER: oper=%d mac=" MACSTR
8614 " --> res=%d (%s)", nl80211_oper, MAC2STR(peer), res,
8615 strerror(-res));
8616 return res;
03ea1786
AN
8617}
8618
72b2605f
AN
8619
8620static int
8621nl80211_tdls_enable_channel_switch(void *priv, const u8 *addr, u8 oper_class,
8622 const struct hostapd_freq_params *params)
8623{
8624 struct i802_bss *bss = priv;
8625 struct wpa_driver_nl80211_data *drv = bss->drv;
8626 struct nl_msg *msg;
8627 int ret = -ENOBUFS;
8628
8629 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) ||
8630 !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH))
8631 return -EOPNOTSUPP;
8632
8633 wpa_printf(MSG_DEBUG, "nl80211: Enable TDLS channel switch " MACSTR
8634 " oper_class=%u freq=%u",
8635 MAC2STR(addr), oper_class, params->freq);
8636 msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_TDLS_CHANNEL_SWITCH);
8637 if (!msg ||
8638 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
8639 nla_put_u8(msg, NL80211_ATTR_OPER_CLASS, oper_class) ||
8640 (ret = nl80211_put_freq_params(msg, params))) {
8641 nlmsg_free(msg);
8642 wpa_printf(MSG_DEBUG, "nl80211: Could not build TDLS chan switch");
8643 return ret;
8644 }
8645
8646 return send_and_recv_msgs(drv, msg, NULL, NULL);
8647}
8648
8649
8650static int
8651nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr)
8652{
8653 struct i802_bss *bss = priv;
8654 struct wpa_driver_nl80211_data *drv = bss->drv;
8655 struct nl_msg *msg;
8656
8657 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) ||
8658 !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH))
8659 return -EOPNOTSUPP;
8660
8661 wpa_printf(MSG_DEBUG, "nl80211: Disable TDLS channel switch " MACSTR,
8662 MAC2STR(addr));
8663 msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH);
8664 if (!msg ||
8665 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
8666 nlmsg_free(msg);
8667 wpa_printf(MSG_DEBUG,
8668 "nl80211: Could not build TDLS cancel chan switch");
8669 return -ENOBUFS;
8670 }
8671
8672 return send_and_recv_msgs(drv, msg, NULL, NULL);
8673}
8674
03ea1786
AN
8675#endif /* CONFIG TDLS */
8676
8677
9ebce9c5
JM
8678static int driver_nl80211_set_key(const char *ifname, void *priv,
8679 enum wpa_alg alg, const u8 *addr,
8680 int key_idx, int set_tx,
8681 const u8 *seq, size_t seq_len,
8682 const u8 *key, size_t key_len)
8683{
8684 struct i802_bss *bss = priv;
8685 return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
8686 set_tx, seq, seq_len, key, key_len);
8687}
8688
8689
8690static int driver_nl80211_scan2(void *priv,
8691 struct wpa_driver_scan_params *params)
8692{
8693 struct i802_bss *bss = priv;
b658547d 8694#ifdef CONFIG_DRIVER_NL80211_QCA
adcd7c4b
KV
8695 struct wpa_driver_nl80211_data *drv = bss->drv;
8696
8697 /*
8698 * Do a vendor specific scan if possible. If only_new_results is
8699 * set, do a normal scan since a kernel (cfg80211) BSS cache flush
8700 * cannot be achieved through a vendor scan. The below condition may
8701 * need to be modified if new scan flags are added in the future whose
8702 * functionality can only be achieved through a normal scan.
8703 */
8704 if (drv->scan_vendor_cmd_avail && !params->only_new_results)
8705 return wpa_driver_nl80211_vendor_scan(bss, params);
b658547d 8706#endif /* CONFIG_DRIVER_NL80211_QCA */
9ebce9c5
JM
8707 return wpa_driver_nl80211_scan(bss, params);
8708}
8709
8710
8711static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
4be17ffb 8712 u16 reason_code)
9ebce9c5
JM
8713{
8714 struct i802_bss *bss = priv;
8715 return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
8716}
8717
8718
8719static int driver_nl80211_authenticate(void *priv,
8720 struct wpa_driver_auth_params *params)
8721{
8722 struct i802_bss *bss = priv;
8723 return wpa_driver_nl80211_authenticate(bss, params);
8724}
8725
8726
8727static void driver_nl80211_deinit(void *priv)
8728{
8729 struct i802_bss *bss = priv;
8730 wpa_driver_nl80211_deinit(bss);
8731}
8732
8733
8734static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
8735 const char *ifname)
8736{
8737 struct i802_bss *bss = priv;
8738 return wpa_driver_nl80211_if_remove(bss, type, ifname);
8739}
8740
8741
8742static int driver_nl80211_send_mlme(void *priv, const u8 *data,
5d180a77 8743 size_t data_len, int noack,
2d3943ce 8744 unsigned int freq,
665a3007
JM
8745 const u16 *csa_offs, size_t csa_offs_len,
8746 int no_encrypt)
9ebce9c5
JM
8747{
8748 struct i802_bss *bss = priv;
8749 return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
2d3943ce 8750 freq, 0, 0, 0, csa_offs,
27cc06d0 8751 csa_offs_len, no_encrypt);
9ebce9c5
JM
8752}
8753
8754
8755static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
8756{
8757 struct i802_bss *bss = priv;
59d7148a 8758 return wpa_driver_nl80211_sta_remove(bss, addr, -1, 0);
9ebce9c5
JM
8759}
8760
8761
9ebce9c5
JM
8762static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
8763 const char *ifname, int vlan_id)
8764{
8765 struct i802_bss *bss = priv;
8766 return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
8767}
9ebce9c5
JM
8768
8769
8770static int driver_nl80211_read_sta_data(void *priv,
8771 struct hostap_sta_driver_data *data,
8772 const u8 *addr)
8773{
8774 struct i802_bss *bss = priv;
7824bf77
JC
8775
8776 os_memset(data, 0, sizeof(*data));
9ebce9c5
JM
8777 return i802_read_sta_data(bss, data, addr);
8778}
8779
8780
8781static int driver_nl80211_send_action(void *priv, unsigned int freq,
8782 unsigned int wait_time,
8783 const u8 *dst, const u8 *src,
8784 const u8 *bssid,
8785 const u8 *data, size_t data_len,
8786 int no_cck)
8787{
8788 struct i802_bss *bss = priv;
8789 return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
8790 bssid, data, data_len, no_cck);
8791}
8792
8793
8794static int driver_nl80211_probe_req_report(void *priv, int report)
8795{
8796 struct i802_bss *bss = priv;
8797 return wpa_driver_nl80211_probe_req_report(bss, report);
8798}
8799
8800
6a1ce395
DG
8801static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
8802 const u8 *ies, size_t ies_len)
8803{
8804 int ret;
8805 struct nl_msg *msg;
8806 struct i802_bss *bss = priv;
8807 struct wpa_driver_nl80211_data *drv = bss->drv;
8808 u16 mdid = WPA_GET_LE16(md);
8809
6a1ce395 8810 wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
9725b784 8811 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_UPDATE_FT_IES)) ||
a862e4a3
JM
8812 nla_put(msg, NL80211_ATTR_IE, ies_len, ies) ||
8813 nla_put_u16(msg, NL80211_ATTR_MDID, mdid)) {
8814 nlmsg_free(msg);
8815 return -ENOBUFS;
8816 }
6a1ce395
DG
8817
8818 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8819 if (ret) {
8820 wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
8821 "err=%d (%s)", ret, strerror(-ret));
8822 }
8823
8824 return ret;
6a1ce395
DG
8825}
8826
8827
d1836e23
LD
8828static int nl80211_update_dh_ie(void *priv, const u8 *peer_mac,
8829 u16 reason_code, const u8 *ie, size_t ie_len)
8830{
8831 int ret;
8832 struct nl_msg *msg;
8833 struct i802_bss *bss = priv;
8834 struct wpa_driver_nl80211_data *drv = bss->drv;
8835
8836 wpa_printf(MSG_DEBUG, "nl80211: Updating DH IE peer: " MACSTR
8837 " reason %u", MAC2STR(peer_mac), reason_code);
8838 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_UPDATE_OWE_INFO)) ||
8839 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer_mac) ||
8840 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, reason_code) ||
8841 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie))) {
8842 nlmsg_free(msg);
8843 return -ENOBUFS;
8844 }
8845
8846 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8847 if (ret) {
8848 wpa_printf(MSG_DEBUG,
8849 "nl80211: update_dh_ie failed err=%d (%s)",
8850 ret, strerror(-ret));
8851 }
8852
8853 return ret;
8854}
8855
8856
47754718 8857static const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
597b94f5
AS
8858{
8859 struct i802_bss *bss = priv;
8860 struct wpa_driver_nl80211_data *drv = bss->drv;
8861
8862 if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
8863 return NULL;
8864
8865 return bss->addr;
8866}
8867
8868
a771c07d
JM
8869static const char * scan_state_str(enum scan_states scan_state)
8870{
8871 switch (scan_state) {
8872 case NO_SCAN:
8873 return "NO_SCAN";
8874 case SCAN_REQUESTED:
8875 return "SCAN_REQUESTED";
8876 case SCAN_STARTED:
8877 return "SCAN_STARTED";
8878 case SCAN_COMPLETED:
8879 return "SCAN_COMPLETED";
8880 case SCAN_ABORTED:
8881 return "SCAN_ABORTED";
8882 case SCHED_SCAN_STARTED:
8883 return "SCHED_SCAN_STARTED";
8884 case SCHED_SCAN_STOPPED:
8885 return "SCHED_SCAN_STOPPED";
8886 case SCHED_SCAN_RESULTS:
8887 return "SCHED_SCAN_RESULTS";
8888 }
8889
8890 return "??";
8891}
8892
8893
8894static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
8895{
8896 struct i802_bss *bss = priv;
8897 struct wpa_driver_nl80211_data *drv = bss->drv;
8898 int res;
8899 char *pos, *end;
fea49f8f
JM
8900 struct nl_msg *msg;
8901 char alpha2[3] = { 0, 0, 0 };
a771c07d
JM
8902
8903 pos = buf;
8904 end = buf + buflen;
8905
8906 res = os_snprintf(pos, end - pos,
8907 "ifindex=%d\n"
8908 "ifname=%s\n"
8909 "brname=%s\n"
8910 "addr=" MACSTR "\n"
8911 "freq=%d\n"
c809756f 8912 "%s%s%s%s%s%s",
a771c07d
JM
8913 bss->ifindex,
8914 bss->ifname,
8915 bss->brname,
8916 MAC2STR(bss->addr),
8917 bss->freq,
8918 bss->beacon_set ? "beacon_set=1\n" : "",
8919 bss->added_if_into_bridge ?
8920 "added_if_into_bridge=1\n" : "",
c809756f 8921 bss->already_in_bridge ? "already_in_bridge=1\n" : "",
a771c07d
JM
8922 bss->added_bridge ? "added_bridge=1\n" : "",
8923 bss->in_deinit ? "in_deinit=1\n" : "",
8924 bss->if_dynamic ? "if_dynamic=1\n" : "");
d85e1fc8 8925 if (os_snprintf_error(end - pos, res))
a771c07d
JM
8926 return pos - buf;
8927 pos += res;
8928
8929 if (bss->wdev_id_set) {
8930 res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
8931 (unsigned long long) bss->wdev_id);
d85e1fc8 8932 if (os_snprintf_error(end - pos, res))
a771c07d
JM
8933 return pos - buf;
8934 pos += res;
8935 }
8936
8937 res = os_snprintf(pos, end - pos,
8938 "phyname=%s\n"
fee354c7 8939 "perm_addr=" MACSTR "\n"
a771c07d
JM
8940 "drv_ifindex=%d\n"
8941 "operstate=%d\n"
8942 "scan_state=%s\n"
8943 "auth_bssid=" MACSTR "\n"
8944 "auth_attempt_bssid=" MACSTR "\n"
8945 "bssid=" MACSTR "\n"
8946 "prev_bssid=" MACSTR "\n"
8947 "associated=%d\n"
8948 "assoc_freq=%u\n"
8949 "monitor_sock=%d\n"
8950 "monitor_ifidx=%d\n"
8951 "monitor_refcount=%d\n"
8952 "last_mgmt_freq=%u\n"
8953 "eapol_tx_sock=%d\n"
97752f79 8954 "%s%s%s%s%s%s%s%s%s%s%s%s%s",
a771c07d 8955 drv->phyname,
fee354c7 8956 MAC2STR(drv->perm_addr),
a771c07d
JM
8957 drv->ifindex,
8958 drv->operstate,
8959 scan_state_str(drv->scan_state),
8960 MAC2STR(drv->auth_bssid),
8961 MAC2STR(drv->auth_attempt_bssid),
8962 MAC2STR(drv->bssid),
8963 MAC2STR(drv->prev_bssid),
8964 drv->associated,
8965 drv->assoc_freq,
8966 drv->monitor_sock,
8967 drv->monitor_ifidx,
8968 drv->monitor_refcount,
8969 drv->last_mgmt_freq,
8970 drv->eapol_tx_sock,
8971 drv->ignore_if_down_event ?
8972 "ignore_if_down_event=1\n" : "",
8973 drv->scan_complete_events ?
8974 "scan_complete_events=1\n" : "",
8975 drv->disabled_11b_rates ?
8976 "disabled_11b_rates=1\n" : "",
8977 drv->pending_remain_on_chan ?
8978 "pending_remain_on_chan=1\n" : "",
8979 drv->in_interface_list ? "in_interface_list=1\n" : "",
8980 drv->device_ap_sme ? "device_ap_sme=1\n" : "",
8981 drv->poll_command_supported ?
8982 "poll_command_supported=1\n" : "",
8983 drv->data_tx_status ? "data_tx_status=1\n" : "",
8984 drv->scan_for_auth ? "scan_for_auth=1\n" : "",
8985 drv->retry_auth ? "retry_auth=1\n" : "",
8986 drv->use_monitor ? "use_monitor=1\n" : "",
8987 drv->ignore_next_local_disconnect ?
8988 "ignore_next_local_disconnect=1\n" : "",
d6a36f39 8989 drv->ignore_next_local_deauth ?
97752f79 8990 "ignore_next_local_deauth=1\n" : "");
d85e1fc8 8991 if (os_snprintf_error(end - pos, res))
a771c07d
JM
8992 return pos - buf;
8993 pos += res;
8994
8995 if (drv->has_capability) {
8996 res = os_snprintf(pos, end - pos,
8997 "capa.key_mgmt=0x%x\n"
8998 "capa.enc=0x%x\n"
8999 "capa.auth=0x%x\n"
24bd4e0b 9000 "capa.flags=0x%llx\n"
a0a34d53 9001 "capa.rrm_flags=0x%x\n"
a771c07d
JM
9002 "capa.max_scan_ssids=%d\n"
9003 "capa.max_sched_scan_ssids=%d\n"
9004 "capa.sched_scan_supported=%d\n"
9005 "capa.max_match_sets=%d\n"
9006 "capa.max_remain_on_chan=%u\n"
9007 "capa.max_stations=%u\n"
9008 "capa.probe_resp_offloads=0x%x\n"
9009 "capa.max_acl_mac_addrs=%u\n"
86056fea
IP
9010 "capa.num_multichan_concurrent=%u\n"
9011 "capa.mac_addr_rand_sched_scan_supported=%d\n"
079a28f7
AK
9012 "capa.mac_addr_rand_scan_supported=%d\n"
9013 "capa.conc_capab=%u\n"
9014 "capa.max_conc_chan_2_4=%u\n"
09ea4309
AS
9015 "capa.max_conc_chan_5_0=%u\n"
9016 "capa.max_sched_scan_plans=%u\n"
9017 "capa.max_sched_scan_plan_interval=%u\n"
9018 "capa.max_sched_scan_plan_iterations=%u\n",
a771c07d
JM
9019 drv->capa.key_mgmt,
9020 drv->capa.enc,
9021 drv->capa.auth,
24bd4e0b 9022 (unsigned long long) drv->capa.flags,
a0a34d53 9023 drv->capa.rrm_flags,
a771c07d
JM
9024 drv->capa.max_scan_ssids,
9025 drv->capa.max_sched_scan_ssids,
9026 drv->capa.sched_scan_supported,
9027 drv->capa.max_match_sets,
9028 drv->capa.max_remain_on_chan,
9029 drv->capa.max_stations,
9030 drv->capa.probe_resp_offloads,
9031 drv->capa.max_acl_mac_addrs,
86056fea
IP
9032 drv->capa.num_multichan_concurrent,
9033 drv->capa.mac_addr_rand_sched_scan_supported,
079a28f7
AK
9034 drv->capa.mac_addr_rand_scan_supported,
9035 drv->capa.conc_capab,
9036 drv->capa.max_conc_chan_2_4,
09ea4309
AS
9037 drv->capa.max_conc_chan_5_0,
9038 drv->capa.max_sched_scan_plans,
9039 drv->capa.max_sched_scan_plan_interval,
9040 drv->capa.max_sched_scan_plan_iterations);
d85e1fc8 9041 if (os_snprintf_error(end - pos, res))
a771c07d
JM
9042 return pos - buf;
9043 pos += res;
9044 }
9045
fea49f8f
JM
9046 msg = nlmsg_alloc();
9047 if (msg &&
9048 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG) &&
9049 nla_put_u32(msg, NL80211_ATTR_WIPHY, drv->wiphy_idx) == 0) {
9050 if (send_and_recv_msgs(drv, msg, nl80211_get_country,
9051 alpha2) == 0 &&
9052 alpha2[0]) {
9053 res = os_snprintf(pos, end - pos, "country=%s\n",
9054 alpha2);
9055 if (os_snprintf_error(end - pos, res))
9056 return pos - buf;
9057 pos += res;
9058 }
9059 } else {
9060 nlmsg_free(msg);
9061 }
9062
a771c07d
JM
9063 return pos - buf;
9064}
9065
9066
1c4ffa87
AO
9067static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
9068{
a862e4a3
JM
9069 if ((settings->head &&
9070 nla_put(msg, NL80211_ATTR_BEACON_HEAD,
9071 settings->head_len, settings->head)) ||
9072 (settings->tail &&
9073 nla_put(msg, NL80211_ATTR_BEACON_TAIL,
9074 settings->tail_len, settings->tail)) ||
9075 (settings->beacon_ies &&
9076 nla_put(msg, NL80211_ATTR_IE,
9077 settings->beacon_ies_len, settings->beacon_ies)) ||
9078 (settings->proberesp_ies &&
9079 nla_put(msg, NL80211_ATTR_IE_PROBE_RESP,
9080 settings->proberesp_ies_len, settings->proberesp_ies)) ||
9081 (settings->assocresp_ies &&
9082 nla_put(msg, NL80211_ATTR_IE_ASSOC_RESP,
9083 settings->assocresp_ies_len, settings->assocresp_ies)) ||
9084 (settings->probe_resp &&
9085 nla_put(msg, NL80211_ATTR_PROBE_RESP,
9086 settings->probe_resp_len, settings->probe_resp)))
9087 return -ENOBUFS;
1c4ffa87
AO
9088
9089 return 0;
1c4ffa87
AO
9090}
9091
9092
9093static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
9094{
9095 struct nl_msg *msg;
9096 struct i802_bss *bss = priv;
9097 struct wpa_driver_nl80211_data *drv = bss->drv;
9098 struct nlattr *beacon_csa;
9099 int ret = -ENOBUFS;
366179d2
AO
9100 int csa_off_len = 0;
9101 int i;
1c4ffa87 9102
8d1fdde7 9103 wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
1c4ffa87 9104 settings->cs_count, settings->block_tx,
8d1fdde7
JD
9105 settings->freq_params.freq, settings->freq_params.bandwidth,
9106 settings->freq_params.center_freq1,
9107 settings->freq_params.center_freq2);
1c4ffa87 9108
991aa9c7 9109 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
1c4ffa87
AO
9110 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
9111 return -EOPNOTSUPP;
9112 }
9113
0928b629
PO
9114 if (drv->nlmode != NL80211_IFTYPE_AP &&
9115 drv->nlmode != NL80211_IFTYPE_P2P_GO &&
9116 drv->nlmode != NL80211_IFTYPE_MESH_POINT)
1c4ffa87
AO
9117 return -EOPNOTSUPP;
9118
366179d2
AO
9119 /*
9120 * Remove empty counters, assuming Probe Response and Beacon frame
9121 * counters match. This implementation assumes that there are only two
9122 * counters.
9123 */
9124 if (settings->counter_offset_beacon[0] &&
9125 !settings->counter_offset_beacon[1]) {
9126 csa_off_len = 1;
9127 } else if (settings->counter_offset_beacon[1] &&
9128 !settings->counter_offset_beacon[0]) {
9129 csa_off_len = 1;
9130 settings->counter_offset_beacon[0] =
9131 settings->counter_offset_beacon[1];
9132 settings->counter_offset_presp[0] =
9133 settings->counter_offset_presp[1];
9134 } else if (settings->counter_offset_beacon[1] &&
9135 settings->counter_offset_beacon[0]) {
9136 csa_off_len = 2;
9137 } else {
9138 wpa_printf(MSG_ERROR, "nl80211: No CSA counters provided");
9139 return -EINVAL;
9140 }
9141
9142 /* Check CSA counters validity */
9143 if (drv->capa.max_csa_counters &&
9144 csa_off_len > drv->capa.max_csa_counters) {
9145 wpa_printf(MSG_ERROR,
9146 "nl80211: Too many CSA counters provided");
1c4ffa87 9147 return -EINVAL;
366179d2 9148 }
1c4ffa87 9149
366179d2 9150 if (!settings->beacon_csa.tail)
1c4ffa87
AO
9151 return -EINVAL;
9152
366179d2
AO
9153 for (i = 0; i < csa_off_len; i++) {
9154 u16 csa_c_off_bcn = settings->counter_offset_beacon[i];
9155 u16 csa_c_off_presp = settings->counter_offset_presp[i];
9156
9157 if ((settings->beacon_csa.tail_len <= csa_c_off_bcn) ||
9158 (settings->beacon_csa.tail[csa_c_off_bcn] !=
9159 settings->cs_count))
9160 return -EINVAL;
9161
9162 if (settings->beacon_csa.probe_resp &&
9163 ((settings->beacon_csa.probe_resp_len <=
9164 csa_c_off_presp) ||
9165 (settings->beacon_csa.probe_resp[csa_c_off_presp] !=
9166 settings->cs_count)))
9167 return -EINVAL;
9168 }
9169
13f83980 9170 if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_CHANNEL_SWITCH)) ||
a862e4a3
JM
9171 nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT,
9172 settings->cs_count) ||
9173 (ret = nl80211_put_freq_params(msg, &settings->freq_params)) ||
9174 (settings->block_tx &&
9175 nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX)))
1c4ffa87
AO
9176 goto error;
9177
1c4ffa87
AO
9178 /* beacon_after params */
9179 ret = set_beacon_data(msg, &settings->beacon_after);
9180 if (ret)
9181 goto error;
9182
9183 /* beacon_csa params */
9184 beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
9185 if (!beacon_csa)
a862e4a3 9186 goto fail;
1c4ffa87
AO
9187
9188 ret = set_beacon_data(msg, &settings->beacon_csa);
9189 if (ret)
9190 goto error;
9191
366179d2
AO
9192 if (nla_put(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
9193 csa_off_len * sizeof(u16),
9194 settings->counter_offset_beacon) ||
a862e4a3 9195 (settings->beacon_csa.probe_resp &&
366179d2
AO
9196 nla_put(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
9197 csa_off_len * sizeof(u16),
9198 settings->counter_offset_presp)))
a862e4a3 9199 goto fail;
1c4ffa87
AO
9200
9201 nla_nest_end(msg, beacon_csa);
9202 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9203 if (ret) {
9204 wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
9205 ret, strerror(-ret));
9206 }
9207 return ret;
9208
a862e4a3 9209fail:
1c4ffa87
AO
9210 ret = -ENOBUFS;
9211error:
9212 nlmsg_free(msg);
9213 wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
9214 return ret;
9215}
9216
9217
dfa87878
MB
9218static int nl80211_add_ts(void *priv, u8 tsid, const u8 *addr,
9219 u8 user_priority, u16 admitted_time)
9220{
9221 struct i802_bss *bss = priv;
9222 struct wpa_driver_nl80211_data *drv = bss->drv;
9223 struct nl_msg *msg;
9224 int ret;
9225
9226 wpa_printf(MSG_DEBUG,
9227 "nl80211: add_ts request: tsid=%u admitted_time=%u up=%d",
9228 tsid, admitted_time, user_priority);
9229
9230 if (!is_sta_interface(drv->nlmode))
9231 return -ENOTSUP;
9232
56f77852
JM
9233 msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_ADD_TX_TS);
9234 if (!msg ||
a862e4a3
JM
9235 nla_put_u8(msg, NL80211_ATTR_TSID, tsid) ||
9236 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9237 nla_put_u8(msg, NL80211_ATTR_USER_PRIO, user_priority) ||
9238 nla_put_u16(msg, NL80211_ATTR_ADMITTED_TIME, admitted_time)) {
9239 nlmsg_free(msg);
9240 return -ENOBUFS;
9241 }
dfa87878
MB
9242
9243 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9244 if (ret)
9245 wpa_printf(MSG_DEBUG, "nl80211: add_ts failed err=%d (%s)",
9246 ret, strerror(-ret));
9247 return ret;
dfa87878
MB
9248}
9249
9250
9251static int nl80211_del_ts(void *priv, u8 tsid, const u8 *addr)
9252{
9253 struct i802_bss *bss = priv;
9254 struct wpa_driver_nl80211_data *drv = bss->drv;
9255 struct nl_msg *msg;
9256 int ret;
9257
9258 wpa_printf(MSG_DEBUG, "nl80211: del_ts request: tsid=%u", tsid);
9259
9260 if (!is_sta_interface(drv->nlmode))
9261 return -ENOTSUP;
9262
56f77852 9263 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_TX_TS)) ||
a862e4a3
JM
9264 nla_put_u8(msg, NL80211_ATTR_TSID, tsid) ||
9265 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
9266 nlmsg_free(msg);
9267 return -ENOBUFS;
9268 }
dfa87878
MB
9269
9270 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9271 if (ret)
9272 wpa_printf(MSG_DEBUG, "nl80211: del_ts failed err=%d (%s)",
9273 ret, strerror(-ret));
9274 return ret;
dfa87878
MB
9275}
9276
9277
6b9f7af6
JM
9278#ifdef CONFIG_TESTING_OPTIONS
9279static int cmd_reply_handler(struct nl_msg *msg, void *arg)
9280{
9281 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9282 struct wpabuf *buf = arg;
9283
9284 if (!buf)
9285 return NL_SKIP;
9286
9287 if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
9288 wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
9289 return NL_SKIP;
9290 }
9291
9292 wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
9293 genlmsg_attrlen(gnlh, 0));
9294
9295 return NL_SKIP;
9296}
9297#endif /* CONFIG_TESTING_OPTIONS */
9298
9299
adef8948
BL
9300static int vendor_reply_handler(struct nl_msg *msg, void *arg)
9301{
9302 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9303 struct nlattr *nl_vendor_reply, *nl;
9304 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9305 struct wpabuf *buf = arg;
9306 int rem;
9307
9308 if (!buf)
9309 return NL_SKIP;
9310
9311 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9312 genlmsg_attrlen(gnlh, 0), NULL);
9313 nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
9314
9315 if (!nl_vendor_reply)
9316 return NL_SKIP;
9317
9318 if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
9319 wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
9320 return NL_SKIP;
9321 }
9322
9323 nla_for_each_nested(nl, nl_vendor_reply, rem) {
9324 wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
9325 }
9326
9327 return NL_SKIP;
9328}
9329
9330
9331static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
9332 unsigned int subcmd, const u8 *data,
9333 size_t data_len, struct wpabuf *buf)
9334{
9335 struct i802_bss *bss = priv;
9336 struct wpa_driver_nl80211_data *drv = bss->drv;
9337 struct nl_msg *msg;
9338 int ret;
9339
6b9f7af6
JM
9340#ifdef CONFIG_TESTING_OPTIONS
9341 if (vendor_id == 0xffffffff) {
56f77852
JM
9342 msg = nlmsg_alloc();
9343 if (!msg)
9344 return -ENOMEM;
9345
6b9f7af6
JM
9346 nl80211_cmd(drv, msg, 0, subcmd);
9347 if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
9348 0)
a862e4a3 9349 goto fail;
6b9f7af6
JM
9350 ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
9351 if (ret)
9352 wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
9353 ret);
9354 return ret;
9355 }
9356#endif /* CONFIG_TESTING_OPTIONS */
9357
56f77852 9358 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) ||
a862e4a3
JM
9359 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, vendor_id) ||
9360 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd) ||
9361 (data &&
9362 nla_put(msg, NL80211_ATTR_VENDOR_DATA, data_len, data)))
9363 goto fail;
adef8948
BL
9364
9365 ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
9366 if (ret)
9367 wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
9368 ret);
9369 return ret;
9370
a862e4a3 9371fail:
adef8948
BL
9372 nlmsg_free(msg);
9373 return -ENOBUFS;
9374}
9375
9376
049105b4
KP
9377static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
9378 u8 qos_map_set_len)
9379{
9380 struct i802_bss *bss = priv;
9381 struct wpa_driver_nl80211_data *drv = bss->drv;
9382 struct nl_msg *msg;
9383 int ret;
9384
049105b4
KP
9385 wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
9386 qos_map_set, qos_map_set_len);
9387
9725b784 9388 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) ||
a862e4a3
JM
9389 nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) {
9390 nlmsg_free(msg);
9391 return -ENOBUFS;
9392 }
049105b4
KP
9393
9394 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9395 if (ret)
9396 wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
9397
9398 return ret;
049105b4
KP
9399}
9400
9401
82ba4f2d
MC
9402static int get_wowlan_handler(struct nl_msg *msg, void *arg)
9403{
9404 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9405 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9406 int *wowlan_enabled = arg;
9407
9408 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9409 genlmsg_attrlen(gnlh, 0), NULL);
9410
9411 *wowlan_enabled = !!tb[NL80211_ATTR_WOWLAN_TRIGGERS];
9412
9413 return NL_SKIP;
9414}
9415
9416
9417static int nl80211_get_wowlan(void *priv)
9418{
9419 struct i802_bss *bss = priv;
9420 struct wpa_driver_nl80211_data *drv = bss->drv;
9421 struct nl_msg *msg;
9422 int wowlan_enabled;
9423 int ret;
9424
9425 wpa_printf(MSG_DEBUG, "nl80211: Getting wowlan status");
9426
9427 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_WOWLAN);
9428
9429 ret = send_and_recv_msgs(drv, msg, get_wowlan_handler, &wowlan_enabled);
9430 if (ret) {
9431 wpa_printf(MSG_DEBUG, "nl80211: Getting wowlan status failed");
9432 return 0;
9433 }
9434
9435 wpa_printf(MSG_DEBUG, "nl80211: wowlan is %s",
9436 wowlan_enabled ? "enabled" : "disabled");
9437
9438 return wowlan_enabled;
9439}
9440
9441
e4fa8b12
EP
9442static int nl80211_set_wowlan(void *priv,
9443 const struct wowlan_triggers *triggers)
9444{
9445 struct i802_bss *bss = priv;
9446 struct wpa_driver_nl80211_data *drv = bss->drv;
9447 struct nl_msg *msg;
9448 struct nlattr *wowlan_triggers;
9449 int ret;
9450
e4fa8b12
EP
9451 wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan");
9452
1ac977bd 9453 if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_SET_WOWLAN)) ||
a862e4a3
JM
9454 !(wowlan_triggers = nla_nest_start(msg,
9455 NL80211_ATTR_WOWLAN_TRIGGERS)) ||
9456 (triggers->any &&
9457 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
9458 (triggers->disconnect &&
9459 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
9460 (triggers->magic_pkt &&
9461 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
9462 (triggers->gtk_rekey_failure &&
9463 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
9464 (triggers->eap_identity_req &&
9465 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
9466 (triggers->four_way_handshake &&
9467 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
9468 (triggers->rfkill_release &&
9469 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) {
9470 nlmsg_free(msg);
9471 return -ENOBUFS;
9472 }
e4fa8b12
EP
9473
9474 nla_nest_end(msg, wowlan_triggers);
9475
9476 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9477 if (ret)
9478 wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan failed");
9479
9480 return ret;
e4fa8b12
EP
9481}
9482
9483
b658547d 9484#ifdef CONFIG_DRIVER_NL80211_QCA
0800f9ee
JM
9485static int nl80211_roaming(void *priv, int allowed, const u8 *bssid)
9486{
9487 struct i802_bss *bss = priv;
9488 struct wpa_driver_nl80211_data *drv = bss->drv;
9489 struct nl_msg *msg;
9490 struct nlattr *params;
9491
9492 wpa_printf(MSG_DEBUG, "nl80211: Roaming policy: allowed=%d", allowed);
9493
9494 if (!drv->roaming_vendor_cmd_avail) {
9495 wpa_printf(MSG_DEBUG,
9496 "nl80211: Ignore roaming policy change since driver does not provide command for setting it");
9497 return -1;
9498 }
9499
9725b784 9500 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
a862e4a3
JM
9501 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9502 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9503 QCA_NL80211_VENDOR_SUBCMD_ROAMING) ||
9504 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9505 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY,
9506 allowed ? QCA_ROAMING_ALLOWED_WITHIN_ESS :
9507 QCA_ROAMING_NOT_ALLOWED) ||
9508 (bssid &&
9509 nla_put(msg, QCA_WLAN_VENDOR_ATTR_MAC_ADDR, ETH_ALEN, bssid))) {
9510 nlmsg_free(msg);
9511 return -1;
9512 }
0800f9ee
JM
9513 nla_nest_end(msg, params);
9514
9515 return send_and_recv_msgs(drv, msg, NULL, NULL);
0800f9ee 9516}
b04854ce
AP
9517
9518
d98038bb 9519static int nl80211_disable_fils(void *priv, int disable)
9520{
9521 struct i802_bss *bss = priv;
9522 struct wpa_driver_nl80211_data *drv = bss->drv;
9523 struct nl_msg *msg;
9524 struct nlattr *params;
9525
9526 wpa_printf(MSG_DEBUG, "nl80211: Disable FILS=%d", disable);
9527
9528 if (!drv->set_wifi_conf_vendor_cmd_avail)
9529 return -1;
9530
9531 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
9532 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9533 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9534 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
9535 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9536 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS,
9537 disable)) {
9538 nlmsg_free(msg);
9539 return -1;
9540 }
9541 nla_nest_end(msg, params);
9542
9543 return send_and_recv_msgs(drv, msg, NULL, NULL);
9544}
9545
9546
b04854ce
AP
9547/* Reserved QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID value for wpa_supplicant */
9548#define WPA_SUPPLICANT_CLIENT_ID 1
9549
9550static int nl80211_set_bssid_blacklist(void *priv, unsigned int num_bssid,
9551 const u8 *bssid)
9552{
9553 struct i802_bss *bss = priv;
9554 struct wpa_driver_nl80211_data *drv = bss->drv;
9555 struct nl_msg *msg;
9556 struct nlattr *params, *nlbssids, *attr;
9557 unsigned int i;
9558
9559 wpa_printf(MSG_DEBUG, "nl80211: Set blacklist BSSID (num=%u)",
9560 num_bssid);
9561
9562 if (!drv->roam_vendor_cmd_avail)
9563 return -1;
9564
9565 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
9566 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9567 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9568 QCA_NL80211_VENDOR_SUBCMD_ROAM) ||
9569 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9570 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD,
1425caac 9571 QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID) ||
b04854ce
AP
9572 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID,
9573 WPA_SUPPLICANT_CLIENT_ID) ||
9574 nla_put_u32(msg,
9575 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID,
9576 num_bssid))
9577 goto fail;
9578
9579 nlbssids = nla_nest_start(
9580 msg, QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS);
9581 if (!nlbssids)
9582 goto fail;
9583
9584 for (i = 0; i < num_bssid; i++) {
9585 attr = nla_nest_start(msg, i);
9586 if (!attr)
9587 goto fail;
9588 if (nla_put(msg,
9589 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID,
9590 ETH_ALEN, &bssid[i * ETH_ALEN]))
9591 goto fail;
9592 wpa_printf(MSG_DEBUG, "nl80211: BSSID[%u]: " MACSTR, i,
9593 MAC2STR(&bssid[i * ETH_ALEN]));
9594 nla_nest_end(msg, attr);
9595 }
9596 nla_nest_end(msg, nlbssids);
9597 nla_nest_end(msg, params);
9598
9599 return send_and_recv_msgs(drv, msg, NULL, NULL);
9600
9601fail:
9602 nlmsg_free(msg);
9603 return -1;
9604}
9605
df3b2e22
SSG
9606
9607static int nl80211_add_sta_node(void *priv, const u8 *addr, u16 auth_alg)
9608{
9609 struct i802_bss *bss = priv;
9610 struct wpa_driver_nl80211_data *drv = bss->drv;
9611 struct nl_msg *msg;
9612 struct nlattr *params;
9613
9614 if (!drv->add_sta_node_vendor_cmd_avail)
9615 return -EOPNOTSUPP;
9616
9617 wpa_printf(MSG_DEBUG, "nl80211: Add STA node");
9618
9619 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
9620 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9621 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9622 QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE) ||
9623 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9624 (addr &&
9625 nla_put(msg, QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_MAC_ADDR, ETH_ALEN,
9626 addr)) ||
9627 nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_AUTH_ALGO,
9628 auth_alg)) {
9629 nlmsg_free(msg);
9630 wpa_printf(MSG_ERROR,
9631 "%s: err in adding vendor_cmd and vendor_data",
9632 __func__);
9633 return -1;
9634 }
9635 nla_nest_end(msg, params);
9636
9637 return send_and_recv_msgs(drv, msg, NULL, NULL);
9638}
9639
b658547d 9640#endif /* CONFIG_DRIVER_NL80211_QCA */
0800f9ee
JM
9641
9642
fee354c7
JM
9643static int nl80211_set_mac_addr(void *priv, const u8 *addr)
9644{
9645 struct i802_bss *bss = priv;
9646 struct wpa_driver_nl80211_data *drv = bss->drv;
9647 int new_addr = addr != NULL;
9648
9ce3e610
JM
9649 if (TEST_FAIL())
9650 return -1;
9651
fee354c7
JM
9652 if (!addr)
9653 addr = drv->perm_addr;
9654
9655 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) < 0)
9656 return -1;
9657
9658 if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname, addr) < 0)
9659 {
9660 wpa_printf(MSG_DEBUG,
9661 "nl80211: failed to set_mac_addr for %s to " MACSTR,
9662 bss->ifname, MAC2STR(addr));
9663 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
9664 1) < 0) {
9665 wpa_printf(MSG_DEBUG,
9666 "nl80211: Could not restore interface UP after failed set_mac_addr");
9667 }
9668 return -1;
9669 }
9670
9671 wpa_printf(MSG_DEBUG, "nl80211: set_mac_addr for %s to " MACSTR,
9672 bss->ifname, MAC2STR(addr));
9673 drv->addr_changed = new_addr;
9674 os_memcpy(bss->addr, addr, ETH_ALEN);
9675
9676 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1) < 0)
9677 {
9678 wpa_printf(MSG_DEBUG,
9679 "nl80211: Could not restore interface UP after set_mac_addr");
9680 }
9681
9682 return 0;
9683}
9684
9685
6c1664f6
BC
9686#ifdef CONFIG_MESH
9687
9688static int wpa_driver_nl80211_init_mesh(void *priv)
9689{
9690 if (wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_MESH_POINT)) {
9691 wpa_printf(MSG_INFO,
9692 "nl80211: Failed to set interface into mesh mode");
9693 return -1;
9694 }
9695 return 0;
9696}
9697
9698
21c74e84
JM
9699static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id,
9700 size_t mesh_id_len)
9701{
9702 if (mesh_id) {
21cd8f83
JM
9703 wpa_printf(MSG_DEBUG, " * Mesh ID (SSID)=%s",
9704 wpa_ssid_txt(mesh_id, mesh_id_len));
21c74e84
JM
9705 return nla_put(msg, NL80211_ATTR_MESH_ID, mesh_id_len, mesh_id);
9706 }
9707
9708 return 0;
9709}
9710
9711
4ffb3f87
MH
9712static int nl80211_put_mesh_config(struct nl_msg *msg,
9713 struct wpa_driver_mesh_bss_params *params)
9714{
9715 struct nlattr *container;
9716
9717 container = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
9718 if (!container)
9719 return -1;
9720
2bd62171 9721 if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
963d3149
JM
9722 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
9723 params->auto_plinks)) ||
2bd62171
MH
9724 ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS) &&
9725 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
31a856a1
MH
9726 params->max_peer_links)) ||
9727 ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD) &&
9728 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
9729 params->rssi_threshold)))
4ffb3f87
MH
9730 return -1;
9731
9732 /*
9733 * Set NL80211_MESHCONF_PLINK_TIMEOUT even if user mpm is used because
9734 * the timer could disconnect stations even in that case.
9735 */
2bd62171
MH
9736 if ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_PEER_LINK_TIMEOUT) &&
9737 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
4ffb3f87
MH
9738 params->peer_link_timeout)) {
9739 wpa_printf(MSG_ERROR, "nl80211: Failed to set PLINK_TIMEOUT");
9740 return -1;
9741 }
9742
052b8d38
MH
9743 if ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE) &&
9744 nla_put_u16(msg, NL80211_MESHCONF_HT_OPMODE, params->ht_opmode)) {
9745 wpa_printf(MSG_ERROR, "nl80211: Failed to set HT_OP_MODE");
9746 return -1;
9747 }
9748
4ffb3f87
MH
9749 nla_nest_end(msg, container);
9750
9751 return 0;
9752}
9753
9754
0cb5f8d9 9755static int nl80211_join_mesh(struct i802_bss *bss,
6c1664f6
BC
9756 struct wpa_driver_mesh_join_params *params)
9757{
6c1664f6
BC
9758 struct wpa_driver_nl80211_data *drv = bss->drv;
9759 struct nl_msg *msg;
9760 struct nlattr *container;
7451a217 9761 int ret = -1;
6c1664f6 9762
6c1664f6 9763 wpa_printf(MSG_DEBUG, "nl80211: mesh join (ifindex=%d)", drv->ifindex);
9725b784 9764 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_MESH);
f7e889fa
JM
9765 if (!msg ||
9766 nl80211_put_freq_params(msg, &params->freq) ||
21c74e84
JM
9767 nl80211_put_basic_rates(msg, params->basic_rates) ||
9768 nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
4ac2ea57
MH
9769 nl80211_put_beacon_int(msg, params->beacon_int) ||
9770 nl80211_put_dtim_period(msg, params->dtim_period))
85e1fad8 9771 goto fail;
9c58c5f7 9772
6c1664f6
BC
9773 wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags);
9774
9775 container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP);
9776 if (!container)
a862e4a3 9777 goto fail;
6c1664f6
BC
9778
9779 if (params->ies) {
9780 wpa_hexdump(MSG_DEBUG, " * IEs", params->ies, params->ie_len);
a862e4a3
JM
9781 if (nla_put(msg, NL80211_MESH_SETUP_IE, params->ie_len,
9782 params->ies))
9783 goto fail;
6c1664f6
BC
9784 }
9785 /* WPA_DRIVER_MESH_FLAG_OPEN_AUTH is treated as default by nl80211 */
9786 if (params->flags & WPA_DRIVER_MESH_FLAG_SAE_AUTH) {
a862e4a3
JM
9787 if (nla_put_u8(msg, NL80211_MESH_SETUP_AUTH_PROTOCOL, 0x1) ||
9788 nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AUTH))
9789 goto fail;
6c1664f6 9790 }
a862e4a3
JM
9791 if ((params->flags & WPA_DRIVER_MESH_FLAG_AMPE) &&
9792 nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AMPE))
9793 goto fail;
9794 if ((params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM) &&
9795 nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_MPM))
9796 goto fail;
6c1664f6
BC
9797 nla_nest_end(msg, container);
9798
2bd62171
MH
9799 params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS;
9800 params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_PEER_LINK_TIMEOUT;
9801 params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS;
4ffb3f87 9802 if (nl80211_put_mesh_config(msg, &params->conf) < 0)
5a2a6de6 9803 goto fail;
6c1664f6
BC
9804
9805 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9806 msg = NULL;
9807 if (ret) {
9808 wpa_printf(MSG_DEBUG, "nl80211: mesh join failed: ret=%d (%s)",
9809 ret, strerror(-ret));
a862e4a3 9810 goto fail;
6c1664f6
BC
9811 }
9812 ret = 0;
92a515b8 9813 drv->assoc_freq = bss->freq = params->freq.freq;
6c1664f6
BC
9814 wpa_printf(MSG_DEBUG, "nl80211: mesh join request send successfully");
9815
a862e4a3 9816fail:
6c1664f6
BC
9817 nlmsg_free(msg);
9818 return ret;
9819}
9820
9821
0cb5f8d9
MH
9822static int
9823wpa_driver_nl80211_join_mesh(void *priv,
9824 struct wpa_driver_mesh_join_params *params)
9825{
9826 struct i802_bss *bss = priv;
9827 int ret, timeout;
9828
9829 timeout = params->conf.peer_link_timeout;
9830
9831 /* Disable kernel inactivity timer */
9832 if (params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM)
9833 params->conf.peer_link_timeout = 0;
9834
9835 ret = nl80211_join_mesh(bss, params);
9836 if (ret == -EINVAL && params->conf.peer_link_timeout == 0) {
9837 wpa_printf(MSG_DEBUG,
9838 "nl80211: Mesh join retry for peer_link_timeout");
9839 /*
9840 * Old kernel does not support setting
9841 * NL80211_MESHCONF_PLINK_TIMEOUT to zero, so set 60 seconds
9842 * into future from peer_link_timeout.
9843 */
9844 params->conf.peer_link_timeout = timeout + 60;
9845 ret = nl80211_join_mesh(priv, params);
9846 }
9847
9848 params->conf.peer_link_timeout = timeout;
9849 return ret;
9850}
9851
9852
6c1664f6
BC
9853static int wpa_driver_nl80211_leave_mesh(void *priv)
9854{
9855 struct i802_bss *bss = priv;
9856 struct wpa_driver_nl80211_data *drv = bss->drv;
9857 struct nl_msg *msg;
9725b784 9858 int ret;
6c1664f6
BC
9859
9860 wpa_printf(MSG_DEBUG, "nl80211: mesh leave (ifindex=%d)", drv->ifindex);
9725b784 9861 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_MESH);
6c1664f6 9862 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6c1664f6
BC
9863 if (ret) {
9864 wpa_printf(MSG_DEBUG, "nl80211: mesh leave failed: ret=%d (%s)",
9865 ret, strerror(-ret));
a862e4a3
JM
9866 } else {
9867 wpa_printf(MSG_DEBUG,
9868 "nl80211: mesh leave request send successfully");
6c1664f6 9869 }
6c1664f6 9870
f33c82d2
JM
9871 if (wpa_driver_nl80211_set_mode(drv->first_bss,
9872 NL80211_IFTYPE_STATION)) {
9873 wpa_printf(MSG_INFO,
9874 "nl80211: Failed to set interface into station mode");
9875 }
6c1664f6
BC
9876 return ret;
9877}
9878
c36109e4
PKC
9879
9880static int nl80211_probe_mesh_link(void *priv, const u8 *addr, const u8 *eth,
9881 size_t len)
9882{
9883 struct i802_bss *bss = priv;
9884 struct wpa_driver_nl80211_data *drv = bss->drv;
9885 struct nl_msg *msg;
9886 int ret;
9887
9888 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_PROBE_MESH_LINK);
9889 if (!msg ||
9890 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9891 nla_put(msg, NL80211_ATTR_FRAME, len, eth)) {
9892 nlmsg_free(msg);
9893 return -ENOBUFS;
9894 }
9895
9896 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9897 if (ret) {
9898 wpa_printf(MSG_DEBUG, "nl80211: mesh link probe to " MACSTR
9899 " failed: ret=%d (%s)",
9900 MAC2STR(addr), ret, strerror(-ret));
9901 } else {
9902 wpa_printf(MSG_DEBUG, "nl80211: Mesh link to " MACSTR
9903 " probed successfully", MAC2STR(addr));
9904 }
9905
9906 return ret;
9907}
9908
6c1664f6
BC
9909#endif /* CONFIG_MESH */
9910
9911
ed4ddb6d
KP
9912static int wpa_driver_br_add_ip_neigh(void *priv, u8 version,
9913 const u8 *ipaddr, int prefixlen,
9914 const u8 *addr)
71103bed
KP
9915{
9916#ifdef CONFIG_LIBNL3_ROUTE
9917 struct i802_bss *bss = priv;
9918 struct wpa_driver_nl80211_data *drv = bss->drv;
9919 struct rtnl_neigh *rn;
9920 struct nl_addr *nl_ipaddr = NULL;
9921 struct nl_addr *nl_lladdr = NULL;
ed4ddb6d 9922 int family, addrsize;
71103bed
KP
9923 int res;
9924
ed4ddb6d 9925 if (!ipaddr || prefixlen == 0 || !addr)
71103bed
KP
9926 return -EINVAL;
9927
9928 if (bss->br_ifindex == 0) {
9929 wpa_printf(MSG_DEBUG,
9930 "nl80211: bridge must be set before adding an ip neigh to it");
9931 return -1;
9932 }
9933
9934 if (!drv->rtnl_sk) {
9935 wpa_printf(MSG_DEBUG,
9936 "nl80211: nl_sock for NETLINK_ROUTE is not initialized");
9937 return -1;
9938 }
9939
ed4ddb6d
KP
9940 if (version == 4) {
9941 family = AF_INET;
9942 addrsize = 4;
9943 } else if (version == 6) {
9944 family = AF_INET6;
9945 addrsize = 16;
9946 } else {
9947 return -EINVAL;
9948 }
9949
71103bed
KP
9950 rn = rtnl_neigh_alloc();
9951 if (rn == NULL)
9952 return -ENOMEM;
9953
9954 /* set the destination ip address for neigh */
ed4ddb6d 9955 nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
71103bed
KP
9956 if (nl_ipaddr == NULL) {
9957 wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
9958 res = -ENOMEM;
9959 goto errout;
9960 }
9961 nl_addr_set_prefixlen(nl_ipaddr, prefixlen);
9962 res = rtnl_neigh_set_dst(rn, nl_ipaddr);
9963 if (res) {
9964 wpa_printf(MSG_DEBUG,
9965 "nl80211: neigh set destination addr failed");
9966 goto errout;
9967 }
9968
9969 /* set the corresponding lladdr for neigh */
9970 nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN);
9971 if (nl_lladdr == NULL) {
9972 wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed");
9973 res = -ENOMEM;
9974 goto errout;
9975 }
9976 rtnl_neigh_set_lladdr(rn, nl_lladdr);
9977
9978 rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
9979 rtnl_neigh_set_state(rn, NUD_PERMANENT);
9980
9981 res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
9982 if (res) {
9983 wpa_printf(MSG_DEBUG,
9984 "nl80211: Adding bridge ip neigh failed: %s",
3ea58a05 9985 nl_geterror(res));
71103bed
KP
9986 }
9987errout:
9988 if (nl_lladdr)
9989 nl_addr_put(nl_lladdr);
9990 if (nl_ipaddr)
9991 nl_addr_put(nl_ipaddr);
9992 if (rn)
9993 rtnl_neigh_put(rn);
9994 return res;
9995#else /* CONFIG_LIBNL3_ROUTE */
9996 return -1;
9997#endif /* CONFIG_LIBNL3_ROUTE */
9998}
9999
10000
ed4ddb6d
KP
10001static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
10002 const u8 *ipaddr)
71103bed
KP
10003{
10004#ifdef CONFIG_LIBNL3_ROUTE
10005 struct i802_bss *bss = priv;
10006 struct wpa_driver_nl80211_data *drv = bss->drv;
10007 struct rtnl_neigh *rn;
10008 struct nl_addr *nl_ipaddr;
ed4ddb6d 10009 int family, addrsize;
71103bed
KP
10010 int res;
10011
ed4ddb6d 10012 if (!ipaddr)
71103bed
KP
10013 return -EINVAL;
10014
ed4ddb6d
KP
10015 if (version == 4) {
10016 family = AF_INET;
10017 addrsize = 4;
10018 } else if (version == 6) {
10019 family = AF_INET6;
10020 addrsize = 16;
10021 } else {
10022 return -EINVAL;
10023 }
10024
71103bed
KP
10025 if (bss->br_ifindex == 0) {
10026 wpa_printf(MSG_DEBUG,
10027 "nl80211: bridge must be set to delete an ip neigh");
10028 return -1;
10029 }
10030
10031 if (!drv->rtnl_sk) {
10032 wpa_printf(MSG_DEBUG,
10033 "nl80211: nl_sock for NETLINK_ROUTE is not initialized");
10034 return -1;
10035 }
10036
10037 rn = rtnl_neigh_alloc();
10038 if (rn == NULL)
10039 return -ENOMEM;
10040
10041 /* set the destination ip address for neigh */
ed4ddb6d 10042 nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
71103bed
KP
10043 if (nl_ipaddr == NULL) {
10044 wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
10045 res = -ENOMEM;
10046 goto errout;
10047 }
10048 res = rtnl_neigh_set_dst(rn, nl_ipaddr);
10049 if (res) {
10050 wpa_printf(MSG_DEBUG,
10051 "nl80211: neigh set destination addr failed");
10052 goto errout;
10053 }
10054
10055 rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
10056
10057 res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
10058 if (res) {
10059 wpa_printf(MSG_DEBUG,
10060 "nl80211: Deleting bridge ip neigh failed: %s",
3ea58a05 10061 nl_geterror(res));
71103bed
KP
10062 }
10063errout:
10064 if (nl_ipaddr)
10065 nl_addr_put(nl_ipaddr);
10066 if (rn)
10067 rtnl_neigh_put(rn);
10068 return res;
10069#else /* CONFIG_LIBNL3_ROUTE */
10070 return -1;
10071#endif /* CONFIG_LIBNL3_ROUTE */
10072}
10073
10074
73d2294f
KP
10075static int linux_write_system_file(const char *path, unsigned int val)
10076{
10077 char buf[50];
10078 int fd, len;
10079
10080 len = os_snprintf(buf, sizeof(buf), "%u\n", val);
a9aaacbb 10081 if (os_snprintf_error(sizeof(buf), len))
73d2294f
KP
10082 return -1;
10083
10084 fd = open(path, O_WRONLY);
10085 if (fd < 0)
10086 return -1;
10087
10088 if (write(fd, buf, len) < 0) {
10089 wpa_printf(MSG_DEBUG,
10090 "nl80211: Failed to write Linux system file: %s with the value of %d",
10091 path, val);
10092 close(fd);
10093 return -1;
10094 }
10095 close(fd);
10096
10097 return 0;
10098}
10099
10100
10101static const char * drv_br_port_attr_str(enum drv_br_port_attr attr)
10102{
10103 switch (attr) {
10104 case DRV_BR_PORT_ATTR_PROXYARP:
bea8d9a3 10105 return "proxyarp_wifi";
73d2294f
KP
10106 case DRV_BR_PORT_ATTR_HAIRPIN_MODE:
10107 return "hairpin_mode";
10108 }
10109
10110 return NULL;
10111}
10112
10113
10114static int wpa_driver_br_port_set_attr(void *priv, enum drv_br_port_attr attr,
10115 unsigned int val)
10116{
10117 struct i802_bss *bss = priv;
10118 char path[128];
10119 const char *attr_txt;
10120
10121 attr_txt = drv_br_port_attr_str(attr);
10122 if (attr_txt == NULL)
10123 return -EINVAL;
10124
10125 os_snprintf(path, sizeof(path), "/sys/class/net/%s/brport/%s",
10126 bss->ifname, attr_txt);
10127
10128 if (linux_write_system_file(path, val))
10129 return -1;
10130
10131 return 0;
10132}
10133
10134
7565752d
KP
10135static const char * drv_br_net_param_str(enum drv_br_net_param param)
10136{
10137 switch (param) {
10138 case DRV_BR_NET_PARAM_GARP_ACCEPT:
10139 return "arp_accept";
60eb9e17
JM
10140 default:
10141 return NULL;
7565752d 10142 }
7565752d
KP
10143}
10144
10145
10146static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
10147 unsigned int val)
10148{
10149 struct i802_bss *bss = priv;
10150 char path[128];
10151 const char *param_txt;
10152 int ip_version = 4;
10153
60eb9e17
JM
10154 if (param == DRV_BR_MULTICAST_SNOOPING) {
10155 os_snprintf(path, sizeof(path),
10156 "/sys/devices/virtual/net/%s/bridge/multicast_snooping",
10157 bss->brname);
10158 goto set_val;
10159 }
10160
7565752d
KP
10161 param_txt = drv_br_net_param_str(param);
10162 if (param_txt == NULL)
10163 return -EINVAL;
10164
10165 switch (param) {
10166 case DRV_BR_NET_PARAM_GARP_ACCEPT:
10167 ip_version = 4;
10168 break;
10169 default:
10170 return -EINVAL;
10171 }
10172
10173 os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s",
10174 ip_version, bss->brname, param_txt);
10175
60eb9e17 10176set_val:
7565752d
KP
10177 if (linux_write_system_file(path, val))
10178 return -1;
10179
10180 return 0;
10181}
10182
10183
b658547d
JM
10184#ifdef CONFIG_DRIVER_NL80211_QCA
10185
16689c7c
PX
10186static int hw_mode_to_qca_acs(enum hostapd_hw_mode hw_mode)
10187{
10188 switch (hw_mode) {
10189 case HOSTAPD_MODE_IEEE80211B:
10190 return QCA_ACS_MODE_IEEE80211B;
10191 case HOSTAPD_MODE_IEEE80211G:
10192 return QCA_ACS_MODE_IEEE80211G;
10193 case HOSTAPD_MODE_IEEE80211A:
10194 return QCA_ACS_MODE_IEEE80211A;
10195 case HOSTAPD_MODE_IEEE80211AD:
10196 return QCA_ACS_MODE_IEEE80211AD;
3784c058
PX
10197 case HOSTAPD_MODE_IEEE80211ANY:
10198 return QCA_ACS_MODE_IEEE80211ANY;
16689c7c
PX
10199 default:
10200 return -1;
10201 }
10202}
10203
10204
e86ba912
AB
10205static int add_acs_ch_list(struct nl_msg *msg, const int *freq_list)
10206{
10207 int num_channels = 0, num_freqs;
10208 u8 *ch_list;
10209 enum hostapd_hw_mode hw_mode;
10210 int ret = 0;
10211 int i;
10212
10213 if (!freq_list)
10214 return 0;
10215
10216 num_freqs = int_array_len(freq_list);
10217 ch_list = os_malloc(sizeof(u8) * num_freqs);
10218 if (!ch_list)
10219 return -1;
10220
10221 for (i = 0; i < num_freqs; i++) {
10222 const int freq = freq_list[i];
10223
10224 if (freq == 0)
10225 break;
10226 /* Send 2.4 GHz and 5 GHz channels with
10227 * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST to maintain backwards
10228 * compatibility.
10229 */
10230 if (!(freq >= 2412 && freq <= 2484) &&
10231 !(freq >= 5180 && freq <= 5900))
10232 continue;
10233 hw_mode = ieee80211_freq_to_chan(freq, &ch_list[num_channels]);
10234 if (hw_mode != NUM_HOSTAPD_MODES)
10235 num_channels++;
10236 }
10237
10238 if (num_channels)
10239 ret = nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST,
10240 num_channels, ch_list);
10241
10242 os_free(ch_list);
10243 return ret;
10244}
10245
10246
d0cdccd3
PX
10247static int add_acs_freq_list(struct nl_msg *msg, const int *freq_list)
10248{
10249 int i, len, ret;
10250 u32 *freqs;
10251
10252 if (!freq_list)
10253 return 0;
10254 len = int_array_len(freq_list);
10255 freqs = os_malloc(sizeof(u32) * len);
10256 if (!freqs)
10257 return -1;
10258 for (i = 0; i < len; i++)
10259 freqs[i] = freq_list[i];
10260 ret = nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST,
10261 sizeof(u32) * len, freqs);
10262 os_free(freqs);
10263 return ret;
10264}
10265
10266
16689c7c
PX
10267static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
10268{
10269 struct i802_bss *bss = priv;
10270 struct wpa_driver_nl80211_data *drv = bss->drv;
10271 struct nl_msg *msg;
10272 struct nlattr *data;
a862e4a3 10273 int ret;
16689c7c
PX
10274 int mode;
10275
10276 mode = hw_mode_to_qca_acs(params->hw_mode);
10277 if (mode < 0)
10278 return -1;
10279
9725b784 10280 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
a862e4a3
JM
10281 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10282 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10283 QCA_NL80211_VENDOR_SUBCMD_DO_ACS) ||
10284 !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10285 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, mode) ||
10286 (params->ht_enabled &&
10287 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED)) ||
10288 (params->ht40_enabled &&
857d9422
MM
10289 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED)) ||
10290 (params->vht_enabled &&
10291 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED)) ||
10292 nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
10293 params->ch_width) ||
e86ba912 10294 add_acs_ch_list(msg, params->freq_list) ||
d0cdccd3 10295 add_acs_freq_list(msg, params->freq_list)) {
a862e4a3
JM
10296 nlmsg_free(msg);
10297 return -ENOBUFS;
10298 }
16689c7c
PX
10299 nla_nest_end(msg, data);
10300
857d9422 10301 wpa_printf(MSG_DEBUG,
e86ba912 10302 "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d",
857d9422 10303 params->hw_mode, params->ht_enabled, params->ht40_enabled,
e86ba912 10304 params->vht_enabled, params->ch_width);
857d9422 10305
16689c7c 10306 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
16689c7c
PX
10307 if (ret) {
10308 wpa_printf(MSG_DEBUG,
10309 "nl80211: Failed to invoke driver ACS function: %s",
3ea58a05 10310 strerror(-ret));
16689c7c 10311 }
16689c7c
PX
10312 return ret;
10313}
10314
10315
844dfeb8
SD
10316static int nl80211_set_band(void *priv, enum set_band band)
10317{
10318 struct i802_bss *bss = priv;
10319 struct wpa_driver_nl80211_data *drv = bss->drv;
10320 struct nl_msg *msg;
10321 struct nlattr *data;
10322 int ret;
10323 enum qca_set_band qca_band;
10324
10325 if (!drv->setband_vendor_cmd_avail)
10326 return -1;
10327
10328 switch (band) {
10329 case WPA_SETBAND_AUTO:
10330 qca_band = QCA_SETBAND_AUTO;
10331 break;
10332 case WPA_SETBAND_5G:
10333 qca_band = QCA_SETBAND_5G;
10334 break;
10335 case WPA_SETBAND_2G:
10336 qca_band = QCA_SETBAND_2G;
10337 break;
10338 default:
10339 return -1;
10340 }
10341
10342 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10343 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10344 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10345 QCA_NL80211_VENDOR_SUBCMD_SETBAND) ||
10346 !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10347 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE, qca_band)) {
10348 nlmsg_free(msg);
10349 return -ENOBUFS;
10350 }
10351 nla_nest_end(msg, data);
10352
10353 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10354 if (ret) {
10355 wpa_printf(MSG_DEBUG,
10356 "nl80211: Driver setband function failed: %s",
3ea58a05 10357 strerror(-ret));
844dfeb8
SD
10358 }
10359 return ret;
10360}
10361
10362
98342208
AK
10363struct nl80211_pcl {
10364 unsigned int num;
10365 unsigned int *freq_list;
10366};
10367
10368static int preferred_freq_info_handler(struct nl_msg *msg, void *arg)
10369{
10370 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10371 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10372 struct nl80211_pcl *param = arg;
10373 struct nlattr *nl_vend, *attr;
10374 enum qca_iface_type iface_type;
10375 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
10376 unsigned int num, max_num;
10377 u32 *freqs;
10378
10379 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10380 genlmsg_attrlen(gnlh, 0), NULL);
10381
10382 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
10383 if (!nl_vend)
10384 return NL_SKIP;
10385
10386 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
10387 nla_data(nl_vend), nla_len(nl_vend), NULL);
10388
10389 attr = tb_vendor[
10390 QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE];
10391 if (!attr) {
10392 wpa_printf(MSG_ERROR, "nl80211: iface_type couldn't be found");
10393 param->num = 0;
10394 return NL_SKIP;
10395 }
10396
10397 iface_type = (enum qca_iface_type) nla_get_u32(attr);
10398 wpa_printf(MSG_DEBUG, "nl80211: Driver returned iface_type=%d",
10399 iface_type);
10400
10401 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST];
10402 if (!attr) {
10403 wpa_printf(MSG_ERROR,
10404 "nl80211: preferred_freq_list couldn't be found");
10405 param->num = 0;
10406 return NL_SKIP;
10407 }
10408
10409 /*
10410 * param->num has the maximum number of entries for which there
10411 * is room in the freq_list provided by the caller.
10412 */
10413 freqs = nla_data(attr);
10414 max_num = nla_len(attr) / sizeof(u32);
10415 if (max_num > param->num)
10416 max_num = param->num;
10417 for (num = 0; num < max_num; num++)
10418 param->freq_list[num] = freqs[num];
10419 param->num = num;
10420
10421 return NL_SKIP;
10422}
10423
10424
10425static int nl80211_get_pref_freq_list(void *priv,
10426 enum wpa_driver_if_type if_type,
10427 unsigned int *num,
10428 unsigned int *freq_list)
10429{
10430 struct i802_bss *bss = priv;
10431 struct wpa_driver_nl80211_data *drv = bss->drv;
10432 struct nl_msg *msg;
10433 int ret;
10434 unsigned int i;
10435 struct nlattr *params;
10436 struct nl80211_pcl param;
10437 enum qca_iface_type iface_type;
10438
10439 if (!drv->get_pref_freq_list)
10440 return -1;
10441
10442 switch (if_type) {
10443 case WPA_IF_STATION:
10444 iface_type = QCA_IFACE_TYPE_STA;
10445 break;
10446 case WPA_IF_AP_BSS:
10447 iface_type = QCA_IFACE_TYPE_AP;
10448 break;
10449 case WPA_IF_P2P_GO:
10450 iface_type = QCA_IFACE_TYPE_P2P_GO;
10451 break;
10452 case WPA_IF_P2P_CLIENT:
10453 iface_type = QCA_IFACE_TYPE_P2P_CLIENT;
10454 break;
10455 case WPA_IF_IBSS:
10456 iface_type = QCA_IFACE_TYPE_IBSS;
10457 break;
10458 case WPA_IF_TDLS:
10459 iface_type = QCA_IFACE_TYPE_TDLS;
10460 break;
10461 default:
10462 return -1;
10463 }
10464
10465 param.num = *num;
10466 param.freq_list = freq_list;
10467
10468 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10469 nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex) ||
10470 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10471 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10472 QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST) ||
10473 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10474 nla_put_u32(msg,
10475 QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE,
10476 iface_type)) {
10477 wpa_printf(MSG_ERROR,
10478 "%s: err in adding vendor_cmd and vendor_data",
10479 __func__);
10480 nlmsg_free(msg);
10481 return -1;
10482 }
10483 nla_nest_end(msg, params);
10484
10485 os_memset(freq_list, 0, *num * sizeof(freq_list[0]));
10486 ret = send_and_recv_msgs(drv, msg, preferred_freq_info_handler, &param);
10487 if (ret) {
10488 wpa_printf(MSG_ERROR,
10489 "%s: err in send_and_recv_msgs", __func__);
10490 return ret;
10491 }
10492
10493 *num = param.num;
10494
10495 for (i = 0; i < *num; i++) {
10496 wpa_printf(MSG_DEBUG, "nl80211: preferred_channel_list[%d]=%d",
10497 i, freq_list[i]);
10498 }
10499
10500 return 0;
10501}
10502
10503
7c813acf
AK
10504static int nl80211_set_prob_oper_freq(void *priv, unsigned int freq)
10505{
10506 struct i802_bss *bss = priv;
10507 struct wpa_driver_nl80211_data *drv = bss->drv;
10508 struct nl_msg *msg;
10509 int ret;
10510 struct nlattr *params;
10511
10512 if (!drv->set_prob_oper_freq)
10513 return -1;
10514
10515 wpa_printf(MSG_DEBUG,
10516 "nl80211: Set P2P probable operating freq %u for ifindex %d",
10517 freq, bss->ifindex);
10518
10519 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10520 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10521 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10522 QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL) ||
10523 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10524 nla_put_u32(msg,
10525 QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE,
10526 QCA_IFACE_TYPE_P2P_CLIENT) ||
10527 nla_put_u32(msg,
10528 QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ,
10529 freq)) {
10530 wpa_printf(MSG_ERROR,
10531 "%s: err in adding vendor_cmd and vendor_data",
10532 __func__);
10533 nlmsg_free(msg);
10534 return -1;
10535 }
10536 nla_nest_end(msg, params);
10537
10538 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10539 msg = NULL;
10540 if (ret) {
10541 wpa_printf(MSG_ERROR, "%s: err in send_and_recv_msgs",
10542 __func__);
10543 return ret;
10544 }
10545 nlmsg_free(msg);
10546 return 0;
10547}
10548
a6f5b193
PX
10549
10550static int nl80211_p2p_lo_start(void *priv, unsigned int freq,
10551 unsigned int period, unsigned int interval,
10552 unsigned int count, const u8 *device_types,
10553 size_t dev_types_len,
10554 const u8 *ies, size_t ies_len)
10555{
10556 struct i802_bss *bss = priv;
10557 struct wpa_driver_nl80211_data *drv = bss->drv;
10558 struct nl_msg *msg;
10559 struct nlattr *container;
10560 int ret;
10561
10562 wpa_printf(MSG_DEBUG,
10563 "nl80211: Start P2P Listen offload: freq=%u, period=%u, interval=%u, count=%u",
10564 freq, period, interval, count);
10565
10566 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD))
10567 return -1;
10568
10569 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10570 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10571 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10572 QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START))
10573 goto fail;
10574
10575 container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
10576 if (!container)
10577 goto fail;
10578
10579 if (nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL,
10580 freq) ||
10581 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD,
10582 period) ||
10583 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL,
10584 interval) ||
10585 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT,
10586 count) ||
10587 nla_put(msg, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES,
10588 dev_types_len, device_types) ||
10589 nla_put(msg, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE,
10590 ies_len, ies))
10591 goto fail;
10592
10593 nla_nest_end(msg, container);
10594 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10595 msg = NULL;
10596 if (ret) {
10597 wpa_printf(MSG_DEBUG,
10598 "nl80211: Failed to send P2P Listen offload vendor command");
10599 goto fail;
10600 }
10601
10602 return 0;
10603
10604fail:
10605 nlmsg_free(msg);
10606 return -1;
10607}
10608
10609
10610static int nl80211_p2p_lo_stop(void *priv)
10611{
10612 struct i802_bss *bss = priv;
10613 struct wpa_driver_nl80211_data *drv = bss->drv;
10614 struct nl_msg *msg;
10615
10616 wpa_printf(MSG_DEBUG, "nl80211: Stop P2P Listen offload");
10617
10618 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD))
10619 return -1;
10620
10621 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10622 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10623 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10624 QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP)) {
10625 nlmsg_free(msg);
10626 return -1;
10627 }
10628
10629 return send_and_recv_msgs(drv, msg, NULL, NULL);
10630}
10631
2e4e4fb7
SD
10632
10633static int nl80211_set_tdls_mode(void *priv, int tdls_external_control)
10634{
10635 struct i802_bss *bss = priv;
10636 struct wpa_driver_nl80211_data *drv = bss->drv;
10637 struct nl_msg *msg;
10638 struct nlattr *params;
10639 int ret;
10640 u32 tdls_mode;
10641
10642 wpa_printf(MSG_DEBUG,
10643 "nl80211: Set TDKS mode: tdls_external_control=%d",
10644 tdls_external_control);
10645
10646 if (tdls_external_control == 1)
10647 tdls_mode = QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT |
10648 QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL;
10649 else
10650 tdls_mode = QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT;
10651
10652 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10653 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10654 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10655 QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS))
10656 goto fail;
10657
10658 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
10659 if (!params)
10660 goto fail;
10661
10662 if (nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE,
10663 tdls_mode))
10664 goto fail;
10665
10666 nla_nest_end(msg, params);
10667
10668 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10669 msg = NULL;
10670 if (ret) {
10671 wpa_printf(MSG_ERROR,
10672 "nl80211: Set TDLS mode failed: ret=%d (%s)",
10673 ret, strerror(-ret));
10674 goto fail;
10675 }
10676 return 0;
10677fail:
10678 nlmsg_free(msg);
10679 return -1;
10680}
10681
3ab48492
KV
10682
10683#ifdef CONFIG_MBO
10684
10685static enum mbo_transition_reject_reason
10686nl80211_mbo_reject_reason_mapping(enum qca_wlan_btm_candidate_status status)
10687{
10688 switch (status) {
10689 case QCA_STATUS_REJECT_EXCESSIVE_FRAME_LOSS_EXPECTED:
10690 return MBO_TRANSITION_REJECT_REASON_FRAME_LOSS;
10691 case QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED:
10692 return MBO_TRANSITION_REJECT_REASON_DELAY;
10693 case QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY:
10694 return MBO_TRANSITION_REJECT_REASON_QOS_CAPACITY;
10695 case QCA_STATUS_REJECT_LOW_RSSI:
10696 return MBO_TRANSITION_REJECT_REASON_RSSI;
10697 case QCA_STATUS_REJECT_HIGH_INTERFERENCE:
10698 return MBO_TRANSITION_REJECT_REASON_INTERFERENCE;
10699 case QCA_STATUS_REJECT_UNKNOWN:
10700 default:
10701 return MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
10702 }
10703}
10704
10705
10706static void nl80211_parse_btm_candidate_info(struct candidate_list *candidate,
10707 struct nlattr *tb[], int num)
10708{
10709 enum qca_wlan_btm_candidate_status status;
10710 char buf[50];
10711
10712 os_memcpy(candidate->bssid,
10713 nla_data(tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID]),
10714 ETH_ALEN);
10715
10716 status = nla_get_u32(
10717 tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS]);
10718 candidate->is_accept = status == QCA_STATUS_ACCEPT;
10719 candidate->reject_reason = nl80211_mbo_reject_reason_mapping(status);
10720
10721 if (candidate->is_accept)
10722 os_snprintf(buf, sizeof(buf), "Accepted");
10723 else
10724 os_snprintf(buf, sizeof(buf),
10725 "Rejected, Reject_reason: %d",
10726 candidate->reject_reason);
10727 wpa_printf(MSG_DEBUG, "nl80211: BSSID[%d]: " MACSTR " %s",
10728 num, MAC2STR(candidate->bssid), buf);
10729}
10730
10731
10732static int
10733nl80211_get_bss_transition_status_handler(struct nl_msg *msg, void *arg)
10734{
10735 struct wpa_bss_candidate_info *info = arg;
10736 struct candidate_list *candidate = info->candidates;
10737 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
10738 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
10739 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX + 1];
10740 static struct nla_policy policy[
10741 QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX + 1] = {
10742 [QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID] = {
10743 .minlen = ETH_ALEN
10744 },
10745 [QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS] = {
10746 .type = NLA_U32,
10747 },
10748 };
10749 struct nlattr *attr;
10750 int rem;
10751 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10752 u8 num;
10753
10754 num = info->num; /* number of candidates sent to driver */
10755 info->num = 0;
10756 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10757 genlmsg_attrlen(gnlh, 0), NULL);
10758
10759 if (!tb_msg[NL80211_ATTR_VENDOR_DATA] ||
10760 nla_parse_nested(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
10761 tb_msg[NL80211_ATTR_VENDOR_DATA], NULL) ||
10762 !tb_vendor[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO])
10763 return NL_SKIP;
10764
10765 wpa_printf(MSG_DEBUG,
10766 "nl80211: WNM Candidate list received from driver");
10767 nla_for_each_nested(attr,
10768 tb_vendor[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO],
10769 rem) {
10770 if (info->num >= num ||
10771 nla_parse_nested(
10772 tb, QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX,
10773 attr, policy) ||
10774 !tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID] ||
10775 !tb[QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS])
10776 break;
10777
10778 nl80211_parse_btm_candidate_info(candidate, tb, info->num);
10779
10780 candidate++;
10781 info->num++;
10782 }
10783
10784 return NL_SKIP;
10785}
10786
10787
10788static struct wpa_bss_candidate_info *
10789nl80211_get_bss_transition_status(void *priv, struct wpa_bss_trans_info *params)
10790{
10791 struct i802_bss *bss = priv;
10792 struct wpa_driver_nl80211_data *drv = bss->drv;
10793 struct nl_msg *msg;
10794 struct nlattr *attr, *attr1, *attr2;
10795 struct wpa_bss_candidate_info *info;
10796 u8 i;
10797 int ret;
10798 u8 *pos;
10799
10800 if (!drv->fetch_bss_trans_status)
10801 return NULL;
10802
10803 info = os_zalloc(sizeof(*info));
10804 if (!info)
10805 return NULL;
10806 /* Allocate memory for number of candidates sent to driver */
10807 info->candidates = os_calloc(params->n_candidates,
10808 sizeof(*info->candidates));
10809 if (!info->candidates) {
10810 os_free(info);
10811 return NULL;
10812 }
10813
10814 /* Copy the number of candidates being sent to driver. This is used in
10815 * nl80211_get_bss_transition_status_handler() to limit the number of
10816 * candidates that can be populated in info->candidates and will be
10817 * later overwritten with the actual number of candidates received from
10818 * the driver.
10819 */
10820 info->num = params->n_candidates;
10821
10822 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10823 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10824 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10825 QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS))
10826 goto fail;
10827
10828 attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
10829 if (!attr)
10830 goto fail;
10831
10832 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON,
10833 params->mbo_transition_reason))
10834 goto fail;
10835
10836 attr1 = nla_nest_start(msg, QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO);
10837 if (!attr1)
10838 goto fail;
10839
10840 wpa_printf(MSG_DEBUG,
10841 "nl80211: WNM Candidate list info sending to driver: mbo_transition_reason: %d n_candidates: %d",
10842 params->mbo_transition_reason, params->n_candidates);
10843 pos = params->bssid;
10844 for (i = 0; i < params->n_candidates; i++) {
10845 wpa_printf(MSG_DEBUG, "nl80211: BSSID[%d]: " MACSTR, i,
10846 MAC2STR(pos));
10847 attr2 = nla_nest_start(msg, i);
10848 if (!attr2 ||
10849 nla_put(msg, QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID,
10850 ETH_ALEN, pos))
10851 goto fail;
10852 pos += ETH_ALEN;
10853 nla_nest_end(msg, attr2);
10854 }
10855
10856 nla_nest_end(msg, attr1);
10857 nla_nest_end(msg, attr);
10858
10859 ret = send_and_recv_msgs(drv, msg,
10860 nl80211_get_bss_transition_status_handler,
10861 info);
10862 msg = NULL;
10863 if (ret) {
10864 wpa_printf(MSG_ERROR,
10865 "nl80211: WNM Get BSS transition status failed: ret=%d (%s)",
10866 ret, strerror(-ret));
10867 goto fail;
10868 }
10869 return info;
10870
10871fail:
10872 nlmsg_free(msg);
10873 os_free(info->candidates);
10874 os_free(info);
10875 return NULL;
10876}
10877
178553b7
VK
10878
10879/**
10880 * nl80211_ignore_assoc_disallow - Configure driver to ignore assoc_disallow
10881 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
10882 * @ignore_assoc_disallow: 0 to not ignore, 1 to ignore
10883 * Returns: 0 on success, -1 on failure
10884 */
10885static int nl80211_ignore_assoc_disallow(void *priv, int ignore_disallow)
10886{
10887 struct i802_bss *bss = priv;
10888 struct wpa_driver_nl80211_data *drv = bss->drv;
10889 struct nl_msg *msg;
10890 struct nlattr *attr;
10891 int ret = -1;
10892
10893 if (!drv->set_wifi_conf_vendor_cmd_avail)
10894 return -1;
10895
10896 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
10897 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10898 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10899 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION))
10900 goto fail;
10901
10902 attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
10903 if (!attr)
10904 goto fail;
10905
10906 wpa_printf(MSG_DEBUG, "nl80211: Set ignore_assoc_disallow %d",
10907 ignore_disallow);
10908 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED,
10909 ignore_disallow))
10910 goto fail;
10911
10912 nla_nest_end(msg, attr);
10913
10914 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10915 msg = NULL;
10916 if (ret) {
10917 wpa_printf(MSG_ERROR,
10918 "nl80211: Set ignore_assoc_disallow failed: ret=%d (%s)",
10919 ret, strerror(-ret));
10920 goto fail;
10921 }
10922
10923fail:
10924 nlmsg_free(msg);
10925 return ret;
10926}
10927
3ab48492
KV
10928#endif /* CONFIG_MBO */
10929
b658547d
JM
10930#endif /* CONFIG_DRIVER_NL80211_QCA */
10931
7c813acf 10932
6922d440
IP
10933static int nl80211_write_to_file(const char *name, unsigned int val)
10934{
10935 int fd, len;
10936 char tmp[128];
3b726df8 10937 int ret = 0;
6922d440
IP
10938
10939 fd = open(name, O_RDWR);
10940 if (fd < 0) {
3b726df8
BN
10941 int level;
10942 /*
10943 * Flags may not exist on older kernels, or while we're tearing
10944 * down a disappearing device.
10945 */
10946 if (errno == ENOENT) {
10947 ret = 0;
10948 level = MSG_DEBUG;
10949 } else {
10950 ret = -1;
10951 level = MSG_ERROR;
10952 }
10953 wpa_printf(level, "nl80211: Failed to open %s: %s",
6922d440 10954 name, strerror(errno));
3b726df8 10955 return ret;
6922d440
IP
10956 }
10957
10958 len = os_snprintf(tmp, sizeof(tmp), "%u\n", val);
10959 len = write(fd, tmp, len);
3b726df8
BN
10960 if (len < 0) {
10961 ret = -1;
6922d440
IP
10962 wpa_printf(MSG_ERROR, "nl80211: Failed to write to %s: %s",
10963 name, strerror(errno));
3b726df8 10964 }
6922d440
IP
10965 close(fd);
10966
3b726df8 10967 return ret;
6922d440
IP
10968}
10969
10970
10971static int nl80211_configure_data_frame_filters(void *priv, u32 filter_flags)
10972{
10973 struct i802_bss *bss = priv;
10974 char path[128];
10975 int ret;
10976
10977 wpa_printf(MSG_DEBUG, "nl80211: Data frame filter flags=0x%x",
10978 filter_flags);
10979
10980 /* Configure filtering of unicast frame encrypted using GTK */
10981 ret = os_snprintf(path, sizeof(path),
10982 "/proc/sys/net/ipv4/conf/%s/drop_unicast_in_l2_multicast",
10983 bss->ifname);
bd86ea08
JM
10984 if (os_snprintf_error(sizeof(path), ret))
10985 return -1;
6922d440
IP
10986
10987 ret = nl80211_write_to_file(path,
10988 !!(filter_flags &
10989 WPA_DATA_FRAME_FILTER_FLAG_GTK));
10990 if (ret) {
10991 wpa_printf(MSG_ERROR,
10992 "nl80211: Failed to set IPv4 unicast in multicast filter");
10993 return ret;
10994 }
10995
10996 os_snprintf(path, sizeof(path),
10997 "/proc/sys/net/ipv6/conf/%s/drop_unicast_in_l2_multicast",
10998 bss->ifname);
10999 ret = nl80211_write_to_file(path,
11000 !!(filter_flags &
11001 WPA_DATA_FRAME_FILTER_FLAG_GTK));
11002
11003 if (ret) {
11004 wpa_printf(MSG_ERROR,
11005 "nl80211: Failed to set IPv6 unicast in multicast filter");
11006 return ret;
11007 }
11008
11009 /* Configure filtering of unicast frame encrypted using GTK */
11010 os_snprintf(path, sizeof(path),
11011 "/proc/sys/net/ipv4/conf/%s/drop_gratuitous_arp",
11012 bss->ifname);
11013 ret = nl80211_write_to_file(path,
11014 !!(filter_flags &
11015 WPA_DATA_FRAME_FILTER_FLAG_ARP));
11016 if (ret) {
11017 wpa_printf(MSG_ERROR,
11018 "nl80211: Failed set gratuitous ARP filter");
11019 return ret;
11020 }
11021
11022 /* Configure filtering of IPv6 NA frames */
11023 os_snprintf(path, sizeof(path),
11024 "/proc/sys/net/ipv6/conf/%s/drop_unsolicited_na",
11025 bss->ifname);
11026 ret = nl80211_write_to_file(path,
11027 !!(filter_flags &
11028 WPA_DATA_FRAME_FILTER_FLAG_NA));
11029 if (ret) {
11030 wpa_printf(MSG_ERROR,
11031 "nl80211: Failed to set unsolicited NA filter");
11032 return ret;
11033 }
11034
11035 return 0;
11036}
11037
11038
cc9a2575
KV
11039static int nl80211_get_ext_capab(void *priv, enum wpa_driver_if_type type,
11040 const u8 **ext_capa, const u8 **ext_capa_mask,
11041 unsigned int *ext_capa_len)
11042{
11043 struct i802_bss *bss = priv;
11044 struct wpa_driver_nl80211_data *drv = bss->drv;
11045 enum nl80211_iftype nlmode;
11046 unsigned int i;
11047
11048 if (!ext_capa || !ext_capa_mask || !ext_capa_len)
11049 return -1;
11050
11051 nlmode = wpa_driver_nl80211_if_type(type);
11052
11053 /* By default, use the per-radio values */
11054 *ext_capa = drv->extended_capa;
11055 *ext_capa_mask = drv->extended_capa_mask;
11056 *ext_capa_len = drv->extended_capa_len;
11057
11058 /* Replace the default value if a per-interface type value exists */
11059 for (i = 0; i < drv->num_iface_ext_capa; i++) {
11060 if (nlmode == drv->iface_ext_capa[i].iftype) {
11061 *ext_capa = drv->iface_ext_capa[i].ext_capa;
11062 *ext_capa_mask = drv->iface_ext_capa[i].ext_capa_mask;
11063 *ext_capa_len = drv->iface_ext_capa[i].ext_capa_len;
11064 break;
11065 }
11066 }
11067
11068 return 0;
11069}
11070
11071
3c67e977
VK
11072static int nl80211_update_connection_params(
11073 void *priv, struct wpa_driver_associate_params *params,
11074 enum wpa_drv_update_connect_params_mask mask)
11075{
11076 struct i802_bss *bss = priv;
11077 struct wpa_driver_nl80211_data *drv = bss->drv;
11078 struct nl_msg *msg;
11079 int ret = -1;
11080 enum nl80211_auth_type type;
11081
c574a3ff
SD
11082 /* Update Connection Params is intended for drivers that implement
11083 * internal SME and expect these updated connection params from
11084 * wpa_supplicant. Do not send this request for the drivers using
11085 * SME from wpa_supplicant.
11086 */
11087 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME)
11088 return 0;
11089
3c67e977
VK
11090 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_UPDATE_CONNECT_PARAMS);
11091 if (!msg)
11092 goto fail;
11093
11094 wpa_printf(MSG_DEBUG, "nl80211: Update connection params (ifindex=%d)",
11095 drv->ifindex);
11096
11097 if ((mask & WPA_DRV_UPDATE_ASSOC_IES) && params->wpa_ie) {
11098 if (nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len,
11099 params->wpa_ie))
11100 goto fail;
11101 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie,
11102 params->wpa_ie_len);
11103 }
11104
11105 if (mask & WPA_DRV_UPDATE_AUTH_TYPE) {
11106 type = get_nl_auth_type(params->auth_alg);
11107 if (type == NL80211_AUTHTYPE_MAX ||
11108 nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
11109 goto fail;
11110 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
11111 }
11112
11113 if ((mask & WPA_DRV_UPDATE_FILS_ERP_INFO) &&
11114 nl80211_put_fils_connect_params(drv, params, msg))
11115 goto fail;
11116
11117 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11118 msg = NULL;
11119 if (ret)
11120 wpa_dbg(drv->ctx, MSG_DEBUG,
11121 "nl80211: Update connect params command failed: ret=%d (%s)",
11122 ret, strerror(-ret));
11123
11124fail:
11125 nlmsg_free(msg);
11126 return ret;
11127}
11128
11129
ba71cb82
SD
11130static int nl80211_send_external_auth_status(void *priv,
11131 struct external_auth *params)
11132{
11133 struct i802_bss *bss = priv;
11134 struct wpa_driver_nl80211_data *drv = bss->drv;
11135 struct nl_msg *msg = NULL;
11136 int ret = -1;
11137
236e793e 11138 /* External auth command/status is intended for drivers that implement
1730a6a5
JM
11139 * internal SME but want to offload authentication processing (e.g.,
11140 * SAE) to hostapd/wpa_supplicant. Do not send the status to drivers
236e793e
SD
11141 * which do not support AP SME or use wpa_supplicant/hostapd SME.
11142 */
2552a373 11143 if ((is_ap_interface(drv->nlmode) && !bss->drv->device_ap_sme) ||
236e793e
SD
11144 (drv->capa.flags & WPA_DRIVER_FLAGS_SME))
11145 return -1;
11146
ba71cb82
SD
11147 wpa_dbg(drv->ctx, MSG_DEBUG,
11148 "nl80211: External auth status: %u", params->status);
11149
11150 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_EXTERNAL_AUTH);
11151 if (!msg ||
11152 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, params->status) ||
dd1a8cef 11153 (params->ssid && params->ssid_len &&
236e793e
SD
11154 nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid)) ||
11155 (params->pmkid &&
11156 nla_put(msg, NL80211_ATTR_PMKID, PMKID_LEN, params->pmkid)) ||
dd1a8cef
JM
11157 (params->bssid &&
11158 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid)))
ba71cb82
SD
11159 goto fail;
11160 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11161 msg = NULL;
11162 if (ret) {
11163 wpa_printf(MSG_DEBUG,
11164 "nl80211: External Auth status update failed: ret=%d (%s)",
11165 ret, strerror(-ret));
11166 goto fail;
11167 }
11168fail:
11169 nlmsg_free(msg);
11170 return ret;
11171}
11172
11173
5abc7823
VN
11174static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname,
11175 int val)
11176{
11177 struct i802_bss *bss = priv;
11178 struct wpa_driver_nl80211_data *drv = bss->drv;
11179 struct nl_msg *msg;
11180 int ret = -ENOBUFS;
11181
11182 wpa_printf(MSG_DEBUG, "nl80211: %s 4addr mode (bridge_ifname: %s)",
11183 val ? "Enable" : "Disable", bridge_ifname);
11184
11185 msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
11186 if (!msg || nla_put_u8(msg, NL80211_ATTR_4ADDR, val))
11187 goto fail;
11188
11189 if (bridge_ifname[0] && bss->added_if_into_bridge && !val) {
11190 if (linux_br_del_if(drv->global->ioctl_sock,
11191 bridge_ifname, bss->ifname)) {
11192 wpa_printf(MSG_ERROR,
11193 "nl80211: Failed to remove interface %s from bridge %s",
11194 bss->ifname, bridge_ifname);
11195 return -1;
11196 }
11197 bss->added_if_into_bridge = 0;
11198 }
11199
11200 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11201 msg = NULL;
11202 if (!ret) {
11203 if (bridge_ifname[0] && val &&
11204 i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
11205 return -1;
11206 return 0;
11207 }
11208
11209fail:
11210 nlmsg_free(msg);
11211 wpa_printf(MSG_ERROR, "nl80211: Failed to enable/disable 4addr");
11212
11213 return ret;
11214}
11215
11216
3f5285e8
JM
11217const struct wpa_driver_ops wpa_driver_nl80211_ops = {
11218 .name = "nl80211",
11219 .desc = "Linux nl80211/cfg80211",
11220 .get_bssid = wpa_driver_nl80211_get_bssid,
11221 .get_ssid = wpa_driver_nl80211_get_ssid,
9ebce9c5
JM
11222 .set_key = driver_nl80211_set_key,
11223 .scan2 = driver_nl80211_scan2,
d21c63b9
LC
11224 .sched_scan = wpa_driver_nl80211_sched_scan,
11225 .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
3f5285e8 11226 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
4f30addb 11227 .abort_scan = wpa_driver_nl80211_abort_scan,
9ebce9c5
JM
11228 .deauthenticate = driver_nl80211_deauthenticate,
11229 .authenticate = driver_nl80211_authenticate,
3f5285e8 11230 .associate = wpa_driver_nl80211_associate,
f2ed8023
JM
11231 .global_init = nl80211_global_init,
11232 .global_deinit = nl80211_global_deinit,
11233 .init2 = wpa_driver_nl80211_init,
9ebce9c5 11234 .deinit = driver_nl80211_deinit,
3f5285e8
JM
11235 .get_capa = wpa_driver_nl80211_get_capa,
11236 .set_operstate = wpa_driver_nl80211_set_operstate,
01652550 11237 .set_supp_port = wpa_driver_nl80211_set_supp_port,
6d158490 11238 .set_country = wpa_driver_nl80211_set_country,
f0793bf1 11239 .get_country = wpa_driver_nl80211_get_country,
19c3b566 11240 .set_ap = wpa_driver_nl80211_set_ap,
3c4ca363 11241 .set_acl = wpa_driver_nl80211_set_acl,
22a7c9d7 11242 .if_add = wpa_driver_nl80211_if_add,
9ebce9c5
JM
11243 .if_remove = driver_nl80211_if_remove,
11244 .send_mlme = driver_nl80211_send_mlme,
0fafeb54 11245 .get_hw_feature_data = nl80211_get_hw_feature_data,
0f4e8b4f 11246 .sta_add = wpa_driver_nl80211_sta_add,
9ebce9c5 11247 .sta_remove = driver_nl80211_sta_remove,
db149ac9 11248 .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
a8d6ffa4 11249 .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
1d6f6385 11250 .sta_set_airtime_weight = driver_nl80211_sta_set_airtime_weight,
c5121837 11251 .hapd_init = i802_init,
c5121837 11252 .hapd_deinit = i802_deinit,
f7b3920c 11253 .set_wds_sta = i802_set_wds_sta,
c5121837
JM
11254 .get_seqnum = i802_get_seqnum,
11255 .flush = i802_flush,
c5121837
JM
11256 .get_inact_sec = i802_get_inact_sec,
11257 .sta_clear_stats = i802_sta_clear_stats,
c5121837
JM
11258 .set_rts = i802_set_rts,
11259 .set_frag = i802_set_frag,
c5121837 11260 .set_tx_queue_params = i802_set_tx_queue_params,
9ebce9c5 11261 .set_sta_vlan = driver_nl80211_set_sta_vlan,
ee7ab173
JB
11262 .sta_deauth = i802_sta_deauth,
11263 .sta_disassoc = i802_sta_disassoc,
9ebce9c5 11264 .read_sta_data = driver_nl80211_read_sta_data,
e3802622 11265 .set_freq = i802_set_freq,
9ebce9c5 11266 .send_action = driver_nl80211_send_action,
5dfca53f 11267 .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
55777702
JM
11268 .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
11269 .cancel_remain_on_channel =
11270 wpa_driver_nl80211_cancel_remain_on_channel,
9ebce9c5 11271 .probe_req_report = driver_nl80211_probe_req_report,
af473088 11272 .deinit_ap = wpa_driver_nl80211_deinit_ap,
3c29244e 11273 .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
207ef3fb 11274 .resume = wpa_driver_nl80211_resume,
b625473c 11275 .signal_monitor = nl80211_signal_monitor,
1c5c7273 11276 .signal_poll = nl80211_signal_poll,
7f00dc6e 11277 .channel_info = nl80211_channel_info,
c55f774d 11278 .set_param = nl80211_set_param,
6859f1cb 11279 .get_radio_name = nl80211_get_radio_name,
a6efc65d
JM
11280 .add_pmkid = nl80211_add_pmkid,
11281 .remove_pmkid = nl80211_remove_pmkid,
11282 .flush_pmkid = nl80211_flush_pmkid,
b14a210c 11283 .set_rekey_info = nl80211_set_rekey_info,
bcf24348 11284 .poll_client = nl80211_poll_client,
29f338af 11285 .set_p2p_powersave = nl80211_set_p2p_powersave,
f90e9c1c 11286 .start_dfs_cac = nl80211_start_radar_detection,
695c7038 11287 .stop_ap = wpa_driver_nl80211_stop_ap,
03ea1786
AN
11288#ifdef CONFIG_TDLS
11289 .send_tdls_mgmt = nl80211_send_tdls_mgmt,
11290 .tdls_oper = nl80211_tdls_oper,
72b2605f
AN
11291 .tdls_enable_channel_switch = nl80211_tdls_enable_channel_switch,
11292 .tdls_disable_channel_switch = nl80211_tdls_disable_channel_switch,
03ea1786 11293#endif /* CONFIG_TDLS */
6a1ce395 11294 .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
d1836e23 11295 .update_dh_ie = nl80211_update_dh_ie,
597b94f5 11296 .get_mac_addr = wpa_driver_nl80211_get_macaddr,
0185007c 11297 .get_survey = wpa_driver_nl80211_get_survey,
a771c07d 11298 .status = wpa_driver_nl80211_status,
1c4ffa87 11299 .switch_channel = nl80211_switch_channel,
0de38036
JM
11300#ifdef ANDROID_P2P
11301 .set_noa = wpa_driver_set_p2p_noa,
11302 .get_noa = wpa_driver_get_p2p_noa,
11303 .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
11304#endif /* ANDROID_P2P */
5e2c3490 11305#ifdef ANDROID
ded14ce9 11306#ifndef ANDROID_LIB_STUB
5e2c3490 11307 .driver_cmd = wpa_driver_nl80211_driver_cmd,
ded14ce9 11308#endif /* !ANDROID_LIB_STUB */
5e2c3490 11309#endif /* ANDROID */
adef8948 11310 .vendor_cmd = nl80211_vendor_cmd,
049105b4 11311 .set_qos_map = nl80211_set_qos_map,
82ba4f2d 11312 .get_wowlan = nl80211_get_wowlan,
e4fa8b12 11313 .set_wowlan = nl80211_set_wowlan,
fee354c7 11314 .set_mac_addr = nl80211_set_mac_addr,
6c1664f6
BC
11315#ifdef CONFIG_MESH
11316 .init_mesh = wpa_driver_nl80211_init_mesh,
11317 .join_mesh = wpa_driver_nl80211_join_mesh,
11318 .leave_mesh = wpa_driver_nl80211_leave_mesh,
c36109e4 11319 .probe_mesh_link = nl80211_probe_mesh_link,
6c1664f6 11320#endif /* CONFIG_MESH */
71103bed
KP
11321 .br_add_ip_neigh = wpa_driver_br_add_ip_neigh,
11322 .br_delete_ip_neigh = wpa_driver_br_delete_ip_neigh,
73d2294f 11323 .br_port_set_attr = wpa_driver_br_port_set_attr,
7565752d 11324 .br_set_net_param = wpa_driver_br_set_net_param,
dfa87878
MB
11325 .add_tx_ts = nl80211_add_ts,
11326 .del_tx_ts = nl80211_del_ts,
45e3fc72 11327 .get_ifindex = nl80211_get_ifindex,
b658547d 11328#ifdef CONFIG_DRIVER_NL80211_QCA
9607a1ae 11329 .roaming = nl80211_roaming,
d98038bb 11330 .disable_fils = nl80211_disable_fils,
16689c7c 11331 .do_acs = wpa_driver_do_acs,
844dfeb8 11332 .set_band = nl80211_set_band,
98342208 11333 .get_pref_freq_list = nl80211_get_pref_freq_list,
7c813acf 11334 .set_prob_oper_freq = nl80211_set_prob_oper_freq,
a6f5b193
PX
11335 .p2p_lo_start = nl80211_p2p_lo_start,
11336 .p2p_lo_stop = nl80211_p2p_lo_stop,
cc9985d1 11337 .set_default_scan_ies = nl80211_set_default_scan_ies,
2e4e4fb7 11338 .set_tdls_mode = nl80211_set_tdls_mode,
3ab48492
KV
11339#ifdef CONFIG_MBO
11340 .get_bss_transition_status = nl80211_get_bss_transition_status,
178553b7 11341 .ignore_assoc_disallow = nl80211_ignore_assoc_disallow,
3ab48492 11342#endif /* CONFIG_MBO */
b04854ce 11343 .set_bssid_blacklist = nl80211_set_bssid_blacklist,
df3b2e22 11344 .add_sta_node = nl80211_add_sta_node,
b658547d 11345#endif /* CONFIG_DRIVER_NL80211_QCA */
6922d440 11346 .configure_data_frame_filters = nl80211_configure_data_frame_filters,
cc9a2575 11347 .get_ext_capab = nl80211_get_ext_capab,
3c67e977 11348 .update_connect_params = nl80211_update_connection_params,
ba71cb82 11349 .send_external_auth_status = nl80211_send_external_auth_status,
5abc7823 11350 .set_4addr_mode = nl80211_set_4addr_mode,
3f5285e8 11351};