git: 9d0442463402 - stable/13 - wpa: Import wpa_supplicant/hostapd commit 14ab4a816

From: Cy Schubert <cy_at_FreeBSD.org>
Date: Mon, 03 Jan 2022 23:30:02 UTC
The branch stable/13 has been updated by cy:

URL: https://cgit.FreeBSD.org/src/commit/?id=9d04424634024aef04bafa3104f24e0df9f4cce7

commit 9d04424634024aef04bafa3104f24e0df9f4cce7
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2021-12-02 23:00:32 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-01-03 23:04:46 +0000

    wpa: Import wpa_supplicant/hostapd commit 14ab4a816
    
    This is the November update to vendor/wpa committed upstream 2021-11-26.
    
    (cherry picked from commit 4b72b91a7132df1f77bbae194e1071ac621f1edb)
---
 contrib/wpa/hostapd/config_file.c                  |   25 +-
 contrib/wpa/hostapd/ctrl_iface.c                   |   43 +-
 contrib/wpa/hostapd/hlr_auc_gw.milenage_db         |    2 +-
 contrib/wpa/hostapd/hostapd.conf                   |   10 +-
 contrib/wpa/hostapd/hostapd_cli.c                  |    2 +-
 contrib/wpa/src/ap/acs.c                           |    4 +-
 contrib/wpa/src/ap/ap_config.c                     |   11 +-
 contrib/wpa/src/ap/ap_config.h                     |    3 +
 contrib/wpa/src/ap/beacon.c                        |   79 +-
 contrib/wpa/src/ap/ctrl_iface_ap.c                 |   56 +-
 contrib/wpa/src/ap/dhcp_snoop.c                    |    2 +
 contrib/wpa/src/ap/dpp_hostapd.c                   |   19 +-
 contrib/wpa/src/ap/hostapd.h                       |    2 +
 contrib/wpa/src/ap/hw_features.c                   |    2 +
 contrib/wpa/src/ap/ieee802_11.c                    |  388 +++-
 contrib/wpa/src/ap/ieee802_11.h                    |    2 +
 contrib/wpa/src/ap/ieee802_11_he.c                 |    3 +
 contrib/wpa/src/ap/ndisc_snoop.c                   |    2 +
 contrib/wpa/src/ap/neighbor_db.c                   |    8 +-
 contrib/wpa/src/ap/neighbor_db.h                   |    3 +-
 contrib/wpa/src/ap/wnm_ap.c                        |   12 +-
 contrib/wpa/src/ap/wnm_ap.h                        |    4 +-
 contrib/wpa/src/ap/wpa_auth.c                      |   18 +-
 contrib/wpa/src/ap/wpa_auth_ft.c                   |   16 +-
 contrib/wpa/src/ap/wps_hostapd.c                   |    5 +
 contrib/wpa/src/common/dpp.c                       |  175 +-
 contrib/wpa/src/common/dpp.h                       |   30 +-
 contrib/wpa/src/common/dpp_auth.c                  |   18 +-
 contrib/wpa/src/common/dpp_backup.c                |   75 +-
 contrib/wpa/src/common/dpp_crypto.c                | 1885 +++++---------------
 contrib/wpa/src/common/dpp_i.h                     |   70 +-
 contrib/wpa/src/common/dpp_pkex.c                  |  280 ++-
 contrib/wpa/src/common/dpp_reconfig.c              |   34 +-
 contrib/wpa/src/common/dpp_tcp.c                   |   13 +-
 contrib/wpa/src/common/hw_features_common.c        |   25 +-
 contrib/wpa/src/common/ieee802_11_common.c         |   44 +-
 contrib/wpa/src/common/ieee802_11_common.h         |    2 +
 contrib/wpa/src/common/ieee802_11_defs.h           |   56 +
 contrib/wpa/src/common/ptksa_cache.c               |   18 +-
 contrib/wpa/src/common/qca-vendor.h                |  665 ++++++-
 contrib/wpa/src/common/sae.c                       |   12 +-
 contrib/wpa/src/common/wpa_common.c                |    5 +
 contrib/wpa/src/common/wpa_common.h                |    1 +
 contrib/wpa/src/common/wpa_ctrl.h                  |    8 +
 contrib/wpa/src/crypto/crypto.h                    |  371 +++-
 contrib/wpa/src/crypto/crypto_internal-rsa.c       |    2 +-
 contrib/wpa/src/crypto/crypto_openssl.c            | 1119 ++++++++++--
 contrib/wpa/src/crypto/crypto_wolfssl.c            |    8 +-
 contrib/wpa/src/crypto/random.c                    |   42 +-
 contrib/wpa/src/crypto/tls_openssl.c               |   23 +
 contrib/wpa/src/drivers/driver.h                   |    6 +-
 contrib/wpa/src/drivers/driver_common.c            |    2 +-
 contrib/wpa/src/drivers/driver_hostap.h            |    2 -
 contrib/wpa/src/drivers/driver_macsec_qca.c        |   58 +-
 contrib/wpa/src/drivers/driver_ndis.c              |   16 +-
 contrib/wpa/src/drivers/driver_nl80211.c           |   29 +-
 contrib/wpa/src/drivers/driver_nl80211.h           |    1 +
 contrib/wpa/src/drivers/driver_nl80211_capa.c      |    2 +-
 contrib/wpa/src/eap_peer/eap_proxy_dummy.c         |    2 +-
 contrib/wpa/src/eap_peer/eap_teap.c                |   10 +-
 contrib/wpa/src/eap_peer/eap_tls_common.h          |    2 +-
 contrib/wpa/src/eap_server/eap_tls_common.h        |    2 +-
 contrib/wpa/src/l2_packet/l2_packet_none.c         |    2 +-
 contrib/wpa/src/p2p/p2p.c                          |    4 +-
 contrib/wpa/src/p2p/p2p_build.c                    |    2 +-
 contrib/wpa/src/p2p/p2p_go_neg.c                   |    4 +-
 contrib/wpa/src/p2p/p2p_i.h                        |    3 +-
 contrib/wpa/src/p2p/p2p_pd.c                       |    2 +-
 contrib/wpa/src/pae/ieee802_1x_kay.c               |   10 +-
 contrib/wpa/src/radius/radius_client.c             |    5 +-
 contrib/wpa/src/rsn_supp/pmksa_cache.c             |   92 +-
 contrib/wpa/src/rsn_supp/pmksa_cache.h             |    9 +
 contrib/wpa/src/rsn_supp/tdls.c                    |   43 +-
 contrib/wpa/src/rsn_supp/wpa.c                     |   27 +-
 contrib/wpa/src/rsn_supp/wpa.h                     |    6 +
 contrib/wpa/src/rsn_supp/wpa_i.h                   |    3 +-
 contrib/wpa/src/utils/config.c                     |   18 +-
 contrib/wpa/src/utils/eloop.c                      |   25 +-
 contrib/wpa/src/wps/wps.c                          |    2 +-
 contrib/wpa/src/wps/wps_defs.h                     |    2 +-
 contrib/wpa/src/wps/wps_registrar.c                |   26 +-
 contrib/wpa/src/wps/wps_upnp.c                     |    2 +-
 contrib/wpa/wpa_supplicant/Android.mk              |    3 +-
 contrib/wpa/wpa_supplicant/ChangeLog               |    3 +-
 contrib/wpa/wpa_supplicant/Makefile                |   12 +-
 contrib/wpa/wpa_supplicant/README                  |   84 +
 contrib/wpa/wpa_supplicant/ap.c                    |  126 +-
 contrib/wpa/wpa_supplicant/ap.h                    |    1 +
 contrib/wpa/wpa_supplicant/config.c                |   50 +-
 contrib/wpa/wpa_supplicant/config.h                |   11 +
 contrib/wpa/wpa_supplicant/config_file.c           |   13 +
 contrib/wpa/wpa_supplicant/config_none.c           |    2 +-
 contrib/wpa/wpa_supplicant/config_ssid.h           |   16 +
 contrib/wpa/wpa_supplicant/ctrl_iface.c            |  623 ++++++-
 .../wpa_supplicant/doc/docbook/wpa_supplicant.sgml |    2 +-
 contrib/wpa/wpa_supplicant/eapol_test.py           |   37 +-
 contrib/wpa/wpa_supplicant/events.c                |  237 ++-
 contrib/wpa/wpa_supplicant/gas_query.c             |   10 -
 contrib/wpa/wpa_supplicant/gas_query.h             |    1 -
 contrib/wpa/wpa_supplicant/mesh.c                  |   31 +
 contrib/wpa/wpa_supplicant/mesh_mpm.c              |   10 +-
 contrib/wpa/wpa_supplicant/notify.c                |   10 +-
 contrib/wpa/wpa_supplicant/op_classes.c            |    8 +-
 contrib/wpa/wpa_supplicant/p2p_supplicant.c        |  164 +-
 contrib/wpa/wpa_supplicant/p2p_supplicant.h        |    5 +-
 contrib/wpa/wpa_supplicant/p2p_supplicant_sd.c     |    4 +-
 contrib/wpa/wpa_supplicant/preauth_test.c          |    6 +-
 contrib/wpa/wpa_supplicant/robust_av.c             | 1332 ++++++++++++++
 contrib/wpa/wpa_supplicant/scan.c                  |   57 +-
 .../systemd/wpa_supplicant.service.in              |    1 +
 contrib/wpa/wpa_supplicant/wpa_cli.c               |   47 +
 contrib/wpa/wpa_supplicant/wpa_supplicant.c        |  284 ++-
 contrib/wpa/wpa_supplicant/wpa_supplicant.conf     |    2 +-
 contrib/wpa/wpa_supplicant/wpa_supplicant_i.h      |  138 +-
 contrib/wpa/wpa_supplicant/wpas_glue.c             |    2 +
 115 files changed, 7047 insertions(+), 2406 deletions(-)

