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