[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