diff --git a/contrib/wpa/hostapd/config_file.c b/contrib/wpa/hostapd/config_file.c
index 9bc1dc7756e9..daf3f37ad99e 100644
--- a/contrib/wpa/hostapd/config_file.c
+++ b/contrib/wpa/hostapd/config_file.c
@@ -13,6 +13,7 @@
 
 #include "utils/common.h"
 #include "utils/uuid.h"
+#include "utils/crc32.h"
 #include "common/ieee802_11_defs.h"
 #include "common/sae.h"
 #include "crypto/sha256.h"
@@ -2396,16 +2397,19 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		wpa_printf(MSG_INFO, "Line %d: DEPRECATED: 'dump_file' configuration variable is not used anymore",
 			   line);
 	} else if (os_strcmp(buf, "ssid") == 0) {
-		bss->ssid.ssid_len = os_strlen(pos);
-		if (bss->ssid.ssid_len > SSID_MAX_LEN ||
-		    bss->ssid.ssid_len < 1) {
+		struct hostapd_ssid *ssid = &bss->ssid;
+
+		ssid->ssid_len = os_strlen(pos);
+		if (ssid->ssid_len > SSID_MAX_LEN || ssid->ssid_len < 1) {
 			wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
 				   line, pos);
 			return 1;
 		}
-		os_memcpy(bss->ssid.ssid, pos, bss->ssid.ssid_len);
-		bss->ssid.ssid_set = 1;
+		os_memcpy(ssid->ssid, pos, ssid->ssid_len);
+		ssid->ssid_set = 1;
+		ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
 	} else if (os_strcmp(buf, "ssid2") == 0) {
+		struct hostapd_ssid *ssid = &bss->ssid;
 		size_t slen;
 		char *str = wpa_config_parse_string(pos, &slen);
 		if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
@@ -2414,9 +2418,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 			os_free(str);
 			return 1;
 		}
