Home | History | Annotate | Line # | Download | only in ap
      1 /*
      2  * hostapd / Callback functions for driver wrappers
      3  * Copyright (c) 2002-2013, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "radius/radius.h"
     14 #include "drivers/driver.h"
     15 #include "common/ieee802_11_defs.h"
     16 #include "common/ieee802_11_common.h"
     17 #include "common/wpa_ctrl.h"
     18 #include "common/dpp.h"
     19 #include "common/sae.h"
     20 #include "common/hw_features_common.h"
     21 #include "crypto/random.h"
     22 #include "p2p/p2p.h"
     23 #include "wps/wps.h"
     24 #include "fst/fst.h"
     25 #include "wnm_ap.h"
     26 #include "hostapd.h"
     27 #include "ieee802_11.h"
     28 #include "ieee802_11_auth.h"
     29 #include "sta_info.h"
     30 #include "accounting.h"
     31 #include "tkip_countermeasures.h"
     32 #include "ieee802_1x.h"
     33 #include "wpa_auth.h"
     34 #include "wps_hostapd.h"
     35 #include "ap_drv_ops.h"
     36 #include "ap_config.h"
     37 #include "ap_mlme.h"
     38 #include "hw_features.h"
     39 #include "dfs.h"
     40 #include "beacon.h"
     41 #include "mbo_ap.h"
     42 #include "dpp_hostapd.h"
     43 #include "fils_hlp.h"
     44 #include "neighbor_db.h"
     45 #include "nan_usd_ap.h"
     46 
     47 
     48 #ifdef CONFIG_FILS
     49 void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
     50 				      struct sta_info *sta)
     51 {
     52 	u16 reply_res = WLAN_STATUS_SUCCESS;
     53 	struct ieee802_11_elems elems;
     54 	u8 buf[IEEE80211_MAX_MMPDU_SIZE], *p = buf;
     55 	int new_assoc;
     56 	bool updated;
     57 
     58 	wpa_printf(MSG_DEBUG, "%s FILS: Finish association with " MACSTR,
     59 		   __func__, MAC2STR(sta->addr));
     60 	eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
     61 	if (!sta->fils_pending_assoc_req)
     62 		return;
     63 
     64 	if (ieee802_11_parse_elems(sta->fils_pending_assoc_req,
     65 				   sta->fils_pending_assoc_req_len, &elems,
     66 				   0) == ParseFailed ||
     67 	    !elems.fils_session) {
     68 		wpa_printf(MSG_DEBUG, "%s failed to find FILS Session element",
     69 			   __func__);
     70 		return;
     71 	}
     72 
     73 	p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
     74 					   elems.fils_session,
     75 					   sta->fils_hlp_resp);
     76 
     77 	reply_res = hostapd_sta_assoc(hapd, sta->addr,
     78 				      sta->fils_pending_assoc_is_reassoc,
     79 				      WLAN_STATUS_SUCCESS,
     80 				      buf, p - buf);
     81 	updated = ap_sta_set_authorized_flag(hapd, sta, 1);
     82 	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
     83 	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
     84 	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
     85 	hostapd_set_sta_flags(hapd, sta);
     86 	if (updated)
     87 		ap_sta_set_authorized_event(hapd, sta, 1);
     88 	wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS);
     89 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
     90 	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
     91 	os_free(sta->fils_pending_assoc_req);
     92 	sta->fils_pending_assoc_req = NULL;
     93 	sta->fils_pending_assoc_req_len = 0;
     94 	wpabuf_free(sta->fils_hlp_resp);
     95 	sta->fils_hlp_resp = NULL;
     96 	wpabuf_free(sta->hlp_dhcp_discover);
     97 	sta->hlp_dhcp_discover = NULL;
     98 	fils_hlp_deinit(hapd);
     99 
    100 	/*
    101 	 * Remove the station in case transmission of a success response fails
    102 	 * (the STA was added associated to the driver) or if the station was
    103 	 * previously added unassociated.
    104 	 */
    105 	if (reply_res != WLAN_STATUS_SUCCESS || sta->added_unassoc) {
    106 		hostapd_drv_sta_remove(hapd, sta->addr);
    107 		sta->added_unassoc = 0;
    108 	}
    109 }
    110 #endif /* CONFIG_FILS */
    111 
    112 
    113 static bool check_sa_query_need(struct hostapd_data *hapd, struct sta_info *sta)
    114 {
    115 	if ((sta->flags &
    116 	     (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) !=
    117 	    (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED))
    118 		return false;
    119 
    120 	if (!sta->sa_query_timed_out && sta->sa_query_count > 0)
    121 		ap_check_sa_query_timeout(hapd, sta);
    122 
    123 	if (!sta->sa_query_timed_out && (sta->auth_alg != WLAN_AUTH_FT)) {
    124 		/*
    125 		 * STA has already been associated with MFP and SA Query timeout
    126 		 * has not been reached. Reject the association attempt
    127 		 * temporarily and start SA Query, if one is not pending.
    128 		 */
    129 		if (sta->sa_query_count == 0)
    130 			ap_sta_start_sa_query(hapd, sta);
    131 
    132 		return true;
    133 	}
    134 
    135 	return false;
    136 }
    137 
    138 
    139 #ifdef CONFIG_IEEE80211BE
    140 static int hostapd_update_sta_links_status(struct hostapd_data *hapd,
    141 					   struct sta_info *sta,
    142 					   const u8 *resp_ies,
    143 					   size_t resp_ies_len)
    144 {
    145 	struct mld_info *info = &sta->mld_info;
    146 	struct wpabuf *mlebuf;
    147 	const u8 *mle, *pos;
    148 	struct ieee802_11_elems elems;
    149 	size_t mle_len, rem_len;
    150 	int ret = 0;
    151 
    152 	if (!resp_ies) {
    153 		wpa_printf(MSG_DEBUG,
    154 			   "MLO: (Re)Association Response frame elements not available");
    155 		return -1;
    156 	}
    157 
    158 	if (ieee802_11_parse_elems(resp_ies, resp_ies_len, &elems, 0) ==
    159 	    ParseFailed) {
    160 		wpa_printf(MSG_DEBUG,
    161 			   "MLO: Failed to parse (Re)Association Response frame elements");
    162 		return -1;
    163 	}
    164 
    165 	mlebuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true);
    166 	if (!mlebuf) {
    167 		wpa_printf(MSG_ERROR,
    168 			   "MLO: Basic Multi-Link element not found in (Re)Association Response frame");
    169 		return -1;
    170 	}
    171 
    172 	mle = wpabuf_head(mlebuf);
    173 	mle_len = wpabuf_len(mlebuf);
    174 	if (mle_len < MULTI_LINK_CONTROL_LEN + 1 ||
    175 	    mle_len - MULTI_LINK_CONTROL_LEN < mle[MULTI_LINK_CONTROL_LEN]) {
    176 		wpa_printf(MSG_ERROR,
    177 			   "MLO: Invalid Multi-Link element in (Re)Association Response frame");
    178 		ret = -1;
    179 		goto out;
    180 	}
    181 
    182 	/* Skip Common Info */
    183 	pos = mle + MULTI_LINK_CONTROL_LEN + mle[MULTI_LINK_CONTROL_LEN];
    184 	rem_len = mle_len -
    185 		(MULTI_LINK_CONTROL_LEN + mle[MULTI_LINK_CONTROL_LEN]);
    186 
    187 	/* Parse Subelements */
    188 	while (rem_len > 2) {
    189 		size_t ie_len = 2 + pos[1];
    190 
    191 		if (rem_len < ie_len)
    192 			break;
    193 
    194 		if (pos[0] == MULTI_LINK_SUB_ELEM_ID_PER_STA_PROFILE) {
    195 			u8 link_id;
    196 			const u8 *sta_profile;
    197 			size_t sta_profile_len;
    198 			u16 sta_ctrl;
    199 
    200 			if (pos[1] < BASIC_MLE_STA_CTRL_LEN + 1) {
    201 				wpa_printf(MSG_DEBUG,
    202 					   "MLO: Invalid per-STA profile IE");
    203 				goto next_subelem;
    204 			}
    205 
    206 			sta_profile_len = pos[1];
    207 			sta_profile = &pos[2];
    208 			sta_ctrl = WPA_GET_LE16(sta_profile);
    209 			link_id = sta_ctrl & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
    210 			if (link_id >= MAX_NUM_MLD_LINKS) {
    211 				wpa_printf(MSG_DEBUG,
    212 					   "MLO: Invalid link ID in per-STA profile IE");
    213 				goto next_subelem;
    214 			}
    215 
    216 			/* Skip STA Control and STA Info */
    217 			if (sta_profile_len - BASIC_MLE_STA_CTRL_LEN <
    218 			    sta_profile[BASIC_MLE_STA_CTRL_LEN]) {
    219 				wpa_printf(MSG_DEBUG,
    220 					   "MLO: Invalid STA info in per-STA profile IE");
    221 				goto next_subelem;
    222 			}
    223 
    224 			sta_profile_len = sta_profile_len -
    225 				(BASIC_MLE_STA_CTRL_LEN +
    226 				 sta_profile[BASIC_MLE_STA_CTRL_LEN]);
    227 			sta_profile = sta_profile + BASIC_MLE_STA_CTRL_LEN +
    228 				sta_profile[BASIC_MLE_STA_CTRL_LEN];
    229 
    230 			/* Skip Capabilities Information field */
    231 			if (sta_profile_len < 2)
    232 				goto next_subelem;
    233 			sta_profile_len -= 2;
    234 			sta_profile += 2;
    235 
    236 			/* Get status of the link */
    237 			info->links[link_id].status = WPA_GET_LE16(sta_profile);
    238 		}
    239 next_subelem:
    240 		pos += ie_len;
    241 		rem_len -= ie_len;
    242 	}
    243 
    244 out:
    245 	wpabuf_free(mlebuf);
    246 	return ret;
    247 }
    248 #endif /* CONFIG_IEEE80211BE */
    249 
    250 
    251 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
    252 			const u8 *req_ies, size_t req_ies_len,
    253 			const u8 *resp_ies, size_t resp_ies_len,
    254 			const u8 *link_addr, int reassoc)
    255 {
    256 	struct sta_info *sta;
    257 	int new_assoc;
    258 	enum wpa_validate_result res;
    259 	struct ieee802_11_elems elems;
    260 	const u8 *ie;
    261 	size_t ielen;
    262 	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
    263 	u8 *p = buf;
    264 	u16 reason = WLAN_REASON_UNSPECIFIED;
    265 	int status = WLAN_STATUS_SUCCESS;
    266 	const u8 *p2p_dev_addr = NULL;
    267 #ifdef CONFIG_OWE
    268 	struct hostapd_iface *iface = hapd->iface;
    269 #endif /* CONFIG_OWE */
    270 	bool updated = false;
    271 
    272 	if (addr == NULL) {
    273 		/*
    274 		 * This could potentially happen with unexpected event from the
    275 		 * driver wrapper. This was seen at least in one case where the
    276 		 * driver ended up being set to station mode while hostapd was
    277 		 * running, so better make sure we stop processing such an
    278 		 * event here.
    279 		 */
    280 		wpa_printf(MSG_DEBUG,
    281 			   "hostapd_notif_assoc: Skip event with no address");
    282 		return -1;
    283 	}
    284 
    285 	if (is_multicast_ether_addr(addr) ||
    286 	    is_zero_ether_addr(addr) ||
    287 	    ether_addr_equal(addr, hapd->own_addr)) {
    288 		/* Do not process any frames with unexpected/invalid SA so that
    289 		 * we do not add any state for unexpected STA addresses or end
    290 		 * up sending out frames to unexpected destination. */
    291 		wpa_printf(MSG_DEBUG, "%s: Invalid SA=" MACSTR
    292 			   " in received indication - ignore this indication silently",
    293 			   __func__, MAC2STR(addr));
    294 		return 0;
    295 	}
    296 
    297 	random_add_randomness(addr, ETH_ALEN);
    298 
    299 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
    300 		       HOSTAPD_LEVEL_INFO, "associated");
    301 
    302 	if (ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0) ==
    303 	    ParseFailed) {
    304 		wpa_printf(MSG_DEBUG, "%s: Could not parse elements", __func__);
    305 		return -1;
    306 	}
    307 
    308 	if (elems.wps_ie) {
    309 		ie = elems.wps_ie - 2;
    310 		ielen = elems.wps_ie_len + 2;
    311 		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
    312 	} else if (elems.rsn_ie) {
    313 		ie = elems.rsn_ie - 2;
    314 		ielen = elems.rsn_ie_len + 2;
    315 		wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
    316 	} else if (elems.wpa_ie) {
    317 		ie = elems.wpa_ie - 2;
    318 		ielen = elems.wpa_ie_len + 2;
    319 		wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
    320 #ifdef CONFIG_HS20
    321 	} else if (elems.osen) {
    322 		ie = elems.osen - 2;
    323 		ielen = elems.osen_len + 2;
    324 		wpa_printf(MSG_DEBUG, "STA included OSEN IE in (Re)AssocReq");
    325 #endif /* CONFIG_HS20 */
    326 	} else {
    327 		ie = NULL;
    328 		ielen = 0;
    329 		wpa_printf(MSG_DEBUG,
    330 			   "STA did not include WPS/RSN/WPA IE in (Re)AssocReq");
    331 	}
    332 
    333 	sta = ap_get_sta(hapd, addr);
    334 	if (sta) {
    335 		ap_sta_no_session_timeout(hapd, sta);
    336 		accounting_sta_stop(hapd, sta);
    337 
    338 		/*
    339 		 * Make sure that the previously registered inactivity timer
    340 		 * will not remove the STA immediately.
    341 		 */
    342 		sta->timeout_next = STA_NULLFUNC;
    343 	} else {
    344 		sta = ap_sta_add(hapd, addr);
    345 		if (sta == NULL) {
    346 			hostapd_drv_sta_disassoc(hapd, addr,
    347 						 WLAN_REASON_DISASSOC_AP_BUSY);
    348 			return -1;
    349 		}
    350 	}
    351 
    352 	if (hapd->conf->wpa && check_sa_query_need(hapd, sta)) {
    353 		status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
    354 		p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
    355 		hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
    356 
    357 		return 0;
    358 	}
    359 
    360 #ifdef CONFIG_IEEE80211BE
    361 	if (link_addr) {
    362 		struct mld_info *info = &sta->mld_info;
    363 		int i, num_valid_links = 0;
    364 		u8 link_id = hapd->mld_link_id;
    365 
    366 		ap_sta_set_mld(sta, true);
    367 		sta->mld_assoc_link_id = link_id;
    368 		os_memcpy(info->common_info.mld_addr, addr, ETH_ALEN);
    369 		info->links[link_id].valid = true;
    370 		os_memcpy(info->links[link_id].peer_addr, link_addr, ETH_ALEN);
    371 		os_memcpy(info->links[link_id].local_addr, hapd->own_addr,
    372 			  ETH_ALEN);
    373 
    374 		if (!elems.basic_mle ||
    375 		    hostapd_process_ml_assoc_req(hapd, &elems, sta) !=
    376 		    WLAN_STATUS_SUCCESS) {
    377 			reason = WLAN_REASON_UNSPECIFIED;
    378 			wpa_printf(MSG_DEBUG,
    379 				   "Failed to get STA non-assoc links info");
    380 			goto fail;
    381 		}
    382 
    383 		for (i = 0 ; i < MAX_NUM_MLD_LINKS; i++) {
    384 			if (info->links[i].valid)
    385 				num_valid_links++;
    386 		}
    387 		if (num_valid_links > 1 &&
    388 		    hostapd_update_sta_links_status(hapd, sta, resp_ies,
    389 						    resp_ies_len)) {
    390 			wpa_printf(MSG_DEBUG,
    391 				   "Failed to get STA non-assoc links status info");
    392 			reason = WLAN_REASON_UNSPECIFIED;
    393 			goto fail;
    394 		}
    395 	}
    396 #endif /* CONFIG_IEEE80211BE */
    397 
    398 	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
    399 
    400 	/*
    401 	 * ACL configurations to the drivers (implementing AP SME and ACL
    402 	 * offload) without hostapd's knowledge, can result in a disconnection
    403 	 * though the driver accepts the connection. Skip the hostapd check for
    404 	 * ACL if the driver supports ACL offload to avoid potentially
    405 	 * conflicting ACL rules.
    406 	 */
    407 	if (hapd->iface->drv_max_acl_mac_addrs == 0 &&
    408 	    hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) {
    409 		wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
    410 			   MAC2STR(addr));
    411 		reason = WLAN_REASON_UNSPECIFIED;
    412 		goto fail;
    413 	}
    414 
    415 #ifdef CONFIG_P2P
    416 	if (elems.p2p) {
    417 		wpabuf_free(sta->p2p_ie);
    418 		sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
    419 							  P2P_IE_VENDOR_TYPE);
    420 		if (sta->p2p_ie)
    421 			p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
    422 	}
    423 #endif /* CONFIG_P2P */
    424 
    425 #ifdef NEED_AP_MLME
    426 	if (elems.ht_capabilities &&
    427 	    (hapd->iface->conf->ht_capab &
    428 	     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
    429 		struct ieee80211_ht_capabilities *ht_cap =
    430 			(struct ieee80211_ht_capabilities *)
    431 			elems.ht_capabilities;
    432 
    433 		if (le_to_host16(ht_cap->ht_capabilities_info) &
    434 		    HT_CAP_INFO_40MHZ_INTOLERANT)
    435 			ht40_intolerant_add(hapd->iface, sta);
    436 	}
    437 #endif /* NEED_AP_MLME */
    438 
    439 	check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
    440 
    441 #ifdef CONFIG_HS20
    442 	wpabuf_free(sta->hs20_ie);
    443 	if (elems.hs20 && elems.hs20_len > 4) {
    444 		sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
    445 						 elems.hs20_len - 4);
    446 	} else
    447 		sta->hs20_ie = NULL;
    448 
    449 	wpabuf_free(sta->roaming_consortium);
    450 	if (elems.roaming_cons_sel)
    451 		sta->roaming_consortium = wpabuf_alloc_copy(
    452 			elems.roaming_cons_sel + 4,
    453 			elems.roaming_cons_sel_len - 4);
    454 	else
    455 		sta->roaming_consortium = NULL;
    456 #endif /* CONFIG_HS20 */
    457 
    458 #ifdef CONFIG_FST
    459 	wpabuf_free(sta->mb_ies);
    460 	if (hapd->iface->fst)
    461 		sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
    462 	else
    463 		sta->mb_ies = NULL;
    464 #endif /* CONFIG_FST */
    465 
    466 	mbo_ap_check_sta_assoc(hapd, sta, &elems);
    467 
    468 	ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
    469 				    elems.supp_op_classes_len);
    470 
    471 	if (hapd->conf->wpa) {
    472 		if (ie == NULL || ielen == 0) {
    473 #ifdef CONFIG_WPS
    474 			if (hapd->conf->wps_state) {
    475 				wpa_printf(MSG_DEBUG,
    476 					   "STA did not include WPA/RSN IE in (Re)Association Request - possible WPS use");
    477 				sta->flags |= WLAN_STA_MAYBE_WPS;
    478 				goto skip_wpa_check;
    479 			}
    480 #endif /* CONFIG_WPS */
    481 
    482 			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
    483 			reason = WLAN_REASON_INVALID_IE;
    484 			status = WLAN_STATUS_INVALID_IE;
    485 			goto fail;
    486 		}
    487 #ifdef CONFIG_WPS
    488 		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
    489 		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
    490 			struct wpabuf *wps;
    491 
    492 			sta->flags |= WLAN_STA_WPS;
    493 			wps = ieee802_11_vendor_ie_concat(ie, ielen,
    494 							  WPS_IE_VENDOR_TYPE);
    495 			if (wps) {
    496 				if (wps_is_20(wps)) {
    497 					wpa_printf(MSG_DEBUG,
    498 						   "WPS: STA supports WPS 2.0");
    499 					sta->flags |= WLAN_STA_WPS2;
    500 				}
    501 				wpabuf_free(wps);
    502 			}
    503 			goto skip_wpa_check;
    504 		}
    505 #endif /* CONFIG_WPS */
    506 
    507 		if (sta->wpa_sm == NULL)
    508 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    509 							sta->addr,
    510 							p2p_dev_addr);
    511 		if (sta->wpa_sm == NULL) {
    512 			wpa_printf(MSG_ERROR,
    513 				   "Failed to initialize WPA state machine");
    514 			return -1;
    515 		}
    516 #ifdef CONFIG_IEEE80211BE
    517 		if (ap_sta_is_mld(hapd, sta)) {
    518 			wpa_printf(MSG_DEBUG,
    519 				   "MLD: Set ML info in RSN Authenticator");
    520 			wpa_auth_set_ml_info(sta->wpa_sm,
    521 					     sta->mld_assoc_link_id,
    522 					     &sta->mld_info);
    523 		}
    524 #endif /* CONFIG_IEEE80211BE */
    525 		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
    526 					  hapd->iface->freq,
    527 					  ie, ielen,
    528 					  elems.rsnxe ? elems.rsnxe - 2 : NULL,
    529 					  elems.rsnxe ? elems.rsnxe_len + 2 : 0,
    530 					  elems.mdie, elems.mdie_len,
    531 					  elems.owe_dh, elems.owe_dh_len, NULL);
    532 		reason = WLAN_REASON_INVALID_IE;
    533 		status = WLAN_STATUS_INVALID_IE;
    534 		switch (res) {
    535 		case WPA_IE_OK:
    536 			reason = WLAN_REASON_UNSPECIFIED;
    537 			status = WLAN_STATUS_SUCCESS;
    538 			break;
    539 		case WPA_INVALID_IE:
    540 			reason = WLAN_REASON_INVALID_IE;
    541 			status = WLAN_STATUS_INVALID_IE;
    542 			break;
    543 		case WPA_INVALID_GROUP:
    544 			reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
    545 			status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
    546 			break;
    547 		case WPA_INVALID_PAIRWISE:
    548 			reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
    549 			status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
    550 			break;
    551 		case WPA_INVALID_AKMP:
    552 			reason = WLAN_REASON_AKMP_NOT_VALID;
    553 			status = WLAN_STATUS_AKMP_NOT_VALID;
    554 			break;
    555 		case WPA_NOT_ENABLED:
    556 			reason = WLAN_REASON_INVALID_IE;
    557 			status = WLAN_STATUS_INVALID_IE;
    558 			break;
    559 		case WPA_ALLOC_FAIL:
    560 			reason = WLAN_REASON_UNSPECIFIED;
    561 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
    562 			break;
    563 		case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
    564 			reason = WLAN_REASON_INVALID_IE;
    565 			status = WLAN_STATUS_INVALID_IE;
    566 			break;
    567 		case WPA_INVALID_MGMT_GROUP_CIPHER:
    568 			reason = WLAN_REASON_CIPHER_SUITE_REJECTED;
    569 			status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
    570 			break;
    571 		case WPA_INVALID_MDIE:
    572 			reason = WLAN_REASON_INVALID_MDE;
    573 			status = WLAN_STATUS_INVALID_MDIE;
    574 			break;
    575 		case WPA_INVALID_PROTO:
    576 			reason = WLAN_REASON_INVALID_IE;
    577 			status = WLAN_STATUS_INVALID_IE;
    578 			break;
    579 		case WPA_INVALID_PMKID:
    580 			reason = WLAN_REASON_INVALID_PMKID;
    581 			status = WLAN_STATUS_INVALID_PMKID;
    582 			break;
    583 		case WPA_DENIED_OTHER_REASON:
    584 			reason = WLAN_REASON_UNSPECIFIED;
    585 			status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
    586 			break;
    587 		}
    588 		if (status != WLAN_STATUS_SUCCESS) {
    589 			wpa_printf(MSG_DEBUG,
    590 				   "WPA/RSN information element rejected? (res %u)",
    591 				   res);
    592 			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
    593 			goto fail;
    594 		}
    595 
    596 		if (wpa_auth_uses_mfp(sta->wpa_sm))
    597 			sta->flags |= WLAN_STA_MFP;
    598 		else
    599 			sta->flags &= ~WLAN_STA_MFP;
    600 
    601 #ifdef CONFIG_IEEE80211R_AP
    602 		if (sta->auth_alg == WLAN_AUTH_FT) {
    603 			status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
    604 							 req_ies_len);
    605 			if (status != WLAN_STATUS_SUCCESS) {
    606 				if (status == WLAN_STATUS_INVALID_PMKID)
    607 					reason = WLAN_REASON_INVALID_IE;
    608 				if (status == WLAN_STATUS_INVALID_MDIE)
    609 					reason = WLAN_REASON_INVALID_IE;
    610 				if (status == WLAN_STATUS_INVALID_FTIE)
    611 					reason = WLAN_REASON_INVALID_IE;
    612 				goto fail;
    613 			}
    614 		}
    615 #endif /* CONFIG_IEEE80211R_AP */
    616 #ifdef CONFIG_SAE
    617 		if (hapd->conf->sae_pwe == SAE_PWE_BOTH &&
    618 		    sta->auth_alg == WLAN_AUTH_SAE &&
    619 		    sta->sae && !sta->sae->h2e &&
    620 		    ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
    621 					      WLAN_RSNX_CAPAB_SAE_H2E)) {
    622 			wpa_printf(MSG_INFO, "SAE: " MACSTR
    623 				   " indicates support for SAE H2E, but did not use it",
    624 				   MAC2STR(sta->addr));
    625 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
    626 			reason = WLAN_REASON_UNSPECIFIED;
    627 			goto fail;
    628 		}
    629 #endif /* CONFIG_SAE */
    630 	} else if (hapd->conf->wps_state) {
    631 #ifdef CONFIG_WPS
    632 		struct wpabuf *wps;
    633 
    634 		if (req_ies)
    635 			wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
    636 							  WPS_IE_VENDOR_TYPE);
    637 		else
    638 			wps = NULL;
    639 #ifdef CONFIG_WPS_STRICT
    640 		if (wps && wps_validate_assoc_req(wps) < 0) {
    641 			reason = WLAN_REASON_INVALID_IE;
    642 			status = WLAN_STATUS_INVALID_IE;
    643 			wpabuf_free(wps);
    644 			goto fail;
    645 		}
    646 #endif /* CONFIG_WPS_STRICT */
    647 		if (wps) {
    648 			sta->flags |= WLAN_STA_WPS;
    649 			if (wps_is_20(wps)) {
    650 				wpa_printf(MSG_DEBUG,
    651 					   "WPS: STA supports WPS 2.0");
    652 				sta->flags |= WLAN_STA_WPS2;
    653 			}
    654 		} else
    655 			sta->flags |= WLAN_STA_MAYBE_WPS;
    656 		wpabuf_free(wps);
    657 #endif /* CONFIG_WPS */
    658 #ifdef CONFIG_HS20
    659 	} else if (hapd->conf->osen) {
    660 		if (elems.osen == NULL) {
    661 			hostapd_logger(
    662 				hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    663 				HOSTAPD_LEVEL_INFO,
    664 				"No HS 2.0 OSEN element in association request");
    665 			return WLAN_STATUS_INVALID_IE;
    666 		}
    667 
    668 		wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
    669 		if (sta->wpa_sm == NULL)
    670 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    671 							sta->addr, NULL);
    672 		if (sta->wpa_sm == NULL) {
    673 			wpa_printf(MSG_WARNING,
    674 				   "Failed to initialize WPA state machine");
    675 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
    676 		}
    677 		if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
    678 				      elems.osen - 2, elems.osen_len + 2) < 0)
    679 			return WLAN_STATUS_INVALID_IE;
    680 #endif /* CONFIG_HS20 */
    681 	}
    682 #ifdef CONFIG_WPS
    683 skip_wpa_check:
    684 #endif /* CONFIG_WPS */
    685 
    686 #ifdef CONFIG_MBO
    687 	if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
    688 	    elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
    689 	    hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
    690 		wpa_printf(MSG_INFO,
    691 			   "MBO: Reject WPA2 association without PMF");
    692 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
    693 	}
    694 #endif /* CONFIG_MBO */
    695 
    696 #ifdef CONFIG_IEEE80211R_AP
    697 	p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
    698 					sta->auth_alg, req_ies, req_ies_len,
    699 					!elems.rsnxe);
    700 	if (!p) {
    701 		wpa_printf(MSG_DEBUG, "FT: Failed to write AssocResp IEs");
    702 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
    703 	}
    704 #endif /* CONFIG_IEEE80211R_AP */
    705 
    706 #ifdef CONFIG_FILS
    707 	if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
    708 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
    709 	    sta->auth_alg == WLAN_AUTH_FILS_PK) {
    710 		int delay_assoc = 0;
    711 
    712 		if (!req_ies)
    713 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
    714 
    715 		if (!wpa_fils_validate_fils_session(sta->wpa_sm, req_ies,
    716 						    req_ies_len,
    717 						    sta->fils_session)) {
    718 			wpa_printf(MSG_DEBUG,
    719 				   "FILS: Session validation failed");
    720 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
    721 		}
    722 
    723 		res = wpa_fils_validate_key_confirm(sta->wpa_sm, req_ies,
    724 						    req_ies_len);
    725 		if (res < 0) {
    726 			wpa_printf(MSG_DEBUG,
    727 				   "FILS: Key Confirm validation failed");
    728 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
    729 		}
    730 
    731 		if (fils_process_hlp(hapd, sta, req_ies, req_ies_len) > 0) {
    732 			wpa_printf(MSG_DEBUG,
    733 				   "FILS: Delaying Assoc Response (HLP)");
    734 			delay_assoc = 1;
    735 		} else {
    736 			wpa_printf(MSG_DEBUG,
    737 				   "FILS: Going ahead with Assoc Response (no HLP)");
    738 		}
    739 
    740 		if (sta) {
    741 			wpa_printf(MSG_DEBUG, "FILS: HLP callback cleanup");
    742 			eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
    743 			os_free(sta->fils_pending_assoc_req);
    744 			sta->fils_pending_assoc_req = NULL;
    745 			sta->fils_pending_assoc_req_len = 0;
    746 			wpabuf_free(sta->fils_hlp_resp);
    747 			sta->fils_hlp_resp = NULL;
    748 			sta->fils_drv_assoc_finish = 0;
    749 		}
    750 
    751 		if (sta && delay_assoc && status == WLAN_STATUS_SUCCESS) {
    752 			u8 *req_tmp;
    753 
    754 			req_tmp = os_malloc(req_ies_len);
    755 			if (!req_tmp) {
    756 				wpa_printf(MSG_DEBUG,
    757 					   "FILS: buffer allocation failed for assoc req");
    758 				goto fail;
    759 			}
    760 			os_memcpy(req_tmp, req_ies, req_ies_len);
    761 			sta->fils_pending_assoc_req = req_tmp;
    762 			sta->fils_pending_assoc_req_len = req_ies_len;
    763 			sta->fils_pending_assoc_is_reassoc = reassoc;
    764 			sta->fils_drv_assoc_finish = 1;
    765 			wpa_printf(MSG_DEBUG,
    766 				   "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
    767 				   MACSTR, MAC2STR(sta->addr));
    768 			eloop_register_timeout(
    769 				0, hapd->conf->fils_hlp_wait_time * 1024,
    770 				fils_hlp_timeout, hapd, sta);
    771 			return 0;
    772 		}
    773 		p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
    774 						   elems.fils_session,
    775 						   sta->fils_hlp_resp);
    776 		wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)",
    777 			    buf, p - buf);
    778 	}
    779 #endif /* CONFIG_FILS */
    780 
    781 #ifdef CONFIG_OWE
    782 	if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
    783 	    !(iface->drv_flags2 & WPA_DRIVER_FLAGS2_OWE_OFFLOAD_AP) &&
    784 	    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
    785 	    elems.owe_dh) {
    786 		u8 *npos;
    787 		u16 ret_status;
    788 
    789 		npos = owe_assoc_req_process(hapd, sta,
    790 					     elems.owe_dh, elems.owe_dh_len,
    791 					     p, sizeof(buf) - (p - buf),
    792 					     &ret_status);
    793 		status = ret_status;
    794 		if (npos)
    795 			p = npos;
    796 
    797 		if (!npos &&
    798 		    status == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
    799 			hostapd_sta_assoc(hapd, addr, reassoc, ret_status, buf,
    800 					  p - buf);
    801 			return 0;
    802 		}
    803 
    804 		if (!npos || status != WLAN_STATUS_SUCCESS)
    805 			goto fail;
    806 	}
    807 #endif /* CONFIG_OWE */
    808 
    809 #ifdef CONFIG_DPP2
    810 		dpp_pfs_free(sta->dpp_pfs);
    811 		sta->dpp_pfs = NULL;
    812 
    813 		if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
    814 		    hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
    815 		    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
    816 		    elems.owe_dh) {
    817 			sta->dpp_pfs = dpp_pfs_init(
    818 				wpabuf_head(hapd->conf->dpp_netaccesskey),
    819 				wpabuf_len(hapd->conf->dpp_netaccesskey));
    820 			if (!sta->dpp_pfs) {
    821 				wpa_printf(MSG_DEBUG,
    822 					   "DPP: Could not initialize PFS");
    823 				/* Try to continue without PFS */
    824 				goto pfs_fail;
    825 			}
    826 
    827 			if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh,
    828 					    elems.owe_dh_len) < 0) {
    829 				dpp_pfs_free(sta->dpp_pfs);
    830 				sta->dpp_pfs = NULL;
    831 				reason = WLAN_REASON_UNSPECIFIED;
    832 				goto fail;
    833 			}
    834 		}
    835 
    836 		wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ?
    837 				   sta->dpp_pfs->secret : NULL);
    838 	pfs_fail:
    839 #endif /* CONFIG_DPP2 */
    840 
    841 	if (elems.rrm_enabled &&
    842 	    elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
    843 	    os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
    844 		      sizeof(sta->rrm_enabled_capa));
    845 
    846 #if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_FILS) || defined(CONFIG_OWE)
    847 	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
    848 
    849 	if (sta->auth_alg == WLAN_AUTH_FT ||
    850 	    sta->auth_alg == WLAN_AUTH_FILS_SK ||
    851 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
    852 	    sta->auth_alg == WLAN_AUTH_FILS_PK)
    853 		updated = ap_sta_set_authorized_flag(hapd, sta, 1);
    854 #else /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
    855 	/* Keep compiler silent about unused variables */
    856 	if (status) {
    857 	}
    858 #endif /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
    859 
    860 #ifdef CONFIG_IEEE80211BE
    861 	if (hostapd_process_assoc_ml_info(hapd, sta, req_ies, req_ies_len,
    862 					  !!reassoc, WLAN_STATUS_SUCCESS,
    863 					  true)) {
    864 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
    865 		reason = WLAN_REASON_UNSPECIFIED;
    866 		goto fail;
    867 	}
    868 #endif /* CONFIG_IEEE80211BE */
    869 
    870 	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
    871 	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
    872 	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
    873 
    874 	hostapd_set_sta_flags(hapd, sta);
    875 	if (updated)
    876 		ap_sta_set_authorized_event(hapd, sta, 1);
    877 
    878 	if (reassoc && (sta->auth_alg == WLAN_AUTH_FT))
    879 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
    880 #ifdef CONFIG_FILS
    881 	else if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
    882 		 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
    883 		 sta->auth_alg == WLAN_AUTH_FILS_PK)
    884 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS);
    885 #endif /* CONFIG_FILS */
    886 	else
    887 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
    888 
    889 	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
    890 
    891 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
    892 
    893 #ifdef CONFIG_P2P
    894 	if (req_ies) {
    895 		p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
    896 				      req_ies, req_ies_len);
    897 	}
    898 #endif /* CONFIG_P2P */
    899 
    900 	return 0;
    901 
    902 fail:
    903 #ifdef CONFIG_IEEE80211R_AP
    904 	if (status >= 0)
    905 		hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
    906 #endif /* CONFIG_IEEE80211R_AP */
    907 	hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
    908 	ap_free_sta(hapd, sta);
    909 	return -1;
    910 }
    911 
    912 
    913 static void hostapd_remove_sta(struct hostapd_data *hapd, struct sta_info *sta)
    914 {
    915 	ap_sta_set_authorized(hapd, sta, 0);
    916 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
    917 	hostapd_set_sta_flags(hapd, sta);
    918 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
    919 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
    920 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    921 	ap_free_sta(hapd, sta);
    922 }
    923 
    924 
    925 #ifdef CONFIG_IEEE80211BE
    926 static void hostapd_notif_disassoc_mld(struct hostapd_data *assoc_hapd,
    927 				       struct sta_info *sta,
    928 				       const u8 *addr)
    929 {
    930 	unsigned int link_id, i;
    931 	struct hostapd_data *tmp_hapd;
    932 	struct hapd_interfaces *interfaces = assoc_hapd->iface->interfaces;
    933 
    934 	/* Remove STA entry in non-assoc links */
    935 	for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
    936 		if (!sta->mld_info.links[link_id].valid)
    937 			continue;
    938 
    939 		for (i = 0; i < interfaces->count; i++) {
    940 			struct sta_info *tmp_sta;
    941 
    942 			tmp_hapd = interfaces->iface[i]->bss[0];
    943 
    944 			if (!tmp_hapd->conf->mld_ap ||
    945 			    assoc_hapd == tmp_hapd ||
    946 			    assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
    947 				continue;
    948 
    949 			tmp_sta = ap_get_sta(tmp_hapd, addr);
    950 			if (tmp_sta)
    951 				ap_free_sta(tmp_hapd, tmp_sta);
    952 		}
    953 	}
    954 
    955 	/* Remove STA in assoc link */
    956 	hostapd_remove_sta(assoc_hapd, sta);
    957 }
    958 #endif /* CONFIG_IEEE80211BE */
    959 
    960 
    961 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
    962 {
    963 	struct sta_info *sta;
    964 
    965 	if (addr == NULL) {
    966 		/*
    967 		 * This could potentially happen with unexpected event from the
    968 		 * driver wrapper. This was seen at least in one case where the
    969 		 * driver ended up reporting a station mode event while hostapd
    970 		 * was running, so better make sure we stop processing such an
    971 		 * event here.
    972 		 */
    973 		wpa_printf(MSG_DEBUG,
    974 			   "hostapd_notif_disassoc: Skip event with no address");
    975 		return;
    976 	}
    977 
    978 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
    979 		       HOSTAPD_LEVEL_INFO, "disassociated");
    980 
    981 	sta = ap_get_sta(hapd, addr);
    982 #ifdef CONFIG_IEEE80211BE
    983 	if (hostapd_is_mld_ap(hapd)) {
    984 		struct hostapd_data *assoc_hapd;
    985 		unsigned int i;
    986 
    987 		if (!sta) {
    988 			/* Find non-MLO cases from any of the affiliated AP
    989 			 * links. */
    990 			for (i = 0; i < hapd->iface->interfaces->count; ++i) {
    991 				struct hostapd_iface *h =
    992 					hapd->iface->interfaces->iface[i];
    993 				struct hostapd_data *h_hapd = h->bss[0];
    994 				struct hostapd_bss_config *hconf = h_hapd->conf;
    995 
    996 				if (!hconf->mld_ap ||
    997 				    hconf->mld_id != hapd->conf->mld_id)
    998 					continue;
    999 
   1000 				sta = ap_get_sta(h_hapd, addr);
   1001 				if (sta) {
   1002 					if (!sta->mld_info.mld_sta) {
   1003 						hapd = h_hapd;
   1004 						goto legacy;
   1005 					}
   1006 					break;
   1007 				}
   1008 			}
   1009 		} else if (!sta->mld_info.mld_sta) {
   1010 			goto legacy;
   1011 		}
   1012 		if (!sta) {
   1013 			wpa_printf(MSG_DEBUG,
   1014 			   "Disassociation notification for unknown STA "
   1015 			   MACSTR, MAC2STR(addr));
   1016 			return;
   1017 		}
   1018 		sta = hostapd_ml_get_assoc_sta(hapd, sta, &assoc_hapd);
   1019 		if (sta)
   1020 			hostapd_notif_disassoc_mld(assoc_hapd, sta, addr);
   1021 		return;
   1022 	}
   1023 
   1024 legacy:
   1025 #endif /* CONFIG_IEEE80211BE */
   1026 	if (sta == NULL) {
   1027 		wpa_printf(MSG_DEBUG,
   1028 			   "Disassociation notification for unknown STA "
   1029 			   MACSTR, MAC2STR(addr));
   1030 		return;
   1031 	}
   1032 
   1033 	hostapd_remove_sta(hapd, sta);
   1034 }
   1035 
   1036 
   1037 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
   1038 {
   1039 	struct sta_info *sta = ap_get_sta(hapd, addr);
   1040 
   1041 	if (!sta || !hapd->conf->disassoc_low_ack || sta->agreed_to_steer)
   1042 		return;
   1043 
   1044 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
   1045 		       HOSTAPD_LEVEL_INFO,
   1046 		       "disconnected due to excessive missing ACKs");
   1047 	hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
   1048 	ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
   1049 }
   1050 
   1051 
   1052 void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
   1053 				      enum smps_mode smps_mode,
   1054 				      enum chan_width chan_width, u8 rx_nss)
   1055 {
   1056 	struct sta_info *sta = ap_get_sta(hapd, addr);
   1057 	const char *txt;
   1058 
   1059 	if (!sta)
   1060 		return;
   1061 
   1062 	switch (smps_mode) {
   1063 	case SMPS_AUTOMATIC:
   1064 		txt = "automatic";
   1065 		break;
   1066 	case SMPS_OFF:
   1067 		txt = "off";
   1068 		break;
   1069 	case SMPS_DYNAMIC:
   1070 		txt = "dynamic";
   1071 		break;
   1072 	case SMPS_STATIC:
   1073 		txt = "static";
   1074 		break;
   1075 	default:
   1076 		txt = NULL;
   1077 		break;
   1078 	}
   1079 	if (txt) {
   1080 		wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_SMPS_MODE_CHANGED
   1081 			MACSTR " %s", MAC2STR(addr), txt);
   1082 	}
   1083 
   1084 	switch (chan_width) {
   1085 	case CHAN_WIDTH_20_NOHT:
   1086 		txt = "20(no-HT)";
   1087 		break;
   1088 	case CHAN_WIDTH_20:
   1089 		txt = "20";
   1090 		break;
   1091 	case CHAN_WIDTH_40:
   1092 		txt = "40";
   1093 		break;
   1094 	case CHAN_WIDTH_80:
   1095 		txt = "80";
   1096 		break;
   1097 	case CHAN_WIDTH_80P80:
   1098 		txt = "80+80";
   1099 		break;
   1100 	case CHAN_WIDTH_160:
   1101 		txt = "160";
   1102 		break;
   1103 	case CHAN_WIDTH_320:
   1104 		txt = "320";
   1105 		break;
   1106 	default:
   1107 		txt = NULL;
   1108 		break;
   1109 	}
   1110 	if (txt) {
   1111 		wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_MAX_BW_CHANGED
   1112 			MACSTR " %s", MAC2STR(addr), txt);
   1113 	}
   1114 
   1115 	if (rx_nss != 0xff) {
   1116 		wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_N_SS_CHANGED
   1117 			MACSTR " %d", MAC2STR(addr), rx_nss);
   1118 	}
   1119 }
   1120 
   1121 
   1122 void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
   1123 			     int offset, int width, int cf1, int cf2,
   1124 			     u16 punct_bitmap, int finished)
   1125 {
   1126 #ifdef NEED_AP_MLME
   1127 	int channel, chwidth, is_dfs0, is_dfs;
   1128 	u8 seg0_idx = 0, seg1_idx = 0, op_class, chan_no;
   1129 	size_t i;
   1130 
   1131 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
   1132 		       HOSTAPD_LEVEL_INFO,
   1133 		       "driver %s channel switch: iface->freq=%d, freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d, puncturing_bitmap=0x%x",
   1134 		       finished ? "had" : "starting",
   1135 		       hapd->iface->freq,
   1136 		       freq, ht, hapd->iconf->ch_switch_vht_config,
   1137 		       hapd->iconf->ch_switch_he_config,
   1138 		       hapd->iconf->ch_switch_eht_config, offset,
   1139 		       width, channel_width_to_string(width), cf1, cf2,
   1140 		       punct_bitmap);
   1141 
   1142 	if (!hapd->iface->current_mode) {
   1143 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
   1144 			       HOSTAPD_LEVEL_WARNING,
   1145 			       "ignore channel switch since the interface is not yet ready");
   1146 		return;
   1147 	}
   1148 
   1149 	/* Check if any of configured channels require DFS */
   1150 	is_dfs0 = hostapd_is_dfs_required(hapd->iface);
   1151 	hapd->iface->freq = freq;
   1152 
   1153 	channel = hostapd_hw_get_channel(hapd, freq);
   1154 	if (!channel) {
   1155 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
   1156 			       HOSTAPD_LEVEL_WARNING,
   1157 			       "driver switched to bad channel!");
   1158 		return;
   1159 	}
   1160 
   1161 	switch (width) {
   1162 	case CHAN_WIDTH_80:
   1163 		chwidth = CONF_OPER_CHWIDTH_80MHZ;
   1164 		break;
   1165 	case CHAN_WIDTH_80P80:
   1166 		chwidth = CONF_OPER_CHWIDTH_80P80MHZ;
   1167 		break;
   1168 	case CHAN_WIDTH_160:
   1169 		chwidth = CONF_OPER_CHWIDTH_160MHZ;
   1170 		break;
   1171 	case CHAN_WIDTH_320:
   1172 		chwidth = CONF_OPER_CHWIDTH_320MHZ;
   1173 		break;
   1174 	case CHAN_WIDTH_20_NOHT:
   1175 	case CHAN_WIDTH_20:
   1176 	case CHAN_WIDTH_40:
   1177 	default:
   1178 		chwidth = CONF_OPER_CHWIDTH_USE_HT;
   1179 		break;
   1180 	}
   1181 
   1182 	/* The operating channel changed when CSA finished, so need to update
   1183 	 * hw_mode for all following operations to cover the cases where the
   1184 	 * driver changed the operating band. */
   1185 	if (finished && hostapd_csa_update_hwmode(hapd->iface))
   1186 		return;
   1187 
   1188 	switch (hapd->iface->current_mode->mode) {
   1189 	case HOSTAPD_MODE_IEEE80211A:
   1190 		if (cf1 == 5935)
   1191 			seg0_idx = (cf1 - 5925) / 5;
   1192 		else if (cf1 > 5950)
   1193 			seg0_idx = (cf1 - 5950) / 5;
   1194 		else if (cf1 > 5000)
   1195 			seg0_idx = (cf1 - 5000) / 5;
   1196 
   1197 		if (cf2 == 5935)
   1198 			seg1_idx = (cf2 - 5925) / 5;
   1199 		else if (cf2 > 5950)
   1200 			seg1_idx = (cf2 - 5950) / 5;
   1201 		else if (cf2 > 5000)
   1202 			seg1_idx = (cf2 - 5000) / 5;
   1203 		break;
   1204 	default:
   1205 		ieee80211_freq_to_chan(cf1, &seg0_idx);
   1206 		ieee80211_freq_to_chan(cf2, &seg1_idx);
   1207 		break;
   1208 	}
   1209 
   1210 	hapd->iconf->channel = channel;
   1211 	hapd->iconf->ieee80211n = ht;
   1212 	if (!ht)
   1213 		hapd->iconf->ieee80211ac = 0;
   1214 	if (hapd->iconf->ch_switch_vht_config) {
   1215 		/* CHAN_SWITCH VHT config */
   1216 		if (hapd->iconf->ch_switch_vht_config &
   1217 		    CH_SWITCH_VHT_ENABLED)
   1218 			hapd->iconf->ieee80211ac = 1;
   1219 		else if (hapd->iconf->ch_switch_vht_config &
   1220 			 CH_SWITCH_VHT_DISABLED)
   1221 			hapd->iconf->ieee80211ac = 0;
   1222 	}
   1223 	if (hapd->iconf->ch_switch_he_config) {
   1224 		/* CHAN_SWITCH HE config */
   1225 		if (hapd->iconf->ch_switch_he_config &
   1226 		    CH_SWITCH_HE_ENABLED) {
   1227 			hapd->iconf->ieee80211ax = 1;
   1228 			if (hapd->iface->freq > 4000 &&
   1229 			    hapd->iface->freq < 5895)
   1230 				hapd->iconf->ieee80211ac = 1;
   1231 		}
   1232 		else if (hapd->iconf->ch_switch_he_config &
   1233 			 CH_SWITCH_HE_DISABLED)
   1234 			hapd->iconf->ieee80211ax = 0;
   1235 	}
   1236 #ifdef CONFIG_IEEE80211BE
   1237 	if (hapd->iconf->ch_switch_eht_config) {
   1238 		/* CHAN_SWITCH EHT config */
   1239 		if (hapd->iconf->ch_switch_eht_config &
   1240 		    CH_SWITCH_EHT_ENABLED) {
   1241 			hapd->iconf->ieee80211be = 1;
   1242 			hapd->iconf->ieee80211ax = 1;
   1243 			if (!is_6ghz_freq(hapd->iface->freq) &&
   1244 			    hapd->iface->freq > 4000)
   1245 				hapd->iconf->ieee80211ac = 1;
   1246 		} else if (hapd->iconf->ch_switch_eht_config &
   1247 			   CH_SWITCH_EHT_DISABLED)
   1248 			hapd->iconf->ieee80211be = 0;
   1249 	}
   1250 #endif /* CONFIG_IEEE80211BE */
   1251 	hapd->iconf->ch_switch_vht_config = 0;
   1252 	hapd->iconf->ch_switch_he_config = 0;
   1253 	hapd->iconf->ch_switch_eht_config = 0;
   1254 
   1255 	if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 ||
   1256 	    width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160 ||
   1257 	    width == CHAN_WIDTH_320)
   1258 		hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
   1259 	else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT)
   1260 		hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
   1261 
   1262 	hapd->iconf->secondary_channel = offset;
   1263 	if (ieee80211_freq_to_channel_ext(freq, offset, chwidth,
   1264 					  &op_class, &chan_no) !=
   1265 	    NUM_HOSTAPD_MODES)
   1266 		hapd->iconf->op_class = op_class;
   1267 	hostapd_set_oper_chwidth(hapd->iconf, chwidth);
   1268 	hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
   1269 	hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
   1270 	/* Auto-detect new bw320_offset */
   1271 	hostapd_set_and_check_bw320_offset(hapd->iconf, 0);
   1272 #ifdef CONFIG_IEEE80211BE
   1273 	hapd->iconf->punct_bitmap = punct_bitmap;
   1274 #endif /* CONFIG_IEEE80211BE */
   1275 	if (hapd->iconf->ieee80211ac) {
   1276 		hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK;
   1277 		if (chwidth == CONF_OPER_CHWIDTH_160MHZ)
   1278 			hapd->iconf->vht_capab |=
   1279 				VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
   1280 		else if (chwidth == CONF_OPER_CHWIDTH_80P80MHZ)
   1281 			hapd->iconf->vht_capab |=
   1282 				VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
   1283 	}
   1284 
   1285 	is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
   1286 				  hapd->iface->num_hw_features);
   1287 
   1288 	wpa_msg(hapd->msg_ctx, MSG_INFO,
   1289 		"%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d is_dfs0=%d dfs=%d puncturing_bitmap=0x%04x",
   1290 		finished ? WPA_EVENT_CHANNEL_SWITCH :
   1291 		WPA_EVENT_CHANNEL_SWITCH_STARTED,
   1292 		freq, ht, offset, channel_width_to_string(width),
   1293 		cf1, cf2, is_dfs0, is_dfs, punct_bitmap);
   1294 	if (!finished)
   1295 		return;
   1296 
   1297 	if (hapd->csa_in_progress &&
   1298 	    freq == hapd->cs_freq_params.freq) {
   1299 		hostapd_cleanup_cs_params(hapd);
   1300 		ieee802_11_set_beacon(hapd);
   1301 
   1302 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
   1303 			"freq=%d dfs=%d", freq, is_dfs);
   1304 	} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
   1305 		/* Complete AP configuration for the first bring up. */
   1306 		if (is_dfs0 > 0 &&
   1307 		    hostapd_is_dfs_required(hapd->iface) <= 0 &&
   1308 		    hapd->iface->state != HAPD_IFACE_ENABLED) {
   1309 			/* Fake a CAC start bit to skip setting channel */
   1310 			hapd->iface->cac_started = 1;
   1311 			hostapd_setup_interface_complete(hapd->iface, 0);
   1312 		}
   1313 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
   1314 			"freq=%d dfs=%d", freq, is_dfs);
   1315 	} else if (is_dfs &&
   1316 		   hostapd_is_dfs_required(hapd->iface) &&
   1317 		   !hostapd_is_dfs_chan_available(hapd->iface) &&
   1318 		   !hapd->iface->cac_started) {
   1319 		hostapd_disable_iface(hapd->iface);
   1320 		hostapd_enable_iface(hapd->iface);
   1321 	}
   1322 
   1323 	for (i = 0; i < hapd->iface->num_bss; i++)
   1324 		hostapd_neighbor_set_own_report(hapd->iface->bss[i]);
   1325 
   1326 #ifdef CONFIG_OCV
   1327 	if (hapd->conf->ocv &&
   1328 	    !(hapd->iface->drv_flags2 &
   1329 	      WPA_DRIVER_FLAGS2_SA_QUERY_OFFLOAD_AP)) {
   1330 		struct sta_info *sta;
   1331 		bool check_sa_query = false;
   1332 
   1333 		for (sta = hapd->sta_list; sta; sta = sta->next) {
   1334 			if (wpa_auth_uses_ocv(sta->wpa_sm) &&
   1335 			    !(sta->flags & WLAN_STA_WNM_SLEEP_MODE)) {
   1336 				sta->post_csa_sa_query = 1;
   1337 				check_sa_query = true;
   1338 			}
   1339 		}
   1340 
   1341 		if (check_sa_query) {
   1342 			wpa_printf(MSG_DEBUG,
   1343 				   "OCV: Check post-CSA SA Query initiation in 15 seconds");
   1344 			eloop_register_timeout(15, 0,
   1345 					       hostapd_ocv_check_csa_sa_query,
   1346 					       hapd, NULL);
   1347 		}
   1348 	}
   1349 #endif /* CONFIG_OCV */
   1350 #endif /* NEED_AP_MLME */
   1351 }
   1352 
   1353 
   1354 void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
   1355 					 const u8 *addr, int reason_code)
   1356 {
   1357 	switch (reason_code) {
   1358 	case MAX_CLIENT_REACHED:
   1359 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
   1360 			MAC2STR(addr));
   1361 		break;
   1362 	case BLOCKED_CLIENT:
   1363 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
   1364 			MAC2STR(addr));
   1365 		break;
   1366 	}
   1367 }
   1368 
   1369 
   1370 #ifdef CONFIG_ACS
   1371 void hostapd_acs_channel_selected(struct hostapd_data *hapd,
   1372 				  struct acs_selected_channels *acs_res)
   1373 {
   1374 	int ret, i;
   1375 	int err = 0;
   1376 	struct hostapd_channel_data *pri_chan;
   1377 
   1378 #ifdef CONFIG_IEEE80211BE
   1379 	if (acs_res->link_id != -1) {
   1380 		hapd = hostapd_mld_get_link_bss(hapd, acs_res->link_id);
   1381 		if (!hapd) {
   1382 			wpa_printf(MSG_ERROR,
   1383 				   "MLD: Failed to get link BSS for EVENT_ACS_CHANNEL_SELECTED link_id=%d",
   1384 				   acs_res->link_id);
   1385 			return;
   1386 		}
   1387 	}
   1388 #endif /* CONFIG_IEEE80211BE */
   1389 
   1390 	if (hapd->iconf->channel) {
   1391 		wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
   1392 			   hapd->iconf->channel);
   1393 		return;
   1394 	}
   1395 
   1396 	hapd->iface->freq = acs_res->pri_freq;
   1397 
   1398 	if (!hapd->iface->current_mode) {
   1399 		for (i = 0; i < hapd->iface->num_hw_features; i++) {
   1400 			struct hostapd_hw_modes *mode =
   1401 				&hapd->iface->hw_features[i];
   1402 
   1403 			if (mode->mode == acs_res->hw_mode) {
   1404 				if (hapd->iface->freq > 0 &&
   1405 				    !hw_get_chan(mode->mode,
   1406 						 hapd->iface->freq,
   1407 						 hapd->iface->hw_features,
   1408 						 hapd->iface->num_hw_features))
   1409 					continue;
   1410 				hapd->iface->current_mode = mode;
   1411 				break;
   1412 			}
   1413 		}
   1414 		if (!hapd->iface->current_mode) {
   1415 			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
   1416 				       HOSTAPD_LEVEL_WARNING,
   1417 				       "driver selected to bad hw_mode");
   1418 			err = 1;
   1419 			goto out;
   1420 		}
   1421 	}
   1422 
   1423 	if (!acs_res->pri_freq) {
   1424 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
   1425 			       HOSTAPD_LEVEL_WARNING,
   1426 			       "driver switched to bad channel");
   1427 		err = 1;
   1428 		goto out;
   1429 	}
   1430 	pri_chan = hw_get_channel_freq(hapd->iface->current_mode->mode,
   1431 				       acs_res->pri_freq, NULL,
   1432 				       hapd->iface->hw_features,
   1433 				       hapd->iface->num_hw_features);
   1434 	if (!pri_chan) {
   1435 		wpa_printf(MSG_ERROR,
   1436 			   "ACS: Could not determine primary channel number from pri_freq %u",
   1437 			   acs_res->pri_freq);
   1438 		err = 1;
   1439 		goto out;
   1440 	}
   1441 
   1442 	hapd->iconf->channel = pri_chan->chan;
   1443 	hapd->iconf->acs = 1;
   1444 
   1445 	if (acs_res->sec_freq == 0)
   1446 		hapd->iconf->secondary_channel = 0;
   1447 	else if (acs_res->sec_freq < acs_res->pri_freq)
   1448 		hapd->iconf->secondary_channel = -1;
   1449 	else if (acs_res->sec_freq > acs_res->pri_freq)
   1450 		hapd->iconf->secondary_channel = 1;
   1451 	else {
   1452 		wpa_printf(MSG_ERROR, "Invalid secondary channel!");
   1453 		err = 1;
   1454 		goto out;
   1455 	}
   1456 
   1457 	hapd->iconf->edmg_channel = acs_res->edmg_channel;
   1458 
   1459 	if (hapd->iface->conf->ieee80211ac || hapd->iface->conf->ieee80211ax) {
   1460 		/* set defaults for backwards compatibility */
   1461 		hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
   1462 		hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, 0);
   1463 		hostapd_set_oper_chwidth(hapd->iconf, CONF_OPER_CHWIDTH_USE_HT);
   1464 		if (acs_res->ch_width == 40) {
   1465 			if (is_6ghz_freq(acs_res->pri_freq))
   1466 				hostapd_set_oper_centr_freq_seg0_idx(
   1467 					hapd->iconf,
   1468 					acs_res->vht_seg0_center_ch);
   1469 		} else if (acs_res->ch_width == 80) {
   1470 			hostapd_set_oper_centr_freq_seg0_idx(
   1471 				hapd->iconf, acs_res->vht_seg0_center_ch);
   1472 			if (acs_res->vht_seg1_center_ch == 0) {
   1473 				hostapd_set_oper_chwidth(
   1474 					hapd->iconf, CONF_OPER_CHWIDTH_80MHZ);
   1475 			} else {
   1476 				hostapd_set_oper_chwidth(
   1477 					hapd->iconf,
   1478 					CONF_OPER_CHWIDTH_80P80MHZ);
   1479 				hostapd_set_oper_centr_freq_seg1_idx(
   1480 					hapd->iconf,
   1481 					acs_res->vht_seg1_center_ch);
   1482 			}
   1483 		} else if (acs_res->ch_width == 160) {
   1484 			hostapd_set_oper_chwidth(hapd->iconf,
   1485 						 CONF_OPER_CHWIDTH_160MHZ);
   1486 			hostapd_set_oper_centr_freq_seg0_idx(
   1487 				hapd->iconf, acs_res->vht_seg1_center_ch);
   1488 		}
   1489 	}
   1490 
   1491 #ifdef CONFIG_IEEE80211BE
   1492 	if (hapd->iface->conf->ieee80211be && acs_res->ch_width == 320) {
   1493 		hostapd_set_oper_chwidth(hapd->iconf, CONF_OPER_CHWIDTH_320MHZ);
   1494 		hostapd_set_oper_centr_freq_seg0_idx(
   1495 			hapd->iconf, acs_res->vht_seg1_center_ch);
   1496 		hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
   1497 	}
   1498 
   1499 	if (hapd->iface->conf->ieee80211be && acs_res->puncture_bitmap)
   1500 		hapd->iconf->punct_bitmap = acs_res->puncture_bitmap;
   1501 #endif /* CONFIG_IEEE80211BE */
   1502 
   1503 out:
   1504 	ret = hostapd_acs_completed(hapd->iface, err);
   1505 	if (ret) {
   1506 		wpa_printf(MSG_ERROR,
   1507 			   "ACS: Possibly channel configuration is invalid");
   1508 	}
   1509 }
   1510 #endif /* CONFIG_ACS */
   1511 
   1512 
   1513 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
   1514 			 const u8 *bssid, const u8 *ie, size_t ie_len,
   1515 			 int ssi_signal)
   1516 {
   1517 	size_t i;
   1518 	int ret = 0;
   1519 
   1520 	if (sa == NULL || ie == NULL)
   1521 		return -1;
   1522 
   1523 	random_add_randomness(sa, ETH_ALEN);
   1524 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
   1525 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
   1526 					    sa, da, bssid, ie, ie_len,
   1527 					    ssi_signal) > 0) {
   1528 			ret = 1;
   1529 			break;
   1530 		}
   1531 	}
   1532 	return ret;
   1533 }
   1534 
   1535 
   1536 #ifdef HOSTAPD
   1537 
   1538 #ifdef CONFIG_IEEE80211R_AP
   1539 static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
   1540 					  u16 auth_transaction, u16 status,
   1541 					  const u8 *ies, size_t ies_len)
   1542 {
   1543 	struct hostapd_data *hapd = ctx;
   1544 	struct sta_info *sta;
   1545 
   1546 	sta = ap_get_sta(hapd, dst);
   1547 	if (sta == NULL)
   1548 		return;
   1549 
   1550 	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
   1551 		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
   1552 	sta->flags |= WLAN_STA_AUTH;
   1553 
   1554 	hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len);
   1555 }
   1556 #endif /* CONFIG_IEEE80211R_AP */
   1557 
   1558 
   1559 #ifdef CONFIG_FILS
   1560 static void hostapd_notify_auth_fils_finish(struct hostapd_data *hapd,
   1561 					    struct sta_info *sta, u16 resp,
   1562 					    struct wpabuf *data, int pub)
   1563 {
   1564 	if (resp == WLAN_STATUS_SUCCESS) {
   1565 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
   1566 			       HOSTAPD_LEVEL_DEBUG, "authentication OK (FILS)");
   1567 		sta->flags |= WLAN_STA_AUTH;
   1568 		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
   1569 		sta->auth_alg = WLAN_AUTH_FILS_SK;
   1570 		mlme_authenticate_indication(hapd, sta);
   1571 	} else {
   1572 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
   1573 			       HOSTAPD_LEVEL_DEBUG,
   1574 			       "authentication failed (FILS)");
   1575 	}
   1576 
   1577 	hostapd_sta_auth(hapd, sta->addr, 2, resp,
   1578 			 data ? wpabuf_head(data) : NULL,
   1579 			 data ? wpabuf_len(data) : 0);
   1580 	wpabuf_free(data);
   1581 }
   1582 #endif /* CONFIG_FILS */
   1583 
   1584 
   1585 static void hostapd_notif_auth(struct hostapd_data *hapd,
   1586 			       struct auth_info *rx_auth)
   1587 {
   1588 	struct sta_info *sta;
   1589 	u16 status = WLAN_STATUS_SUCCESS;
   1590 	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
   1591 	size_t resp_ies_len = 0;
   1592 
   1593 	sta = ap_get_sta(hapd, rx_auth->peer);
   1594 	if (!sta) {
   1595 		sta = ap_sta_add(hapd, rx_auth->peer);
   1596 		if (sta == NULL) {
   1597 			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
   1598 			goto fail;
   1599 		}
   1600 	}
   1601 	sta->flags &= ~WLAN_STA_PREAUTH;
   1602 	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
   1603 #ifdef CONFIG_IEEE80211R_AP
   1604 	if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) {
   1605 		sta->auth_alg = WLAN_AUTH_FT;
   1606 		if (sta->wpa_sm == NULL)
   1607 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
   1608 							sta->addr, NULL);
   1609 		if (sta->wpa_sm == NULL) {
   1610 			wpa_printf(MSG_DEBUG,
   1611 				   "FT: Failed to initialize WPA state machine");
   1612 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
   1613 			goto fail;
   1614 		}
   1615 		wpa_ft_process_auth(sta->wpa_sm,
   1616 				    rx_auth->auth_transaction, rx_auth->ies,
   1617 				    rx_auth->ies_len,
   1618 				    hostapd_notify_auth_ft_finish, hapd);
   1619 		return;
   1620 	}
   1621 #endif /* CONFIG_IEEE80211R_AP */
   1622 
   1623 #ifdef CONFIG_FILS
   1624 	if (rx_auth->auth_type == WLAN_AUTH_FILS_SK) {
   1625 		sta->auth_alg = WLAN_AUTH_FILS_SK;
   1626 		handle_auth_fils(hapd, sta, rx_auth->ies, rx_auth->ies_len,
   1627 				 rx_auth->auth_type, rx_auth->auth_transaction,
   1628 				 rx_auth->status_code,
   1629 				 hostapd_notify_auth_fils_finish);
   1630 		return;
   1631 	}
   1632 #endif /* CONFIG_FILS */
   1633 
   1634 fail:
   1635 	hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
   1636 			 status, resp_ies, resp_ies_len);
   1637 }
   1638 
   1639 
   1640 #ifndef NEED_AP_MLME
   1641 static void hostapd_action_rx(struct hostapd_data *hapd,
   1642 			      struct rx_mgmt *drv_mgmt)
   1643 {
   1644 	struct ieee80211_mgmt *mgmt;
   1645 	struct sta_info *sta;
   1646 	size_t plen __maybe_unused;
   1647 	u16 fc;
   1648 	u8 *action __maybe_unused;
   1649 
   1650 	if (drv_mgmt->frame_len < IEEE80211_HDRLEN + 2 + 1)
   1651 		return;
   1652 
   1653 	plen = drv_mgmt->frame_len - IEEE80211_HDRLEN;
   1654 
   1655 	mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
   1656 	fc = le_to_host16(mgmt->frame_control);
   1657 	if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
   1658 		return; /* handled by the driver */
   1659 
   1660 	action = (u8 *) &mgmt->u.action.u;
   1661 	wpa_printf(MSG_DEBUG, "RX_ACTION category %u action %u sa " MACSTR
   1662 		   " da " MACSTR " plen %d",
   1663 		   mgmt->u.action.category, *action,
   1664 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), (int) plen);
   1665 
   1666 	sta = ap_get_sta(hapd, mgmt->sa);
   1667 	if (sta == NULL) {
   1668 		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
   1669 		return;
   1670 	}
   1671 #ifdef CONFIG_IEEE80211R_AP
   1672 	if (mgmt->u.action.category == WLAN_ACTION_FT) {
   1673 		wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, plen);
   1674 		return;
   1675 	}
   1676 #endif /* CONFIG_IEEE80211R_AP */
   1677 	if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY) {
   1678 		ieee802_11_sa_query_action(hapd, mgmt, drv_mgmt->frame_len);
   1679 		return;
   1680 	}
   1681 #ifdef CONFIG_WNM_AP
   1682 	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
   1683 		ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
   1684 		return;
   1685 	}
   1686 #endif /* CONFIG_WNM_AP */
   1687 #ifdef CONFIG_FST
   1688 	if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
   1689 		fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
   1690 		return;
   1691 	}
   1692 #endif /* CONFIG_FST */
   1693 #ifdef CONFIG_DPP
   1694 	if (plen >= 2 + 4 &&
   1695 	    mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
   1696 	    mgmt->u.action.u.vs_public_action.action ==
   1697 	    WLAN_PA_VENDOR_SPECIFIC &&
   1698 	    WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
   1699 	    OUI_WFA &&
   1700 	    mgmt->u.action.u.vs_public_action.variable[0] ==
   1701 	    DPP_OUI_TYPE) {
   1702 		const u8 *pos, *end;
   1703 
   1704 		pos = mgmt->u.action.u.vs_public_action.oui;
   1705 		end = drv_mgmt->frame + drv_mgmt->frame_len;
   1706 		hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
   1707 				      drv_mgmt->freq);
   1708 		return;
   1709 	}
   1710 #endif /* CONFIG_DPP */
   1711 #ifdef CONFIG_NAN_USD
   1712 	if (mgmt->u.action.category == WLAN_ACTION_PUBLIC && plen >= 5 &&
   1713 	    mgmt->u.action.u.vs_public_action.action ==
   1714 	    WLAN_PA_VENDOR_SPECIFIC &&
   1715 	    WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
   1716 	    OUI_WFA &&
   1717 	    mgmt->u.action.u.vs_public_action.variable[0] == NAN_OUI_TYPE) {
   1718 		const u8 *pos, *end;
   1719 
   1720 		pos = mgmt->u.action.u.vs_public_action.variable;
   1721 		end = drv_mgmt->frame + drv_mgmt->frame_len;
   1722 		pos++;
   1723 		hostapd_nan_usd_rx_sdf(hapd, mgmt->sa, drv_mgmt->freq,
   1724 				       pos, end - pos);
   1725 		return;
   1726 	}
   1727 #endif /* CONFIG_NAN_USD */
   1728 }
   1729 #endif /* NEED_AP_MLME */
   1730 
   1731 
   1732 #ifdef NEED_AP_MLME
   1733 
   1734 static struct hostapd_data *
   1735 switch_link_hapd(struct hostapd_data *hapd, int link_id)
   1736 {
   1737 #ifdef CONFIG_IEEE80211BE
   1738 	if (hapd->conf->mld_ap && link_id >= 0) {
   1739 		struct hostapd_data *link_bss;
   1740 
   1741 		link_bss = hostapd_mld_get_link_bss(hapd, link_id);
   1742 		if (link_bss)
   1743 			return link_bss;
   1744 	}
   1745 #endif /* CONFIG_IEEE80211BE */
   1746 
   1747 	return hapd;
   1748 }
   1749 
   1750 
   1751 static struct hostapd_data *
   1752 switch_link_scan(struct hostapd_data *hapd, u64 scan_cookie)
   1753 {
   1754 #ifdef CONFIG_IEEE80211BE
   1755 	if (hapd->conf->mld_ap && scan_cookie != 0) {
   1756 		unsigned int i;
   1757 
   1758 		for (i = 0; i < hapd->iface->interfaces->count; i++) {
   1759 			struct hostapd_iface *h;
   1760 			struct hostapd_data *h_hapd;
   1761 
   1762 			h = hapd->iface->interfaces->iface[i];
   1763 			h_hapd = h->bss[0];
   1764 			if (!hostapd_is_ml_partner(hapd, h_hapd))
   1765 				continue;
   1766 
   1767 			if (h_hapd->scan_cookie == scan_cookie) {
   1768 				h_hapd->scan_cookie = 0;
   1769 				return h_hapd;
   1770 			}
   1771 		}
   1772 	}
   1773 #endif /* CONFIG_IEEE80211BE */
   1774 
   1775 	return hapd;
   1776 }
   1777 
   1778 
   1779 #define HAPD_BROADCAST ((struct hostapd_data *) -1)
   1780 
   1781 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
   1782 					    const u8 *bssid, int link_id)
   1783 {
   1784 	size_t i;
   1785 
   1786 	if (bssid == NULL)
   1787 		return NULL;
   1788 	if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
   1789 	    bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
   1790 		return HAPD_BROADCAST;
   1791 
   1792 	for (i = 0; i < iface->num_bss; i++) {
   1793 		struct hostapd_data *hapd;
   1794 #ifdef CONFIG_IEEE80211BE
   1795 		struct hostapd_data *p_hapd;
   1796 #endif /* CONFIG_IEEE80211BE */
   1797 
   1798 		hapd = iface->bss[i];
   1799 		if (ether_addr_equal(bssid, hapd->own_addr))
   1800 			return hapd;
   1801 
   1802 #ifdef CONFIG_IEEE80211BE
   1803 		if (ether_addr_equal(bssid, hapd->own_addr) ||
   1804 		    (hapd->conf->mld_ap &&
   1805 		     ether_addr_equal(bssid, hapd->mld->mld_addr) &&
   1806 		     link_id == hapd->mld_link_id))
   1807 			return hapd;
   1808 
   1809 		if (!hapd->conf->mld_ap)
   1810 			continue;
   1811 
   1812 		for_each_mld_link(p_hapd, hapd) {
   1813 			if (p_hapd == hapd)
   1814 				continue;
   1815 
   1816 			if (ether_addr_equal(bssid, p_hapd->own_addr) ||
   1817 			    (ether_addr_equal(bssid, p_hapd->mld->mld_addr) &&
   1818 			     link_id == p_hapd->mld_link_id))
   1819 				return p_hapd;
   1820 		}
   1821 #endif /* CONFIG_IEEE80211BE */
   1822 	}
   1823 
   1824 	return NULL;
   1825 }
   1826 
   1827 
   1828 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
   1829 					const u8 *bssid, const u8 *addr,
   1830 					int wds)
   1831 {
   1832 	hapd = get_hapd_bssid(hapd->iface, bssid, -1);
   1833 	if (hapd == NULL || hapd == HAPD_BROADCAST)
   1834 		return;
   1835 
   1836 	ieee802_11_rx_from_unknown(hapd, addr, wds);
   1837 }
   1838 
   1839 
   1840 static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
   1841 {
   1842 	struct hostapd_iface *iface;
   1843 	const struct ieee80211_hdr *hdr;
   1844 	const u8 *bssid;
   1845 	struct hostapd_frame_info fi;
   1846 	int ret;
   1847 
   1848 	if (rx_mgmt->ctx)
   1849 		hapd = rx_mgmt->ctx;
   1850 	hapd = switch_link_hapd(hapd, rx_mgmt->link_id);
   1851 	iface = hapd->iface;
   1852 
   1853 #ifdef CONFIG_TESTING_OPTIONS
   1854 	if (hapd->ext_mgmt_frame_handling) {
   1855 		size_t hex_len = 2 * rx_mgmt->frame_len + 1;
   1856 		char *hex = os_malloc(hex_len);
   1857 
   1858 		if (hex) {
   1859 			wpa_snprintf_hex(hex, hex_len, rx_mgmt->frame,
   1860 					 rx_mgmt->frame_len);
   1861 			wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
   1862 			os_free(hex);
   1863 		}
   1864 		return 1;
   1865 	}
   1866 #endif /* CONFIG_TESTING_OPTIONS */
   1867 
   1868 	hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
   1869 	bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
   1870 	if (bssid == NULL)
   1871 		return 0;
   1872 
   1873 	hapd = get_hapd_bssid(iface, bssid, rx_mgmt->link_id);
   1874 
   1875 	if (!hapd) {
   1876 		u16 fc = le_to_host16(hdr->frame_control);
   1877 
   1878 		/*
   1879 		 * Drop frames to unknown BSSIDs except for Beacon frames which
   1880 		 * could be used to update neighbor information.
   1881 		 */
   1882 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
   1883 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
   1884 			hapd = iface->bss[0];
   1885 		else
   1886 			return 0;
   1887 	}
   1888 
   1889 	os_memset(&fi, 0, sizeof(fi));
   1890 	fi.freq = rx_mgmt->freq;
   1891 	fi.datarate = rx_mgmt->datarate;
   1892 	fi.ssi_signal = rx_mgmt->ssi_signal;
   1893 
   1894 	if (hapd == HAPD_BROADCAST) {
   1895 		size_t i;
   1896 
   1897 		ret = 0;
   1898 		for (i = 0; i < iface->num_bss; i++) {
   1899 			/* if bss is set, driver will call this function for
   1900 			 * each bss individually. */
   1901 			if (rx_mgmt->drv_priv &&
   1902 			    (iface->bss[i]->drv_priv != rx_mgmt->drv_priv))
   1903 				continue;
   1904 
   1905 			if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
   1906 					    rx_mgmt->frame_len, &fi) > 0)
   1907 				ret = 1;
   1908 		}
   1909 	} else
   1910 		ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len,
   1911 				      &fi);
   1912 
   1913 	random_add_randomness(&fi, sizeof(fi));
   1914 
   1915 	return ret;
   1916 }
   1917 
   1918 
   1919 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
   1920 			       size_t len, u16 stype, int ok, int link_id)
   1921 {
   1922 	struct ieee80211_hdr *hdr;
   1923 	struct hostapd_data *orig_hapd, *tmp_hapd;
   1924 
   1925 	orig_hapd = hapd;
   1926 
   1927 	hdr = (struct ieee80211_hdr *) buf;
   1928 	hapd = switch_link_hapd(hapd, link_id);
   1929 	tmp_hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len), link_id);
   1930 	if (tmp_hapd) {
   1931 		hapd = tmp_hapd;
   1932 #ifdef CONFIG_IEEE80211BE
   1933 	} else if (hapd->conf->mld_ap &&
   1934 		   ether_addr_equal(hapd->mld->mld_addr,
   1935 				    get_hdr_bssid(hdr, len))) {
   1936 		/* AP MLD address match - use hapd pointer as-is */
   1937 #endif /* CONFIG_IEEE80211BE */
   1938 	} else {
   1939 		return;
   1940 	}
   1941 
   1942 	if (hapd == HAPD_BROADCAST) {
   1943 		if (stype != WLAN_FC_STYPE_ACTION || len <= 25 ||
   1944 		    buf[24] != WLAN_ACTION_PUBLIC)
   1945 			return;
   1946 		hapd = get_hapd_bssid(orig_hapd->iface, hdr->addr2, link_id);
   1947 		if (!hapd || hapd == HAPD_BROADCAST)
   1948 			return;
   1949 		/*
   1950 		 * Allow processing of TX status for a Public Action frame that
   1951 		 * used wildcard BBSID.
   1952 		 */
   1953 	}
   1954 	ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
   1955 }
   1956 
   1957 #endif /* NEED_AP_MLME */
   1958 
   1959 
   1960 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
   1961 {
   1962 	struct sta_info *sta = ap_get_sta(hapd, addr);
   1963 
   1964 	if (sta)
   1965 		return 0;
   1966 
   1967 	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
   1968 		   " - adding a new STA", MAC2STR(addr));
   1969 	sta = ap_sta_add(hapd, addr);
   1970 	if (sta) {
   1971 		hostapd_new_assoc_sta(hapd, sta, 0);
   1972 	} else {
   1973 		wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
   1974 			   MAC2STR(addr));
   1975 		return -1;
   1976 	}
   1977 
   1978 	return 0;
   1979 }
   1980 
   1981 
   1982 static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
   1983 						 const u8 *src, bool rsn,
   1984 						 struct sta_info **sta_ret)
   1985 {
   1986 	struct hostapd_data *hapd;
   1987 	struct sta_info *sta;
   1988 	unsigned int j;
   1989 
   1990 	if (sta_ret)
   1991 		*sta_ret = NULL;
   1992 
   1993 	for (j = 0; j < iface->num_bss; j++) {
   1994 		hapd = iface->bss[j];
   1995 		sta = ap_get_sta(hapd, src);
   1996 		if (sta && (sta->flags & WLAN_STA_ASSOC) &&
   1997 		    (!rsn || sta->wpa_sm)) {
   1998 			if (sta_ret)
   1999 				*sta_ret = sta;
   2000 			return hapd;
   2001 		}
   2002 #ifdef CONFIG_IEEE80211BE
   2003 		if (hapd->conf->mld_ap) {
   2004 			struct hostapd_data *p_hapd;
   2005 
   2006 			for_each_mld_link(p_hapd, hapd) {
   2007 				if (p_hapd == hapd)
   2008 					continue;
   2009 
   2010 				sta = ap_get_sta(p_hapd, src);
   2011 				if (sta && (sta->flags & WLAN_STA_ASSOC) &&
   2012 				    (!rsn || sta->wpa_sm)) {
   2013 					if (sta_ret)
   2014 						*sta_ret = sta;
   2015 					return p_hapd;
   2016 				}
   2017 			}
   2018 		}
   2019 #endif /* CONFIG_IEEE80211BE */
   2020 	}
   2021 
   2022 	return NULL;
   2023 }
   2024 
   2025 
   2026 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
   2027 				   const u8 *data, size_t data_len,
   2028 				   enum frame_encryption encrypted,
   2029 				   int link_id)
   2030 {
   2031 	struct hostapd_data *orig_hapd = hapd;
   2032 
   2033 #ifdef CONFIG_IEEE80211BE
   2034 	hapd = switch_link_hapd(hapd, link_id);
   2035 	hapd = hostapd_find_by_sta(hapd->iface, src, true, NULL);
   2036 #else /* CONFIG_IEEE80211BE */
   2037 	hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL);
   2038 #endif /* CONFIG_IEEE80211BE */
   2039 
   2040 	if (!hapd) {
   2041 		/* WLAN cases need to have an existing association, but non-WLAN
   2042 		 * cases (mainly, wired IEEE 802.1X) need to be able to process
   2043 		 * EAPOL frames from new devices that do not yet have a STA
   2044 		 * entry and as such, do not get a match in
   2045 		 * hostapd_find_by_sta(). */
   2046 		wpa_printf(MSG_DEBUG,
   2047 			   "No STA-specific hostapd instance for EAPOL RX found - fall back to initial context");
   2048 		hapd = orig_hapd;
   2049 	}
   2050 
   2051 	ieee802_1x_receive(hapd, src, data, data_len, encrypted);
   2052 }
   2053 
   2054 #endif /* HOSTAPD */
   2055 
   2056 
   2057 static struct hostapd_channel_data *
   2058 hostapd_get_mode_chan(struct hostapd_hw_modes *mode, unsigned int freq)
   2059 {
   2060 	int i;
   2061 	struct hostapd_channel_data *chan;
   2062 
   2063 	for (i = 0; i < mode->num_channels; i++) {
   2064 		chan = &mode->channels[i];
   2065 		if ((unsigned int) chan->freq == freq)
   2066 			return chan;
   2067 	}
   2068 
   2069 	return NULL;
   2070 }
   2071 
   2072 
   2073 static struct hostapd_channel_data * hostapd_get_mode_channel(
   2074 	struct hostapd_iface *iface, unsigned int freq)
   2075 {
   2076 	int i;
   2077 	struct hostapd_channel_data *chan;
   2078 
   2079 	for (i = 0; i < iface->num_hw_features; i++) {
   2080 		if (hostapd_hw_skip_mode(iface, &iface->hw_features[i]))
   2081 			continue;
   2082 		chan = hostapd_get_mode_chan(&iface->hw_features[i], freq);
   2083 		if (chan)
   2084 			return chan;
   2085 	}
   2086 
   2087 	return NULL;
   2088 }
   2089 
   2090 
   2091 static void hostapd_update_nf(struct hostapd_iface *iface,
   2092 			      struct hostapd_channel_data *chan,
   2093 			      struct freq_survey *survey)
   2094 {
   2095 	if (!iface->chans_surveyed) {
   2096 		chan->min_nf = survey->nf;
   2097 		iface->lowest_nf = survey->nf;
   2098 	} else {
   2099 		if (dl_list_empty(&chan->survey_list))
   2100 			chan->min_nf = survey->nf;
   2101 		else if (survey->nf < chan->min_nf)
   2102 			chan->min_nf = survey->nf;
   2103 		if (survey->nf < iface->lowest_nf)
   2104 			iface->lowest_nf = survey->nf;
   2105 	}
   2106 }
   2107 
   2108 
   2109 static void hostapd_single_channel_get_survey(struct hostapd_iface *iface,
   2110 					      struct survey_results *survey_res)
   2111 {
   2112 	struct hostapd_channel_data *chan;
   2113 	struct freq_survey *survey;
   2114 	u64 divisor, dividend;
   2115 
   2116 	survey = dl_list_first(&survey_res->survey_list, struct freq_survey,
   2117 			       list);
   2118 	if (!survey || !survey->freq)
   2119 		return;
   2120 
   2121 	chan = hostapd_get_mode_channel(iface, survey->freq);
   2122 	if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED)
   2123 		return;
   2124 
   2125 	wpa_printf(MSG_DEBUG,
   2126 		   "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)",
   2127 		   survey->freq,
   2128 		   (unsigned long int) survey->channel_time,
   2129 		   (unsigned long int) survey->channel_time_busy);
   2130 
   2131 	if (survey->channel_time > iface->last_channel_time &&
   2132 	    survey->channel_time > survey->channel_time_busy) {
   2133 		dividend = survey->channel_time_busy -
   2134 			iface->last_channel_time_busy;
   2135 		divisor = survey->channel_time - iface->last_channel_time;
   2136 
   2137 		iface->channel_utilization = dividend * 255 / divisor;
   2138 		wpa_printf(MSG_DEBUG, "Channel Utilization: %d",
   2139 			   iface->channel_utilization);
   2140 	}
   2141 	iface->last_channel_time = survey->channel_time;
   2142 	iface->last_channel_time_busy = survey->channel_time_busy;
   2143 }
   2144 
   2145 
   2146 void hostapd_event_get_survey(struct hostapd_iface *iface,
   2147 			      struct survey_results *survey_results)
   2148 {
   2149 	struct freq_survey *survey, *tmp;
   2150 	struct hostapd_channel_data *chan;
   2151 
   2152 	if (dl_list_empty(&survey_results->survey_list)) {
   2153 		wpa_printf(MSG_DEBUG, "No survey data received");
   2154 		return;
   2155 	}
   2156 
   2157 	if (survey_results->freq_filter) {
   2158 		hostapd_single_channel_get_survey(iface, survey_results);
   2159 		return;
   2160 	}
   2161 
   2162 	dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
   2163 			      struct freq_survey, list) {
   2164 		chan = hostapd_get_mode_channel(iface, survey->freq);
   2165 		if (!chan)
   2166 			continue;
   2167 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
   2168 			continue;
   2169 
   2170 		dl_list_del(&survey->list);
   2171 		dl_list_add_tail(&chan->survey_list, &survey->list);
   2172 
   2173 		hostapd_update_nf(iface, chan, survey);
   2174 
   2175 		iface->chans_surveyed++;
   2176 	}
   2177 }
   2178 
   2179 
   2180 #ifdef HOSTAPD
   2181 #ifdef NEED_AP_MLME
   2182 
   2183 static void hostapd_event_iface_unavailable(struct hostapd_data *hapd)
   2184 {
   2185 	wpa_printf(MSG_DEBUG, "Interface %s is unavailable -- stopped",
   2186 		   hapd->conf->iface);
   2187 
   2188 	if (hapd->csa_in_progress) {
   2189 		wpa_printf(MSG_INFO, "CSA failed (%s was stopped)",
   2190 			   hapd->conf->iface);
   2191 		hostapd_switch_channel_fallback(hapd->iface,
   2192 						&hapd->cs_freq_params);
   2193 	}
   2194 }
   2195 
   2196 
   2197 static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd,
   2198 					     struct dfs_event *radar)
   2199 {
   2200 	wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
   2201 	hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled,
   2202 				   radar->chan_offset, radar->chan_width,
   2203 				   radar->cf1, radar->cf2);
   2204 }
   2205 
   2206 
   2207 static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd,
   2208 					      struct dfs_event *radar)
   2209 {
   2210 	wpa_printf(MSG_DEBUG, "DFS Pre-CAC expired on %d MHz", radar->freq);
   2211 	hostapd_dfs_pre_cac_expired(hapd->iface, radar->freq, radar->ht_enabled,
   2212 				    radar->chan_offset, radar->chan_width,
   2213 				    radar->cf1, radar->cf2);
   2214 }
   2215 
   2216 
   2217 static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd,
   2218 					   struct dfs_event *radar)
   2219 {
   2220 	wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
   2221 	hostapd_dfs_complete_cac(hapd->iface, 1, radar->freq, radar->ht_enabled,
   2222 				 radar->chan_offset, radar->chan_width,
   2223 				 radar->cf1, radar->cf2);
   2224 }
   2225 
   2226 
   2227 static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd,
   2228 					  struct dfs_event *radar)
   2229 {
   2230 	wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
   2231 	hostapd_dfs_complete_cac(hapd->iface, 0, radar->freq, radar->ht_enabled,
   2232 				 radar->chan_offset, radar->chan_width,
   2233 				 radar->cf1, radar->cf2);
   2234 }
   2235 
   2236 
   2237 static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd,
   2238 					   struct dfs_event *radar)
   2239 {
   2240 	wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
   2241 	hostapd_dfs_nop_finished(hapd->iface, radar->freq, radar->ht_enabled,
   2242 				 radar->chan_offset, radar->chan_width,
   2243 				 radar->cf1, radar->cf2);
   2244 }
   2245 
   2246 
   2247 static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
   2248 					  struct dfs_event *radar)
   2249 {
   2250 	wpa_printf(MSG_DEBUG, "DFS offload CAC started on %d MHz", radar->freq);
   2251 	hostapd_dfs_start_cac(hapd->iface, radar->freq, radar->ht_enabled,
   2252 			      radar->chan_offset, radar->chan_width,
   2253 			      radar->cf1, radar->cf2);
   2254 }
   2255 
   2256 #endif /* NEED_AP_MLME */
   2257 
   2258 
   2259 static void hostapd_event_wds_sta_interface_status(struct hostapd_data *hapd,
   2260 						   int istatus,
   2261 						   const char *ifname,
   2262 						   const u8 *addr)
   2263 {
   2264 	struct sta_info *sta = ap_get_sta(hapd, addr);
   2265 
   2266 	if (sta) {
   2267 		os_free(sta->ifname_wds);
   2268 		if (istatus == INTERFACE_ADDED)
   2269 			sta->ifname_wds = os_strdup(ifname);
   2270 		else
   2271 			sta->ifname_wds = NULL;
   2272 	}
   2273 
   2274 	wpa_msg(hapd->msg_ctx, MSG_INFO, "%sifname=%s sta_addr=" MACSTR,
   2275 		istatus == INTERFACE_ADDED ?
   2276 		WDS_STA_INTERFACE_ADDED : WDS_STA_INTERFACE_REMOVED,
   2277 		ifname, MAC2STR(addr));
   2278 }
   2279 
   2280 
   2281 #ifdef CONFIG_OWE
   2282 static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd,
   2283 				      const u8 *peer, const u8 *ie,
   2284 				      size_t ie_len, const u8 *link_addr)
   2285 {
   2286 	u16 status;
   2287 	struct sta_info *sta;
   2288 	struct ieee802_11_elems elems;
   2289 
   2290 	if (!hapd || !hapd->wpa_auth) {
   2291 		wpa_printf(MSG_DEBUG, "OWE: Invalid hapd context");
   2292 		return -1;
   2293 	}
   2294 	if (!peer) {
   2295 		wpa_printf(MSG_DEBUG, "OWE: Peer unknown");
   2296 		return -1;
   2297 	}
   2298 	if (!(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE)) {
   2299 		wpa_printf(MSG_DEBUG, "OWE: No OWE AKM configured");
   2300 		status = WLAN_STATUS_AKMP_NOT_VALID;
   2301 		goto err;
   2302 	}
   2303 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 1) == ParseFailed) {
   2304 		wpa_printf(MSG_DEBUG, "OWE: Failed to parse OWE IE for "
   2305 			   MACSTR, MAC2STR(peer));
   2306 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
   2307 		goto err;
   2308 	}
   2309 	status = owe_validate_request(hapd, peer, elems.rsn_ie,
   2310 				      elems.rsn_ie_len,
   2311 				      elems.owe_dh, elems.owe_dh_len);
   2312 	if (status != WLAN_STATUS_SUCCESS)
   2313 		goto err;
   2314 
   2315 	sta = ap_get_sta(hapd, peer);
   2316 	if (sta) {
   2317 		ap_sta_no_session_timeout(hapd, sta);
   2318 		accounting_sta_stop(hapd, sta);
   2319 
   2320 		/*
   2321 		 * Make sure that the previously registered inactivity timer
   2322 		 * will not remove the STA immediately.
   2323 		 */
   2324 		sta->timeout_next = STA_NULLFUNC;
   2325 	} else {
   2326 		sta = ap_sta_add(hapd, peer);
   2327 		if (!sta) {
   2328 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
   2329 			goto err;
   2330 		}
   2331 	}
   2332 	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
   2333 
   2334 #ifdef CONFIG_IEEE80211BE
   2335 	if (link_addr) {
   2336 		struct mld_info *info = &sta->mld_info;
   2337 		u8 link_id = hapd->mld_link_id;
   2338 
   2339 		ap_sta_set_mld(sta, true);
   2340 		sta->mld_assoc_link_id = link_id;
   2341 		os_memcpy(info->common_info.mld_addr, peer, ETH_ALEN);
   2342 		info->links[link_id].valid = true;
   2343 		os_memcpy(info->links[link_id].local_addr, hapd->own_addr,
   2344 			  ETH_ALEN);
   2345 		os_memcpy(info->links[link_id].peer_addr, link_addr, ETH_ALEN);
   2346 	}
   2347 #endif /* CONFIG_IEEE80211BE */
   2348 
   2349 	status = owe_process_rsn_ie(hapd, sta, elems.rsn_ie,
   2350 				    elems.rsn_ie_len, elems.owe_dh,
   2351 				    elems.owe_dh_len, link_addr);
   2352 	if (status != WLAN_STATUS_SUCCESS)
   2353 		ap_free_sta(hapd, sta);
   2354 
   2355 	return 0;
   2356 err:
   2357 	hostapd_drv_update_dh_ie(hapd, link_addr ? link_addr : peer, status,
   2358 				 NULL, 0);
   2359 	return 0;
   2360 }
   2361 #endif /* CONFIG_OWE */
   2362 
   2363 
   2364 #ifdef NEED_AP_MLME
   2365 static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
   2366 				    const u8 *data, size_t len, int ack,
   2367 				    int link_id)
   2368 {
   2369 	struct sta_info *sta;
   2370 
   2371 	hapd = switch_link_hapd(hapd, link_id);
   2372 	hapd = hostapd_find_by_sta(hapd->iface, dst, false, &sta);
   2373 
   2374 	if (!sta) {
   2375 		wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
   2376 			   MACSTR " that is not currently associated",
   2377 			   MAC2STR(dst));
   2378 		return;
   2379 	}
   2380 
   2381 	ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
   2382 }
   2383 #endif /* NEED_AP_MLME */
   2384 
   2385 
   2386 #ifdef CONFIG_IEEE80211AX
   2387 static void hostapd_event_color_change(struct hostapd_data *hapd, bool success)
   2388 {
   2389 	struct hostapd_data *bss;
   2390 	size_t i;
   2391 
   2392 	for (i = 0; i < hapd->iface->num_bss; i++) {
   2393 		bss = hapd->iface->bss[i];
   2394 		if (bss->cca_color == 0)
   2395 			continue;
   2396 
   2397 		if (success)
   2398 			hapd->iface->conf->he_op.he_bss_color = bss->cca_color;
   2399 
   2400 		bss->cca_in_progress = 0;
   2401 		if (ieee802_11_set_beacon(bss)) {
   2402 			wpa_printf(MSG_ERROR, "Failed to remove BCCA element");
   2403 			bss->cca_in_progress = 1;
   2404 		} else {
   2405 			hostapd_cleanup_cca_params(bss);
   2406 		}
   2407 	}
   2408 }
   2409 #endif  /* CONFIG_IEEE80211AX */
   2410 
   2411 
   2412 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
   2413 			  union wpa_event_data *data)
   2414 {
   2415 	struct hostapd_data *hapd = ctx;
   2416 	struct sta_info *sta;
   2417 #ifndef CONFIG_NO_STDOUT_DEBUG
   2418 	int level = MSG_DEBUG;
   2419 
   2420 	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
   2421 	    data->rx_mgmt.frame_len >= 24) {
   2422 		const struct ieee80211_hdr *hdr;
   2423 		u16 fc;
   2424 
   2425 		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
   2426 		fc = le_to_host16(hdr->frame_control);
   2427 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
   2428 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
   2429 			level = MSG_EXCESSIVE;
   2430 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
   2431 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ)
   2432 			level = MSG_EXCESSIVE;
   2433 	}
   2434 
   2435 	wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
   2436 		event_to_string(event), event);
   2437 #endif /* CONFIG_NO_STDOUT_DEBUG */
   2438 
   2439 	switch (event) {
   2440 	case EVENT_MICHAEL_MIC_FAILURE:
   2441 		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
   2442 		break;
   2443 	case EVENT_SCAN_RESULTS:
   2444 #ifdef NEED_AP_MLME
   2445 		if (data)
   2446 			hapd = switch_link_scan(hapd,
   2447 						data->scan_info.scan_cookie);
   2448 #endif /* NEED_AP_MLME */
   2449 		if (hapd->iface->scan_cb)
   2450 			hapd->iface->scan_cb(hapd->iface);
   2451 #ifdef CONFIG_IEEE80211BE
   2452 		if (!hapd->iface->scan_cb && hapd->conf->mld_ap) {
   2453 			/* Other links may be waiting for HT scan result */
   2454 			unsigned int i;
   2455 
   2456 			for (i = 0; i < hapd->iface->interfaces->count; i++) {
   2457 				struct hostapd_iface *h =
   2458 					hapd->iface->interfaces->iface[i];
   2459 				struct hostapd_data *h_hapd = h->bss[0];
   2460 
   2461 				if (hostapd_is_ml_partner(hapd, h_hapd) &&
   2462 				    h_hapd->iface->scan_cb)
   2463 					h_hapd->iface->scan_cb(h_hapd->iface);
   2464 			}
   2465 		}
   2466 #endif /* CONFIG_IEEE80211BE */
   2467 		break;
   2468 	case EVENT_WPS_BUTTON_PUSHED:
   2469 		hostapd_wps_button_pushed(hapd, NULL);
   2470 		break;
   2471 #ifdef NEED_AP_MLME
   2472 	case EVENT_TX_STATUS:
   2473 		switch (data->tx_status.type) {
   2474 		case WLAN_FC_TYPE_MGMT:
   2475 			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
   2476 					   data->tx_status.data_len,
   2477 					   data->tx_status.stype,
   2478 					   data->tx_status.ack,
   2479 					   data->tx_status.link_id);
   2480 			break;
   2481 		case WLAN_FC_TYPE_DATA:
   2482 			hostapd_tx_status(hapd, data->tx_status.dst,
   2483 					  data->tx_status.data,
   2484 					  data->tx_status.data_len,
   2485 					  data->tx_status.ack);
   2486 			break;
   2487 		}
   2488 		break;
   2489 	case EVENT_EAPOL_TX_STATUS:
   2490 		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
   2491 					data->eapol_tx_status.data,
   2492 					data->eapol_tx_status.data_len,
   2493 					data->eapol_tx_status.ack,
   2494 					data->eapol_tx_status.link_id);
   2495 		break;
   2496 	case EVENT_DRIVER_CLIENT_POLL_OK:
   2497 		hostapd_client_poll_ok(hapd, data->client_poll.addr);
   2498 		break;
   2499 	case EVENT_RX_FROM_UNKNOWN:
   2500 		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
   2501 					    data->rx_from_unknown.addr,
   2502 					    data->rx_from_unknown.wds);
   2503 		break;
   2504 #endif /* NEED_AP_MLME */
   2505 	case EVENT_RX_MGMT:
   2506 		if (!data->rx_mgmt.frame)
   2507 			break;
   2508 #ifdef NEED_AP_MLME
   2509 		hostapd_mgmt_rx(hapd, &data->rx_mgmt);
   2510 #else /* NEED_AP_MLME */
   2511 		hostapd_action_rx(hapd, &data->rx_mgmt);
   2512 #endif /* NEED_AP_MLME */
   2513 		break;
   2514 	case EVENT_RX_PROBE_REQ:
   2515 		if (data->rx_probe_req.sa == NULL ||
   2516 		    data->rx_probe_req.ie == NULL)
   2517 			break;
   2518 		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
   2519 				     data->rx_probe_req.da,
   2520 				     data->rx_probe_req.bssid,
   2521 				     data->rx_probe_req.ie,
   2522 				     data->rx_probe_req.ie_len,
   2523 				     data->rx_probe_req.ssi_signal);
   2524 		break;
   2525 	case EVENT_NEW_STA:
   2526 		hostapd_event_new_sta(hapd, data->new_sta.addr);
   2527 		break;
   2528 	case EVENT_EAPOL_RX:
   2529 		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
   2530 				       data->eapol_rx.data,
   2531 				       data->eapol_rx.data_len,
   2532 				       data->eapol_rx.encrypted,
   2533 				       data->eapol_rx.link_id);
   2534 		break;
   2535 	case EVENT_ASSOC:
   2536 		if (!data)
   2537 			return;
   2538 #ifdef CONFIG_IEEE80211BE
   2539 		if (data->assoc_info.assoc_link_id != -1) {
   2540 			hapd = hostapd_mld_get_link_bss(
   2541 				hapd, data->assoc_info.assoc_link_id);
   2542 			if (!hapd) {
   2543 				wpa_printf(MSG_ERROR,
   2544 					   "MLD: Failed to get link BSS for EVENT_ASSOC");
   2545 				return;
   2546 			}
   2547 		}
   2548 #endif /* CONFIG_IEEE80211BE */
   2549 		hostapd_notif_assoc(hapd, data->assoc_info.addr,
   2550 				    data->assoc_info.req_ies,
   2551 				    data->assoc_info.req_ies_len,
   2552 				    data->assoc_info.resp_ies,
   2553 				    data->assoc_info.resp_ies_len,
   2554 				    data->assoc_info.link_addr,
   2555 				    data->assoc_info.reassoc);
   2556 		break;
   2557 	case EVENT_PORT_AUTHORIZED:
   2558 		/* Port authorized event for an associated STA */
   2559 		sta = ap_get_sta(hapd, data->port_authorized.sta_addr);
   2560 		if (sta)
   2561 			ap_sta_set_authorized(hapd, sta, 1);
   2562 		else
   2563 			wpa_printf(MSG_DEBUG,
   2564 				   "No STA info matching port authorized event found");
   2565 		break;
   2566 #ifdef CONFIG_OWE
   2567 	case EVENT_UPDATE_DH:
   2568 		if (!data)
   2569 			return;
   2570 #ifdef CONFIG_IEEE80211BE
   2571 		if (data->update_dh.assoc_link_id != -1) {
   2572 			hapd = hostapd_mld_get_link_bss(
   2573 				hapd, data->update_dh.assoc_link_id);
   2574 			if (!hapd) {
   2575 				wpa_printf(MSG_ERROR,
   2576 					   "MLD: Failed to get link BSS for EVENT_UPDATE_DH assoc_link_id=%d",
   2577 					   data->update_dh.assoc_link_id);
   2578 				return;
   2579 			}
   2580 		}
   2581 #endif /* CONFIG_IEEE80211BE */
   2582 		hostapd_notif_update_dh_ie(hapd, data->update_dh.peer,
   2583 					   data->update_dh.ie,
   2584 					   data->update_dh.ie_len,
   2585 					   data->update_dh.link_addr);
   2586 		break;
   2587 #endif /* CONFIG_OWE */
   2588 	case EVENT_DISASSOC:
   2589 		if (data)
   2590 			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
   2591 		break;
   2592 	case EVENT_DEAUTH:
   2593 		if (data)
   2594 			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
   2595 		break;
   2596 	case EVENT_STATION_LOW_ACK:
   2597 		if (!data)
   2598 			break;
   2599 		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
   2600 		break;
   2601 	case EVENT_AUTH:
   2602 		hostapd_notif_auth(hapd, &data->auth);
   2603 		break;
   2604 	case EVENT_CH_SWITCH_STARTED:
   2605 	case EVENT_CH_SWITCH:
   2606 		if (!data)
   2607 			break;
   2608 #ifdef CONFIG_IEEE80211BE
   2609 		if (data->ch_switch.link_id != -1) {
   2610 			hapd = hostapd_mld_get_link_bss(
   2611 				hapd, data->ch_switch.link_id);
   2612 			if (!hapd) {
   2613 				wpa_printf(MSG_ERROR,
   2614 					   "MLD: Failed to get link (ID %d) BSS for EVENT_CH_SWITCH/EVENT_CH_SWITCH_STARTED",
   2615 					   data->ch_switch.link_id);
   2616 				break;
   2617 			}
   2618 		}
   2619 #endif /* CONFIG_IEEE80211BE */
   2620 		hostapd_event_ch_switch(hapd, data->ch_switch.freq,
   2621 					data->ch_switch.ht_enabled,
   2622 					data->ch_switch.ch_offset,
   2623 					data->ch_switch.ch_width,
   2624 					data->ch_switch.cf1,
   2625 					data->ch_switch.cf2,
   2626 					data->ch_switch.punct_bitmap,
   2627 					event == EVENT_CH_SWITCH);
   2628 		break;
   2629 	case EVENT_CONNECT_FAILED_REASON:
   2630 		if (!data)
   2631 			break;
   2632 		hostapd_event_connect_failed_reason(
   2633 			hapd, data->connect_failed_reason.addr,
   2634 			data->connect_failed_reason.code);
   2635 		break;
   2636 	case EVENT_SURVEY:
   2637 		hostapd_event_get_survey(hapd->iface, &data->survey_results);
   2638 		break;
   2639 #ifdef NEED_AP_MLME
   2640 	case EVENT_INTERFACE_UNAVAILABLE:
   2641 		hostapd_event_iface_unavailable(hapd);
   2642 		break;
   2643 	case EVENT_DFS_RADAR_DETECTED:
   2644 		if (!data)
   2645 			break;
   2646 		hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
   2647 		hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
   2648 		break;
   2649 	case EVENT_DFS_PRE_CAC_EXPIRED:
   2650 		if (!data)
   2651 			break;
   2652 		hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
   2653 		hostapd_event_dfs_pre_cac_expired(hapd, &data->dfs_event);
   2654 		break;
   2655 	case EVENT_DFS_CAC_FINISHED:
   2656 		if (!data)
   2657 			break;
   2658 		hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
   2659 		hostapd_event_dfs_cac_finished(hapd, &data->dfs_event);
   2660 		break;
   2661 	case EVENT_DFS_CAC_ABORTED:
   2662 		if (!data)
   2663 			break;
   2664 		hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
   2665 		hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event);
   2666 		break;
   2667 	case EVENT_DFS_NOP_FINISHED:
   2668 		if (!data)
   2669 			break;
   2670 		hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
   2671 		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
   2672 		break;
   2673 	case EVENT_CHANNEL_LIST_CHANGED:
   2674 		/* channel list changed (regulatory?), update channel list */
   2675 		/* TODO: check this. hostapd_get_hw_features() initializes
   2676 		 * too much stuff. */
   2677 		/* hostapd_get_hw_features(hapd->iface); */
   2678 		hostapd_channel_list_updated(
   2679 			hapd->iface, data->channel_list_changed.initiator);
   2680 		break;
   2681 	case EVENT_DFS_CAC_STARTED:
   2682 		if (!data)
   2683 			break;
   2684 		hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
   2685 		hostapd_event_dfs_cac_started(hapd, &data->dfs_event);
   2686 		break;
   2687 #endif /* NEED_AP_MLME */
   2688 	case EVENT_INTERFACE_ENABLED:
   2689 		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
   2690 		if (hapd->disabled && hapd->started) {
   2691 			hapd->disabled = 0;
   2692 			/*
   2693 			 * Try to re-enable interface if the driver stopped it
   2694 			 * when the interface got disabled.
   2695 			 */
   2696 			if (hapd->wpa_auth)
   2697 				wpa_auth_reconfig_group_keys(hapd->wpa_auth);
   2698 			else
   2699 				hostapd_reconfig_encryption(hapd);
   2700 			hapd->reenable_beacon = 1;
   2701 			ieee802_11_set_beacon(hapd);
   2702 #ifdef NEED_AP_MLME
   2703 		} else if (hapd->disabled && hapd->iface->cac_started) {
   2704 			wpa_printf(MSG_DEBUG, "DFS: restarting pending CAC");
   2705 			hostapd_handle_dfs(hapd->iface);
   2706 #endif /* NEED_AP_MLME */
   2707 		}
   2708 		break;
   2709 	case EVENT_INTERFACE_DISABLED:
   2710 		hostapd_free_stas(hapd);
   2711 		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
   2712 		hapd->disabled = 1;
   2713 		break;
   2714 #ifdef CONFIG_ACS
   2715 	case EVENT_ACS_CHANNEL_SELECTED:
   2716 		hostapd_acs_channel_selected(hapd,
   2717 					     &data->acs_selected_channels);
   2718 		break;
   2719 #endif /* CONFIG_ACS */
   2720 	case EVENT_STATION_OPMODE_CHANGED:
   2721 		hostapd_event_sta_opmode_changed(hapd, data->sta_opmode.addr,
   2722 						 data->sta_opmode.smps_mode,
   2723 						 data->sta_opmode.chan_width,
   2724 						 data->sta_opmode.rx_nss);
   2725 		break;
   2726 	case EVENT_WDS_STA_INTERFACE_STATUS:
   2727 		hostapd_event_wds_sta_interface_status(
   2728 			hapd, data->wds_sta_interface.istatus,
   2729 			data->wds_sta_interface.ifname,
   2730 			data->wds_sta_interface.sta_addr);
   2731 		break;
   2732 #ifdef CONFIG_IEEE80211AX
   2733 	case EVENT_BSS_COLOR_COLLISION:
   2734 		/* The BSS color is shared amongst all BBSs on a specific phy.
   2735 		 * Therefore we always start the color change on the primary
   2736 		 * BSS. */
   2737 		hapd = switch_link_hapd(hapd,
   2738 					data->bss_color_collision.link_id);
   2739 		wpa_printf(MSG_DEBUG, "BSS color collision on %s",
   2740 			   hapd->conf->iface);
   2741 		hostapd_switch_color(hapd->iface->bss[0],
   2742 				     data->bss_color_collision.bitmap);
   2743 		break;
   2744 	case EVENT_CCA_STARTED_NOTIFY:
   2745 		hapd = switch_link_hapd(hapd,
   2746 					data->bss_color_collision.link_id);
   2747 		wpa_printf(MSG_DEBUG, "CCA started on %s",
   2748 			   hapd->conf->iface);
   2749 		break;
   2750 	case EVENT_CCA_ABORTED_NOTIFY:
   2751 		hapd = switch_link_hapd(hapd,
   2752 					data->bss_color_collision.link_id);
   2753 		wpa_printf(MSG_DEBUG, "CCA aborted on %s",
   2754 			   hapd->conf->iface);
   2755 		hostapd_event_color_change(hapd, false);
   2756 		break;
   2757 	case EVENT_CCA_NOTIFY:
   2758 		hapd = switch_link_hapd(hapd,
   2759 					data->bss_color_collision.link_id);
   2760 		wpa_printf(MSG_DEBUG, "CCA finished on %s",
   2761 			   hapd->conf->iface);
   2762 		hostapd_event_color_change(hapd, true);
   2763 		break;
   2764 #endif /* CONFIG_IEEE80211AX */
   2765 	default:
   2766 		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
   2767 		break;
   2768 	}
   2769 }
   2770 
   2771 
   2772 void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
   2773 				 union wpa_event_data *data)
   2774 {
   2775 	struct hapd_interfaces *interfaces = ctx;
   2776 	struct hostapd_data *hapd;
   2777 
   2778 	if (event != EVENT_INTERFACE_STATUS)
   2779 		return;
   2780 
   2781 	hapd = hostapd_get_iface(interfaces, data->interface_status.ifname);
   2782 	if (hapd && hapd->driver && hapd->driver->get_ifindex &&
   2783 	    hapd->drv_priv) {
   2784 		unsigned int ifindex;
   2785 
   2786 		ifindex = hapd->driver->get_ifindex(hapd->drv_priv);
   2787 		if (ifindex != data->interface_status.ifindex) {
   2788 			wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
   2789 				"interface status ifindex %d mismatch (%d)",
   2790 				ifindex, data->interface_status.ifindex);
   2791 			return;
   2792 		}
   2793 	}
   2794 	if (hapd)
   2795 		wpa_supplicant_event(hapd, event, data);
   2796 }
   2797 
   2798 #endif /* HOSTAPD */
   2799