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