-		os_memcpy(bss->ssid.ssid, str, slen);
-		bss->ssid.ssid_len = slen;
-		bss->ssid.ssid_set = 1;
+		os_memcpy(ssid->ssid, str, slen);
+		ssid->ssid_len = slen;
+		ssid->ssid_set = 1;
+		ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
 		os_free(str);
 	} else if (os_strcmp(buf, "utf8_ssid") == 0) {
 		bss->ssid.utf8_ssid = atoi(pos) > 0;
@@ -3515,6 +3520,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		conf->he_op.he_twt_responder = atoi(pos);
 	} else if (os_strcmp(buf, "he_rts_threshold") == 0) {
 		conf->he_op.he_rts_threshold = atoi(pos);
+	} else if (os_strcmp(buf, "he_er_su_disable") == 0) {
+		conf->he_op.he_er_su_disable = atoi(pos);
 	} else if (os_strcmp(buf, "he_basic_mcs_nss_set") == 0) {
 		conf->he_op.he_basic_mcs_nss_set = atoi(pos);
 	} else if (os_strcmp(buf, "he_mu_edca_qos_info_param_count") == 0) {
@@ -4705,6 +4712,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		if (get_hex_config(bss->ext_capa, EXT_CAPA_MAX_LEN,
 				   line, "ext_capa", pos))
 			return 1;
+	} else if (os_strcmp(buf, "rnr") == 0) {
+		bss->rnr = atoi(pos);
 	} else {
 		wpa_printf(MSG_ERROR,
 			   "Line %d: unknown configuration item '%s'",
diff --git a/contrib/wpa/hostapd/ctrl_iface.c b/contrib/wpa/hostapd/ctrl_iface.c
index 4a2d60627070..6c99a3105f49 100644
--- a/contrib/wpa/hostapd/ctrl_iface.c
+++ b/contrib/wpa/hostapd/ctrl_iface.c
@@ -840,7 +840,7 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
 	const char *pos, *end;
 	int disassoc_timer = 0;
 	struct sta_info *sta;
-	u8 req_mode = 0, valid_int = 0x01;
+	u8 req_mode = 0, valid_int = 0x01, dialog_token = 0x01;
 	u8 bss_term_dur[12];
 	char *url = NULL;
 	int ret;
@@ -878,6 +878,12 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
 		valid_int = atoi(pos);
 	}
 
+	pos = os_strstr(cmd, " dialog_token=");
+	if (pos) {
+		pos += 14;
+		dialog_token = atoi(pos);
+	}
+
 	pos = os_strstr(cmd, " bss_term=");
 	if (pos) {
 		pos += 10;
@@ -984,7 +990,7 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
 #endif /* CONFIG_MBO */
 
 	ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
-				  valid_int, bss_term_dur, url,
+				  valid_int, bss_term_dur, dialog_token, url,
 				  nei_len ? nei_rep : NULL, nei_len,
 				  mbo_len ? mbo : NULL, mbo_len);
 #ifdef CONFIG_MBO
@@ -1455,10 +1461,10 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
 				   wps_version_number & 0x0f);
 			hostapd_wps_update_ie(hapd);
 		}
-	} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
-		wps_testing_dummy_cred = atoi(value);
-		wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
-			   wps_testing_dummy_cred);
+	} else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
+		wps_testing_stub_cred = atoi(value);
+		wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
+			   wps_testing_stub_cred);
 	} else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
 		wps_corrupt_pkhash = atoi(value);
 		wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
@@ -3185,8 +3191,9 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
 	u8 bssid[ETH_ALEN];
 	struct wpabuf *nr, *lci = NULL, *civic = NULL;
 	int stationary = 0;
