[wpa_supplicant] Cumulative patch from c4e90da6d

Bug: 124017368
Test: Device boots up and connects to WPA3/OWE wifi networks, run traffic.
Test: Able to turn on/off softap, associate wifi STA, run traffic.
Test: DPP functional test.
Test: Regression test passed (Bug: 124052942)

c4e90da6d MBO: Move the WNM-Notification subtype definitions to common location
105b14f54 HS 2.0: Update the T&C Acceptance subtype value
65b487ae5 HS 2.0: Add QUIET=1 support for building hs20-osu-client
73f285dad Add FT-PSK to GET_CAPABILITY key_mgmt
6110753b1 nl80211: Clear PMKID add command message buffer
0fa33e05b nl80211: Clear connect command message buffer
b14e8ea1d nl80211: Request kernel to trim off payload of netlink requests from acks
789b48bb4 EAP peer: Clear temporary message buffers before freeing
8f99a3c26 Clear config item writing buffer before freeing it
a68e9b698 D-Bus: Fix P2P DeleteService dict iteration
0607346f1 D-Bus: Fix a memory leak in DeleteService handler
d05dda61d PEAP: Explicitly clear temporary keys from memory when using CMK
4e1cd3468 EAP-PEAP: Derive EMSK and use 128-octet derivation for MSK
d8c20ec59 DPP: Clear dpp_listen_freq on remain-on-channel failure
59fa20538 P2P: Allow the avoid channels for P2P discovery/negotiation
e34cd9f06 WNM: Fix WNM-Sleep Mode Request bounds checking
159a7fbde crl_reload_interval: Add CRL reloading support
83c860813 AP: Add wpa_psk_file reloading in runtime
ec5c39a55 AP: Allow identifying which passphrase station used with wpa_psk_file
b08c9ad0c AP: Expose PMK outside of wpa_auth module
89896c000 tests: Use python3 compatible print statement
bab493b90 tests: Use python3 compatible "except" statement
0dab47733 Write multi_ap_backhaul_sta to wpa_supplicant config
98251c6f2 dbus: Document more possible BSS/RSA/KeyMgmt values
1e591df06 Check supported types in wpas_mac_addr_rand_scan_set()
c85249aa1 Fix test compilation error related to sme_event_unprot_disconnect()
42d308635 SAE: Advertise Password Identifier use
59c693064 HS 2.0 server: Command line option to fetch the version information
2d1762fa4 HS 2.0 server: Alternative subrem updateNode for certificate credentials
d97cf2a11 HS 2.0 server: Use noMOUpdate in client certificate subrem
13a200a92 FILS: Remove notes about experimental implementation
86d4e0537 dbus: Expose support of SAE key management in BSS properties

Change-Id: I83ffca34ff5349c226db6215ff1ae35c3b7ab335
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index ef28ffe..8ede2bb 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -293,6 +293,13 @@
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
 		return;
 
+	if (os_reltime_initialized(&wpa_s->session_start)) {
+		os_reltime_age(&wpa_s->session_start, &wpa_s->session_length);
+		wpa_s->session_start.sec = 0;
+		wpa_s->session_start.usec = 0;
+		wpas_notify_session_length(wpa_s);
+	}
+
 	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 	bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
 	os_memset(wpa_s->bssid, 0, ETH_ALEN);
@@ -324,6 +331,9 @@
 	os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk));
 #endif /* CONFIG_TESTING_OPTIONS */
 	wpa_s->ieee80211ac = 0;
+
+	if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
+		wpa_s->enabled_4addr_mode = 0;
 }
 
 
@@ -1335,10 +1345,10 @@
 			continue;
 		}
 
-		if (wpa_is_bss_tmp_disallowed(wpa_s, bss->bssid)) {
+		if (wpa_is_bss_tmp_disallowed(wpa_s, bss)) {
 			if (debug_print)
 				wpa_dbg(wpa_s, MSG_DEBUG,
-					"   skip - MBO retry delay has not passed yet");
+					"   skip - AP temporarily disallowed");
 			continue;
 		}
 #ifdef CONFIG_TESTING_OPTIONS
@@ -2267,6 +2277,50 @@
 #endif /* CONFIG_INTERWORKING */
 
 
