1 /*
2 * Driver interaction with Linux nl80211/cfg80211 - Event processing
3 * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (c) 2009-2010, Atheros Communications
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 */
10
11 #include "includes.h"
12 #include <netlink/genl/genl.h>
13
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "common/qca-vendor.h"
17 #include "common/qca-vendor-attr.h"
18 #include "common/brcm_vendor.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/ieee802_11_common.h"
21 #include "driver_nl80211.h"
22
23
24 static void
25 nl80211_control_port_frame_tx_status(struct i802_bss *bss,
26 const u8 *frame, size_t len,
27 struct nlattr *ack, struct nlattr *cookie);
28
29
nl80211_command_to_string(enum nl80211_commands cmd)30 static const char * nl80211_command_to_string(enum nl80211_commands cmd)
31 {
32 #define C2S(x) case x: return #x;
33 switch (cmd) {
34 C2S(NL80211_CMD_UNSPEC)
35 C2S(NL80211_CMD_GET_WIPHY)
36 C2S(NL80211_CMD_SET_WIPHY)
37 C2S(NL80211_CMD_NEW_WIPHY)
38 C2S(NL80211_CMD_DEL_WIPHY)
39 C2S(NL80211_CMD_GET_INTERFACE)
40 C2S(NL80211_CMD_SET_INTERFACE)
41 C2S(NL80211_CMD_NEW_INTERFACE)
42 C2S(NL80211_CMD_DEL_INTERFACE)
43 C2S(NL80211_CMD_GET_KEY)
44 C2S(NL80211_CMD_SET_KEY)
45 C2S(NL80211_CMD_NEW_KEY)
46 C2S(NL80211_CMD_DEL_KEY)
47 C2S(NL80211_CMD_GET_BEACON)
48 C2S(NL80211_CMD_SET_BEACON)
49 C2S(NL80211_CMD_START_AP)
50 C2S(NL80211_CMD_STOP_AP)
51 C2S(NL80211_CMD_GET_STATION)
52 C2S(NL80211_CMD_SET_STATION)
53 C2S(NL80211_CMD_NEW_STATION)
54 C2S(NL80211_CMD_DEL_STATION)
55 C2S(NL80211_CMD_GET_MPATH)
56 C2S(NL80211_CMD_SET_MPATH)
57 C2S(NL80211_CMD_NEW_MPATH)
58 C2S(NL80211_CMD_DEL_MPATH)
59 C2S(NL80211_CMD_SET_BSS)
60 C2S(NL80211_CMD_SET_REG)
61 C2S(NL80211_CMD_REQ_SET_REG)
62 C2S(NL80211_CMD_GET_MESH_CONFIG)
63 C2S(NL80211_CMD_SET_MESH_CONFIG)
64 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
65 C2S(NL80211_CMD_GET_REG)
66 C2S(NL80211_CMD_GET_SCAN)
67 C2S(NL80211_CMD_TRIGGER_SCAN)
68 C2S(NL80211_CMD_NEW_SCAN_RESULTS)
69 C2S(NL80211_CMD_SCAN_ABORTED)
70 C2S(NL80211_CMD_REG_CHANGE)
71 C2S(NL80211_CMD_AUTHENTICATE)
72 C2S(NL80211_CMD_ASSOCIATE)
73 C2S(NL80211_CMD_DEAUTHENTICATE)
74 C2S(NL80211_CMD_DISASSOCIATE)
75 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
76 C2S(NL80211_CMD_REG_BEACON_HINT)
77 C2S(NL80211_CMD_JOIN_IBSS)
78 C2S(NL80211_CMD_LEAVE_IBSS)
79 C2S(NL80211_CMD_TESTMODE)
80 C2S(NL80211_CMD_CONNECT)
81 C2S(NL80211_CMD_ROAM)
82 C2S(NL80211_CMD_DISCONNECT)
83 C2S(NL80211_CMD_SET_WIPHY_NETNS)
84 C2S(NL80211_CMD_GET_SURVEY)
85 C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
86 C2S(NL80211_CMD_SET_PMKSA)
87 C2S(NL80211_CMD_DEL_PMKSA)
88 C2S(NL80211_CMD_FLUSH_PMKSA)
89 C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
90 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
91 C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
92 C2S(NL80211_CMD_REGISTER_FRAME)
93 C2S(NL80211_CMD_FRAME)
94 C2S(NL80211_CMD_FRAME_TX_STATUS)
95 C2S(NL80211_CMD_SET_POWER_SAVE)
96 C2S(NL80211_CMD_GET_POWER_SAVE)
97 C2S(NL80211_CMD_SET_CQM)
98 C2S(NL80211_CMD_NOTIFY_CQM)
99 C2S(NL80211_CMD_SET_CHANNEL)
100 C2S(NL80211_CMD_SET_WDS_PEER)
101 C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
102 C2S(NL80211_CMD_JOIN_MESH)
103 C2S(NL80211_CMD_LEAVE_MESH)
104 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
105 C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
106 C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
107 C2S(NL80211_CMD_GET_WOWLAN)
108 C2S(NL80211_CMD_SET_WOWLAN)
109 C2S(NL80211_CMD_START_SCHED_SCAN)
110 C2S(NL80211_CMD_STOP_SCHED_SCAN)
111 C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
112 C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
113 C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
114 C2S(NL80211_CMD_PMKSA_CANDIDATE)
115 C2S(NL80211_CMD_TDLS_OPER)
116 C2S(NL80211_CMD_TDLS_MGMT)
117 C2S(NL80211_CMD_UNEXPECTED_FRAME)
118 C2S(NL80211_CMD_PROBE_CLIENT)
119 C2S(NL80211_CMD_REGISTER_BEACONS)
120 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
121 C2S(NL80211_CMD_SET_NOACK_MAP)
122 C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
123 C2S(NL80211_CMD_START_P2P_DEVICE)
124 C2S(NL80211_CMD_STOP_P2P_DEVICE)
125 C2S(NL80211_CMD_CONN_FAILED)
126 C2S(NL80211_CMD_SET_MCAST_RATE)
127 C2S(NL80211_CMD_SET_MAC_ACL)
128 C2S(NL80211_CMD_RADAR_DETECT)
129 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
130 C2S(NL80211_CMD_UPDATE_FT_IES)
131 C2S(NL80211_CMD_FT_EVENT)
132 C2S(NL80211_CMD_CRIT_PROTOCOL_START)
133 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
134 C2S(NL80211_CMD_GET_COALESCE)
135 C2S(NL80211_CMD_SET_COALESCE)
136 C2S(NL80211_CMD_CHANNEL_SWITCH)
137 C2S(NL80211_CMD_VENDOR)
138 C2S(NL80211_CMD_SET_QOS_MAP)
139 C2S(NL80211_CMD_ADD_TX_TS)
140 C2S(NL80211_CMD_DEL_TX_TS)
141 C2S(NL80211_CMD_GET_MPP)
142 C2S(NL80211_CMD_JOIN_OCB)
143 C2S(NL80211_CMD_LEAVE_OCB)
144 C2S(NL80211_CMD_CH_SWITCH_STARTED_NOTIFY)
145 C2S(NL80211_CMD_TDLS_CHANNEL_SWITCH)
146 C2S(NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH)
147 C2S(NL80211_CMD_WIPHY_REG_CHANGE)
148 C2S(NL80211_CMD_ABORT_SCAN)
149 C2S(NL80211_CMD_START_NAN)
150 C2S(NL80211_CMD_STOP_NAN)
151 C2S(NL80211_CMD_ADD_NAN_FUNCTION)
152 C2S(NL80211_CMD_DEL_NAN_FUNCTION)
153 C2S(NL80211_CMD_CHANGE_NAN_CONFIG)
154 C2S(NL80211_CMD_NAN_MATCH)
155 C2S(NL80211_CMD_SET_MULTICAST_TO_UNICAST)
156 C2S(NL80211_CMD_UPDATE_CONNECT_PARAMS)
157 C2S(NL80211_CMD_SET_PMK)
158 C2S(NL80211_CMD_DEL_PMK)
159 C2S(NL80211_CMD_PORT_AUTHORIZED)
160 C2S(NL80211_CMD_RELOAD_REGDB)
161 C2S(NL80211_CMD_EXTERNAL_AUTH)
162 C2S(NL80211_CMD_STA_OPMODE_CHANGED)
163 C2S(NL80211_CMD_CONTROL_PORT_FRAME)
164 C2S(NL80211_CMD_GET_FTM_RESPONDER_STATS)
165 C2S(NL80211_CMD_PEER_MEASUREMENT_START)
166 C2S(NL80211_CMD_PEER_MEASUREMENT_RESULT)
167 C2S(NL80211_CMD_PEER_MEASUREMENT_COMPLETE)
168 C2S(NL80211_CMD_NOTIFY_RADAR)
169 C2S(NL80211_CMD_UPDATE_OWE_INFO)
170 C2S(NL80211_CMD_PROBE_MESH_LINK)
171 C2S(NL80211_CMD_SET_TID_CONFIG)
172 C2S(NL80211_CMD_UNPROT_BEACON)
173 C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS)
174 C2S(NL80211_CMD_SET_SAR_SPECS)
175 C2S(NL80211_CMD_OBSS_COLOR_COLLISION)
176 C2S(NL80211_CMD_COLOR_CHANGE_REQUEST)
177 C2S(NL80211_CMD_COLOR_CHANGE_STARTED)
178 C2S(NL80211_CMD_COLOR_CHANGE_ABORTED)
179 C2S(NL80211_CMD_COLOR_CHANGE_COMPLETED)
180 C2S(NL80211_CMD_SET_FILS_AAD)
181 C2S(NL80211_CMD_ASSOC_COMEBACK)
182 C2S(NL80211_CMD_ADD_LINK)
183 C2S(NL80211_CMD_REMOVE_LINK)
184 C2S(NL80211_CMD_ADD_LINK_STA)
185 C2S(NL80211_CMD_MODIFY_LINK_STA)
186 C2S(NL80211_CMD_REMOVE_LINK_STA)
187 C2S(NL80211_CMD_SET_HW_TIMESTAMP)
188 C2S(NL80211_CMD_LINKS_REMOVED)
189 C2S(__NL80211_CMD_AFTER_LAST)
190 }
191 #undef C2S
192
193 return "NL80211_CMD_UNKNOWN";
194 }
195
196
mlme_event_auth(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len)197 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
198 const u8 *frame, size_t len)
199 {
200 const struct ieee80211_mgmt *mgmt;
201 union wpa_event_data event;
202
203 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
204 drv->force_connect_cmd) {
205 /*
206 * Avoid reporting two association events that would confuse
207 * the core code.
208 */
209 wpa_printf(MSG_DEBUG,
210 "nl80211: Ignore auth event when using driver SME");
211 return;
212 }
213
214 wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
215 mgmt = (const struct ieee80211_mgmt *) frame;
216 if (len < 24 + sizeof(mgmt->u.auth)) {
217 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
218 "frame");
219 return;
220 }
221
222 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
223 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
224 os_memset(&event, 0, sizeof(event));
225 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
226 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
227 event.auth.auth_transaction =
228 le_to_host16(mgmt->u.auth.auth_transaction);
229 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
230 if (len > 24 + sizeof(mgmt->u.auth)) {
231 event.auth.ies = mgmt->u.auth.variable;
232 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
233 }
234
235 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
236 }
237
238
nl80211_parse_wmm_params(struct nlattr * wmm_attr,struct wmm_params * wmm_params)239 static void nl80211_parse_wmm_params(struct nlattr *wmm_attr,
240 struct wmm_params *wmm_params)
241 {
242 struct nlattr *wmm_info[NL80211_STA_WME_MAX + 1];
243 static struct nla_policy wme_policy[NL80211_STA_WME_MAX + 1] = {
244 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
245 };
246
247 if (!wmm_attr ||
248 nla_parse_nested(wmm_info, NL80211_STA_WME_MAX, wmm_attr,
249 wme_policy) ||
250 !wmm_info[NL80211_STA_WME_UAPSD_QUEUES])
251 return;
252
253 wmm_params->uapsd_queues =
254 nla_get_u8(wmm_info[NL80211_STA_WME_UAPSD_QUEUES]);
255 wmm_params->info_bitmap |= WMM_PARAMS_UAPSD_QUEUES_INFO;
256 }
257
258
mlme_event_assoc(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len,struct nlattr * wmm,struct nlattr * req_ie)259 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
260 const u8 *frame, size_t len, struct nlattr *wmm,
261 struct nlattr *req_ie)
262 {
263 const struct ieee80211_mgmt *mgmt;
264 union wpa_event_data event;
265 u16 status;
266 int ssid_len;
267
268 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
269 drv->force_connect_cmd) {
270 /*
271 * Avoid reporting two association events that would confuse
272 * the core code.
273 */
274 wpa_printf(MSG_DEBUG,
275 "nl80211: Ignore assoc event when using driver SME");
276 return;
277 }
278
279 wpa_printf(MSG_DEBUG, "nl80211: Associate event");
280 mgmt = (const struct ieee80211_mgmt *) frame;
281 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
282 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
283 "frame");
284 return;
285 }
286
287 status = le_to_host16(mgmt->u.assoc_resp.status_code);
288 if (status != WLAN_STATUS_SUCCESS) {
289 os_memset(&event, 0, sizeof(event));
290 event.assoc_reject.bssid = mgmt->bssid;
291 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
292 event.assoc_reject.resp_ies =
293 (u8 *) mgmt->u.assoc_resp.variable;
294 event.assoc_reject.resp_ies_len =
295 len - 24 - sizeof(mgmt->u.assoc_resp);
296 }
297 event.assoc_reject.status_code = status;
298
299 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
300 return;
301 }
302
303 drv->associated = 1;
304 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
305 os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
306
307 os_memset(&event, 0, sizeof(event));
308 event.assoc_info.resp_frame = frame;
309 event.assoc_info.resp_frame_len = len;
310 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
311 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
312 event.assoc_info.resp_ies_len =
313 len - 24 - sizeof(mgmt->u.assoc_resp);
314 }
315
316 if (req_ie) {
317 event.assoc_info.req_ies = nla_data(req_ie);
318 event.assoc_info.req_ies_len = nla_len(req_ie);
319 }
320
321 /* When this association was initiated outside of wpa_supplicant,
322 * drv->ssid needs to be set here to satisfy later checking. */
323 ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
324 if (ssid_len > 0) {
325 drv->ssid_len = ssid_len;
326 wpa_printf(MSG_DEBUG,
327 "nl80211: Set drv->ssid based on scan res info to '%s'",
328 wpa_ssid_txt(drv->ssid, drv->ssid_len));
329 }
330
331 event.assoc_info.freq = drv->assoc_freq;
332 drv->first_bss->flink->freq = drv->assoc_freq;
333
334 nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
335
336 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
337 }
338
339
340 #ifdef CONFIG_DRIVER_NL80211_QCA
341
qca_drv_connect_fail_reason_code_handler(struct nl_msg * msg,void * arg)342 static int qca_drv_connect_fail_reason_code_handler(struct nl_msg *msg,
343 void *arg)
344 {
345 struct nlattr *tb[NL80211_ATTR_MAX + 1];
346 struct nlattr *tb_sta_info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
347 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
348 u32 *reason_code = arg;
349
350 *reason_code = 0;
351 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
352 genlmsg_attrlen(gnlh, 0), NULL);
353
354 if (!tb[NL80211_ATTR_VENDOR_DATA]) {
355 wpa_printf(MSG_ERROR, "%s: Vendor data not found", __func__);
356 return NL_SKIP;
357 }
358
359 nla_parse(tb_sta_info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
360 nla_data(tb[NL80211_ATTR_VENDOR_DATA]),
361 nla_len(tb[NL80211_ATTR_VENDOR_DATA]), NULL);
362
363 if (!tb_sta_info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE]) {
364 wpa_printf(MSG_INFO, "%s: Vendor attr not found", __func__);
365 return NL_SKIP;
366 }
367
368 *reason_code = nla_get_u32(tb_sta_info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE]);
369
370 return NL_SKIP;
371 }
372
373
374 static enum qca_sta_connect_fail_reason_codes
drv_get_connect_fail_reason_code(struct wpa_driver_nl80211_data * drv)375 drv_get_connect_fail_reason_code(struct wpa_driver_nl80211_data *drv)
376 {
377 enum qca_sta_connect_fail_reason_codes reason_code;
378 struct nl_msg *msg;
379 int ret;
380
381 msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
382 if (!msg || nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
383 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
384 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
385 nlmsg_free(msg);
386 return 0;
387 }
388
389 ret = send_and_recv_resp(drv, msg,
390 qca_drv_connect_fail_reason_code_handler,
391 &reason_code);
392 if (ret)
393 wpa_printf(MSG_DEBUG,
394 "nl80211: Get connect fail reason_code failed: ret=%d (%s)",
395 ret, strerror(-ret));
396
397 return reason_code;
398 }
399
400
401 static enum sta_connect_fail_reason_codes
convert_connect_fail_reason_codes(enum qca_sta_connect_fail_reason_codes reason_code)402 convert_connect_fail_reason_codes(enum qca_sta_connect_fail_reason_codes
403 reason_code)
404 {
405 switch (reason_code) {
406 case QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND:
407 return STA_CONNECT_FAIL_REASON_NO_BSS_FOUND;
408 case QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL:
409 return STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL;
410 case QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED:
411 return STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED;
412 case QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED:
413 return STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED;
414 case QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL:
415 return STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL;
416 case QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED:
417 return STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED;
418 case QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED:
419 return STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED;
420 default:
421 return STA_CONNECT_FAIL_REASON_UNSPECIFIED;
422 }
423 }
424
425
qca_nl80211_link_reconfig_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)426 static void qca_nl80211_link_reconfig_event(struct wpa_driver_nl80211_data *drv,
427 u8 *data, size_t len)
428 {
429 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_MAX + 1];
430 u16 removed_links;
431 u8 *ap_mld;
432 int i;
433
434 if (!data)
435 return;
436
437 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_MAX,
438 (struct nlattr *) data, len, NULL) ||
439 !tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_AP_MLD_ADDR])
440 return;
441
442 ap_mld = nla_data(tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_AP_MLD_ADDR]);
443 wpa_printf(MSG_DEBUG, "nl80211: AP MLD address " MACSTR
444 " received in link reconfig event", MAC2STR(ap_mld));
445 if (!drv->sta_mlo_info.valid_links ||
446 !ether_addr_equal(drv->sta_mlo_info.ap_mld_addr, ap_mld)) {
447 if (drv->pending_link_reconfig_data == data) {
448 wpa_printf(MSG_DEBUG,
449 "nl80211: Drop pending link reconfig event since AP MLD not matched even after new connect/roam event");
450 os_free(drv->pending_link_reconfig_data);
451 drv->pending_link_reconfig_data = NULL;
452 return;
453 }
454
455 wpa_printf(MSG_DEBUG,
456 "nl80211: Cache new link reconfig event till next connect/roam event");
457 if (drv->pending_link_reconfig_data) {
458 wpa_printf(MSG_DEBUG, "nl80211: Override old link reconfig event data");
459 os_free(drv->pending_link_reconfig_data);
460 }
461 drv->pending_link_reconfig_data = os_memdup(data, len);
462 if (!drv->pending_link_reconfig_data)
463 return;
464 drv->pending_link_reconfig_data_len = len;
465 return;
466 }
467
468 if (!tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_REMOVED_LINKS])
469 return;
470 removed_links = nla_get_u16(
471 tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_REMOVED_LINKS]);
472
473 drv->sta_mlo_info.valid_links &= ~removed_links;
474
475 /*
476 * Set default BSSID to the BSSID of the lowest link ID of remaining
477 * links when the link used for (re)association is removed.
478 */
479 if (removed_links & BIT(drv->sta_mlo_info.assoc_link_id)) {
480 for_each_link(drv->sta_mlo_info.valid_links, i) {
481 os_memcpy(drv->bssid, drv->sta_mlo_info.links[i].bssid,
482 ETH_ALEN);
483 drv->sta_mlo_info.assoc_link_id = i;
484 break;
485 }
486 }
487
488 wpa_printf(MSG_DEBUG, "nl80211: Removed MLO links bitmap: 0x%x",
489 removed_links);
490
491 wpa_supplicant_event(drv->ctx, EVENT_LINK_RECONFIG, NULL);
492 }
493
494
495 static void
nl80211_parse_qca_vendor_mlo_link_info(struct driver_sta_mlo_info * mlo,struct nlattr * mlo_links)496 nl80211_parse_qca_vendor_mlo_link_info(struct driver_sta_mlo_info *mlo,
497 struct nlattr *mlo_links)
498 {
499 struct nlattr *link;
500 int rem_links;
501
502 nla_for_each_nested(link, mlo_links, rem_links) {
503 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAX + 1];
504 int link_id;
505
506 nla_parse(tb,QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAX, nla_data(link),
507 nla_len(link), NULL);
508
509 if (!tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID] ||
510 !tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR] ||
511 !tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID])
512 continue;
513
514 link_id = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID]);
515 if (link_id >= MAX_NUM_MLD_LINKS)
516 continue;
517
518 mlo->valid_links |= BIT(link_id);
519 os_memcpy(mlo->links[link_id].addr,
520 nla_data(tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR]),
521 ETH_ALEN);
522 os_memcpy(mlo->links[link_id].bssid,
523 nla_data(tb[QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID]),
524 ETH_ALEN);
525 wpa_printf(MSG_DEBUG, "nl80211: MLO link[%u] addr " MACSTR
526 " bssid " MACSTR,
527 link_id, MAC2STR(mlo->links[link_id].addr),
528 MAC2STR(mlo->links[link_id].bssid));
529 }
530 }
531
532 #endif /* CONFIG_DRIVER_NL80211_QCA */
533
534
nl80211_parse_mlo_link_info(struct driver_sta_mlo_info * mlo,struct nlattr * mlo_links)535 static void nl80211_parse_mlo_link_info(struct driver_sta_mlo_info *mlo,
536 struct nlattr *mlo_links)
537 {
538 struct nlattr *link;
539 int rem_links;
540
541 nla_for_each_nested(link, mlo_links, rem_links) {
542 struct nlattr *tb[NL80211_ATTR_MAX + 1];
543 int link_id;
544
545 nla_parse(tb, NL80211_ATTR_MAX, nla_data(link), nla_len(link),
546 NULL);
547
548 if (!tb[NL80211_ATTR_MLO_LINK_ID] || !tb[NL80211_ATTR_MAC] ||
549 !tb[NL80211_ATTR_BSSID])
550 continue;
551
552 link_id = nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
553 if (link_id >= MAX_NUM_MLD_LINKS)
554 continue;
555
556 if (tb[NL80211_ATTR_STATUS_CODE]) {
557 /* Set requested links only when status indicated */
558 mlo->req_links |= BIT(link_id);
559 if (nla_get_u16(tb[NL80211_ATTR_STATUS_CODE]) ==
560 WLAN_STATUS_SUCCESS)
561 mlo->valid_links |= BIT(link_id);
562 } else {
563 mlo->valid_links |= BIT(link_id);
564 }
565
566 os_memcpy(mlo->links[link_id].addr,
567 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
568 os_memcpy(mlo->links[link_id].bssid,
569 nla_data(tb[NL80211_ATTR_BSSID]), ETH_ALEN);
570 wpa_printf(MSG_DEBUG, "nl80211: MLO link[%u] addr " MACSTR
571 " bssid " MACSTR,
572 link_id, MAC2STR(mlo->links[link_id].addr),
573 MAC2STR(mlo->links[link_id].bssid));
574 }
575 }
576
577
578 struct links_info {
579 /* bitmap of link IDs in Per-STA profile subelements */
580 u16 non_assoc_links;
581 u8 addr[MAX_NUM_MLD_LINKS][ETH_ALEN];
582 };
583
584
nl80211_get_basic_mle_links_info(const u8 * mle,size_t mle_len,struct links_info * info)585 static void nl80211_get_basic_mle_links_info(const u8 *mle, size_t mle_len,
586 struct links_info *info)
587 {
588 size_t rem_len;
589 const u8 *pos;
590
591 if (mle_len < MULTI_LINK_CONTROL_LEN + 1 ||
592 mle_len - MULTI_LINK_CONTROL_LEN < mle[MULTI_LINK_CONTROL_LEN])
593 return;
594
595 /* Skip Common Info */
596 pos = mle + MULTI_LINK_CONTROL_LEN + mle[MULTI_LINK_CONTROL_LEN];
597 rem_len = mle_len -
598 (MULTI_LINK_CONTROL_LEN + mle[MULTI_LINK_CONTROL_LEN]);
599
600 /* Parse Subelements */
601 while (rem_len > 2) {
602 size_t ie_len = 2 + pos[1];
603
604 if (rem_len < ie_len)
605 break;
606
607 if (pos[0] == MULTI_LINK_SUB_ELEM_ID_PER_STA_PROFILE) {
608 u8 link_id;
609 const u8 *sta_profile;
610 u16 sta_ctrl;
611
612 if (pos[1] < BASIC_MLE_STA_PROF_STA_MAC_IDX + ETH_ALEN)
613 goto next_subelem;
614
615 sta_profile = &pos[2];
616 sta_ctrl = WPA_GET_LE16(sta_profile);
617 link_id = sta_ctrl & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
618 if (link_id >= MAX_NUM_MLD_LINKS)
619 goto next_subelem;
620
621 if (!(sta_ctrl & BASIC_MLE_STA_CTRL_PRES_STA_MAC))
622 goto next_subelem;
623
624 info->non_assoc_links |= BIT(link_id);
625 os_memcpy(info->addr[link_id],
626 &sta_profile[BASIC_MLE_STA_PROF_STA_MAC_IDX],
627 ETH_ALEN);
628 }
629 next_subelem:
630 pos += ie_len;
631 rem_len -= ie_len;
632 }
633 }
634
635
nl80211_update_rejected_links_info(struct driver_sta_mlo_info * mlo,struct nlattr * req_ie,struct nlattr * resp_ie)636 static int nl80211_update_rejected_links_info(struct driver_sta_mlo_info *mlo,
637 struct nlattr *req_ie,
638 struct nlattr *resp_ie)
639 {
640 int i;
641 struct wpabuf *mle;
642 struct ieee802_11_elems req_elems, resp_elems;
643 struct links_info req_info, resp_info;
644
645 if (!req_ie || !resp_ie) {
646 wpa_printf(MSG_INFO,
647 "nl80211: MLO: (Re)Association Request/Response frame elements not available");
648 return -1;
649 }
650
651 if (ieee802_11_parse_elems(nla_data(req_ie), nla_len(req_ie),
652 &req_elems, 0) == ParseFailed ||
653 ieee802_11_parse_elems(nla_data(resp_ie), nla_len(resp_ie),
654 &resp_elems, 0) == ParseFailed) {
655 wpa_printf(MSG_INFO,
656 "nl80211: MLO: Failed to parse (Re)Association Request/Response elements");
657 return -1;
658 }
659
660 mle = ieee802_11_defrag(req_elems.basic_mle, req_elems.basic_mle_len,
661 true);
662 if (!mle) {
663 wpa_printf(MSG_INFO,
664 "nl80211: MLO: Basic Multi-Link element not found in Association Request");
665 return -1;
666 }
667 os_memset(&req_info, 0, sizeof(req_info));
668 nl80211_get_basic_mle_links_info(wpabuf_head(mle), wpabuf_len(mle),
669 &req_info);
670 wpabuf_free(mle);
671
672 mle = ieee802_11_defrag(resp_elems.basic_mle, resp_elems.basic_mle_len,
673 true);
674 if (!mle) {
675 wpa_printf(MSG_ERROR,
676 "nl80211: MLO: Basic Multi-Link element not found in Association Response");
677 return -1;
678 }
679 os_memset(&resp_info, 0, sizeof(resp_info));
680 nl80211_get_basic_mle_links_info(wpabuf_head(mle), wpabuf_len(mle),
681 &resp_info);
682 wpabuf_free(mle);
683
684 if (req_info.non_assoc_links != resp_info.non_assoc_links) {
685 wpa_printf(MSG_ERROR,
686 "nl80211: MLO: Association Request and Response links bitmaps not equal (0x%x != 0x%x)",
687 req_info.non_assoc_links,
688 resp_info.non_assoc_links);
689 return -1;
690 }
691
692 mlo->req_links = BIT(mlo->assoc_link_id) | req_info.non_assoc_links;
693 if ((mlo->req_links & mlo->valid_links) != mlo->valid_links) {
694 wpa_printf(MSG_ERROR,
695 "nl80211: MLO: Accepted links are not a subset of requested links (req_links=0x%x valid_links=0x%x non_assoc_links=0x%x assoc_link_id=0x%x)",
696 mlo->req_links, mlo->valid_links,
697 req_info.non_assoc_links, BIT(mlo->assoc_link_id));
698 return -1;
699 }
700
701 /* Get MLO links info for rejected links */
702 for_each_link((mlo->req_links & ~mlo->valid_links), i) {
703 os_memcpy(mlo->links[i].bssid, resp_info.addr[i], ETH_ALEN);
704 os_memcpy(mlo->links[i].addr, req_info.addr[i], ETH_ALEN);
705 }
706
707 return 0;
708 }
709
710
nl80211_get_assoc_link_id(const u8 * data,u8 len)711 static int nl80211_get_assoc_link_id(const u8 *data, u8 len)
712 {
713 u16 control;
714
715 if (len < 2)
716 return -1;
717
718 control = WPA_GET_LE16(data);
719 if (!(control & BASIC_MULTI_LINK_CTRL_PRES_LINK_ID))
720 return -1;
721
722 #define BASIC_ML_IE_COMMON_INFO_LINK_ID_IDX \
723 (2 + /* Multi-Link Control field */ \
724 1 + /* Common Info Length field (Basic) */ \
725 ETH_ALEN) /* MLD MAC Address field (Basic) */
726 if (len <= BASIC_ML_IE_COMMON_INFO_LINK_ID_IDX)
727 return -1;
728
729 return data[BASIC_ML_IE_COMMON_INFO_LINK_ID_IDX] & 0x0F;
730 }
731
732
nl80211_parse_mlo_info(struct wpa_driver_nl80211_data * drv,bool qca_roam_auth,struct nlattr * addr,struct nlattr * mlo_links,struct nlattr * req_ie,struct nlattr * resp_ie)733 static void nl80211_parse_mlo_info(struct wpa_driver_nl80211_data *drv,
734 bool qca_roam_auth,
735 struct nlattr *addr,
736 struct nlattr *mlo_links,
737 struct nlattr *req_ie,
738 struct nlattr *resp_ie)
739 {
740 const u8 *ml_ie;
741 struct driver_sta_mlo_info *mlo = &drv->sta_mlo_info;
742 int res;
743
744 if (!addr || !mlo_links || !resp_ie)
745 return;
746
747 ml_ie = get_ml_ie(nla_data(resp_ie), nla_len(resp_ie),
748 MULTI_LINK_CONTROL_TYPE_BASIC);
749 if (!ml_ie)
750 return;
751
752 res = nl80211_get_assoc_link_id(&ml_ie[3], ml_ie[1] - 1);
753 if (res < 0 || res >= MAX_NUM_MLD_LINKS) {
754 wpa_printf(MSG_DEBUG,
755 "nl80211: Could not find a valid association Link ID (res=%d)",
756 res);
757 return;
758 }
759 drv->sta_mlo_info.assoc_link_id = res;
760
761 os_memcpy(mlo->ap_mld_addr, nla_data(addr), ETH_ALEN);
762 wpa_printf(MSG_DEBUG, "nl80211: AP MLD MAC Address " MACSTR,
763 MAC2STR(mlo->ap_mld_addr));
764
765 if (!qca_roam_auth)
766 nl80211_parse_mlo_link_info(mlo, mlo_links);
767 #ifdef CONFIG_DRIVER_NL80211_QCA
768 if (qca_roam_auth)
769 nl80211_parse_qca_vendor_mlo_link_info(mlo, mlo_links);
770 #endif /* CONFIG_DRIVER_NL80211_QCA */
771
772 if (!(mlo->valid_links & BIT(mlo->assoc_link_id)) ||
773 (!mlo->req_links &&
774 nl80211_update_rejected_links_info(mlo, req_ie, resp_ie))) {
775 wpa_printf(MSG_INFO, "nl80211: Invalid MLO connection info");
776 mlo->valid_links = 0;
777 return;
778 }
779
780 os_memcpy(drv->bssid, mlo->links[drv->sta_mlo_info.assoc_link_id].bssid,
781 ETH_ALEN);
782 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
783 }
784
785
786 #ifdef CONFIG_DRIVER_NL80211_QCA
787 static void
qca_nl80211_tid_to_link_map_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)788 qca_nl80211_tid_to_link_map_event(struct wpa_driver_nl80211_data *drv,
789 u8 *data, size_t len)
790 {
791 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_MAX + 1];
792 struct nlattr *tids;
793 union wpa_event_data event;
794 u8 *ap_mld;
795 int i, rem, tidnum = 0;
796
797 os_memset(&event, 0, sizeof(event));
798
799 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_MAX,
800 (struct nlattr *) data, len, NULL) ||
801 !tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_AP_MLD_ADDR])
802 return;
803
804 ap_mld = nla_data(tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_AP_MLD_ADDR]);
805
806 wpa_printf(MSG_DEBUG, "nl80211: AP MLD address " MACSTR
807 " received in TID to link mapping event", MAC2STR(ap_mld));
808 if (!drv->sta_mlo_info.valid_links ||
809 !ether_addr_equal(drv->sta_mlo_info.ap_mld_addr, ap_mld)) {
810 if (drv->pending_t2lm_data == data) {
811 wpa_printf(MSG_DEBUG,
812 "nl80211: Drop pending TID-to-link mapping event since AP MLD not matched even after new connect/roam event");
813 os_free(drv->pending_t2lm_data);
814 drv->pending_t2lm_data = NULL;
815 return;
816 }
817 wpa_printf(MSG_DEBUG,
818 "nl80211: Cache new TID-to-link map event until the next connect/roam event");
819 if (drv->pending_t2lm_data) {
820 wpa_printf(MSG_DEBUG,
821 "nl80211: Override old TID-to-link map event data");
822 os_free(drv->pending_t2lm_data);
823 }
824 drv->pending_t2lm_data = os_memdup(data, len);
825 if (!drv->pending_t2lm_data)
826 return;
827 drv->pending_t2lm_data_len = len;
828 return;
829 }
830
831 if (!tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_STATUS]) {
832 wpa_printf(MSG_DEBUG, "nl80211: Default TID-to-link map");
833 event.t2l_map_info.default_map = true;
834 goto out;
835 }
836
837 event.t2l_map_info.default_map = false;
838
839 nla_for_each_nested(tids,
840 tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_STATUS],
841 rem) {
842 u16 uplink, downlink;
843 struct nlattr *tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_MAX + 1];
844
845 if (nla_parse_nested(
846 tid, QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_MAX,
847 tids, NULL)) {
848 wpa_printf(MSG_DEBUG,
849 "nl80211: TID-to-link: nla_parse_nested() failed");
850 return;
851 }
852
853 if (!tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_UPLINK]) {
854 wpa_printf(MSG_DEBUG,
855 "nl80211: TID-to-link: uplink not present for tid: %d",
856 tidnum);
857 return;
858 }
859 uplink = nla_get_u16(tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_UPLINK]);
860
861 if (!tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_DOWNLINK]) {
862 wpa_printf(MSG_DEBUG,
863 "nl80211: TID-to-link: downlink not present for tid: %d",
864 tidnum);
865 return;
866 }
867 downlink = nla_get_u16(tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_DOWNLINK]);
868
869 wpa_printf(MSG_DEBUG,
870 "nl80211: TID-to-link: Received uplink %x downlink %x",
871 uplink, downlink);
872 for_each_link(drv->sta_mlo_info.valid_links, i) {
873 if (uplink & BIT(i))
874 event.t2l_map_info.t2lmap[i].uplink |=
875 BIT(tidnum);
876 if (downlink & BIT(i))
877 event.t2l_map_info.t2lmap[i].downlink |=
878 BIT(tidnum);
879 }
880
881 tidnum++;
882 }
883
884 out:
885 drv->sta_mlo_info.default_map = event.t2l_map_info.default_map;
886
887 event.t2l_map_info.valid_links = drv->sta_mlo_info.valid_links;
888 for (i = 0; i < MAX_NUM_MLD_LINKS && !drv->sta_mlo_info.default_map;
889 i++) {
890 if (!(drv->sta_mlo_info.valid_links & BIT(i)))
891 continue;
892
893 drv->sta_mlo_info.links[i].t2lmap.uplink =
894 event.t2l_map_info.t2lmap[i].uplink;
895 drv->sta_mlo_info.links[i].t2lmap.downlink =
896 event.t2l_map_info.t2lmap[i].downlink;
897 }
898
899 wpa_supplicant_event(drv->ctx, EVENT_TID_LINK_MAP, &event);
900 }
901 #endif /* CONFIG_DRIVER_NL80211_QCA */
902
903
mlme_event_connect(struct wpa_driver_nl80211_data * drv,enum nl80211_commands cmd,bool qca_roam_auth,struct nlattr * status,struct nlattr * addr,struct nlattr * req_ie,struct nlattr * resp_ie,struct nlattr * timed_out,struct nlattr * timeout_reason,struct nlattr * authorized,struct nlattr * key_replay_ctr,struct nlattr * ptk_kck,struct nlattr * ptk_kek,struct nlattr * subnet_status,struct nlattr * fils_erp_next_seq_num,struct nlattr * fils_pmk,struct nlattr * fils_pmkid,struct nlattr * mlo_links)904 static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
905 enum nl80211_commands cmd, bool qca_roam_auth,
906 struct nlattr *status,
907 struct nlattr *addr, struct nlattr *req_ie,
908 struct nlattr *resp_ie,
909 struct nlattr *timed_out,
910 struct nlattr *timeout_reason,
911 struct nlattr *authorized,
912 struct nlattr *key_replay_ctr,
913 struct nlattr *ptk_kck,
914 struct nlattr *ptk_kek,
915 struct nlattr *subnet_status,
916 struct nlattr *fils_erp_next_seq_num,
917 struct nlattr *fils_pmk,
918 struct nlattr *fils_pmkid,
919 struct nlattr *mlo_links)
920 {
921 union wpa_event_data event;
922 const u8 *ssid = NULL;
923 u16 status_code;
924 int ssid_len;
925
926 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
927 /*
928 * Avoid reporting two association events that would confuse
929 * the core code.
930 */
931 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
932 "when using userspace SME", cmd);
933 return;
934 }
935
936 drv->connect_reassoc = 0;
937
938 status_code = status ? nla_get_u16(status) : WLAN_STATUS_SUCCESS;
939
940 if (cmd == NL80211_CMD_CONNECT) {
941 wpa_printf(MSG_DEBUG,
942 "nl80211: Connect event (status=%u ignore_next_local_disconnect=%d)",
943 status_code, drv->ignore_next_local_disconnect);
944 } else if (cmd == NL80211_CMD_ROAM) {
945 wpa_printf(MSG_DEBUG, "nl80211: Roam event");
946 }
947
948 os_memset(&event, 0, sizeof(event));
949 if (cmd == NL80211_CMD_CONNECT && status_code != WLAN_STATUS_SUCCESS) {
950 if (addr)
951 event.assoc_reject.bssid = nla_data(addr);
952 if (drv->ignore_next_local_disconnect) {
953 drv->ignore_next_local_disconnect = 0;
954 if (!event.assoc_reject.bssid ||
955 !ether_addr_equal(event.assoc_reject.bssid,
956 drv->auth_attempt_bssid)) {
957 /*
958 * Ignore the event that came without a BSSID or
959 * for the old connection since this is likely
960 * not relevant to the new Connect command.
961 */
962 wpa_printf(MSG_DEBUG,
963 "nl80211: Ignore connection failure event triggered during reassociation");
964 return;
965 }
966 }
967 if (resp_ie) {
968 event.assoc_reject.resp_ies = nla_data(resp_ie);
969 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
970 }
971 event.assoc_reject.status_code = status_code;
972 event.assoc_reject.timed_out = timed_out != NULL;
973 if (timed_out && timeout_reason) {
974 enum nl80211_timeout_reason reason;
975
976 reason = nla_get_u32(timeout_reason);
977 switch (reason) {
978 case NL80211_TIMEOUT_SCAN:
979 event.assoc_reject.timeout_reason = "scan";
980 break;
981 case NL80211_TIMEOUT_AUTH:
982 event.assoc_reject.timeout_reason = "auth";
983 break;
984 case NL80211_TIMEOUT_ASSOC:
985 event.assoc_reject.timeout_reason = "assoc";
986 break;
987 default:
988 break;
989 }
990 }
991 if (fils_erp_next_seq_num)
992 event.assoc_reject.fils_erp_next_seq_num =
993 nla_get_u16(fils_erp_next_seq_num);
994
995 #ifdef CONFIG_DRIVER_NL80211_QCA
996 if (drv->get_sta_info_vendor_cmd_avail) {
997 enum qca_sta_connect_fail_reason_codes reason_code;
998
999 reason_code = drv_get_connect_fail_reason_code(drv);
1000 event.assoc_reject.reason_code =
1001 convert_connect_fail_reason_codes(reason_code);
1002 }
1003 #endif /* CONFIG_DRIVER_NL80211_QCA */
1004
1005 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
1006 return;
1007 }
1008
1009 drv->associated = 1;
1010 os_memset(&drv->sta_mlo_info, 0, sizeof(drv->sta_mlo_info));
1011 nl80211_parse_mlo_info(drv, qca_roam_auth, addr, mlo_links, req_ie,
1012 resp_ie);
1013 if (!drv->sta_mlo_info.valid_links && addr) {
1014 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
1015 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
1016 }
1017
1018 if (req_ie) {
1019 event.assoc_info.req_ies = nla_data(req_ie);
1020 event.assoc_info.req_ies_len = nla_len(req_ie);
1021
1022 if (cmd == NL80211_CMD_ROAM) {
1023 ssid = get_ie(event.assoc_info.req_ies,
1024 event.assoc_info.req_ies_len,
1025 WLAN_EID_SSID);
1026 if (ssid && ssid[1] > 0 && ssid[1] <= 32) {
1027 drv->ssid_len = ssid[1];
1028 os_memcpy(drv->ssid, ssid + 2, ssid[1]);
1029 wpa_printf(MSG_DEBUG,
1030 "nl80211: Set drv->ssid based on req_ie to '%s'",
1031 wpa_ssid_txt(drv->ssid,
1032 drv->ssid_len));
1033 }
1034 }
1035 }
1036 if (resp_ie) {
1037 event.assoc_info.resp_ies = nla_data(resp_ie);
1038 event.assoc_info.resp_ies_len = nla_len(resp_ie);
1039 }
1040
1041 event.assoc_info.freq = nl80211_get_assoc_freq(drv);
1042 drv->first_bss->flink->freq = drv->assoc_freq;
1043
1044 if ((!ssid || ssid[1] == 0 || ssid[1] > 32) &&
1045 (ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid)) > 0) {
1046 /* When this connection was initiated outside of wpa_supplicant,
1047 * drv->ssid needs to be set here to satisfy later checking. */
1048 drv->ssid_len = ssid_len;
1049 wpa_printf(MSG_DEBUG,
1050 "nl80211: Set drv->ssid based on scan res info to '%s'",
1051 wpa_ssid_txt(drv->ssid, drv->ssid_len));
1052 }
1053
1054 if (authorized && nla_get_u8(authorized)) {
1055 event.assoc_info.authorized = 1;
1056 wpa_printf(MSG_DEBUG, "nl80211: connection authorized");
1057 }
1058 if (key_replay_ctr) {
1059 event.assoc_info.key_replay_ctr = nla_data(key_replay_ctr);
1060 event.assoc_info.key_replay_ctr_len = nla_len(key_replay_ctr);
1061 }
1062 if (ptk_kck) {
1063 event.assoc_info.ptk_kck = nla_data(ptk_kck);
1064 event.assoc_info.ptk_kck_len = nla_len(ptk_kck);
1065 }
1066 if (ptk_kek) {
1067 event.assoc_info.ptk_kek = nla_data(ptk_kek);
1068 event.assoc_info.ptk_kek_len = nla_len(ptk_kek);
1069 }
1070
1071 if (subnet_status) {
1072 /*
1073 * At least for now, this is only available from
1074 * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS and that
1075 * attribute has the same values 0, 1, 2 as are used in the
1076 * variable here, so no mapping between different values are
1077 * needed.
1078 */
1079 event.assoc_info.subnet_status = nla_get_u8(subnet_status);
1080 }
1081
1082 if (fils_erp_next_seq_num)
1083 event.assoc_info.fils_erp_next_seq_num =
1084 nla_get_u16(fils_erp_next_seq_num);
1085
1086 if (fils_pmk) {
1087 event.assoc_info.fils_pmk = nla_data(fils_pmk);
1088 event.assoc_info.fils_pmk_len = nla_len(fils_pmk);
1089 }
1090
1091 if (fils_pmkid)
1092 event.assoc_info.fils_pmkid = nla_data(fils_pmkid);
1093
1094 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1095
1096 /* Avoid a race condition by stopping to ignore any following
1097 * disconnection events now that the driver has indicated it is
1098 * connected since that connection could have been triggered by a roam
1099 * operation that happened in parallel with the disconnection request.
1100 */
1101 drv->ignore_next_local_disconnect = 0;
1102
1103 #ifdef CONFIG_DRIVER_NL80211_QCA
1104 if (drv->pending_t2lm_data)
1105 qca_nl80211_tid_to_link_map_event(drv, drv->pending_t2lm_data,
1106 drv->pending_t2lm_data_len);
1107 else
1108 drv->sta_mlo_info.default_map = true;
1109
1110 if (drv->pending_link_reconfig_data)
1111 qca_nl80211_link_reconfig_event(
1112 drv, drv->pending_link_reconfig_data,
1113 drv->pending_link_reconfig_data_len);
1114 #endif /* CONFIG_DRIVER_NL80211_QCA */
1115 }
1116
1117
mlme_event_disconnect(struct wpa_driver_nl80211_data * drv,struct nlattr * reason,struct nlattr * addr,struct nlattr * by_ap)1118 static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
1119 struct nlattr *reason, struct nlattr *addr,
1120 struct nlattr *by_ap)
1121 {
1122 union wpa_event_data data;
1123 unsigned int locally_generated = by_ap == NULL;
1124
1125 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1126 /*
1127 * Avoid reporting two disassociation events that could
1128 * confuse the core code.
1129 */
1130 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1131 "event when using userspace SME");
1132 return;
1133 }
1134
1135 if (drv->ignore_next_local_disconnect) {
1136 drv->ignore_next_local_disconnect = 0;
1137 if (locally_generated) {
1138 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1139 "event triggered during reassociation");
1140 return;
1141 }
1142 wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
1143 "disconnect but got another disconnect "
1144 "event first");
1145 }
1146
1147 wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
1148 nl80211_mark_disconnected(drv);
1149 os_memset(&data, 0, sizeof(data));
1150 if (reason)
1151 data.deauth_info.reason_code = nla_get_u16(reason);
1152 data.deauth_info.locally_generated = by_ap == NULL;
1153 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
1154 }
1155
1156
calculate_chan_offset(int width,int freq,int cf1,int cf2)1157 static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
1158 {
1159 int freq1 = 0;
1160
1161 switch (convert2width(width)) {
1162 case CHAN_WIDTH_20_NOHT:
1163 case CHAN_WIDTH_20:
1164 return 0;
1165 case CHAN_WIDTH_40:
1166 freq1 = cf1 - 10;
1167 break;
1168 case CHAN_WIDTH_80:
1169 freq1 = cf1 - 30;
1170 break;
1171 case CHAN_WIDTH_160:
1172 freq1 = cf1 - 70;
1173 break;
1174 case CHAN_WIDTH_80P80:
1175 freq1 = cf1 - 30;
1176 break;
1177 case CHAN_WIDTH_320:
1178 freq1 = cf1 - 150;
1179 break;
1180 case CHAN_WIDTH_UNKNOWN:
1181 case CHAN_WIDTH_2160:
1182 case CHAN_WIDTH_4320:
1183 case CHAN_WIDTH_6480:
1184 case CHAN_WIDTH_8640:
1185 /* FIXME: implement this */
1186 return 0;
1187 }
1188
1189 return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
1190 }
1191
1192
mlme_event_ch_switch(struct wpa_driver_nl80211_data * drv,struct nlattr * ifindex,struct nlattr * link,struct nlattr * freq,struct nlattr * type,struct nlattr * bw,struct nlattr * cf1,struct nlattr * cf2,struct nlattr * punct_bitmap,int finished)1193 static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
1194 struct nlattr *ifindex, struct nlattr *link,
1195 struct nlattr *freq, struct nlattr *type,
1196 struct nlattr *bw, struct nlattr *cf1,
1197 struct nlattr *cf2,
1198 struct nlattr *punct_bitmap,
1199 int finished)
1200 {
1201 struct i802_bss *bss;
1202 union wpa_event_data data;
1203 int ht_enabled = 1;
1204 int chan_offset = 0;
1205 int ifidx;
1206
1207 wpa_printf(MSG_DEBUG, "nl80211: Channel switch%s event",
1208 finished ? "" : " started");
1209
1210 if (!freq)
1211 return;
1212
1213 ifidx = nla_get_u32(ifindex);
1214 bss = get_bss_ifindex(drv, ifidx);
1215 if (bss == NULL) {
1216 wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
1217 ifidx);
1218 return;
1219 }
1220
1221 if (type) {
1222 enum nl80211_channel_type ch_type = nla_get_u32(type);
1223
1224 wpa_printf(MSG_DEBUG, "nl80211: Channel type: %d", ch_type);
1225 switch (ch_type) {
1226 case NL80211_CHAN_NO_HT:
1227 ht_enabled = 0;
1228 break;
1229 case NL80211_CHAN_HT20:
1230 break;
1231 case NL80211_CHAN_HT40PLUS:
1232 chan_offset = 1;
1233 break;
1234 case NL80211_CHAN_HT40MINUS:
1235 chan_offset = -1;
1236 break;
1237 }
1238 } else if (bw && cf1) {
1239 /* This can happen for example with VHT80 ch switch */
1240 chan_offset = calculate_chan_offset(nla_get_u32(bw),
1241 nla_get_u32(freq),
1242 nla_get_u32(cf1),
1243 cf2 ? nla_get_u32(cf2) : 0);
1244 wpa_printf(MSG_DEBUG, "nl80211: Calculated channel offset: %d",
1245 chan_offset);
1246 } else {
1247 wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
1248 }
1249
1250 os_memset(&data, 0, sizeof(data));
1251 data.ch_switch.freq = nla_get_u32(freq);
1252 data.ch_switch.ht_enabled = ht_enabled;
1253 data.ch_switch.ch_offset = chan_offset;
1254 if (punct_bitmap)
1255 data.ch_switch.punct_bitmap = (u16) nla_get_u32(punct_bitmap);
1256 if (bw)
1257 data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
1258 if (cf1)
1259 data.ch_switch.cf1 = nla_get_u32(cf1);
1260 if (cf2)
1261 data.ch_switch.cf2 = nla_get_u32(cf2);
1262
1263 if (link)
1264 data.ch_switch.link_id = nla_get_u8(link);
1265 else
1266 data.ch_switch.link_id = NL80211_DRV_LINK_ID_NA;
1267
1268 if (finished) {
1269 if (data.ch_switch.link_id != NL80211_DRV_LINK_ID_NA) {
1270 struct i802_link *mld_link;
1271
1272 mld_link = nl80211_get_link(bss,
1273 data.ch_switch.link_id);
1274 mld_link->freq = data.ch_switch.freq;
1275 if (bw)
1276 mld_link->bandwidth = channel_width_to_int(
1277 data.ch_switch.ch_width);
1278 } else {
1279 bss->flink->freq = data.ch_switch.freq;
1280 if (bw)
1281 bss->flink->bandwidth = channel_width_to_int(
1282 data.ch_switch.ch_width);
1283 }
1284 }
1285
1286 if (link && is_sta_interface(drv->nlmode)) {
1287 u8 link_id = data.ch_switch.link_id;
1288
1289 if (link_id < MAX_NUM_MLD_LINKS &&
1290 drv->sta_mlo_info.valid_links & BIT(link_id)) {
1291 drv->sta_mlo_info.links[link_id].freq =
1292 data.ch_switch.freq;
1293 wpa_supplicant_event(
1294 bss->ctx,
1295 finished ? EVENT_LINK_CH_SWITCH :
1296 EVENT_LINK_CH_SWITCH_STARTED, &data);
1297 }
1298
1299 if (link_id != drv->sta_mlo_info.assoc_link_id)
1300 return;
1301 }
1302
1303 drv->assoc_freq = data.ch_switch.freq;
1304
1305 wpa_supplicant_event(bss->ctx, finished ?
1306 EVENT_CH_SWITCH : EVENT_CH_SWITCH_STARTED, &data);
1307 }
1308
1309
mlme_timeout_event(struct wpa_driver_nl80211_data * drv,enum nl80211_commands cmd,struct nlattr * addr)1310 static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
1311 enum nl80211_commands cmd, struct nlattr *addr)
1312 {
1313 union wpa_event_data event;
1314 enum wpa_event_type ev;
1315
1316 if (nla_len(addr) != ETH_ALEN)
1317 return;
1318
1319 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
1320 cmd, MAC2STR((u8 *) nla_data(addr)));
1321
1322 if (cmd == NL80211_CMD_AUTHENTICATE)
1323 ev = EVENT_AUTH_TIMED_OUT;
1324 else if (cmd == NL80211_CMD_ASSOCIATE)
1325 ev = EVENT_ASSOC_TIMED_OUT;
1326 else
1327 return;
1328
1329 os_memset(&event, 0, sizeof(event));
1330 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
1331 wpa_supplicant_event(drv->ctx, ev, &event);
1332 }
1333
1334
mlme_event_mgmt(struct i802_bss * bss,struct nlattr * freq,struct nlattr * sig,const u8 * frame,size_t len,int link_id)1335 static void mlme_event_mgmt(struct i802_bss *bss,
1336 struct nlattr *freq, struct nlattr *sig,
1337 const u8 *frame, size_t len,
1338 int link_id)
1339 {
1340 struct wpa_driver_nl80211_data *drv = bss->drv;
1341 const struct ieee80211_mgmt *mgmt;
1342 union wpa_event_data event;
1343 u16 fc, stype;
1344 int ssi_signal = 0;
1345 int rx_freq = 0;
1346
1347 wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
1348 mgmt = (const struct ieee80211_mgmt *) frame;
1349 if (len < 24) {
1350 wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
1351 return;
1352 }
1353
1354 fc = le_to_host16(mgmt->frame_control);
1355 stype = WLAN_FC_GET_STYPE(fc);
1356
1357 if (sig)
1358 ssi_signal = (s32) nla_get_u32(sig);
1359
1360 os_memset(&event, 0, sizeof(event));
1361 if (freq) {
1362 event.rx_mgmt.freq = nla_get_u32(freq);
1363 rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
1364 }
1365 wpa_printf(MSG_DEBUG,
1366 "nl80211: RX frame da=" MACSTR " sa=" MACSTR " bssid=" MACSTR
1367 " freq=%d ssi_signal=%d fc=0x%x seq_ctrl=0x%x stype=%u (%s) len=%u",
1368 MAC2STR(mgmt->da), MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
1369 rx_freq, ssi_signal, fc,
1370 le_to_host16(mgmt->seq_ctrl), stype, fc2str(fc),
1371 (unsigned int) len);
1372 event.rx_mgmt.frame = frame;
1373 event.rx_mgmt.frame_len = len;
1374 event.rx_mgmt.ssi_signal = ssi_signal;
1375 event.rx_mgmt.drv_priv = bss;
1376 event.rx_mgmt.ctx = bss->ctx;
1377 event.rx_mgmt.link_id = link_id;
1378
1379 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
1380 }
1381
1382
mlme_event_mgmt_tx_status(struct i802_bss * bss,struct nlattr * cookie,const u8 * frame,size_t len,struct nlattr * ack)1383 static void mlme_event_mgmt_tx_status(struct i802_bss *bss,
1384 struct nlattr *cookie, const u8 *frame,
1385 size_t len, struct nlattr *ack)
1386 {
1387 union wpa_event_data event;
1388 const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
1389 struct wpa_driver_nl80211_data *drv = bss->drv;
1390 u16 fc = le_to_host16(hdr->frame_control);
1391 u64 cookie_val = 0;
1392
1393 if (cookie)
1394 cookie_val = nla_get_u64(cookie);
1395 wpa_printf(MSG_DEBUG,
1396 "nl80211: Frame TX status event A1=" MACSTR
1397 " %sstype=%d cookie=0x%llx%s ack=%d",
1398 MAC2STR(hdr->addr1),
1399 WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ? "not-mgmt " : "",
1400 WLAN_FC_GET_STYPE(fc), (long long unsigned int) cookie_val,
1401 cookie ? "" : "(N/A)", ack != NULL);
1402
1403 if (cookie_val && cookie_val == drv->eapol_tx_cookie &&
1404 len >= ETH_HLEN &&
1405 WPA_GET_BE16(frame + 2 * ETH_ALEN) == ETH_P_PAE) {
1406 wpa_printf(MSG_DEBUG,
1407 "nl80211: Work around misdelivered control port TX status for EAPOL");
1408 nl80211_control_port_frame_tx_status(bss, frame, len, ack,
1409 cookie);
1410 return;
1411 }
1412
1413 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
1414 return;
1415
1416 if (!is_ap_interface(drv->nlmode) &&
1417 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
1418 if (!cookie)
1419 return;
1420
1421 wpa_printf(MSG_DEBUG,
1422 "nl80211: Frame TX status: cookie=0x%llx%s (ack=%d)",
1423 (long long unsigned int) cookie_val,
1424 cookie_val == drv->send_frame_cookie ?
1425 " (match)" : " (unknown)", ack != NULL);
1426 if (cookie_val != drv->send_frame_cookie)
1427 return;
1428 } else if (!is_ap_interface(drv->nlmode) &&
1429 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
1430 wpa_printf(MSG_DEBUG,
1431 "nl80211: Authentication frame TX status: ack=%d",
1432 !!ack);
1433 }
1434
1435 os_memset(&event, 0, sizeof(event));
1436 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
1437 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
1438 event.tx_status.dst = hdr->addr1;
1439 event.tx_status.data = frame;
1440 event.tx_status.data_len = len;
1441 event.tx_status.ack = ack != NULL;
1442 event.tx_status.link_id = cookie_val == drv->send_frame_cookie ?
1443 drv->send_frame_link_id : NL80211_DRV_LINK_ID_NA;
1444 wpa_supplicant_event(bss->ctx, EVENT_TX_STATUS, &event);
1445 }
1446
1447
mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data * drv,enum wpa_event_type type,const u8 * frame,size_t len)1448 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
1449 enum wpa_event_type type,
1450 const u8 *frame, size_t len)
1451 {
1452 const struct ieee80211_mgmt *mgmt;
1453 union wpa_event_data event;
1454 const u8 *bssid = NULL;
1455 u16 reason_code = 0;
1456
1457 if (type == EVENT_DEAUTH)
1458 wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
1459 else
1460 wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
1461
1462 mgmt = (const struct ieee80211_mgmt *) frame;
1463 if (len >= 24) {
1464 bssid = mgmt->bssid;
1465
1466 if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
1467 !drv->associated &&
1468 !ether_addr_equal(bssid, drv->auth_bssid) &&
1469 !ether_addr_equal(bssid, drv->auth_attempt_bssid) &&
1470 ether_addr_equal(bssid, drv->prev_bssid)) {
1471 /*
1472 * Avoid issues with some roaming cases where
1473 * disconnection event for the old AP may show up after
1474 * we have started connection with the new AP.
1475 * In case of locally generated event clear
1476 * ignore_next_local_deauth as well, to avoid next local
1477 * deauth event be wrongly ignored.
1478 */
1479 if (ether_addr_equal(mgmt->sa, drv->first_bss->addr) ||
1480 (!is_zero_ether_addr(drv->first_bss->prev_addr) &&
1481 ether_addr_equal(mgmt->sa,
1482 drv->first_bss->prev_addr))) {
1483 wpa_printf(MSG_DEBUG,
1484 "nl80211: Received a locally generated deauth event. Clear ignore_next_local_deauth flag");
1485 drv->ignore_next_local_deauth = 0;
1486 } else {
1487 wpa_printf(MSG_DEBUG,
1488 "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
1489 MAC2STR(bssid),
1490 MAC2STR(drv->auth_attempt_bssid));
1491 }
1492 return;
1493 }
1494
1495 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
1496 drv->connect_reassoc && drv->associated &&
1497 ether_addr_equal(bssid, drv->prev_bssid) &&
1498 !ether_addr_equal(bssid, drv->auth_attempt_bssid)) {
1499 /*
1500 * Avoid issues with some roaming cases where
1501 * disconnection event for the old AP may show up after
1502 * we have started connection with the new AP.
1503 */
1504 wpa_printf(MSG_DEBUG,
1505 "nl80211: Ignore deauth/disassoc event from old AP "
1506 MACSTR
1507 " when already connecting with " MACSTR,
1508 MAC2STR(bssid),
1509 MAC2STR(drv->auth_attempt_bssid));
1510 return;
1511 }
1512
1513 if (drv->associated != 0 &&
1514 !ether_addr_equal(bssid, drv->bssid) &&
1515 !ether_addr_equal(bssid, drv->auth_bssid)) {
1516 /*
1517 * We have presumably received this deauth as a
1518 * response to a clear_state_mismatch() outgoing
1519 * deauth. Don't let it take us offline!
1520 */
1521 wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
1522 "from Unknown BSSID " MACSTR " -- ignoring",
1523 MAC2STR(bssid));
1524 return;
1525 }
1526 }
1527
1528 nl80211_mark_disconnected(drv);
1529 os_memset(&event, 0, sizeof(event));
1530
1531 /* Note: Same offset for Reason Code in both frame subtypes */
1532 if (len >= 24 + sizeof(mgmt->u.deauth))
1533 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1534
1535 if (type == EVENT_DISASSOC) {
1536 event.disassoc_info.locally_generated =
1537 ether_addr_equal(mgmt->sa, drv->first_bss->addr);
1538 event.disassoc_info.addr = bssid;
1539 event.disassoc_info.reason_code = reason_code;
1540 if (frame + len > mgmt->u.disassoc.variable) {
1541 event.disassoc_info.ie = mgmt->u.disassoc.variable;
1542 event.disassoc_info.ie_len = frame + len -
1543 mgmt->u.disassoc.variable;
1544 }
1545 } else {
1546 event.deauth_info.locally_generated =
1547 ether_addr_equal(mgmt->sa, drv->first_bss->addr);
1548 if (drv->ignore_deauth_event) {
1549 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
1550 drv->ignore_deauth_event = 0;
1551 if (event.deauth_info.locally_generated)
1552 drv->ignore_next_local_deauth = 0;
1553 return;
1554 }
1555 if (drv->ignore_next_local_deauth) {
1556 drv->ignore_next_local_deauth = 0;
1557 if (event.deauth_info.locally_generated) {
1558 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
1559 return;
1560 }
1561 wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
1562 }
1563 event.deauth_info.addr = bssid;
1564 event.deauth_info.reason_code = reason_code;
1565 if (frame + len > mgmt->u.deauth.variable) {
1566 event.deauth_info.ie = mgmt->u.deauth.variable;
1567 event.deauth_info.ie_len = frame + len -
1568 mgmt->u.deauth.variable;
1569 }
1570 }
1571
1572 wpa_supplicant_event(drv->ctx, type, &event);
1573 }
1574
1575
mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data * drv,enum wpa_event_type type,const u8 * frame,size_t len)1576 static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
1577 enum wpa_event_type type,
1578 const u8 *frame, size_t len)
1579 {
1580 const struct ieee80211_mgmt *mgmt;
1581 union wpa_event_data event;
1582 u16 reason_code = 0;
1583
1584 if (type == EVENT_UNPROT_DEAUTH)
1585 wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
1586 else
1587 wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
1588
1589 if (len < 24)
1590 return;
1591
1592 mgmt = (const struct ieee80211_mgmt *) frame;
1593
1594 os_memset(&event, 0, sizeof(event));
1595 /* Note: Same offset for Reason Code in both frame subtypes */
1596 if (len >= 24 + sizeof(mgmt->u.deauth))
1597 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1598
1599 if (type == EVENT_UNPROT_DISASSOC) {
1600 event.unprot_disassoc.sa = mgmt->sa;
1601 event.unprot_disassoc.da = mgmt->da;
1602 event.unprot_disassoc.reason_code = reason_code;
1603 } else {
1604 event.unprot_deauth.sa = mgmt->sa;
1605 event.unprot_deauth.da = mgmt->da;
1606 event.unprot_deauth.reason_code = reason_code;
1607 }
1608
1609 wpa_supplicant_event(drv->ctx, type, &event);
1610 }
1611
1612
mlme_event_unprot_beacon(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len)1613 static void mlme_event_unprot_beacon(struct wpa_driver_nl80211_data *drv,
1614 const u8 *frame, size_t len)
1615 {
1616 const struct ieee80211_mgmt *mgmt;
1617 union wpa_event_data event;
1618
1619 if (len < 24)
1620 return;
1621
1622 mgmt = (const struct ieee80211_mgmt *) frame;
1623
1624 os_memset(&event, 0, sizeof(event));
1625 event.unprot_beacon.sa = mgmt->sa;
1626 wpa_supplicant_event(drv->ctx, EVENT_UNPROT_BEACON, &event);
1627 }
1628
1629
1630 static s8
nl80211_get_link_id_by_freq(struct i802_bss * bss,unsigned int freq)1631 nl80211_get_link_id_by_freq(struct i802_bss *bss, unsigned int freq)
1632 {
1633 unsigned int i;
1634
1635 for_each_link(bss->valid_links, i) {
1636 if ((unsigned int) bss->links[i].freq == freq)
1637 return i;
1638 }
1639
1640 return NL80211_DRV_LINK_ID_NA;
1641 }
1642
1643
mlme_event(struct i802_bss * bss,enum nl80211_commands cmd,struct nlattr * frame,struct nlattr * addr,struct nlattr * timed_out,struct nlattr * freq,struct nlattr * ack,struct nlattr * cookie,struct nlattr * sig,struct nlattr * wmm,struct nlattr * req_ie,struct nlattr * link)1644 static void mlme_event(struct i802_bss *bss,
1645 enum nl80211_commands cmd, struct nlattr *frame,
1646 struct nlattr *addr, struct nlattr *timed_out,
1647 struct nlattr *freq, struct nlattr *ack,
1648 struct nlattr *cookie, struct nlattr *sig,
1649 struct nlattr *wmm, struct nlattr *req_ie,
1650 struct nlattr *link)
1651 {
1652 struct wpa_driver_nl80211_data *drv = bss->drv;
1653 u16 stype = 0, auth_type = 0;
1654 const u8 *data;
1655 size_t len;
1656 int link_id = -1;
1657 struct i802_link *mld_link = NULL;
1658
1659 if (timed_out && addr) {
1660 mlme_timeout_event(drv, cmd, addr);
1661 return;
1662 }
1663
1664 if (frame == NULL) {
1665 wpa_printf(MSG_DEBUG,
1666 "nl80211: MLME event %d (%s) without frame data",
1667 cmd, nl80211_command_to_string(cmd));
1668 return;
1669 }
1670
1671 /* Determine the MLD link either by an explicitly provided link id or
1672 * finding a match based on the frequency. */
1673 if (link)
1674 link_id = nla_get_u8(link);
1675 else if (freq)
1676 link_id = nl80211_get_link_id_by_freq(bss, nla_get_u32(freq));
1677
1678 if (nl80211_link_valid(bss->valid_links, link_id))
1679 mld_link = nl80211_get_link(bss, link_id);
1680
1681 data = nla_data(frame);
1682 len = nla_len(frame);
1683 if (len < 4 + 2 * ETH_ALEN) {
1684 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
1685 MACSTR ") - too short",
1686 cmd, nl80211_command_to_string(cmd), bss->ifname,
1687 MAC2STR(bss->addr));
1688 return;
1689 }
1690 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
1691 ") A1=" MACSTR " A2=" MACSTR " on link_id=%d", cmd,
1692 nl80211_command_to_string(cmd), bss->ifname,
1693 MAC2STR(bss->addr), MAC2STR(data + 4),
1694 MAC2STR(data + 4 + ETH_ALEN), link_id);
1695
1696 /* PASN Authentication frame can be received with a different source MAC
1697 * address. Allow NL80211_CMD_FRAME event with foreign addresses also.
1698 */
1699 if (cmd == NL80211_CMD_FRAME && len >= 24) {
1700 const struct ieee80211_mgmt *mgmt;
1701 u16 fc;
1702
1703 mgmt = (const struct ieee80211_mgmt *) data;
1704 fc = le_to_host16(mgmt->frame_control);
1705 stype = WLAN_FC_GET_STYPE(fc);
1706 auth_type = le_to_host16(mgmt->u.auth.auth_alg);
1707 }
1708
1709 if (cmd == NL80211_CMD_FRAME && stype == WLAN_FC_STYPE_AUTH &&
1710 auth_type == host_to_le16(WLAN_AUTH_PASN)) {
1711 wpa_printf(MSG_DEBUG,
1712 "nl80211: %s: Allow PASN frame for foreign address",
1713 bss->ifname);
1714 } else if (cmd != NL80211_CMD_FRAME_TX_STATUS &&
1715 !(data[4] & 0x01) &&
1716 !ether_addr_equal(bss->addr, data + 4) &&
1717 (is_zero_ether_addr(bss->rand_addr) ||
1718 !ether_addr_equal(bss->rand_addr, data + 4)) &&
1719 !ether_addr_equal(bss->addr, data + 4 + ETH_ALEN) &&
1720 (is_zero_ether_addr(drv->first_bss->prev_addr) ||
1721 !ether_addr_equal(bss->prev_addr, data + 4 + ETH_ALEN)) &&
1722 (!mld_link ||
1723 !ether_addr_equal(mld_link->addr, data + 4))) {
1724 wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
1725 "for foreign address", bss->ifname);
1726 return;
1727 }
1728 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
1729 nla_data(frame), nla_len(frame));
1730
1731 switch (cmd) {
1732 case NL80211_CMD_AUTHENTICATE:
1733 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
1734 break;
1735 case NL80211_CMD_ASSOCIATE:
1736 mlme_event_assoc(drv, nla_data(frame), nla_len(frame), wmm,
1737 req_ie);
1738 break;
1739 case NL80211_CMD_DEAUTHENTICATE:
1740 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
1741 nla_data(frame), nla_len(frame));
1742 break;
1743 case NL80211_CMD_DISASSOCIATE:
1744 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
1745 nla_data(frame), nla_len(frame));
1746 break;
1747 case NL80211_CMD_FRAME:
1748 mlme_event_mgmt(bss, freq, sig, nla_data(frame),
1749 nla_len(frame), link_id);
1750 break;
1751 case NL80211_CMD_FRAME_TX_STATUS:
1752 mlme_event_mgmt_tx_status(bss, cookie, nla_data(frame),
1753 nla_len(frame), ack);
1754 break;
1755 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1756 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
1757 nla_data(frame), nla_len(frame));
1758 break;
1759 case NL80211_CMD_UNPROT_DISASSOCIATE:
1760 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
1761 nla_data(frame), nla_len(frame));
1762 break;
1763 case NL80211_CMD_UNPROT_BEACON:
1764 mlme_event_unprot_beacon(drv, nla_data(frame), nla_len(frame));
1765 break;
1766 default:
1767 break;
1768 }
1769 }
1770
1771
mlme_event_michael_mic_failure(struct i802_bss * bss,struct nlattr * tb[])1772 static void mlme_event_michael_mic_failure(struct i802_bss *bss,
1773 struct nlattr *tb[])
1774 {
1775 union wpa_event_data data;
1776
1777 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
1778 os_memset(&data, 0, sizeof(data));
1779 if (tb[NL80211_ATTR_MAC]) {
1780 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
1781 nla_data(tb[NL80211_ATTR_MAC]),
1782 nla_len(tb[NL80211_ATTR_MAC]));
1783 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
1784 }
1785 if (tb[NL80211_ATTR_KEY_SEQ]) {
1786 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
1787 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
1788 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
1789 }
1790 if (tb[NL80211_ATTR_KEY_TYPE]) {
1791 enum nl80211_key_type key_type =
1792 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
1793 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
1794 if (key_type == NL80211_KEYTYPE_PAIRWISE)
1795 data.michael_mic_failure.unicast = 1;
1796 } else
1797 data.michael_mic_failure.unicast = 1;
1798
1799 if (tb[NL80211_ATTR_KEY_IDX]) {
1800 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
1801 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
1802 }
1803
1804 wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
1805 }
1806
1807
mlme_event_join_ibss(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1808 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
1809 struct nlattr *tb[])
1810 {
1811 unsigned int freq;
1812 union wpa_event_data event;
1813
1814 if (tb[NL80211_ATTR_MAC] == NULL) {
1815 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
1816 "event");
1817 return;
1818 }
1819 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1820
1821 drv->associated = 1;
1822 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
1823 MAC2STR(drv->bssid));
1824
1825 freq = nl80211_get_assoc_freq(drv);
1826 if (freq) {
1827 wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
1828 freq);
1829 drv->first_bss->flink->freq = freq;
1830 }
1831
1832 os_memset(&event, 0, sizeof(event));
1833 event.assoc_info.freq = freq;
1834
1835 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1836 }
1837
1838
mlme_event_remain_on_channel(struct wpa_driver_nl80211_data * drv,int cancel_event,struct nlattr * tb[])1839 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
1840 int cancel_event, struct nlattr *tb[])
1841 {
1842 unsigned int freq, chan_type, duration;
1843 union wpa_event_data data;
1844 u64 cookie;
1845
1846 if (tb[NL80211_ATTR_WIPHY_FREQ])
1847 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1848 else
1849 freq = 0;
1850
1851 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
1852 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1853 else
1854 chan_type = 0;
1855
1856 if (tb[NL80211_ATTR_DURATION])
1857 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
1858 else
1859 duration = 0;
1860
1861 if (tb[NL80211_ATTR_COOKIE])
1862 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
1863 else
1864 cookie = 0;
1865
1866 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
1867 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
1868 cancel_event, freq, chan_type, duration,
1869 (long long unsigned int) cookie,
1870 cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
1871
1872 if (cookie != drv->remain_on_chan_cookie)
1873 return; /* not for us */
1874
1875 if (cancel_event)
1876 drv->pending_remain_on_chan = 0;
1877
1878 os_memset(&data, 0, sizeof(data));
1879 data.remain_on_channel.freq = freq;
1880 data.remain_on_channel.duration = duration;
1881 wpa_supplicant_event(drv->ctx, cancel_event ?
1882 EVENT_CANCEL_REMAIN_ON_CHANNEL :
1883 EVENT_REMAIN_ON_CHANNEL, &data);
1884 }
1885
1886
mlme_event_ft_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1887 static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
1888 struct nlattr *tb[])
1889 {
1890 union wpa_event_data data;
1891
1892 os_memset(&data, 0, sizeof(data));
1893
1894 if (tb[NL80211_ATTR_IE]) {
1895 data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
1896 data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
1897 }
1898
1899 if (tb[NL80211_ATTR_IE_RIC]) {
1900 data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
1901 data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
1902 }
1903
1904 if (tb[NL80211_ATTR_MAC])
1905 os_memcpy(data.ft_ies.target_ap,
1906 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1907
1908 wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
1909 MAC2STR(data.ft_ies.target_ap));
1910
1911 wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
1912 }
1913
1914
mlme_event_dh_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr * tb[])1915 static void mlme_event_dh_event(struct wpa_driver_nl80211_data *drv,
1916 struct i802_bss *bss,
1917 struct nlattr *tb[])
1918 {
1919 union wpa_event_data data;
1920 u8 *addr, *link_addr = NULL;
1921 int assoc_link_id = -1;
1922
1923 if (!is_ap_interface(drv->nlmode))
1924 return;
1925 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
1926 return;
1927
1928 os_memset(&data, 0, sizeof(data));
1929 addr = nla_data(tb[NL80211_ATTR_MAC]);
1930
1931 if (!bss->valid_links &&
1932 (tb[NL80211_ATTR_MLO_LINK_ID] ||
1933 tb[NL80211_ATTR_MLD_ADDR])) {
1934 wpa_printf(MSG_ERROR,
1935 "nl80211: Link info not expected for DH event for non-MLD AP");
1936 return;
1937 }
1938
1939 if (tb[NL80211_ATTR_MLO_LINK_ID]) {
1940 assoc_link_id = nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
1941 wpa_printf(MSG_DEBUG,
1942 "nl80211: STA assoc link ID %d in UPDATE_OWE_INFO event",
1943 assoc_link_id);
1944
1945 if (assoc_link_id != NL80211_DRV_LINK_ID_NA &&
1946 tb[NL80211_ATTR_MLD_ADDR]) {
1947 link_addr = addr;
1948 addr = nla_data(tb[NL80211_ATTR_MLD_ADDR]);
1949 wpa_printf(MSG_DEBUG,
1950 "nl80211: STA assoc link addr " MACSTR,
1951 MAC2STR(link_addr));
1952 }
1953 }
1954
1955 data.update_dh.peer = addr;
1956 data.update_dh.ie = nla_data(tb[NL80211_ATTR_IE]);
1957 data.update_dh.ie_len = nla_len(tb[NL80211_ATTR_IE]);
1958 data.update_dh.assoc_link_id = assoc_link_id;
1959 data.update_dh.link_addr = link_addr;
1960
1961 wpa_printf(MSG_DEBUG, "nl80211: DH event - peer " MACSTR,
1962 MAC2STR(data.update_dh.peer));
1963
1964 wpa_supplicant_event(bss->ctx, EVENT_UPDATE_DH, &data);
1965 }
1966
1967
send_scan_event(struct wpa_driver_nl80211_data * drv,int aborted,struct nlattr * tb[],int external_scan)1968 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
1969 struct nlattr *tb[], int external_scan)
1970 {
1971 union wpa_event_data event;
1972 struct nlattr *nl;
1973 int rem;
1974 struct scan_info *info;
1975 #define MAX_REPORT_FREQS 110
1976 int freqs[MAX_REPORT_FREQS];
1977 int num_freqs = 0;
1978
1979 if (!external_scan && drv->scan_for_auth) {
1980 drv->scan_for_auth = 0;
1981 wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
1982 "cfg80211 BSS entry");
1983 wpa_driver_nl80211_authenticate_retry(drv);
1984 return;
1985 }
1986
1987 os_memset(&event, 0, sizeof(event));
1988 info = &event.scan_info;
1989 info->aborted = aborted;
1990 info->external_scan = external_scan;
1991 info->nl_scan_event = 1;
1992
1993 if (tb[NL80211_ATTR_SCAN_SSIDS]) {
1994 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
1995 struct wpa_driver_scan_ssid *s =
1996 &info->ssids[info->num_ssids];
1997 s->ssid = nla_data(nl);
1998 s->ssid_len = nla_len(nl);
1999 wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
2000 wpa_ssid_txt(s->ssid, s->ssid_len));
2001 info->num_ssids++;
2002 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
2003 break;
2004 }
2005 }
2006 if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
2007 char msg[MAX_REPORT_FREQS * 5 + 1], *pos, *end;
2008 int res;
2009
2010 pos = msg;
2011 end = pos + sizeof(msg);
2012 *pos = '\0';
2013
2014 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
2015 {
2016 freqs[num_freqs] = nla_get_u32(nl);
2017 res = os_snprintf(pos, end - pos, " %d",
2018 freqs[num_freqs]);
2019 if (!os_snprintf_error(end - pos, res))
2020 pos += res;
2021 num_freqs++;
2022 if (num_freqs == MAX_REPORT_FREQS)
2023 break;
2024 }
2025 info->freqs = freqs;
2026 info->num_freqs = num_freqs;
2027 msg[sizeof(msg) - 1] = '\0';
2028 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
2029 msg);
2030 }
2031
2032 if (tb[NL80211_ATTR_SCAN_START_TIME_TSF] &&
2033 tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]) {
2034 info->scan_start_tsf =
2035 nla_get_u64(tb[NL80211_ATTR_SCAN_START_TIME_TSF]);
2036 os_memcpy(info->scan_start_tsf_bssid,
2037 nla_data(tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]),
2038 ETH_ALEN);
2039 }
2040
2041 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
2042 }
2043
2044
nl80211_cqm_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])2045 static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
2046 struct nlattr *tb[])
2047 {
2048 static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
2049 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
2050 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
2051 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
2052 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
2053 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
2054 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
2055 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
2056 [NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
2057 };
2058 struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
2059 enum nl80211_cqm_rssi_threshold_event event;
2060 union wpa_event_data ed;
2061 int res;
2062
2063 if (tb[NL80211_ATTR_CQM] == NULL ||
2064 nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
2065 cqm_policy)) {
2066 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
2067 return;
2068 }
2069
2070 os_memset(&ed, 0, sizeof(ed));
2071
2072 if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
2073 if (!tb[NL80211_ATTR_MAC])
2074 return;
2075 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
2076 ETH_ALEN);
2077 ed.low_ack.num_packets =
2078 nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
2079 wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR
2080 " (num_packets %u)",
2081 MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets);
2082 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
2083 return;
2084 }
2085
2086 if (cqm[NL80211_ATTR_CQM_BEACON_LOSS_EVENT]) {
2087 wpa_printf(MSG_DEBUG, "nl80211: Beacon loss event");
2088 wpa_supplicant_event(drv->ctx, EVENT_BEACON_LOSS, NULL);
2089 return;
2090 }
2091
2092 if (cqm[NL80211_ATTR_CQM_TXE_RATE] &&
2093 cqm[NL80211_ATTR_CQM_TXE_PKTS] &&
2094 cqm[NL80211_ATTR_CQM_TXE_INTVL] &&
2095 cqm[NL80211_ATTR_MAC]) {
2096 wpa_printf(MSG_DEBUG, "nl80211: CQM TXE event for " MACSTR
2097 " (rate: %u pkts: %u interval: %u)",
2098 MAC2STR((u8 *) nla_data(cqm[NL80211_ATTR_MAC])),
2099 nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_RATE]),
2100 nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_PKTS]),
2101 nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_INTVL]));
2102 return;
2103 }
2104
2105 if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
2106 wpa_printf(MSG_DEBUG,
2107 "nl80211: Not a CQM RSSI threshold event");
2108 return;
2109 }
2110 event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
2111
2112 if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
2113 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2114 "event: RSSI high");
2115 ed.signal_change.above_threshold = 1;
2116 } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
2117 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2118 "event: RSSI low");
2119 ed.signal_change.above_threshold = 0;
2120 } else {
2121 wpa_printf(MSG_DEBUG,
2122 "nl80211: Unknown CQM RSSI threshold event: %d",
2123 event);
2124 return;
2125 }
2126
2127 /*
2128 * nl80211_get_link_signal() and nl80211_get_link_noise() set default
2129 * values in case querying the driver fails.
2130 */
2131 res = nl80211_get_link_signal(drv, drv->bssid, &ed.signal_change.data);
2132 if (res == 0) {
2133 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %lu",
2134 ed.signal_change.data.signal,
2135 ed.signal_change.data.current_tx_rate);
2136 } else {
2137 wpa_printf(MSG_DEBUG,
2138 "nl80211: Querying the driver for signal info failed");
2139 }
2140
2141 res = nl80211_get_link_noise(drv, &ed.signal_change);
2142 if (res == 0) {
2143 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
2144 ed.signal_change.current_noise);
2145 } else {
2146 wpa_printf(MSG_DEBUG,
2147 "nl80211: Querying the driver for noise info failed");
2148 }
2149
2150 wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
2151 }
2152
2153
nl80211_new_peer_candidate(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2154 static void nl80211_new_peer_candidate(struct wpa_driver_nl80211_data *drv,
2155 struct nlattr **tb)
2156 {
2157 const u8 *addr;
2158 union wpa_event_data data;
2159
2160 if (drv->nlmode != NL80211_IFTYPE_MESH_POINT ||
2161 !tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
2162 return;
2163
2164 addr = nla_data(tb[NL80211_ATTR_MAC]);
2165 wpa_printf(MSG_DEBUG, "nl80211: New peer candidate " MACSTR,
2166 MAC2STR(addr));
2167
2168 os_memset(&data, 0, sizeof(data));
2169 data.mesh_peer.peer = addr;
2170 data.mesh_peer.ies = nla_data(tb[NL80211_ATTR_IE]);
2171 data.mesh_peer.ie_len = nla_len(tb[NL80211_ATTR_IE]);
2172 wpa_supplicant_event(drv->ctx, EVENT_NEW_PEER_CANDIDATE, &data);
2173 }
2174
2175
nl80211_new_station_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr ** tb)2176 static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
2177 struct i802_bss *bss,
2178 struct nlattr **tb)
2179 {
2180 u8 *peer_addr;
2181 union wpa_event_data data;
2182
2183 if (tb[NL80211_ATTR_MAC] == NULL)
2184 return;
2185 peer_addr = nla_data(tb[NL80211_ATTR_MAC]);
2186 wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR,
2187 MAC2STR(peer_addr));
2188
2189 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
2190 u8 *link_addr = NULL;
2191 int assoc_link_id = -1;
2192 u8 *req_ies = NULL, *resp_ies = NULL;
2193 size_t req_ies_len = 0, resp_ies_len = 0;
2194
2195 if (!bss->valid_links &&
2196 (tb[NL80211_ATTR_MLO_LINK_ID] ||
2197 tb[NL80211_ATTR_MLD_ADDR])) {
2198 wpa_printf(MSG_ERROR,
2199 "nl80211: MLO info not expected for new station event for non-MLD AP");
2200 return;
2201 }
2202
2203 if (tb[NL80211_ATTR_MLO_LINK_ID]) {
2204 assoc_link_id =
2205 nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
2206 wpa_printf(MSG_DEBUG, "nl80211: STA assoc link ID %d",
2207 assoc_link_id);
2208 if (tb[NL80211_ATTR_MLD_ADDR]) {
2209 peer_addr = nla_data(tb[NL80211_ATTR_MLD_ADDR]);
2210 link_addr = nla_data(tb[NL80211_ATTR_MAC]);
2211 wpa_printf(MSG_DEBUG,
2212 "nl80211: STA MLD address " MACSTR,
2213 MAC2STR(peer_addr));
2214 }
2215 }
2216
2217 if (tb[NL80211_ATTR_IE]) {
2218 req_ies = nla_data(tb[NL80211_ATTR_IE]);
2219 req_ies_len = nla_len(tb[NL80211_ATTR_IE]);
2220 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs",
2221 req_ies, req_ies_len);
2222 }
2223
2224 if (tb[NL80211_ATTR_RESP_IE]) {
2225 resp_ies = nla_data(tb[NL80211_ATTR_RESP_IE]);
2226 resp_ies_len = nla_len(tb[NL80211_ATTR_RESP_IE]);
2227 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Resp IEs",
2228 resp_ies, resp_ies_len);
2229 }
2230
2231 drv_event_assoc(bss->ctx, peer_addr, req_ies, req_ies_len,
2232 resp_ies, resp_ies_len, link_addr,
2233 assoc_link_id, 0);
2234 return;
2235 }
2236
2237 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2238 return;
2239
2240 os_memset(&data, 0, sizeof(data));
2241 os_memcpy(data.ibss_rsn_start.peer, peer_addr, ETH_ALEN);
2242 wpa_supplicant_event(bss->ctx, EVENT_IBSS_RSN_START, &data);
2243 }
2244
2245
nl80211_del_station_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr ** tb)2246 static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
2247 struct i802_bss *bss,
2248 struct nlattr **tb)
2249 {
2250 u8 *addr;
2251 union wpa_event_data data;
2252
2253 if (tb[NL80211_ATTR_MAC] == NULL)
2254 return;
2255 addr = nla_data(tb[NL80211_ATTR_MAC]);
2256 wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
2257 MAC2STR(addr));
2258
2259 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
2260 drv_event_disassoc(bss->ctx, addr);
2261 return;
2262 }
2263
2264 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2265 return;
2266
2267 os_memset(&data, 0, sizeof(data));
2268 os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
2269 wpa_supplicant_event(bss->ctx, EVENT_IBSS_PEER_LOST, &data);
2270 }
2271
2272
nl80211_rekey_offload_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2273 static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
2274 struct nlattr **tb)
2275 {
2276 struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
2277 static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
2278 [NL80211_REKEY_DATA_KEK] = {
2279 .minlen = NL80211_KEK_LEN,
2280 .maxlen = NL80211_KEK_LEN,
2281 },
2282 [NL80211_REKEY_DATA_KCK] = {
2283 .minlen = NL80211_KCK_LEN,
2284 .maxlen = NL80211_KCK_LEN,
2285 },
2286 [NL80211_REKEY_DATA_REPLAY_CTR] = {
2287 .minlen = NL80211_REPLAY_CTR_LEN,
2288 .maxlen = NL80211_REPLAY_CTR_LEN,
2289 },
2290 };
2291 union wpa_event_data data;
2292
2293 if (!tb[NL80211_ATTR_MAC] ||
2294 !tb[NL80211_ATTR_REKEY_DATA] ||
2295 nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
2296 tb[NL80211_ATTR_REKEY_DATA], rekey_policy) ||
2297 !rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
2298 return;
2299
2300 os_memset(&data, 0, sizeof(data));
2301 data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
2302 wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
2303 MAC2STR(data.driver_gtk_rekey.bssid));
2304 data.driver_gtk_rekey.replay_ctr =
2305 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
2306 wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
2307 data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
2308 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
2309 }
2310
2311
nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2312 static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
2313 struct nlattr **tb)
2314 {
2315 struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
2316 static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
2317 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
2318 [NL80211_PMKSA_CANDIDATE_BSSID] = {
2319 .minlen = ETH_ALEN,
2320 .maxlen = ETH_ALEN,
2321 },
2322 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
2323 };
2324 union wpa_event_data data;
2325
2326 wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
2327
2328 if (!tb[NL80211_ATTR_PMKSA_CANDIDATE] ||
2329 nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
2330 tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy) ||
2331 !cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
2332 !cand[NL80211_PMKSA_CANDIDATE_BSSID])
2333 return;
2334
2335 os_memset(&data, 0, sizeof(data));
2336 os_memcpy(data.pmkid_candidate.bssid,
2337 nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
2338 data.pmkid_candidate.index =
2339 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
2340 data.pmkid_candidate.preauth =
2341 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
2342 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
2343 }
2344
2345
nl80211_client_probe_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2346 static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
2347 struct nlattr **tb)
2348 {
2349 union wpa_event_data data;
2350 const u8 *addr;
2351 u64 cookie = 0;
2352
2353 addr = nla_data(tb[NL80211_ATTR_MAC]);
2354 if (!addr)
2355 return;
2356 if (tb[NL80211_ATTR_COOKIE])
2357 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
2358 wpa_printf(MSG_DEBUG, "nl80211: Probe client event (addr=" MACSTR
2359 " ack=%d cookie=%llu)", MAC2STR(addr),
2360 tb[NL80211_ATTR_ACK] != NULL,
2361 (long long unsigned int) cookie);
2362 if (!tb[NL80211_ATTR_ACK])
2363 return;
2364
2365 os_memset(&data, 0, sizeof(data));
2366 os_memcpy(data.client_poll.addr, addr, ETH_ALEN);
2367 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
2368 }
2369
2370
nl80211_tdls_oper_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2371 static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
2372 struct nlattr **tb)
2373 {
2374 union wpa_event_data data;
2375
2376 wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
2377
2378 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
2379 return;
2380
2381 os_memset(&data, 0, sizeof(data));
2382 os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2383 switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
2384 case NL80211_TDLS_SETUP:
2385 wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
2386 MACSTR, MAC2STR(data.tdls.peer));
2387 data.tdls.oper = TDLS_REQUEST_SETUP;
2388 break;
2389 case NL80211_TDLS_TEARDOWN:
2390 wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
2391 MACSTR, MAC2STR(data.tdls.peer));
2392 data.tdls.oper = TDLS_REQUEST_TEARDOWN;
2393 break;
2394 case NL80211_TDLS_DISCOVERY_REQ:
2395 wpa_printf(MSG_DEBUG,
2396 "nl80211: TDLS discovery request for peer " MACSTR,
2397 MAC2STR(data.tdls.peer));
2398 data.tdls.oper = TDLS_REQUEST_DISCOVER;
2399 break;
2400 default:
2401 wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
2402 "event");
2403 return;
2404 }
2405 if (tb[NL80211_ATTR_REASON_CODE]) {
2406 data.tdls.reason_code =
2407 nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
2408 }
2409
2410 wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
2411 }
2412
2413
nl80211_stop_ap(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2414 static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
2415 struct nlattr **tb)
2416 {
2417 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
2418 }
2419
2420
nl80211_connect_failed_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2421 static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
2422 struct nlattr **tb)
2423 {
2424 union wpa_event_data data;
2425 u32 reason;
2426
2427 wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
2428
2429 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
2430 return;
2431
2432 os_memset(&data, 0, sizeof(data));
2433 os_memcpy(data.connect_failed_reason.addr,
2434 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2435
2436 reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
2437 switch (reason) {
2438 case NL80211_CONN_FAIL_MAX_CLIENTS:
2439 wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
2440 data.connect_failed_reason.code = MAX_CLIENT_REACHED;
2441 break;
2442 case NL80211_CONN_FAIL_BLOCKED_CLIENT:
2443 wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
2444 " tried to connect",
2445 MAC2STR(data.connect_failed_reason.addr));
2446 data.connect_failed_reason.code = BLOCKED_CLIENT;
2447 break;
2448 default:
2449 wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
2450 "%u", reason);
2451 return;
2452 }
2453
2454 wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
2455 }
2456
2457
nl80211_radar_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2458 static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
2459 struct nlattr **tb)
2460 {
2461 union wpa_event_data data;
2462 enum nl80211_radar_event event_type;
2463
2464 if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
2465 return;
2466
2467 os_memset(&data, 0, sizeof(data));
2468 data.dfs_event.link_id = NL80211_DRV_LINK_ID_NA;
2469 data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2470 event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
2471
2472 if (tb[NL80211_ATTR_MLO_LINK_ID]) {
2473 data.dfs_event.link_id =
2474 nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
2475 } else if (data.dfs_event.freq) {
2476 data.dfs_event.link_id =
2477 nl80211_get_link_id_by_freq(drv->first_bss,
2478 data.dfs_event.freq);
2479 }
2480
2481 /* Check HT params */
2482 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2483 data.dfs_event.ht_enabled = 1;
2484 data.dfs_event.chan_offset = 0;
2485
2486 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
2487 case NL80211_CHAN_NO_HT:
2488 data.dfs_event.ht_enabled = 0;
2489 break;
2490 case NL80211_CHAN_HT20:
2491 break;
2492 case NL80211_CHAN_HT40PLUS:
2493 data.dfs_event.chan_offset = 1;
2494 break;
2495 case NL80211_CHAN_HT40MINUS:
2496 data.dfs_event.chan_offset = -1;
2497 break;
2498 }
2499 }
2500
2501 /* Get VHT params */
2502 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
2503 data.dfs_event.chan_width =
2504 convert2width(nla_get_u32(
2505 tb[NL80211_ATTR_CHANNEL_WIDTH]));
2506 if (tb[NL80211_ATTR_CENTER_FREQ1])
2507 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
2508 if (tb[NL80211_ATTR_CENTER_FREQ2])
2509 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
2510
2511 wpa_printf(MSG_DEBUG,
2512 "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz, link_id=%d",
2513 data.dfs_event.freq, data.dfs_event.ht_enabled,
2514 data.dfs_event.chan_offset, data.dfs_event.chan_width,
2515 data.dfs_event.cf1, data.dfs_event.cf2,
2516 data.dfs_event.link_id);
2517
2518 switch (event_type) {
2519 case NL80211_RADAR_DETECTED:
2520 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
2521 break;
2522 case NL80211_RADAR_CAC_FINISHED:
2523 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
2524 break;
2525 case NL80211_RADAR_CAC_ABORTED:
2526 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
2527 break;
2528 case NL80211_RADAR_NOP_FINISHED:
2529 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
2530 break;
2531 case NL80211_RADAR_PRE_CAC_EXPIRED:
2532 wpa_supplicant_event(drv->ctx, EVENT_DFS_PRE_CAC_EXPIRED,
2533 &data);
2534 break;
2535 case NL80211_RADAR_CAC_STARTED:
2536 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
2537 break;
2538 default:
2539 wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
2540 "received", event_type);
2541 break;
2542 }
2543 }
2544
2545
nl80211_spurious_frame(struct i802_bss * bss,struct nlattr ** tb,int wds)2546 static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
2547 int wds)
2548 {
2549 struct wpa_driver_nl80211_data *drv = bss->drv;
2550 union wpa_event_data event;
2551
2552 if (!tb[NL80211_ATTR_MAC])
2553 return;
2554
2555 os_memset(&event, 0, sizeof(event));
2556 event.rx_from_unknown.bssid = bss->addr;
2557 event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
2558 event.rx_from_unknown.wds = wds;
2559
2560 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
2561 }
2562
2563
2564 #ifdef CONFIG_DRIVER_NL80211_QCA
2565
qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2566 static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
2567 const u8 *data, size_t len)
2568 {
2569 u32 i, count;
2570 union wpa_event_data event;
2571 struct wpa_freq_range *range = NULL;
2572 const struct qca_avoid_freq_list *freq_range;
2573
2574 freq_range = (const struct qca_avoid_freq_list *) data;
2575 if (len < sizeof(freq_range->count))
2576 return;
2577
2578 count = freq_range->count;
2579 if (len < sizeof(freq_range->count) +
2580 count * sizeof(struct qca_avoid_freq_range)) {
2581 wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
2582 (unsigned int) len);
2583 return;
2584 }
2585
2586 if (count > 0) {
2587 range = os_calloc(count, sizeof(struct wpa_freq_range));
2588 if (range == NULL)
2589 return;
2590 }
2591
2592 os_memset(&event, 0, sizeof(event));
2593 for (i = 0; i < count; i++) {
2594 unsigned int idx = event.freq_range.num;
2595 range[idx].min = freq_range->range[i].start_freq;
2596 range[idx].max = freq_range->range[i].end_freq;
2597 wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
2598 range[idx].min, range[idx].max);
2599 if (range[idx].min > range[idx].max) {
2600 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
2601 continue;
2602 }
2603 event.freq_range.num++;
2604 }
2605 event.freq_range.range = range;
2606
2607 wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
2608
2609 os_free(range);
2610 }
2611
2612
get_qca_hw_mode(u8 hw_mode)2613 static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
2614 {
2615 switch (hw_mode) {
2616 case QCA_ACS_MODE_IEEE80211B:
2617 return HOSTAPD_MODE_IEEE80211B;
2618 case QCA_ACS_MODE_IEEE80211G:
2619 return HOSTAPD_MODE_IEEE80211G;
2620 case QCA_ACS_MODE_IEEE80211A:
2621 return HOSTAPD_MODE_IEEE80211A;
2622 case QCA_ACS_MODE_IEEE80211AD:
2623 return HOSTAPD_MODE_IEEE80211AD;
2624 case QCA_ACS_MODE_IEEE80211ANY:
2625 return HOSTAPD_MODE_IEEE80211ANY;
2626 default:
2627 return NUM_HOSTAPD_MODES;
2628 }
2629 }
2630
2631
chan_to_freq(struct wpa_driver_nl80211_data * drv,u8 chan,enum hostapd_hw_mode hw_mode)2632 static unsigned int chan_to_freq(struct wpa_driver_nl80211_data *drv,
2633 u8 chan, enum hostapd_hw_mode hw_mode)
2634 {
2635 if (hw_mode == NUM_HOSTAPD_MODES) {
2636 /* For drivers that do not report ACS_HW_MODE */
2637 u16 num_modes, flags;
2638 struct hostapd_hw_modes *modes;
2639 u8 dfs_domain;
2640 int i;
2641
2642 modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
2643 &flags, &dfs_domain);
2644 if (!modes) {
2645 wpa_printf(MSG_DEBUG,
2646 "nl80211: Fetching hardware mode failed");
2647 goto try_2_4_or_5;
2648 }
2649 if (num_modes == 1)
2650 hw_mode = modes[0].mode;
2651
2652 for (i = 0; i < num_modes; i++) {
2653 os_free(modes[i].channels);
2654 os_free(modes[i].rates);
2655 }
2656
2657 os_free(modes);
2658 }
2659
2660 if (hw_mode == HOSTAPD_MODE_IEEE80211AD) {
2661 if (chan >= 1 && chan <= 6)
2662 return 56160 + (2160 * chan);
2663 return 0;
2664 }
2665
2666 try_2_4_or_5:
2667 if (chan >= 1 && chan <= 13)
2668 return 2407 + 5 * chan;
2669 if (chan == 14)
2670 return 2484;
2671 if (chan >= 36 && chan <= 177)
2672 return 5000 + 5 * chan;
2673
2674 return 0;
2675 }
2676
2677
qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2678 static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
2679 const u8 *data, size_t len)
2680 {
2681 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
2682 union wpa_event_data event;
2683 u8 chan;
2684
2685 wpa_printf(MSG_DEBUG,
2686 "nl80211: ACS channel selection vendor event received");
2687
2688 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
2689 (struct nlattr *) data, len, NULL) ||
2690 (!tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY] &&
2691 !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]) ||
2692 (!tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY] &&
2693 !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]))
2694 return;
2695
2696 os_memset(&event, 0, sizeof(event));
2697 event.acs_selected_channels.hw_mode = NUM_HOSTAPD_MODES;
2698
2699 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
2700 u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
2701
2702 event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
2703 if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
2704 event.acs_selected_channels.hw_mode ==
2705 HOSTAPD_MODE_IEEE80211ANY) {
2706 wpa_printf(MSG_DEBUG,
2707 "nl80211: Invalid hw_mode %d in ACS selection event",
2708 hw_mode);
2709 return;
2710 }
2711 }
2712
2713 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]) {
2714 event.acs_selected_channels.pri_freq = nla_get_u32(
2715 tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]);
2716 } else {
2717 chan = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
2718 event.acs_selected_channels.pri_freq =
2719 chan_to_freq(drv, chan,
2720 event.acs_selected_channels.hw_mode);
2721 }
2722
2723 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]) {
2724 event.acs_selected_channels.sec_freq = nla_get_u32(
2725 tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]);
2726 } else {
2727 chan = nla_get_u8(
2728 tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
2729 event.acs_selected_channels.sec_freq =
2730 chan_to_freq(drv, chan,
2731 event.acs_selected_channels.hw_mode);
2732 }
2733
2734 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL])
2735 event.acs_selected_channels.edmg_channel =
2736 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL]);
2737 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
2738 event.acs_selected_channels.vht_seg0_center_ch =
2739 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
2740 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL])
2741 event.acs_selected_channels.vht_seg1_center_ch =
2742 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
2743 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
2744 event.acs_selected_channels.ch_width =
2745 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
2746 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP])
2747 event.acs_selected_channels.puncture_bitmap =
2748 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP]);
2749 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_LINK_ID])
2750 event.acs_selected_channels.link_id =
2751 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_LINK_ID]);
2752 else
2753 event.acs_selected_channels.link_id = -1;
2754
2755 wpa_printf(MSG_INFO,
2756 "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d EDMGCH: %d PUNCBITMAP: 0x%x, LinkId: %d",
2757 event.acs_selected_channels.pri_freq,
2758 event.acs_selected_channels.sec_freq,
2759 event.acs_selected_channels.ch_width,
2760 event.acs_selected_channels.vht_seg0_center_ch,
2761 event.acs_selected_channels.vht_seg1_center_ch,
2762 event.acs_selected_channels.hw_mode,
2763 event.acs_selected_channels.edmg_channel,
2764 event.acs_selected_channels.puncture_bitmap,
2765 event.acs_selected_channels.link_id);
2766
2767 /* Ignore ACS channel list check for backwards compatibility */
2768
2769 wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
2770 }
2771
2772
qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2773 static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
2774 const u8 *data, size_t len)
2775 {
2776 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX + 1];
2777 u8 *bssid;
2778
2779 wpa_printf(MSG_DEBUG,
2780 "nl80211: Key management roam+auth vendor event received");
2781
2782 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX,
2783 (struct nlattr *) data, len, NULL) ||
2784 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID] ||
2785 nla_len(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]) != ETH_ALEN ||
2786 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE] ||
2787 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE] ||
2788 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED])
2789 return;
2790
2791 bssid = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]);
2792 wpa_printf(MSG_DEBUG, " * roam BSSID " MACSTR, MAC2STR(bssid));
2793
2794 mlme_event_connect(drv, NL80211_CMD_ROAM, true, NULL,
2795 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID],
2796 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE],
2797 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE],
2798 NULL, NULL,
2799 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED],
2800 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR],
2801 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK],
2802 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK],
2803 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS],
2804 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM],
2805 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK],
2806 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID],
2807 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS]);
2808
2809 #ifdef ANDROID
2810 #ifdef ANDROID_LIB_EVENT
2811 wpa_driver_nl80211_driver_event(
2812 drv, OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH,
2813 data, len);
2814 #endif /* ANDROID_LIB_EVENT */
2815 #endif /* ANDROID */
2816 }
2817
2818
2819 static void
qca_nl80211_key_mgmt_auth_handler(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2820 qca_nl80211_key_mgmt_auth_handler(struct wpa_driver_nl80211_data *drv,
2821 const u8 *data, size_t len)
2822 {
2823 if (!drv->roam_indication_done) {
2824 wpa_printf(MSG_DEBUG,
2825 "nl80211: Pending roam indication, delay processing roam+auth vendor event");
2826
2827 os_free(drv->pending_roam_data);
2828 drv->pending_roam_data = os_memdup(data, len);
2829 if (!drv->pending_roam_data)
2830 return;
2831 drv->pending_roam_data_len = len;
2832 return;
2833 }
2834 drv->roam_indication_done = false;
2835 qca_nl80211_key_mgmt_auth(drv, data, len);
2836 }
2837
2838
qca_nl80211_dfs_offload_radar_event(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * msg,int length)2839 static void qca_nl80211_dfs_offload_radar_event(
2840 struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
2841 {
2842 union wpa_event_data data;
2843 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2844
2845 wpa_printf(MSG_DEBUG,
2846 "nl80211: DFS offload radar vendor event received");
2847
2848 if (nla_parse(tb, NL80211_ATTR_MAX,
2849 (struct nlattr *) msg, length, NULL))
2850 return;
2851
2852 if (!tb[NL80211_ATTR_WIPHY_FREQ]) {
2853 wpa_printf(MSG_INFO,
2854 "nl80211: Error parsing WIPHY_FREQ in FS offload radar vendor event");
2855 return;
2856 }
2857
2858 os_memset(&data, 0, sizeof(data));
2859 data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2860 data.dfs_event.link_id = NL80211_DRV_LINK_ID_NA;
2861
2862 if (tb[NL80211_ATTR_MLO_LINK_ID]) {
2863 data.dfs_event.link_id =
2864 nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
2865 } else if (data.dfs_event.freq) {
2866 data.dfs_event.link_id =
2867 nl80211_get_link_id_by_freq(drv->first_bss,
2868 data.dfs_event.freq);
2869 }
2870
2871 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, link=%d",
2872 data.dfs_event.freq, data.dfs_event.link_id);
2873
2874 /* Check HT params */
2875 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2876 data.dfs_event.ht_enabled = 1;
2877 data.dfs_event.chan_offset = 0;
2878
2879 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
2880 case NL80211_CHAN_NO_HT:
2881 data.dfs_event.ht_enabled = 0;
2882 break;
2883 case NL80211_CHAN_HT20:
2884 break;
2885 case NL80211_CHAN_HT40PLUS:
2886 data.dfs_event.chan_offset = 1;
2887 break;
2888 case NL80211_CHAN_HT40MINUS:
2889 data.dfs_event.chan_offset = -1;
2890 break;
2891 }
2892 }
2893
2894 /* Get VHT params */
2895 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
2896 data.dfs_event.chan_width =
2897 convert2width(nla_get_u32(
2898 tb[NL80211_ATTR_CHANNEL_WIDTH]));
2899 if (tb[NL80211_ATTR_CENTER_FREQ1])
2900 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
2901 if (tb[NL80211_ATTR_CENTER_FREQ2])
2902 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
2903
2904 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, "
2905 "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
2906 data.dfs_event.freq, data.dfs_event.ht_enabled,
2907 data.dfs_event.chan_offset, data.dfs_event.chan_width,
2908 data.dfs_event.cf1, data.dfs_event.cf2);
2909
2910 switch (subcmd) {
2911 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
2912 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
2913 break;
2914 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
2915 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
2916 break;
2917 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
2918 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
2919 break;
2920 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
2921 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
2922 break;
2923 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
2924 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
2925 break;
2926 default:
2927 wpa_printf(MSG_DEBUG,
2928 "nl80211: Unknown DFS offload radar event %d received",
2929 subcmd);
2930 break;
2931 }
2932 }
2933
2934
qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)2935 static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
2936 u8 *data, size_t len)
2937 {
2938 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
2939 u64 cookie = 0;
2940 union wpa_event_data event;
2941 struct scan_info *info;
2942
2943 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
2944 (struct nlattr *) data, len, NULL) ||
2945 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
2946 return;
2947
2948 cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
2949 if (cookie != drv->vendor_scan_cookie) {
2950 /* External scan trigger event, ignore */
2951 return;
2952 }
2953
2954 /* Cookie match, own scan */
2955 os_memset(&event, 0, sizeof(event));
2956 info = &event.scan_info;
2957 info->external_scan = 0;
2958 info->nl_scan_event = 0;
2959
2960 drv->scan_state = SCAN_STARTED;
2961 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event);
2962 }
2963
2964
send_vendor_scan_event(struct wpa_driver_nl80211_data * drv,int aborted,struct nlattr * tb[],int external_scan)2965 static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
2966 int aborted, struct nlattr *tb[],
2967 int external_scan)
2968 {
2969 union wpa_event_data event;
2970 struct nlattr *nl;
2971 int rem;
2972 struct scan_info *info;
2973 int freqs[MAX_REPORT_FREQS];
2974 int num_freqs = 0;
2975
2976 os_memset(&event, 0, sizeof(event));
2977 info = &event.scan_info;
2978 info->aborted = aborted;
2979 info->external_scan = external_scan;
2980 info->scan_cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
2981
2982 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
2983 nla_for_each_nested(nl,
2984 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], rem) {
2985 struct wpa_driver_scan_ssid *s =
2986 &info->ssids[info->num_ssids];
2987 s->ssid = nla_data(nl);
2988 s->ssid_len = nla_len(nl);
2989 wpa_printf(MSG_DEBUG,
2990 "nl80211: Scan probed for SSID '%s'",
2991 wpa_ssid_txt(s->ssid, s->ssid_len));
2992 info->num_ssids++;
2993 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
2994 break;
2995 }
2996 }
2997
2998 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
2999 char msg[500], *pos, *end;
3000 int res;
3001
3002 pos = msg;
3003 end = pos + sizeof(msg);
3004 *pos = '\0';
3005
3006 nla_for_each_nested(nl,
3007 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
3008 rem) {
3009 freqs[num_freqs] = nla_get_u32(nl);
3010 res = os_snprintf(pos, end - pos, " %d",
3011 freqs[num_freqs]);
3012 if (!os_snprintf_error(end - pos, res))
3013 pos += res;
3014 num_freqs++;
3015 if (num_freqs == MAX_REPORT_FREQS - 1)
3016 break;
3017 }
3018
3019 info->freqs = freqs;
3020 info->num_freqs = num_freqs;
3021 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
3022 msg);
3023 }
3024 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
3025 }
3026
3027
qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)3028 static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
3029 u8 *data, size_t len)
3030 {
3031 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
3032 u64 cookie = 0;
3033 enum scan_status status;
3034 int external_scan;
3035
3036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
3037 (struct nlattr *) data, len, NULL) ||
3038 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS] ||
3039 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
3040 return;
3041
3042 status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS]);
3043 if (status >= VENDOR_SCAN_STATUS_MAX)
3044 return; /* invalid status */
3045
3046 cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
3047 if (cookie != drv->vendor_scan_cookie) {
3048 /* Event from an external scan, get scan results */
3049 external_scan = 1;
3050 } else {
3051 external_scan = 0;
3052 if (status == VENDOR_SCAN_STATUS_NEW_RESULTS)
3053 drv->scan_state = SCAN_COMPLETED;
3054 else
3055 drv->scan_state = SCAN_ABORTED;
3056
3057 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
3058 drv->ctx);
3059 drv->vendor_scan_cookie = 0;
3060 drv->last_scan_cmd = 0;
3061 }
3062
3063 send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb,
3064 external_scan);
3065 }
3066
3067
qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)3068 static void qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data *drv,
3069 u8 *data, size_t len)
3070 {
3071 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1];
3072 union wpa_event_data event;
3073
3074 wpa_printf(MSG_DEBUG,
3075 "nl80211: P2P listen offload stop vendor event received");
3076
3077 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX,
3078 (struct nlattr *) data, len, NULL) ||
3079 !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON])
3080 return;
3081
3082 os_memset(&event, 0, sizeof(event));
3083 event.p2p_lo_stop.reason_code =
3084 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON]);
3085
3086 wpa_printf(MSG_DEBUG,
3087 "nl80211: P2P Listen offload stop reason: %d",
3088 event.p2p_lo_stop.reason_code);
3089 wpa_supplicant_event(drv->ctx, EVENT_P2P_LO_STOP, &event);
3090 }
3091
3092
3093 #ifdef CONFIG_PASN
3094
qca_nl80211_pasn_auth(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)3095 static void qca_nl80211_pasn_auth(struct wpa_driver_nl80211_data *drv,
3096 u8 *data, size_t len)
3097 {
3098 int ret = -EINVAL;
3099 struct nlattr *attr;
3100 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
3101 struct nlattr *cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAX + 1];
3102 unsigned int n_peers = 0, idx = 0;
3103 int rem_conf;
3104 enum qca_wlan_vendor_pasn_action action;
3105 union wpa_event_data event;
3106
3107 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PASN_MAX,
3108 (struct nlattr *) data, len, NULL) ||
3109 !tb[QCA_WLAN_VENDOR_ATTR_PASN_PEERS] ||
3110 !tb[QCA_WLAN_VENDOR_ATTR_PASN_ACTION]) {
3111 return;
3112 }
3113
3114 os_memset(&event, 0, sizeof(event));
3115 action = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_PASN_ACTION]);
3116 switch (action) {
3117 case QCA_WLAN_VENDOR_PASN_ACTION_AUTH:
3118 event.pasn_auth.action = PASN_ACTION_AUTH;
3119 break;
3120 case QCA_WLAN_VENDOR_PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT:
3121 event.pasn_auth.action =
3122 PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT;
3123 break;
3124 default:
3125 return;
3126 }
3127
3128 nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_PASN_PEERS], rem_conf)
3129 n_peers++;
3130
3131 if (n_peers > WPAS_MAX_PASN_PEERS) {
3132 wpa_printf(MSG_DEBUG, "nl80211: PASN auth: too many peers (%d)",
3133 n_peers);
3134 return;
3135 }
3136
3137 nla_for_each_nested(attr, tb[QCA_WLAN_VENDOR_ATTR_PASN_PEERS],
3138 rem_conf) {
3139 struct nlattr *nl_src, *nl_peer;
3140
3141 ret = nla_parse_nested(cfg, QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAX,
3142 attr, NULL);
3143 if (ret)
3144 return;
3145 nl_src = cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR];
3146 nl_peer = cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR];
3147 if (nl_src)
3148 os_memcpy(event.pasn_auth.peer[idx].own_addr,
3149 nla_data(nl_src), ETH_ALEN);
3150 if (nl_peer)
3151 os_memcpy(event.pasn_auth.peer[idx].peer_addr,
3152 nla_data(nl_peer), ETH_ALEN);
3153 if (cfg[QCA_WLAN_VENDOR_ATTR_PASN_PEER_LTF_KEYSEED_REQUIRED])
3154 event.pasn_auth.peer[idx].ltf_keyseed_required = true;
3155 idx++;
3156 }
3157 event.pasn_auth.num_peers = n_peers;
3158
3159 wpa_printf(MSG_DEBUG,
3160 "nl80211: PASN auth action: %u, num_bssids: %d",
3161 event.pasn_auth.action,
3162 event.pasn_auth.num_peers);
3163 wpa_supplicant_event(drv->ctx, EVENT_PASN_AUTH, &event);
3164 }
3165
3166 #endif /* CONFIG_PASN */
3167
3168 #endif /* CONFIG_DRIVER_NL80211_QCA */
3169
3170
nl80211_vendor_event_qca(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * data,size_t len)3171 static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
3172 u32 subcmd, u8 *data, size_t len)
3173 {
3174 switch (subcmd) {
3175 case QCA_NL80211_VENDOR_SUBCMD_TEST:
3176 wpa_hexdump(MSG_DEBUG, "nl80211: QCA test event", data, len);
3177 break;
3178 #ifdef CONFIG_DRIVER_NL80211_QCA
3179 case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
3180 qca_nl80211_avoid_freq(drv, data, len);
3181 break;
3182 case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
3183 qca_nl80211_key_mgmt_auth_handler(drv, data, len);
3184 break;
3185 case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
3186 qca_nl80211_acs_select_ch(drv, data, len);
3187 break;
3188 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
3189 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
3190 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
3191 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
3192 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
3193 qca_nl80211_dfs_offload_radar_event(drv, subcmd, data, len);
3194 break;
3195 case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
3196 qca_nl80211_scan_trigger_event(drv, data, len);
3197 break;
3198 case QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE:
3199 qca_nl80211_scan_done_event(drv, data, len);
3200 break;
3201 case QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP:
3202 qca_nl80211_p2p_lo_stop_event(drv, data, len);
3203 break;
3204 #ifdef CONFIG_PASN
3205 case QCA_NL80211_VENDOR_SUBCMD_PASN:
3206 qca_nl80211_pasn_auth(drv, data, len);
3207 break;
3208 #endif /* CONFIG_PASN */
3209 case QCA_NL80211_VENDOR_SUBCMD_TID_TO_LINK_MAP:
3210 qca_nl80211_tid_to_link_map_event(drv, data, len);
3211 break;
3212 case QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG:
3213 qca_nl80211_link_reconfig_event(drv, data, len);
3214 break;
3215 #endif /* CONFIG_DRIVER_NL80211_QCA */
3216 default:
3217 wpa_printf(MSG_DEBUG,
3218 "nl80211: Ignore unsupported QCA vendor event %u",
3219 subcmd);
3220 break;
3221 }
3222 }
3223
3224
3225 #ifdef CONFIG_DRIVER_NL80211_BRCM
3226
brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)3227 static void brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
3228 const u8 *data, size_t len)
3229 {
3230 struct nlattr *tb[BRCM_VENDOR_ATTR_ACS_LAST + 1];
3231 union wpa_event_data event;
3232
3233 wpa_printf(MSG_DEBUG,
3234 "nl80211: BRCM ACS channel selection vendor event received");
3235
3236 if (nla_parse(tb, BRCM_VENDOR_ATTR_ACS_LAST, (struct nlattr *) data,
3237 len, NULL) ||
3238 !tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ] ||
3239 !tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
3240 return;
3241
3242 os_memset(&event, 0, sizeof(event));
3243 if (tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ])
3244 event.acs_selected_channels.pri_freq =
3245 nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]);
3246 if (tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
3247 event.acs_selected_channels.sec_freq =
3248 nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]);
3249 if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
3250 event.acs_selected_channels.vht_seg0_center_ch =
3251 nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
3252 if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
3253 event.acs_selected_channels.vht_seg1_center_ch =
3254 nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
3255 if (tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH])
3256 event.acs_selected_channels.ch_width =
3257 nla_get_u16(tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]);
3258 if (tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]) {
3259 event.acs_selected_channels.hw_mode = nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]);
3260 if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
3261 event.acs_selected_channels.hw_mode ==
3262 HOSTAPD_MODE_IEEE80211ANY) {
3263 wpa_printf(MSG_DEBUG,
3264 "nl80211: Invalid hw_mode %d in ACS selection event",
3265 event.acs_selected_channels.hw_mode);
3266 return;
3267 }
3268 }
3269
3270 wpa_printf(MSG_DEBUG,
3271 "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
3272 event.acs_selected_channels.pri_freq,
3273 event.acs_selected_channels.sec_freq,
3274 event.acs_selected_channels.ch_width,
3275 event.acs_selected_channels.vht_seg0_center_ch,
3276 event.acs_selected_channels.vht_seg1_center_ch,
3277 event.acs_selected_channels.hw_mode);
3278 wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
3279 }
3280
3281
nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * data,size_t len)3282 static void nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data *drv,
3283 u32 subcmd, u8 *data, size_t len)
3284 {
3285 wpa_printf(MSG_DEBUG, "nl80211: Got BRCM vendor event %u", subcmd);
3286 switch (subcmd) {
3287 case BRCM_VENDOR_EVENT_PRIV_STR:
3288 case BRCM_VENDOR_EVENT_HANGED:
3289 /* Dump the event on to the console */
3290 wpa_msg(NULL, MSG_INFO, "%s", data);
3291 break;
3292 case BRCM_VENDOR_EVENT_ACS:
3293 brcm_nl80211_acs_select_ch(drv, data, len);
3294 break;
3295 default:
3296 wpa_printf(MSG_DEBUG,
3297 "%s: Ignore unsupported BRCM vendor event %u",
3298 __func__, subcmd);
3299 break;
3300 }
3301 }
3302
3303 #endif /* CONFIG_DRIVER_NL80211_BRCM */
3304
3305
nl80211_vendor_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)3306 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
3307 struct nlattr **tb)
3308 {
3309 u32 vendor_id, subcmd, wiphy = 0;
3310 int wiphy_idx;
3311 u8 *data = NULL;
3312 size_t len = 0;
3313
3314 if (!tb[NL80211_ATTR_VENDOR_ID] ||
3315 !tb[NL80211_ATTR_VENDOR_SUBCMD])
3316 return;
3317
3318 vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
3319 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
3320
3321 if (tb[NL80211_ATTR_WIPHY])
3322 wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
3323
3324 wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
3325 wiphy, vendor_id, subcmd);
3326
3327 if (tb[NL80211_ATTR_VENDOR_DATA]) {
3328 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
3329 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
3330 wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
3331 }
3332
3333 wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
3334 if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
3335 wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
3336 wiphy, wiphy_idx);
3337 return;
3338 }
3339
3340 #ifdef ANDROID
3341 #ifdef ANDROID_LIB_EVENT
3342 /* Postpone QCA roam+auth event indication to the point when both that
3343 * and the NL80211_CMD_ROAM event have been received (see calls to
3344 * qca_nl80211_key_mgmt_auth() and drv->pending_roam_data). */
3345 if (!(vendor_id == OUI_QCA &&
3346 subcmd == QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH))
3347 wpa_driver_nl80211_driver_event(drv, vendor_id, subcmd, data,
3348 len);
3349 #endif /* ANDROID_LIB_EVENT */
3350 #endif /* ANDROID */
3351
3352 switch (vendor_id) {
3353 case OUI_QCA:
3354 nl80211_vendor_event_qca(drv, subcmd, data, len);
3355 break;
3356 #ifdef CONFIG_DRIVER_NL80211_BRCM
3357 case OUI_BRCM:
3358 nl80211_vendor_event_brcm(drv, subcmd, data, len);
3359 break;
3360 #endif /* CONFIG_DRIVER_NL80211_BRCM */
3361 default:
3362 wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
3363 break;
3364 }
3365 }
3366
3367
nl80211_reg_change_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])3368 static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
3369 struct nlattr *tb[])
3370 {
3371 union wpa_event_data data;
3372 enum nl80211_reg_initiator init;
3373
3374 wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
3375
3376 if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
3377 return;
3378
3379 os_memset(&data, 0, sizeof(data));
3380 init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
3381 wpa_printf(MSG_DEBUG, " * initiator=%d", init);
3382 switch (init) {
3383 case NL80211_REGDOM_SET_BY_CORE:
3384 data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
3385 break;
3386 case NL80211_REGDOM_SET_BY_USER:
3387 data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
3388 break;
3389 case NL80211_REGDOM_SET_BY_DRIVER:
3390 data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
3391 break;
3392 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
3393 data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
3394 break;
3395 }
3396
3397 if (tb[NL80211_ATTR_REG_TYPE]) {
3398 enum nl80211_reg_type type;
3399 type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
3400 wpa_printf(MSG_DEBUG, " * type=%d", type);
3401 switch (type) {
3402 case NL80211_REGDOM_TYPE_COUNTRY:
3403 data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
3404 break;
3405 case NL80211_REGDOM_TYPE_WORLD:
3406 data.channel_list_changed.type = REGDOM_TYPE_WORLD;
3407 break;
3408 case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
3409 data.channel_list_changed.type =
3410 REGDOM_TYPE_CUSTOM_WORLD;
3411 break;
3412 case NL80211_REGDOM_TYPE_INTERSECTION:
3413 data.channel_list_changed.type =
3414 REGDOM_TYPE_INTERSECTION;
3415 break;
3416 }
3417 }
3418
3419 if (tb[NL80211_ATTR_REG_ALPHA2]) {
3420 os_strlcpy(data.channel_list_changed.alpha2,
3421 nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
3422 sizeof(data.channel_list_changed.alpha2));
3423 wpa_printf(MSG_DEBUG, " * alpha2=%s",
3424 data.channel_list_changed.alpha2);
3425 }
3426
3427 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
3428 }
3429
3430
nl80211_parse_freq_attrs(const char * title,struct nlattr * nl_freq,struct frequency_attrs * attrs)3431 static void nl80211_parse_freq_attrs(const char *title, struct nlattr *nl_freq,
3432 struct frequency_attrs *attrs)
3433 {
3434 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
3435 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
3436 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
3437 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
3438 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
3439 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
3440 };
3441 struct nlattr *tb[NL80211_FREQUENCY_ATTR_MAX + 1];
3442 u32 freq = 0, max_tx_power = 0;
3443
3444 nla_parse(tb, NL80211_FREQUENCY_ATTR_MAX,
3445 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
3446
3447 if (tb[NL80211_FREQUENCY_ATTR_FREQ])
3448 freq = nla_get_u32(tb[NL80211_FREQUENCY_ATTR_FREQ]);
3449 if (tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])
3450 max_tx_power =
3451 nla_get_u32(tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
3452
3453 wpa_printf(MSG_DEBUG,
3454 "nl80211: Channel (%s): freq=%u max_tx_power=%u%s%s%s",
3455 title, freq, max_tx_power,
3456 tb[NL80211_FREQUENCY_ATTR_DISABLED] ? " disabled" : "",
3457 tb[NL80211_FREQUENCY_ATTR_NO_IR] ? " no-IR" : "",
3458 tb[NL80211_FREQUENCY_ATTR_RADAR] ? " radar" : "");
3459
3460 attrs->freq = freq;
3461 attrs->max_tx_power = max_tx_power;
3462 if (tb[NL80211_FREQUENCY_ATTR_DISABLED])
3463 attrs->disabled = true;
3464 if (tb[NL80211_FREQUENCY_ATTR_NO_IR])
3465 attrs->no_ir = true;
3466 if (tb[NL80211_FREQUENCY_ATTR_RADAR])
3467 attrs->radar = true;
3468 }
3469
3470
nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])3471 static void nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data *drv,
3472 struct nlattr *tb[])
3473 {
3474 union wpa_event_data data;
3475
3476 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
3477 os_memset(&data, 0, sizeof(data));
3478 data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
3479
3480 if (tb[NL80211_ATTR_FREQ_BEFORE])
3481 nl80211_parse_freq_attrs(
3482 "before", tb[NL80211_ATTR_FREQ_BEFORE],
3483 &data.channel_list_changed.beacon_hint_before);
3484 if (tb[NL80211_ATTR_FREQ_AFTER])
3485 nl80211_parse_freq_attrs(
3486 "after", tb[NL80211_ATTR_FREQ_AFTER],
3487 &data.channel_list_changed.beacon_hint_after);
3488
3489 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
3490 }
3491
3492
nl80211_external_auth(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)3493 static void nl80211_external_auth(struct wpa_driver_nl80211_data *drv,
3494 struct nlattr **tb)
3495 {
3496 union wpa_event_data event;
3497 enum nl80211_external_auth_action act;
3498 char mld_addr[50];
3499
3500 if (!tb[NL80211_ATTR_AKM_SUITES] ||
3501 !tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION] ||
3502 !tb[NL80211_ATTR_BSSID] ||
3503 !tb[NL80211_ATTR_SSID])
3504 return;
3505
3506 os_memset(&event, 0, sizeof(event));
3507 act = nla_get_u32(tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION]);
3508 switch (act) {
3509 case NL80211_EXTERNAL_AUTH_START:
3510 event.external_auth.action = EXT_AUTH_START;
3511 break;
3512 case NL80211_EXTERNAL_AUTH_ABORT:
3513 event.external_auth.action = EXT_AUTH_ABORT;
3514 break;
3515 default:
3516 return;
3517 }
3518
3519 event.external_auth.key_mgmt_suite =
3520 nla_get_u32(tb[NL80211_ATTR_AKM_SUITES]);
3521
3522 event.external_auth.ssid_len = nla_len(tb[NL80211_ATTR_SSID]);
3523 if (event.external_auth.ssid_len > SSID_MAX_LEN)
3524 return;
3525 event.external_auth.ssid = nla_data(tb[NL80211_ATTR_SSID]);
3526
3527 event.external_auth.bssid = nla_data(tb[NL80211_ATTR_BSSID]);
3528
3529 mld_addr[0] = '\0';
3530 if (tb[NL80211_ATTR_MLD_ADDR]) {
3531 event.external_auth.mld_addr =
3532 nla_data(tb[NL80211_ATTR_MLD_ADDR]);
3533 os_snprintf(mld_addr, sizeof(mld_addr), ", MLD ADDR: " MACSTR,
3534 MAC2STR(event.external_auth.mld_addr));
3535 }
3536
3537 wpa_printf(MSG_DEBUG,
3538 "nl80211: External auth action: %u, AKM: 0x%x, SSID: %s, BSSID: " MACSTR "%s",
3539 event.external_auth.action,
3540 event.external_auth.key_mgmt_suite,
3541 wpa_ssid_txt(event.external_auth.ssid,
3542 event.external_auth.ssid_len),
3543 MAC2STR(event.external_auth.bssid), mld_addr);
3544 wpa_supplicant_event(drv->ctx, EVENT_EXTERNAL_AUTH, &event);
3545 }
3546
3547
nl80211_port_authorized(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)3548 static void nl80211_port_authorized(struct wpa_driver_nl80211_data *drv,
3549 struct nlattr **tb)
3550 {
3551 const u8 *addr;
3552 union wpa_event_data event;
3553
3554 os_memset(&event, 0, sizeof(event));
3555
3556 if (!tb[NL80211_ATTR_MAC] ||
3557 nla_len(tb[NL80211_ATTR_MAC]) != ETH_ALEN) {
3558 wpa_printf(MSG_DEBUG,
3559 "nl80211: Ignore port authorized event without BSSID");
3560 return;
3561 }
3562
3563 addr = nla_data(tb[NL80211_ATTR_MAC]);
3564 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
3565 event.port_authorized.sta_addr = addr;
3566 wpa_printf(MSG_DEBUG,
3567 "nl80211: Port authorized for STA addr " MACSTR,
3568 MAC2STR(addr));
3569 } else if (is_sta_interface(drv->nlmode)) {
3570 const u8 *connected_addr;
3571
3572 connected_addr = drv->sta_mlo_info.valid_links ?
3573 drv->sta_mlo_info.ap_mld_addr : drv->bssid;
3574 if (!ether_addr_equal(addr, connected_addr)) {
3575 wpa_printf(MSG_DEBUG,
3576 "nl80211: Ignore port authorized event for "
3577 MACSTR " (not the currently connected BSSID "
3578 MACSTR ")",
3579 MAC2STR(addr), MAC2STR(connected_addr));
3580 return;
3581 }
3582 }
3583
3584 if (tb[NL80211_ATTR_TD_BITMAP]) {
3585 event.port_authorized.td_bitmap_len =
3586 nla_len(tb[NL80211_ATTR_TD_BITMAP]);
3587 if (event.port_authorized.td_bitmap_len > 0)
3588 event.port_authorized.td_bitmap =
3589 nla_data(tb[NL80211_ATTR_TD_BITMAP]);
3590 }
3591
3592 wpa_supplicant_event(drv->ctx, EVENT_PORT_AUTHORIZED, &event);
3593 }
3594
3595
nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)3596 static void nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data *drv,
3597 struct nlattr **tb)
3598 {
3599 union wpa_event_data ed;
3600 u8 smps_mode, max_bw;
3601
3602 if (!tb[NL80211_ATTR_MAC] ||
3603 (!tb[NL80211_ATTR_CHANNEL_WIDTH] &&
3604 !tb[NL80211_ATTR_SMPS_MODE] &&
3605 !tb[NL80211_ATTR_NSS]))
3606 return;
3607
3608 ed.sta_opmode.smps_mode = SMPS_INVALID;
3609 ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
3610 ed.sta_opmode.rx_nss = 0xff;
3611 ed.sta_opmode.addr = nla_data(tb[NL80211_ATTR_MAC]);
3612
3613 if (tb[NL80211_ATTR_SMPS_MODE]) {
3614 smps_mode = nla_get_u8(tb[NL80211_ATTR_SMPS_MODE]);
3615 switch (smps_mode) {
3616 case NL80211_SMPS_OFF:
3617 ed.sta_opmode.smps_mode = SMPS_OFF;
3618 break;
3619 case NL80211_SMPS_STATIC:
3620 ed.sta_opmode.smps_mode = SMPS_STATIC;
3621 break;
3622 case NL80211_SMPS_DYNAMIC:
3623 ed.sta_opmode.smps_mode = SMPS_DYNAMIC;
3624 break;
3625 default:
3626 ed.sta_opmode.smps_mode = SMPS_INVALID;
3627 break;
3628 }
3629 }
3630
3631 if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
3632 max_bw = nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]);
3633 switch (max_bw) {
3634 case NL80211_CHAN_WIDTH_20_NOHT:
3635 ed.sta_opmode.chan_width = CHAN_WIDTH_20_NOHT;
3636 break;
3637 case NL80211_CHAN_WIDTH_20:
3638 ed.sta_opmode.chan_width = CHAN_WIDTH_20;
3639 break;
3640 case NL80211_CHAN_WIDTH_40:
3641 ed.sta_opmode.chan_width = CHAN_WIDTH_40;
3642 break;
3643 case NL80211_CHAN_WIDTH_80:
3644 ed.sta_opmode.chan_width = CHAN_WIDTH_80;
3645 break;
3646 case NL80211_CHAN_WIDTH_80P80:
3647 ed.sta_opmode.chan_width = CHAN_WIDTH_80P80;
3648 break;
3649 case NL80211_CHAN_WIDTH_160:
3650 ed.sta_opmode.chan_width = CHAN_WIDTH_160;
3651 break;
3652 case NL80211_CHAN_WIDTH_320:
3653 ed.sta_opmode.chan_width = CHAN_WIDTH_320;
3654 break;
3655 default:
3656 ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
3657 break;
3658
3659 }
3660 }
3661
3662 if (tb[NL80211_ATTR_NSS])
3663 ed.sta_opmode.rx_nss = nla_get_u8(tb[NL80211_ATTR_NSS]);
3664
3665 wpa_supplicant_event(drv->ctx, EVENT_STATION_OPMODE_CHANGED, &ed);
3666 }
3667
3668
nl80211_control_port_frame(struct i802_bss * bss,struct nlattr ** tb)3669 static void nl80211_control_port_frame(struct i802_bss *bss, struct nlattr **tb)
3670 {
3671 u8 *src_addr;
3672 u16 ethertype;
3673 enum frame_encryption encrypted;
3674 int link_id;
3675
3676 if (!tb[NL80211_ATTR_MAC] ||
3677 !tb[NL80211_ATTR_FRAME] ||
3678 !tb[NL80211_ATTR_CONTROL_PORT_ETHERTYPE])
3679 return;
3680
3681 src_addr = nla_data(tb[NL80211_ATTR_MAC]);
3682 ethertype = nla_get_u16(tb[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
3683 encrypted = nla_get_flag(tb[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]) ?
3684 FRAME_NOT_ENCRYPTED : FRAME_ENCRYPTED;
3685
3686 if (tb[NL80211_ATTR_MLO_LINK_ID])
3687 link_id = nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
3688 else
3689 link_id = -1;
3690
3691 switch (ethertype) {
3692 case ETH_P_RSN_PREAUTH:
3693 wpa_printf(MSG_INFO, "nl80211: Got pre-auth frame from "
3694 MACSTR " over control port unexpectedly",
3695 MAC2STR(src_addr));
3696 break;
3697 case ETH_P_PAE:
3698 drv_event_eapol_rx2(bss->ctx, src_addr,
3699 nla_data(tb[NL80211_ATTR_FRAME]),
3700 nla_len(tb[NL80211_ATTR_FRAME]),
3701 encrypted, link_id);
3702 break;
3703 default:
3704 wpa_printf(MSG_INFO,
3705 "nl80211: Unexpected ethertype 0x%04x from "
3706 MACSTR " over control port",
3707 ethertype, MAC2STR(src_addr));
3708 break;
3709 }
3710 }
3711
3712
3713 static void
nl80211_control_port_frame_tx_status(struct i802_bss * bss,const u8 * frame,size_t len,struct nlattr * ack,struct nlattr * cookie)3714 nl80211_control_port_frame_tx_status(struct i802_bss *bss,
3715 const u8 *frame, size_t len,
3716 struct nlattr *ack, struct nlattr *cookie)
3717 {
3718 struct wpa_driver_nl80211_data *drv = bss->drv;
3719 union wpa_event_data event;
3720
3721 if (!cookie || len < ETH_HLEN)
3722 return;
3723
3724 wpa_printf(MSG_DEBUG,
3725 "nl80211: Control port TX status (ack=%d), cookie=%llu",
3726 ack != NULL, (long long unsigned int) nla_get_u64(cookie));
3727
3728 os_memset(&event, 0, sizeof(event));
3729 event.eapol_tx_status.dst = frame;
3730 event.eapol_tx_status.data = frame + ETH_HLEN;
3731 event.eapol_tx_status.data_len = len - ETH_HLEN;
3732 event.eapol_tx_status.ack = ack != NULL;
3733 event.eapol_tx_status.link_id =
3734 nla_get_u64(cookie) == drv->eapol_tx_cookie ?
3735 drv->eapol_tx_link_id : NL80211_DRV_LINK_ID_NA;
3736
3737 wpa_supplicant_event(bss->ctx, EVENT_EAPOL_TX_STATUS, &event);
3738 }
3739
3740
nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data * drv,struct nlattr * cookie_attr)3741 static void nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data *drv,
3742 struct nlattr *cookie_attr)
3743 {
3744 unsigned int i;
3745 u64 cookie;
3746 bool match = false;
3747
3748 if (!cookie_attr)
3749 return;
3750 cookie = nla_get_u64(cookie_attr);
3751
3752 for (i = 0; i < drv->num_send_frame_cookies; i++) {
3753 if (cookie == drv->send_frame_cookies[i]) {
3754 match = true;
3755 break;
3756 }
3757 }
3758 wpa_printf(MSG_DEBUG,
3759 "nl80211: TX frame wait expired for cookie 0x%llx%s%s",
3760 (long long unsigned int) cookie,
3761 match ? " (match)" : "",
3762 drv->send_frame_cookie == cookie ? " (match-saved)" : "");
3763 if (drv->send_frame_cookie == cookie) {
3764 drv->send_frame_cookie = (u64) -1;
3765 if (!match)
3766 goto send_event;
3767 }
3768 if (!match)
3769 return;
3770
3771 if (i < drv->num_send_frame_cookies - 1)
3772 os_memmove(&drv->send_frame_cookies[i],
3773 &drv->send_frame_cookies[i + 1],
3774 (drv->num_send_frame_cookies - i - 1) * sizeof(u64));
3775 drv->num_send_frame_cookies--;
3776
3777 send_event:
3778 wpa_supplicant_event(drv->ctx, EVENT_TX_WAIT_EXPIRE, NULL);
3779 }
3780
3781
nl80211_assoc_comeback(struct wpa_driver_nl80211_data * drv,struct nlattr * mac,struct nlattr * timeout)3782 static void nl80211_assoc_comeback(struct wpa_driver_nl80211_data *drv,
3783 struct nlattr *mac, struct nlattr *timeout)
3784 {
3785 if (!mac || !timeout)
3786 return;
3787 wpa_printf(MSG_DEBUG, "nl80211: Association comeback requested by "
3788 MACSTR " (timeout: %u ms)",
3789 MAC2STR((u8 *) nla_data(mac)), nla_get_u32(timeout));
3790 }
3791
3792
3793 #ifdef CONFIG_IEEE80211AX
3794
nl80211_obss_color_event(struct i802_bss * bss,enum nl80211_commands cmd,struct nlattr * tb[])3795 static void nl80211_obss_color_event(struct i802_bss *bss,
3796 enum nl80211_commands cmd,
3797 struct nlattr *tb[])
3798 {
3799 union wpa_event_data data;
3800 enum wpa_event_type event_type;
3801
3802 os_memset(&data, 0, sizeof(data));
3803 data.bss_color_collision.link_id = NL80211_DRV_LINK_ID_NA;
3804
3805 switch (cmd) {
3806 case NL80211_CMD_OBSS_COLOR_COLLISION:
3807 event_type = EVENT_BSS_COLOR_COLLISION;
3808 if (!tb[NL80211_ATTR_OBSS_COLOR_BITMAP])
3809 return;
3810 data.bss_color_collision.bitmap =
3811 nla_get_u64(tb[NL80211_ATTR_OBSS_COLOR_BITMAP]);
3812 wpa_printf(MSG_DEBUG,
3813 "nl80211: BSS color collision - bitmap %08llx",
3814 (long long unsigned int)
3815 data.bss_color_collision.bitmap);
3816 break;
3817 case NL80211_CMD_COLOR_CHANGE_STARTED:
3818 event_type = EVENT_CCA_STARTED_NOTIFY;
3819 wpa_printf(MSG_DEBUG, "nl80211: CCA started");
3820 break;
3821 case NL80211_CMD_COLOR_CHANGE_ABORTED:
3822 event_type = EVENT_CCA_ABORTED_NOTIFY;
3823 wpa_printf(MSG_DEBUG, "nl80211: CCA aborted");
3824 break;
3825 case NL80211_CMD_COLOR_CHANGE_COMPLETED:
3826 event_type = EVENT_CCA_NOTIFY;
3827 wpa_printf(MSG_DEBUG, "nl80211: CCA completed");
3828 break;
3829 default:
3830 wpa_printf(MSG_DEBUG, "nl80211: Unknown CCA command %d", cmd);
3831 return;
3832 }
3833
3834 if (tb[NL80211_ATTR_MLO_LINK_ID]) {
3835 data.bss_color_collision.link_id =
3836 nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
3837
3838 if (!nl80211_link_valid(bss->valid_links,
3839 data.bss_color_collision.link_id)) {
3840 wpa_printf(MSG_DEBUG,
3841 "nl80211: Invalid BSS color event link ID %d",
3842 data.bss_color_collision.link_id);
3843 return;
3844 }
3845
3846 wpa_printf(MSG_DEBUG, "nl80211: BSS color event - Link ID %d",
3847 data.bss_color_collision.link_id);
3848 }
3849
3850 wpa_supplicant_event(bss->ctx, event_type, &data);
3851 }
3852
3853 #endif /* CONFIG_IEEE80211AX */
3854
3855
do_process_drv_event(struct i802_bss * bss,int cmd,struct nlattr ** tb)3856 static void do_process_drv_event(struct i802_bss *bss, int cmd,
3857 struct nlattr **tb)
3858 {
3859 struct wpa_driver_nl80211_data *drv = bss->drv;
3860 int external_scan_event = 0;
3861 struct nlattr *frame = tb[NL80211_ATTR_FRAME];
3862
3863 wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
3864 cmd, nl80211_command_to_string(cmd), bss->ifname);
3865
3866 #ifdef CONFIG_DRIVER_NL80211_QCA
3867 if (cmd == NL80211_CMD_ROAM &&
3868 (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
3869 if (drv->pending_roam_data) {
3870 wpa_printf(MSG_DEBUG,
3871 "nl80211: Process pending roam+auth vendor event");
3872 qca_nl80211_key_mgmt_auth(drv, drv->pending_roam_data,
3873 drv->pending_roam_data_len);
3874 os_free(drv->pending_roam_data);
3875 drv->pending_roam_data = NULL;
3876 return;
3877 }
3878 /*
3879 * Device will use roam+auth vendor event to indicate
3880 * roaming, so ignore the regular roam event.
3881 */
3882 drv->roam_indication_done = true;
3883 wpa_printf(MSG_DEBUG,
3884 "nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
3885 cmd);
3886 return;
3887 }
3888 #endif /* CONFIG_DRIVER_NL80211_QCA */
3889
3890 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
3891 (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
3892 cmd == NL80211_CMD_SCAN_ABORTED))
3893 nl80211_restore_ap_mode(bss);
3894
3895 switch (cmd) {
3896 case NL80211_CMD_TRIGGER_SCAN:
3897 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
3898 drv->scan_state = SCAN_STARTED;
3899 if (drv->scan_for_auth) {
3900 /*
3901 * Cannot indicate EVENT_SCAN_STARTED here since we skip
3902 * EVENT_SCAN_RESULTS in scan_for_auth case and the
3903 * upper layer implementation could get confused about
3904 * scanning state.
3905 */
3906 wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
3907 break;
3908 }
3909 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
3910 break;
3911 case NL80211_CMD_START_SCHED_SCAN:
3912 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
3913 drv->scan_state = SCHED_SCAN_STARTED;
3914 break;
3915 case NL80211_CMD_SCHED_SCAN_STOPPED:
3916 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
3917 drv->scan_state = SCHED_SCAN_STOPPED;
3918 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
3919 break;
3920 case NL80211_CMD_NEW_SCAN_RESULTS:
3921 wpa_dbg(drv->ctx, MSG_DEBUG,
3922 "nl80211: New scan results available");
3923 if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
3924 drv->scan_state = SCAN_COMPLETED;
3925 drv->scan_complete_events = 1;
3926 if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
3927 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
3928 drv, drv->ctx);
3929 drv->last_scan_cmd = 0;
3930 } else {
3931 external_scan_event = 1;
3932 }
3933 send_scan_event(drv, 0, tb, external_scan_event);
3934 break;
3935 case NL80211_CMD_SCHED_SCAN_RESULTS:
3936 wpa_dbg(drv->ctx, MSG_DEBUG,
3937 "nl80211: New sched scan results available");
3938 drv->scan_state = SCHED_SCAN_RESULTS;
3939 send_scan_event(drv, 0, tb, 0);
3940 break;
3941 case NL80211_CMD_SCAN_ABORTED:
3942 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
3943 if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
3944 drv->scan_state = SCAN_ABORTED;
3945 if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
3946 /*
3947 * Need to indicate that scan results are available in
3948 * order not to make wpa_supplicant stop its scanning.
3949 */
3950 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
3951 drv, drv->ctx);
3952 drv->last_scan_cmd = 0;
3953 } else {
3954 external_scan_event = 1;
3955 }
3956 send_scan_event(drv, 1, tb, external_scan_event);
3957 break;
3958 case NL80211_CMD_AUTHENTICATE:
3959 case NL80211_CMD_ASSOCIATE:
3960 case NL80211_CMD_DEAUTHENTICATE:
3961 case NL80211_CMD_DISASSOCIATE:
3962 case NL80211_CMD_FRAME:
3963 case NL80211_CMD_FRAME_TX_STATUS:
3964 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
3965 case NL80211_CMD_UNPROT_DISASSOCIATE:
3966 mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
3967 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3968 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
3969 tb[NL80211_ATTR_COOKIE],
3970 tb[NL80211_ATTR_RX_SIGNAL_DBM],
3971 tb[NL80211_ATTR_STA_WME],
3972 tb[NL80211_ATTR_REQ_IE],
3973 tb[NL80211_ATTR_MLO_LINK_ID]);
3974 break;
3975 case NL80211_CMD_CONNECT:
3976 case NL80211_CMD_ROAM:
3977 mlme_event_connect(drv, cmd, false,
3978 tb[NL80211_ATTR_STATUS_CODE],
3979 tb[NL80211_ATTR_MAC],
3980 tb[NL80211_ATTR_REQ_IE],
3981 tb[NL80211_ATTR_RESP_IE],
3982 tb[NL80211_ATTR_TIMED_OUT],
3983 tb[NL80211_ATTR_TIMEOUT_REASON],
3984 NULL, NULL, NULL,
3985 tb[NL80211_ATTR_FILS_KEK],
3986 NULL,
3987 tb[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM],
3988 tb[NL80211_ATTR_PMK],
3989 tb[NL80211_ATTR_PMKID],
3990 tb[NL80211_ATTR_MLO_LINKS]);
3991 break;
3992 case NL80211_CMD_CH_SWITCH_STARTED_NOTIFY:
3993 mlme_event_ch_switch(drv,
3994 tb[NL80211_ATTR_IFINDEX],
3995 tb[NL80211_ATTR_MLO_LINK_ID],
3996 tb[NL80211_ATTR_WIPHY_FREQ],
3997 tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3998 tb[NL80211_ATTR_CHANNEL_WIDTH],
3999 tb[NL80211_ATTR_CENTER_FREQ1],
4000 tb[NL80211_ATTR_CENTER_FREQ2],
4001 tb[NL80211_ATTR_PUNCT_BITMAP],
4002 0);
4003 break;
4004 case NL80211_CMD_CH_SWITCH_NOTIFY:
4005 mlme_event_ch_switch(drv,
4006 tb[NL80211_ATTR_IFINDEX],
4007 tb[NL80211_ATTR_MLO_LINK_ID],
4008 tb[NL80211_ATTR_WIPHY_FREQ],
4009 tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
4010 tb[NL80211_ATTR_CHANNEL_WIDTH],
4011 tb[NL80211_ATTR_CENTER_FREQ1],
4012 tb[NL80211_ATTR_CENTER_FREQ2],
4013 tb[NL80211_ATTR_PUNCT_BITMAP],
4014 1);
4015 break;
4016 case NL80211_CMD_DISCONNECT:
4017 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
4018 tb[NL80211_ATTR_MAC],
4019 tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
4020 break;
4021 case NL80211_CMD_MICHAEL_MIC_FAILURE:
4022 mlme_event_michael_mic_failure(bss, tb);
4023 break;
4024 case NL80211_CMD_JOIN_IBSS:
4025 mlme_event_join_ibss(drv, tb);
4026 break;
4027 case NL80211_CMD_REMAIN_ON_CHANNEL:
4028 mlme_event_remain_on_channel(drv, 0, tb);
4029 break;
4030 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
4031 mlme_event_remain_on_channel(drv, 1, tb);
4032 break;
4033 case NL80211_CMD_NOTIFY_CQM:
4034 nl80211_cqm_event(drv, tb);
4035 break;
4036 case NL80211_CMD_REG_CHANGE:
4037 case NL80211_CMD_WIPHY_REG_CHANGE:
4038 nl80211_reg_change_event(drv, tb);
4039 break;
4040 case NL80211_CMD_REG_BEACON_HINT:
4041 nl80211_reg_beacon_hint_event(drv, tb);
4042 break;
4043 case NL80211_CMD_NEW_STATION:
4044 nl80211_new_station_event(drv, bss, tb);
4045 break;
4046 case NL80211_CMD_DEL_STATION:
4047 nl80211_del_station_event(drv, bss, tb);
4048 break;
4049 case NL80211_CMD_SET_REKEY_OFFLOAD:
4050 nl80211_rekey_offload_event(drv, tb);
4051 break;
4052 case NL80211_CMD_PMKSA_CANDIDATE:
4053 nl80211_pmksa_candidate_event(drv, tb);
4054 break;
4055 case NL80211_CMD_PROBE_CLIENT:
4056 nl80211_client_probe_event(drv, tb);
4057 break;
4058 case NL80211_CMD_TDLS_OPER:
4059 nl80211_tdls_oper_event(drv, tb);
4060 break;
4061 case NL80211_CMD_CONN_FAILED:
4062 nl80211_connect_failed_event(drv, tb);
4063 break;
4064 case NL80211_CMD_FT_EVENT:
4065 mlme_event_ft_event(drv, tb);
4066 break;
4067 case NL80211_CMD_RADAR_DETECT:
4068 nl80211_radar_event(drv, tb);
4069 break;
4070 case NL80211_CMD_STOP_AP:
4071 nl80211_stop_ap(drv, tb);
4072 break;
4073 case NL80211_CMD_VENDOR:
4074 nl80211_vendor_event(drv, tb);
4075 break;
4076 case NL80211_CMD_NEW_PEER_CANDIDATE:
4077 nl80211_new_peer_candidate(drv, tb);
4078 break;
4079 case NL80211_CMD_PORT_AUTHORIZED:
4080 nl80211_port_authorized(drv, tb);
4081 break;
4082 case NL80211_CMD_STA_OPMODE_CHANGED:
4083 nl80211_sta_opmode_change_event(drv, tb);
4084 break;
4085 case NL80211_CMD_UPDATE_OWE_INFO:
4086 mlme_event_dh_event(drv, bss, tb);
4087 break;
4088 case NL80211_CMD_UNPROT_BEACON:
4089 if (frame)
4090 mlme_event_unprot_beacon(drv, nla_data(frame),
4091 nla_len(frame));
4092 break;
4093 case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS:
4094 if (!frame)
4095 break;
4096 nl80211_control_port_frame_tx_status(bss,
4097 nla_data(frame),
4098 nla_len(frame),
4099 tb[NL80211_ATTR_ACK],
4100 tb[NL80211_ATTR_COOKIE]);
4101 break;
4102 case NL80211_CMD_FRAME_WAIT_CANCEL:
4103 nl80211_frame_wait_cancel(drv, tb[NL80211_ATTR_COOKIE]);
4104 break;
4105 case NL80211_CMD_ASSOC_COMEBACK:
4106 nl80211_assoc_comeback(drv, tb[NL80211_ATTR_MAC],
4107 tb[NL80211_ATTR_TIMEOUT]);
4108 break;
4109 #ifdef CONFIG_IEEE80211AX
4110 case NL80211_CMD_OBSS_COLOR_COLLISION:
4111 case NL80211_CMD_COLOR_CHANGE_STARTED:
4112 case NL80211_CMD_COLOR_CHANGE_ABORTED:
4113 case NL80211_CMD_COLOR_CHANGE_COMPLETED:
4114 nl80211_obss_color_event(bss, cmd, tb);
4115 break;
4116 #endif /* CONFIG_IEEE80211AX */
4117 case NL80211_CMD_LINKS_REMOVED:
4118 wpa_supplicant_event(drv->ctx, EVENT_LINK_RECONFIG, NULL);
4119 break;
4120 default:
4121 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
4122 "(cmd=%d)", cmd);
4123 break;
4124 }
4125 }
4126
4127
nl80211_drv_in_list(struct nl80211_global * global,struct wpa_driver_nl80211_data * drv)4128 static bool nl80211_drv_in_list(struct nl80211_global *global,
4129 struct wpa_driver_nl80211_data *drv)
4130 {
4131 struct wpa_driver_nl80211_data *tmp;
4132
4133 dl_list_for_each(tmp, &global->interfaces,
4134 struct wpa_driver_nl80211_data, list) {
4135 if (drv == tmp)
4136 return true;
4137 }
4138
4139 return false;
4140 }
4141
4142
process_global_event(struct nl_msg * msg,void * arg)4143 int process_global_event(struct nl_msg *msg, void *arg)
4144 {
4145 struct nl80211_global *global = arg;
4146 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4147 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4148 struct wpa_driver_nl80211_data *drv, *tmp;
4149 int ifidx = -1, wiphy_idx = -1, wiphy_idx_rx = -1;
4150 struct i802_bss *bss;
4151 u64 wdev_id = 0;
4152 int wdev_id_set = 0;
4153 int wiphy_idx_set = 0;
4154 bool processed = false;
4155
4156 /* Event marker, all prior events have been processed */
4157 if (gnlh->cmd == NL80211_CMD_GET_PROTOCOL_FEATURES) {
4158 u32 seq = nlmsg_hdr(msg)->nlmsg_seq;
4159
4160 dl_list_for_each_safe(drv, tmp, &global->interfaces,
4161 struct wpa_driver_nl80211_data, list) {
4162 if (drv->ignore_next_local_deauth > 0 &&
4163 drv->ignore_next_local_deauth <= seq) {
4164 wpa_printf(MSG_DEBUG,
4165 "nl80211: No DEAUTHENTICATE event was ignored");
4166 drv->ignore_next_local_deauth = 0;
4167 }
4168
4169 if (drv->ignore_next_local_disconnect > 0 &&
4170 drv->ignore_next_local_disconnect <= seq) {
4171 wpa_printf(MSG_DEBUG,
4172 "nl80211: No DISCONNECT event was ignored");
4173 drv->ignore_next_local_disconnect = 0;
4174 }
4175 }
4176
4177 return NL_SKIP;
4178 }
4179
4180 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4181 genlmsg_attrlen(gnlh, 0), NULL);
4182
4183 if (tb[NL80211_ATTR_IFINDEX])
4184 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
4185 else if (tb[NL80211_ATTR_WDEV]) {
4186 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
4187 wdev_id_set = 1;
4188 } else if (tb[NL80211_ATTR_WIPHY]) {
4189 wiphy_idx_rx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
4190 wiphy_idx_set = 1;
4191 }
4192
4193 dl_list_for_each_safe(drv, tmp, &global->interfaces,
4194 struct wpa_driver_nl80211_data, list) {
4195 for (bss = drv->first_bss; bss; bss = bss->next) {
4196 if (wiphy_idx_set)
4197 wiphy_idx = nl80211_get_wiphy_index(bss);
4198 if ((ifidx == -1 && !wiphy_idx_set && !wdev_id_set) ||
4199 ifidx == bss->ifindex ||
4200 (wiphy_idx_set && wiphy_idx == wiphy_idx_rx) ||
4201 (wdev_id_set && bss->wdev_id_set &&
4202 wdev_id == bss->wdev_id)) {
4203 processed = true;
4204 do_process_drv_event(bss, gnlh->cmd, tb);
4205 if (!wiphy_idx_set)
4206 return NL_SKIP;
4207 /* The driver instance could have been removed,
4208 * e.g., due to NL80211_CMD_RADAR_DETECT event,
4209 * so need to stop the loop if that has
4210 * happened. */
4211 if (!nl80211_drv_in_list(global, drv))
4212 break;
4213 }
4214 }
4215 }
4216
4217 if (processed)
4218 return NL_SKIP;
4219
4220 wpa_printf(MSG_DEBUG,
4221 "nl80211: Ignored event %d (%s) for foreign interface (ifindex %d wdev 0x%llx wiphy %d)",
4222 gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
4223 ifidx, (long long unsigned int) wdev_id, wiphy_idx_rx);
4224
4225 return NL_SKIP;
4226 }
4227
4228
process_bss_event(struct nl_msg * msg,void * arg)4229 int process_bss_event(struct nl_msg *msg, void *arg)
4230 {
4231 struct i802_bss *bss = arg;
4232 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4233 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4234
4235 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4236 genlmsg_attrlen(gnlh, 0), NULL);
4237
4238 wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
4239 gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
4240 bss->ifname);
4241
4242 switch (gnlh->cmd) {
4243 case NL80211_CMD_FRAME:
4244 case NL80211_CMD_FRAME_TX_STATUS:
4245 mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
4246 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
4247 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
4248 tb[NL80211_ATTR_COOKIE],
4249 tb[NL80211_ATTR_RX_SIGNAL_DBM],
4250 tb[NL80211_ATTR_STA_WME], NULL,
4251 tb[NL80211_ATTR_MLO_LINK_ID]);
4252 break;
4253 case NL80211_CMD_UNEXPECTED_FRAME:
4254 nl80211_spurious_frame(bss, tb, 0);
4255 break;
4256 case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
4257 nl80211_spurious_frame(bss, tb, 1);
4258 break;
4259 case NL80211_CMD_EXTERNAL_AUTH:
4260 nl80211_external_auth(bss->drv, tb);
4261 break;
4262 case NL80211_CMD_CONTROL_PORT_FRAME:
4263 nl80211_control_port_frame(bss, tb);
4264 break;
4265 default:
4266 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
4267 "(cmd=%d)", gnlh->cmd);
4268 break;
4269 }
4270
4271 return NL_SKIP;
4272 }
4273