+	int bss_parameters = 0;
 	char *tmp;
-	int ret;
+	int ret = -1;
 
 	if (!(hapd->conf->radio_measurements[0] &
 	      WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
@@ -3240,8 +3247,7 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
 		if (!lci) {
 			wpa_printf(MSG_ERROR,
 				   "CTRL: SET_NEIGHBOR: Bad LCI subelement");
-			wpabuf_free(nr);
-			return -1;
+			goto fail;
 		}
 	}
 
@@ -3257,9 +3263,7 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
 		if (!civic) {
 			wpa_printf(MSG_ERROR,
 				   "CTRL: SET_NEIGHBOR: Bad civic subelement");
-			wpabuf_free(nr);
-			wpabuf_free(lci);
-			return -1;
+			goto fail;
 		}
 	}
 
@@ -3269,10 +3273,21 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
 	if (os_strstr(buf, "stat"))
 		stationary = 1;
 
+	tmp = os_strstr(buf, "bss_parameter=");
+	if (tmp) {
+		bss_parameters = atoi(tmp + 14);
+		if (bss_parameters < 0 || bss_parameters > 0xff) {
+			wpa_printf(MSG_ERROR,
+				   "CTRL: SET_NEIGHBOR: Bad bss_parameters subelement");
+			goto fail;
+		}
+	}
+
 set:
 	ret = hostapd_neighbor_set(hapd, bssid, &ssid, nr, lci, civic,
-				   stationary);
+				   stationary, bss_parameters);
 
+fail:
 	wpabuf_free(nr);
 	wpabuf_free(lci);
 	wpabuf_free(civic);
@@ -4470,7 +4485,7 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
 {
 #ifdef CONFIG_WPS_TESTING
 	wps_version_number = 0x20;
-	wps_testing_dummy_cred = 0;
+	wps_testing_stub_cred = 0;
 	wps_corrupt_pkhash = 0;
 #endif /* CONFIG_WPS_TESTING */
 
diff --git a/contrib/wpa/hostapd/hlr_auc_gw.milenage_db b/contrib/wpa/hostapd/hlr_auc_gw.milenage_db
index c156a29aeda0..a250653108b3 100644
--- a/contrib/wpa/hostapd/hlr_auc_gw.milenage_db
+++ b/contrib/wpa/hostapd/hlr_auc_gw.milenage_db
@@ -3,7 +3,7 @@
 # 4.3.20 Test Set 20. SQN is the last used SQN value.
 # These values can be used for both UMTS (EAP-AKA) and GSM (EAP-SIM)
 # authentication. In case of GSM/EAP-SIM, AMF and SQN values are not used, but
-# dummy values will need to be included in this file.
+# stub values will need to be included in this file.
 
 # IMSI Ki OPc AMF SQN [RES_len]
 232010000000000 90dca4eda45b53cf0f12d7c9c3bc6a89 cb9cccc4b9258e6dca4760379fb82581 61df 000000000000
diff --git a/contrib/wpa/hostapd/hostapd.conf b/contrib/wpa/hostapd/hostapd.conf
index b5d15061f850..67d4cefb920b 100644
--- a/contrib/wpa/hostapd/hostapd.conf
+++ b/contrib/wpa/hostapd/hostapd.conf
@@ -841,6 +841,11 @@ wmm_ac_vo_acm=0
 # unsigned integer = duration in units of 16 us
 #he_rts_threshold=0
 
+#he_er_su_disable: Disable 242-tone HE ER SU PPDU reception by the AP
+# 0 = enable reception (default)
+# 1 = disable reception
+#he_er_su_disable=0
+
 # HE operating channel information; see matching vht_* parameters for details.
 # he_oper_centr_freq_seg0_idx field is used to indicate center frequency of 80
 # and 160 MHz bandwidth operation. In 80+80 MHz operation, it is the center
@@ -1832,7 +1837,7 @@ own_ip_addr=127.0.0.1
 #assoc_sa_query_retry_timeout=201
 
 # ocv: Operating Channel Validation
-# This is a countermeasure against multi-channel man-in-the-middle attacks.
+# This is a countermeasure against multi-channel on-path attacks.
 # Enabling this depends on the driver's support for OCV when the driver SME is
 # used. If hostapd SME is used, this will be enabled just based on this
 # configuration.
@@ -2916,6 +2921,9 @@ own_ip_addr=127.0.0.1
 # that allows sending of such data. Default: 0.
 #stationary_ap=0
 
+# Enable reduced neighbor reporting (RNR)
+#rnr=0
+
 ##### Airtime policy configuration ###########################################
 
 # Set the airtime policy operating mode:
diff --git a/contrib/wpa/hostapd/hostapd_cli.c b/contrib/wpa/hostapd/hostapd_cli.c
index eaa628ad0676..0e7fdd6bccfb 100644
--- a/contrib/wpa/hostapd/hostapd_cli.c
+++ b/contrib/wpa/hostapd/hostapd_cli.c
@@ -1048,7 +1048,7 @@ static char ** hostapd_complete_set(const char *str, int pos)
 	int arg = get_cmd_arg_num(str, pos);
 	const char *fields[] = {
 #ifdef CONFIG_WPS_TESTING
-		"wps_version_number", "wps_testing_dummy_cred",
+		"wps_version_number", "wps_testing_stub_cred",
 		"wps_corrupt_pkhash",
 #endif /* CONFIG_WPS_TESTING */
 #ifdef CONFIG_INTERWORKING
diff --git a/contrib/wpa/src/ap/acs.c b/contrib/wpa/src/ap/acs.c
index a112045364e3..46429f265433 100644
--- a/contrib/wpa/src/ap/acs.c
+++ b/contrib/wpa/src/ap/acs.c
@@ -309,8 +309,6 @@ acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
 	else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX)
 		busy = survey->channel_time_rx;
 	else {
-		/* This shouldn't really happen as survey data is checked in
-		 * acs_sanity_check() */
 		wpa_printf(MSG_ERROR, "ACS: Survey data missing");
 		return 0;
 	}
@@ -392,7 +390,7 @@ static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
 
 static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
 {
-	const int allowed[] = { 5180, 5260, 5550, 5580, 5660, 5745, 5955, 6035,
+	const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
 				6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
 				6755, 6835, 6915, 6995 };
 	unsigned int i;
diff --git a/contrib/wpa/src/ap/ap_config.c b/contrib/wpa/src/ap/ap_config.c
index 7b6d54c35fc2..86b6e097cf89 100644
--- a/contrib/wpa/src/ap/ap_config.c
+++ b/contrib/wpa/src/ap/ap_config.c
@@ -273,7 +273,7 @@ struct hostapd_config * hostapd_config_defaults(void)
 	conf->he_op.he_basic_mcs_nss_set = 0xfffc;
 	conf->he_op.he_bss_color_disabled = 1;
 	conf->he_op.he_bss_color_partial = 0;
-	conf->he_op.he_bss_color = 1;
+	conf->he_op.he_bss_color = os_random() % 63 + 1;
 	conf->he_op.he_twt_responder = 1;
 	conf->he_6ghz_max_mpdu = 2;
 	conf->he_6ghz_max_ampdu_len_exp = 7;
@@ -1423,6 +1423,15 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
 	}
 #endif /* CONFIG_SAE_PK */
 
+#ifdef CONFIG_FILS
+	if (full_config && bss->fils_discovery_min_int &&
+	    bss->unsol_bcast_probe_resp_interval) {
+		wpa_printf(MSG_ERROR,
+			   "Cannot enable both FILS discovery and unsolicited broadcast Probe Response at the same time");
+		return -1;
+	}
+#endif /* CONFIG_FILS */
+
 	return 0;
 }
 