+static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
+					const u8 *ies, size_t ies_len)
+{
+	struct ieee802_11_elems elems;
+	const u8 *map_sub_elem, *pos;
+	size_t len;
+
+	if (!wpa_s->current_ssid ||
+	    !wpa_s->current_ssid->multi_ap_backhaul_sta ||
+	    !ies ||
+	    ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
+		return;
+
+	if (!elems.multi_ap || elems.multi_ap_len < 7) {
+		wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol");
+		goto fail;
+	}
+
+	pos = elems.multi_ap + 4;
+	len = elems.multi_ap_len - 4;
+
+	map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
+	if (!map_sub_elem || map_sub_elem[1] < 1) {
+		wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type");
+		goto fail;
+	}
+
+	if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
+		wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
+		goto fail;
+	}
+
+	if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
+		wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
+		goto fail;
+	}
+	wpa_s->enabled_4addr_mode = 1;
+	return;
+
+fail:
+	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+}
+
+
 #ifdef CONFIG_FST
 static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
 				const u8 *ie, size_t ie_len)
@@ -2343,6 +2397,9 @@
 		    get_ie(data->assoc_info.resp_ies,
 			   data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
 			wpa_s->ieee80211ac = 1;
+
+		multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
+					    data->assoc_info.resp_ies_len);
 	}
 	if (data->assoc_info.beacon_ies)
 		wpa_hexdump(MSG_DEBUG, "beacon_ies",
@@ -2648,6 +2705,16 @@
 
 	wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
 	if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
+		if (os_reltime_initialized(&wpa_s->session_start)) {
+			os_reltime_age(&wpa_s->session_start,
+				       &wpa_s->session_length);
+			wpa_s->session_start.sec = 0;
+			wpa_s->session_start.usec = 0;
+			wpas_notify_session_length(wpa_s);
+		} else {
+			wpas_notify_auth_changed(wpa_s);
+			os_get_reltime(&wpa_s->session_start);
+		}
 		wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
 			MACSTR, MAC2STR(bssid));
 		new_bss = 1;
@@ -2738,7 +2805,7 @@
 	}
 	wpa_supplicant_cancel_scan(wpa_s);
 
-	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
+	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
 	    wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
 		/*
 		 * We are done; the driver will take care of RSN 4-way
@@ -2748,7 +2815,7 @@
 		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
 		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
-	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
+	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
 		   wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
 		/*
 		 * The driver will take care of RSN 4-way handshake, so we need
@@ -3010,7 +3077,7 @@
 	    !disallowed_ssid(wpa_s, fast_reconnect->ssid,
 			     fast_reconnect->ssid_len) &&
 	    !wpas_temp_disabled(wpa_s, fast_reconnect_ssid) &&
-	    !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect->bssid)) {
+	    !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect)) {
 #ifndef CONFIG_NO_SCAN_PROCESSING
 		wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS");
 		if (wpa_supplicant_connect(wpa_s, fast_reconnect,
@@ -3583,8 +3650,8 @@
 }
 
 
-static void wpa_supplicant_update_channel_list(
-	struct wpa_supplicant *wpa_s, struct channel_list_changed *info)
+void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
+					struct channel_list_changed *info)
 {
 	struct wpa_supplicant *ifs;
 	u8 dfs_domain;
@@ -3598,10 +3665,13 @@
 	for (ifs = wpa_s; ifs->parent && ifs != ifs->parent; ifs = ifs->parent)
 		;
 
-	wpa_msg(ifs, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
-		reg_init_str(info->initiator), reg_type_str(info->type),
-		info->alpha2[0] ? " alpha2=" : "",
-		info->alpha2[0] ? info->alpha2 : "");
+	if (info) {
+		wpa_msg(ifs, MSG_INFO,
+			WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
+			reg_init_str(info->initiator), reg_type_str(info->type),
+			info->alpha2[0] ? " alpha2=" : "",
+			info->alpha2[0] ? info->alpha2 : "");
+	}
 
 	if (wpa_s->drv_priv == NULL)
 		return; /* Ignore event during drv initialization */
