[RFC 13/30] WPA: Store the AP SMD Information Element

Ilan Peer ilan.peer at intel.com
Wed Oct 21 06:43:31 PDT 2026


Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/rsn_supp/wpa.c              | 26 ++++++++++++++++++++++++++
 src/rsn_supp/wpa.h              |  1 +
 src/rsn_supp/wpa_i.h            |  1 +
 wpa_supplicant/events.c         | 13 +++++++++++++
 wpa_supplicant/wpa_supplicant.c |  8 +++++++-
 wpa_supplicant/wpas_glue.c      |  5 +++++
 6 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 430d5713d6bf..ab0a87fcfc15 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -4574,6 +4574,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
 	os_free(sm->ap_rsne_override_2);
 	os_free(sm->ap_rsnxe_override);
 	os_free(sm->ap_security_profile);
+	os_free(sm->ap_smd_info);
 	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
 		os_free(sm->mlo.links[i].ap_rsne);
 		os_free(sm->mlo.links[i].ap_rsnxe);
@@ -6047,6 +6048,31 @@ int wpa_sm_set_ap_security_profile(struct wpa_sm *sm, const u8 *elem,
 }
 
 
+int wpa_sm_set_ap_smd_info(struct wpa_sm *sm, const u8 *ie)
+{
+	if (!sm)
+		return -1;
+
+	os_free(sm->ap_smd_info);
+	sm->ap_smd_info = NULL;
+
+	if (!ie) {
+		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+			"RSN: Clearing AP SMD Information element");
+		return 0;
+	}
+
+	wpa_hexdump(MSG_DEBUG, "RSN: Set AP SMD Information element", ie,
+		    sizeof(struct ieee80211_smd_info));
+
+	sm->ap_smd_info = os_memdup(ie, sizeof(struct ieee80211_smd_info));
+	if (!sm->ap_smd_info)
+		return -1;
+
+	return 0;
+}
+
+
 /**
  * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
  * @sm: Pointer to WPA state machine data from wpa_sm_init()
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 056296582c2f..7e51d76692db 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -233,6 +233,7 @@ int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_security_profile(struct wpa_sm *sm, const u8 *elem,
 				   size_t len);
+int wpa_sm_set_ap_smd_info(struct wpa_sm *sm, const u8 *ie);
 int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen);
 
 int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index a4fde79e7d05..c8771e016b25 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -151,6 +151,7 @@ struct wpa_sm {
 	 */
 	u8 *ap_security_profile;
 	size_t ap_security_profile_len;
+	u8 *ap_smd_info;
 
 #ifdef CONFIG_TDLS
 	struct wpa_tdls_peer *tdls;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c0798db71e48..e432ee7dae6c 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -4286,6 +4286,11 @@ no_pfs:
 			wpa_sm_set_ap_security_profile(wpa_s->wpa, p, len);
 		}
 
+		if (p[0] == WLAN_EID_EXTENSION && p[1] >= 1 &&
+		    p[2] == WLAN_EID_EXT_SMD_INFO)
+			wpa_sm_set_ap_smd_info(wpa_s->wpa,
+					       p + 3);
+
 		l -= len;
 		p += len;
 	}
@@ -4298,6 +4303,7 @@ no_pfs:
 		wpa_sm_set_ap_rsne_override(wpa_s->wpa, NULL, 0);
 		wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, NULL, 0);
 		wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, NULL, 0);
+		wpa_sm_set_ap_smd_info(wpa_s->wpa, NULL);
 	}
 	if (!sec_prof_found && data->assoc_info.beacon_ies)
 		wpa_sm_set_ap_security_profile(wpa_s->wpa, NULL, 0);
@@ -4389,6 +4395,7 @@ static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
 	const u8 *bss_wpa = NULL, *bss_rsn = NULL, *bss_rsnx = NULL;
 	const u8 *rsnoe, *rsno2e, *rsnxoe;
 	const u8 *sec_prof;
+	const u8 *bss_smd;
 
 	if (!wpa_s->current_bss || !wpa_s->current_ssid)
 		return -1;
@@ -4425,6 +4432,12 @@ static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
 					   sec_prof ? 2 + sec_prof[1] : 0))
 		return -1;
 
+	bss_smd = wpa_bss_get_ie_ext(wpa_s->current_bss,
+				     WLAN_EID_EXT_SMD_INFO);
+	if (wpa_sm_set_ap_smd_info(wpa_s->wpa,
+				   bss_smd ? bss_smd + 3 : NULL))
+		return -1;
+
 	return 0;
 }
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index c467ed02ebd2..e0ae06a4adcc 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -425,6 +425,7 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
 	wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, NULL, 0);
 	wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, NULL, 0);
 	wpa_sm_set_ap_security_profile(wpa_s->wpa, NULL, 0);
+	wpa_sm_set_ap_smd_info(wpa_s->wpa, NULL);
 	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
 #ifndef CONFIG_NO_WPA
 	wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
@@ -2136,6 +2137,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 	const u8 *bss_sp = NULL; /* AP's Security Profile element */
 	u8 sp_rsnx_buf[2 + 255]; /* Synthetic RSNXE from Security Profile
 				  * element */
+	const u8 *bss_smd = NULL;
 	bool wmm;
 	struct rsn_pmksa_cache_entry *pmksa;
 	const struct security_profile_entry *sel_sp = NULL;
@@ -2383,6 +2385,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 		if (bss) {
 			bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
 			bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+			bss_smd = wpa_bss_get_ie_ext(
+				bss, WLAN_EID_EXT_SMD_INFO);
 			rsnoe = wpa_bss_get_vendor_ie(
 				bss, RSNE_OVERRIDE_IE_VENDOR_TYPE);
 			rsno2e = wpa_bss_get_vendor_ie(
@@ -2407,7 +2411,9 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 						 rsnxoe ? 2 + rsnxoe[1] : 0)||
 		    wpa_sm_set_ap_security_profile(wpa_s->wpa, sec_prof,
 						   sec_prof ? 2 + sec_prof[1] :
-						   0))
+						   0) ||
+		    wpa_sm_set_ap_smd_info(wpa_s->wpa,
+					   bss_smd ? bss_smd + 3 : NULL))
 			return -1;
 	}
 
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index e9f1d5e6c2b4..8bd295c8ac2e 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -473,6 +473,11 @@ static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
 		if (wpa_sm_set_ap_security_profile(wpa_s->wpa, ie,
 						   ie ? 2 + ie[1] : 0))
 			ret = -1;
+
+		ie = wpa_bss_get_ie_ext(curr, WLAN_EID_EXT_SMD_INFO);
+		if (wpa_sm_set_ap_smd_info(wpa_s->wpa,
+					   ie ? ie + 3 : NULL))
+			ret = -1;
 	} else {
 		ret = -1;
 	}
-- 
2.55.0




More information about the Hostap mailing list