diff --git a/contrib/wpa/src/ap/ap_config.h b/contrib/wpa/src/ap/ap_config.h
index ced36f9cc828..b8f791e56307 100644
--- a/contrib/wpa/src/ap/ap_config.h
+++ b/contrib/wpa/src/ap/ap_config.h
@@ -894,6 +894,8 @@ struct hostapd_bss_config {
 
 	u8 ext_capa_mask[EXT_CAPA_MAX_LEN];
 	u8 ext_capa[EXT_CAPA_MAX_LEN];
+
+	u8 rnr;
 };
 
 /**
@@ -916,6 +918,7 @@ struct he_operation {
 	u8 he_twt_required;
 	u8 he_twt_responder;
 	u16 he_rts_threshold;
+	u8 he_er_su_disable;
 	u16 he_basic_mcs_nss_set;
 };
 
diff --git a/contrib/wpa/src/ap/beacon.c b/contrib/wpa/src/ap/beacon.c
index 15fc2b3db064..22782f54e480 100644
--- a/contrib/wpa/src/ap/beacon.c
+++ b/contrib/wpa/src/ap/beacon.c
@@ -469,6 +469,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 	}
 #endif /* CONFIG_IEEE80211AX */
 
+	buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
 	buflen += hostapd_mbo_ie_len(hapd);
 	buflen += hostapd_eid_owe_trans_len(hapd);
 	buflen += hostapd_eid_dpp_cc_len(hapd);
@@ -573,6 +574,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 	    (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
 		pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
 
+	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP);
 	pos = hostapd_eid_fils_indic(hapd, pos, 0);
 	pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
 
@@ -642,7 +644,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 enum ssid_match_result {
 	NO_SSID_MATCH,
 	EXACT_SSID_MATCH,
-	WILDCARD_SSID_MATCH
+	WILDCARD_SSID_MATCH,
+	CO_LOCATED_SSID_MATCH,
 };
 
 static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
@@ -653,7 +656,9 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
 					 size_t short_ssid_list_len)
 {
 	const u8 *pos, *end;
+	struct hostapd_iface *iface = hapd->iface;
 	int wildcard = 0;
+	size_t i, j;
 
 	if (ssid_len == 0)
 		wildcard = 1;
@@ -687,7 +692,33 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
 		}
 	}
 
