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