@@ -3840,7 +3910,7 @@
 				       struct dfs_event *radar)
 {
 #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-	if (wpa_s->ap_iface) {
+	if (wpa_s->ap_iface || wpa_s->ifmsh) {
 		wpas_ap_event_dfs_cac_started(wpa_s, radar);
 	} else
 #endif /* NEED_AP_MLME && CONFIG_AP */
@@ -3861,7 +3931,7 @@
 					struct dfs_event *radar)
 {
 #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-	if (wpa_s->ap_iface) {
+	if (wpa_s->ap_iface || wpa_s->ifmsh) {
 		wpas_ap_event_dfs_cac_finished(wpa_s, radar);
 	} else
 #endif /* NEED_AP_MLME && CONFIG_AP */
@@ -3877,7 +3947,7 @@
 				       struct dfs_event *radar)
 {
 #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-	if (wpa_s->ap_iface) {
+	if (wpa_s->ap_iface || wpa_s->ifmsh) {
 		wpas_ap_event_dfs_cac_aborted(wpa_s, radar);
 	} else
 #endif /* NEED_AP_MLME && CONFIG_AP */
@@ -3985,6 +4055,32 @@
 	}
 #endif /* CONFIG_OWE */
 
+#ifdef CONFIG_MBO
+	if (data->assoc_reject.status_code ==
+	    WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS &&
+	    wpa_s->current_bss && data->assoc_reject.bssid &&
+	    data->assoc_reject.resp_ies) {
+		const u8 *rssi_rej;
+
+		rssi_rej = mbo_get_attr_from_ies(
+			data->assoc_reject.resp_ies,
+			data->assoc_reject.resp_ies_len,
+			OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT);
+		if (rssi_rej && rssi_rej[1] == 2) {
+			wpa_printf(MSG_DEBUG,
+				   "OCE: RSSI-based association rejection from "
+				   MACSTR " (Delta RSSI: %u, Retry Delay: %u)",
+				   MAC2STR(data->assoc_reject.bssid),
+				   rssi_rej[2], rssi_rej[3]);
+			wpa_bss_tmp_disallow(wpa_s,
+					     data->assoc_reject.bssid,
+					     rssi_rej[3],
+					     rssi_rej[2] +
+					     wpa_s->current_bss->level);
+		}
+	}
+#endif /* CONFIG_MBO */
+
 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
 		sme_event_assoc_reject(wpa_s, data);
 		return;
@@ -4032,6 +4128,9 @@
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	int resched;
+#ifndef CONFIG_NO_STDOUT_DEBUG
+	int level = MSG_DEBUG;
+#endif /* CONFIG_NO_STDOUT_DEBUG */
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
 	    event != EVENT_INTERFACE_ENABLED &&
@@ -4045,9 +4144,6 @@
 	}
 
 #ifndef CONFIG_NO_STDOUT_DEBUG
-{
-	int level = MSG_DEBUG;
-
 	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame_len >= 24) {
 		const struct ieee80211_hdr *hdr;
 		u16 fc;
@@ -4060,7 +4156,6 @@
 
 	wpa_dbg(wpa_s, level, "Event %s (%d) received",
 		event_to_string(event), event);
-}
 #endif /* CONFIG_NO_STDOUT_DEBUG */
 
 	switch (event) {
@@ -4072,6 +4167,8 @@
 				   "FST: MB IEs updated from auth IE");
 #endif /* CONFIG_FST */
 		sme_event_auth(wpa_s, data);
+		wpa_s->auth_status_code = data->auth.status_code;
+		wpas_notify_auth_status_code(wpa_s);
 		break;
 	case EVENT_ASSOC:
 #ifdef CONFIG_TESTING_OPTIONS
@@ -4087,6 +4184,7 @@
 		}
 #endif /* CONFIG_TESTING_OPTIONS */
 		wpa_supplicant_event_assoc(wpa_s, data);
+		wpa_s->assoc_status_code = WLAN_STATUS_SUCCESS;
 		if (data &&
 		    (data->assoc_info.authorized ||
 		     (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
@@ -4329,6 +4427,7 @@
 #ifdef CONFIG_AP
 		if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
 		    wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO ||
+		    wpa_s->current_ssid->mode == WPAS_MODE_MESH ||
 		    wpa_s->current_ssid->mode ==
 		    WPAS_MODE_P2P_GROUP_FORMATION) {
 			wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
@@ -4340,6 +4439,9 @@
 		}
 #endif /* CONFIG_AP */
 
+#ifdef CONFIG_IEEE80211W
+		sme_event_ch_switch(wpa_s);
+#endif /* CONFIG_IEEE80211W */
 		wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS);
 		wnm_clear_coloc_intf_reporting(wpa_s);
 		break;