-	return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
+	if (wildcard)
+		return WILDCARD_SSID_MATCH;
+
+	if (!iface->interfaces || iface->interfaces->count <= 1 ||
+	    is_6ghz_op_class(hapd->iconf->op_class))
+		return NO_SSID_MATCH;
+
+	for (i = 0; i < iface->interfaces->count; i++) {
+		struct hostapd_iface *colocated;
+
+		colocated = iface->interfaces->iface[i];
+
+		if (colocated == iface ||
+		    !is_6ghz_op_class(colocated->conf->op_class))
+			continue;
+
+		for (j = 0; j < colocated->num_bss; j++) {
+			struct hostapd_bss_config *conf;
+
+			conf = colocated->bss[j]->conf;
+			if (ssid_len == conf->ssid.ssid_len &&
+			    os_memcmp(ssid, conf->ssid.ssid, ssid_len) == 0)
+				return CO_LOCATED_SSID_MATCH;
+		}
+	}
+
+	return NO_SSID_MATCH;
 }
 
 
@@ -1284,6 +1315,8 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
 		total_len += 3;
 	}
 
+	total_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_ACTION);
+
 	pos = hostapd_eid_fils_indic(hapd, buf, 0);
 	buf_len = pos - buf;
 	total_len += buf_len;
@@ -1352,6 +1385,8 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
 	/* Fill in the Length field value */
 	*length_pos = pos - (length_pos + 1);
 
+	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_ACTION);
+
 	/* FILS Indication element */
 	if (buf_len) {
 		os_memcpy(pos, buf, buf_len);
@@ -1438,6 +1473,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	}
 #endif /* CONFIG_IEEE80211AX */
 
+	tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON);
 	tail_len += hostapd_mbo_ie_len(hapd);
 	tail_len += hostapd_eid_owe_trans_len(hapd);
 	tail_len += hostapd_eid_dpp_cc_len(hapd);
@@ -1562,6 +1598,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	    (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
 		tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
 
+	tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON);
 	tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
 	tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
 
@@ -1743,7 +1780,7 @@ void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
 }
 
 
-int ieee802_11_set_beacon(struct hostapd_data *hapd)
+static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
 {
 	struct wpa_driver_ap_params params;
 	struct hostapd_freq_params freq;
@@ -1832,6 +1869,42 @@ fail:
 }
 
 
+int ieee802_11_set_beacon(struct hostapd_data *hapd)
+{
+	struct hostapd_iface *iface = hapd->iface;
+	int ret;
+	size_t i, j;
+	bool is_6g;
+
+	ret = __ieee802_11_set_beacon(hapd);
+	if (ret != 0)
+		return ret;
+
+	if (!iface->interfaces || iface->interfaces->count <= 1)
+		return 0;
+
+	/* Update Beacon frames in case of 6 GHz colocation */
+	is_6g = is_6ghz_op_class(iface->conf->op_class);
+	for (j = 0; j < iface->interfaces->count; j++) {
+		struct hostapd_iface *colocated;
+
+		colocated = iface->interfaces->iface[j];
+		if (colocated == iface || !colocated || !colocated->conf)
+			continue;
+
+		if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
+			continue;
+
+		for (i = 0; i < colocated->num_bss; i++) {
+			if (colocated->bss[i] && colocated->bss[i]->started)
+				__ieee802_11_set_beacon(colocated->bss[i]);
+		}
+	}
+
+	return 0;
+}
+
+
 int ieee802_11_set_beacons(struct hostapd_iface *iface)
 {
 	size_t i;
diff --git a/contrib/wpa/src/ap/ctrl_iface_ap.c b/contrib/wpa/src/ap/ctrl_iface_ap.c
index 28e40ba9cede..1d8fb8246581 100644
--- a/contrib/wpa/src/ap/ctrl_iface_ap.c
+++ b/contrib/wpa/src/ap/ctrl_iface_ap.c
@@ -50,9 +50,35 @@ static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen,
 }
 
 
-static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
-				 struct sta_info *sta,
-				 char *buf, size_t buflen)
+static int hostapd_get_sta_conn_time(struct sta_info *sta,
+				     struct hostap_sta_driver_data *data,
+				     char *buf, size_t buflen)
+{
+	struct os_reltime age;
+	unsigned long secs;
+	int ret;
+
+	if (sta->connected_time.sec) {
+		/* Locally maintained time in AP mode */
+		os_reltime_age(&sta->connected_time, &age);
+		secs = (unsigned long) age.sec;
+	} else if (data->flags & STA_DRV_DATA_CONN_TIME) {
+		/* Time from the driver in mesh mode */
+		secs = data->connected_sec;
+	} else {
+		return 0;
+	}
+
+	ret = os_snprintf(buf, buflen, "connected_time=%lu\n", secs);
+	if (os_snprintf_error(buflen, ret))
+		return 0;
+	return ret;
+}
+
+
+static int hostapd_get_sta_info(struct hostapd_data *hapd,
+				struct sta_info *sta,
+				char *buf, size_t buflen)
 {
 	struct hostap_sta_driver_data data;
 	int ret;
@@ -160,26 +186,9 @@ static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
 			len += ret;
 	}
 
-	return len;
-}
+	len += hostapd_get_sta_conn_time(sta, &data, buf + len, buflen - len);
 
