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