-
-static int hostapd_get_sta_conn_time(struct sta_info *sta,
-				     char *buf, size_t buflen)
-{
-	struct os_reltime age;
-	int ret;
-
-	if (!sta->connected_time.sec)
-		return 0;
-
-	os_reltime_age(&sta->connected_time, &age);
-
-	ret = os_snprintf(buf, buflen, "connected_time=%u\n",
-			  (unsigned int) age.sec);
-	if (os_snprintf_error(buflen, ret))
-		return 0;
-	return ret;
+	return len;
 }
 
 
@@ -263,8 +272,7 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
 	if (res >= 0)
 		len += res;
 
-	len += hostapd_get_sta_tx_rx(hapd, sta, buf + len, buflen - len);
-	len += hostapd_get_sta_conn_time(sta, buf + len, buflen - len);
+	len += hostapd_get_sta_info(hapd, sta, buf + len, buflen - len);
 
 #ifdef CONFIG_SAE
 	if (sta->sae && sta->sae->state == SAE_ACCEPTED) {
diff --git a/contrib/wpa/src/ap/dhcp_snoop.c b/contrib/wpa/src/ap/dhcp_snoop.c
index edc77da2e797..551936b8e43c 100644
--- a/contrib/wpa/src/ap/dhcp_snoop.c
+++ b/contrib/wpa/src/ap/dhcp_snoop.c
@@ -88,6 +88,7 @@ static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
 		}
 	}
 
+#ifdef CONFIG_HS20
 	if (hapd->conf->disable_dgaf && is_broadcast_ether_addr(buf)) {
 		for (sta = hapd->sta_list; sta; sta = sta->next) {
 			if (!(sta->flags & WLAN_STA_AUTHORIZED))
@@ -96,6 +97,7 @@ static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
 							    (u8 *) buf, len);
 		}
 	}
+#endif /* CONFIG_HS20 */
 
 	if (msgtype == DHCPACK) {
 		if (b->your_ip == 0)
diff --git a/contrib/wpa/src/ap/dpp_hostapd.c b/contrib/wpa/src/ap/dpp_hostapd.c
index 93ffd8cf7c36..41769f475544 100644
--- a/contrib/wpa/src/ap/dpp_hostapd.c
+++ b/contrib/wpa/src/ap/dpp_hostapd.c
@@ -2276,6 +2276,8 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
 			     NULL);
 	hostapd_dpp_chirp_stop(hapd);
+	if (hapd->iface->interfaces)
+		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
 #endif /* CONFIG_DPP2 */
 	dpp_auth_deinit(hapd->dpp_auth);
 	hapd->dpp_auth = NULL;
@@ -2387,6 +2389,7 @@ hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
 	unsigned int i;
 	struct hostapd_hw_modes *mode;
 	int c;
+	bool chan6 = hapd->iface->hw_features == NULL;
 
 	if (!bi)
 		return;
@@ -2406,7 +2409,21 @@ hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
 	}
 
 	/* Preferred chirping channels */
-	int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
+	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
+	if (mode) {
+		for (c = 0; c < mode->num_channels; c++) {
+			struct hostapd_channel_data *chan = &mode->channels[c];
+
+			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+					  HOSTAPD_CHAN_RADAR) ||
+			    chan->freq != 2437)
+				continue;
+			chan6 = true;
+			break;
+		}
+	}
+	if (chan6)
+		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
 
 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
 	if (mode) {
diff --git a/contrib/wpa/src/ap/hostapd.h b/contrib/wpa/src/ap/hostapd.h
index 07d0aaa92100..f3ca7529ac96 100644
--- a/contrib/wpa/src/ap/hostapd.h
+++ b/contrib/wpa/src/ap/hostapd.h
@@ -138,6 +138,8 @@ struct hostapd_neighbor_entry {
 	/* LCI update time */
 	struct os_time lci_date;
 	int stationary;
+	u32 short_ssid;
+	u8 bss_parameters;
 };
 
 struct hostapd_sae_commit_queue {
diff --git a/contrib/wpa/src/ap/hw_features.c b/contrib/wpa/src/ap/hw_features.c
index bb5404fa7dd4..4b66b02f4e16 100644
--- a/contrib/wpa/src/ap/hw_features.c
+++ b/contrib/wpa/src/ap/hw_features.c
@@ -838,6 +838,8 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface)
 				       iface->freq, NULL,
 				       iface->hw_features,
 				       iface->num_hw_features);
+	if (!pri_chan)
+		return 0;
 	hostapd_encode_edmg_chan(iface->conf->enable_edmg,
 				 iface->conf->edmg_channel,
 				 pri_chan->chan,
diff --git a/contrib/wpa/src/ap/ieee802_11.c b/contrib/wpa/src/ap/ieee802_11.c
index 22cce961063e..db41049287fc 100644
--- a/contrib/wpa/src/ap/ieee802_11.c
+++ b/contrib/wpa/src/ap/ieee802_11.c
@@ -2398,7 +2398,7 @@ static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
 	buf_len = wpabuf_len(wd);
 
 	if (buf_len < 6) {
-		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%lu",
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
 			   buf_len);
 		return -1;
 	}
@@ -2474,7 +2474,7 @@ static int pasn_wd_handle_sae_confirm(struct hostapd_data *hapd,
 	buf_len = wpabuf_len(wd);
 
 	if (buf_len < 6) {
-		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%lu",
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
 			   buf_len);
 		return -1;
 	}
@@ -2704,7 +2704,7 @@ static int pasn_wd_handle_fils(struct hostapd_data *hapd, struct sta_info *sta,
 	buf_len = wpabuf_len(wd);
 
 	if (buf_len < 6) {
-		wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%lu",
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%zu",
 			   buf_len);
 		return -1;
 	}
@@ -7071,4 +7071,386 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
 	return eid;
 }
 
+
+static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
+				    size_t *current_len)
+{
+	struct hostapd_neighbor_entry *nr;
+	size_t total_len = 0, len = *current_len;
+
+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+			 list) {
+		if (!nr->nr || wpabuf_len(nr->nr) < 12)
+			continue;
+
+		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
+			continue;
+
+		/* Start a new element */
+		if (!len ||
+		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+			len = RNR_HEADER_LEN;
+			total_len += RNR_HEADER_LEN;
+		}
+
+		len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
+		total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
+	}
+
+	*current_len = len;
+	return total_len;
+}
+
+
+static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
+					struct hostapd_data *reporting_hapd,
+					size_t *current_len)
+{
+	size_t total_len = 0, len = *current_len;
+	int tbtt_count = 0;
+	size_t i, start = 0;
+
+	while (start < hapd->iface->num_bss) {
+		if (!len ||
+		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+			len = RNR_HEADER_LEN;
+			total_len += RNR_HEADER_LEN;
+		}
+
+		len += RNR_TBTT_HEADER_LEN;
+		total_len += RNR_TBTT_HEADER_LEN;
+
+		for (i = start; i < hapd->iface->num_bss; i++) {
+			struct hostapd_data *bss = hapd->iface->bss[i];
+
+			if (!bss || !bss->conf || !bss->started)
+				continue;
+
+			if (bss == reporting_hapd ||
+			    bss->conf->ignore_broadcast_ssid)
+				continue;
+
+			if (len + RNR_TBTT_INFO_LEN > 255 ||
+			    tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
+				break;
+
+			len += RNR_TBTT_INFO_LEN;
+			total_len += RNR_TBTT_INFO_LEN;
+			tbtt_count++;
+		}
+		start = i;
+	}
+
+	if (!tbtt_count)
+		total_len = 0;
+	else
+		*current_len = len;
+
+	return total_len;
+}
+
+
+enum colocation_mode {
+	NO_COLOCATED_6GHZ,
+	STANDALONE_6GHZ,
+	COLOCATED_6GHZ,
+	COLOCATED_LOWER_BAND,
+};
+
+static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
+{
+	u8 i;
+	bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class);
+
+	if (!hapd->iface || !hapd->iface->interfaces)
+		return NO_COLOCATED_6GHZ;
+
+	if (is_6ghz && hapd->iface->interfaces->count == 1)
+		return STANDALONE_6GHZ;
+
+	for (i = 0; i < hapd->iface->interfaces->count; i++) {
+		struct hostapd_iface *iface;
+		bool is_colocated_6ghz;
+
+		iface = hapd->iface->interfaces->iface[i];
+		if (iface == hapd->iface || !iface || !iface->conf)
+			continue;
+
+		is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class);
+		if (!is_6ghz && is_colocated_6ghz)
+			return COLOCATED_LOWER_BAND;
+		if (is_6ghz && !is_colocated_6ghz)
+			return COLOCATED_6GHZ;
+	}
+
+	if (is_6ghz)
+		return STANDALONE_6GHZ;
+
+	return NO_COLOCATED_6GHZ;
+}
+
+
+static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
+					     size_t *current_len)
+{
+	struct hostapd_iface *iface;
+	size_t len = 0;
+	size_t i;
+
+	if (!hapd->iface || !hapd->iface->interfaces)
+		return 0;
+
+	for (i = 0; i < hapd->iface->interfaces->count; i++) {
+		iface = hapd->iface->interfaces->iface[i];
+
+		if (iface == hapd->iface ||
+		    !is_6ghz_op_class(iface->conf->op_class))
+			continue;
+
+		len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
+						 current_len);
+	}
+
+	return len;
+}
+
+
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
+{
+	size_t total_len = 0, current_len = 0;
+	enum colocation_mode mode = get_colocation_mode(hapd);
+
+	switch (type) {
+	case WLAN_FC_STYPE_BEACON:
+		if (hapd->conf->rnr)
+			total_len += hostapd_eid_nr_db_len(hapd, &current_len);
+		/* fallthrough */
+
+	case WLAN_FC_STYPE_PROBE_RESP:
+		if (mode == COLOCATED_LOWER_BAND)
+			total_len += hostapd_eid_rnr_colocation_len(
+				hapd, &current_len);
+
+		if (hapd->conf->rnr && hapd->iface->num_bss > 1)
+			total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
+							       &current_len);
+		break;
+
+	case WLAN_FC_STYPE_ACTION:
+		if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
+			total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
+							       &current_len);
+		break;
*** 13352 LINES SKIPPED ***