[RFC 11/30] BSS: Parse SMD Information Element and store the data
Ilan Peer
ilan.peer at intel.com
Wed Oct 21 06:43:29 PDT 2026
Add support for parsing an SMD Information Element, and
store the SMD Identifier and PTK mode as part of the
BSS object.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/common/ieee802_11_common.c | 28 ++++++++++++++++++
src/common/ieee802_11_common.h | 1 +
wpa_supplicant/bss.c | 53 ++++++++++++++++++++++++++++++++++
wpa_supplicant/bss.h | 9 ++++++
4 files changed, 91 insertions(+)
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index f7076f7923df..dcb93ce7221e 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -3369,6 +3369,34 @@ bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
}
+/**
+ * ieee802_11_sec_prof_rsnx_capab - Check an Extended RSN Capability in the
+ * Extended RSN Capabilities field of a Security Profile element
+ *
+ * @sp: Security Profile element (including the element header) or %NULL
+ * @capab: Extended RSN Capability (WLAN_RSNX_CAPAB_*) to check
+ * Returns: Whether the capability is indicated
+ */
+bool ieee802_11_sec_prof_rsnx_capab(const u8 *sp, unsigned int capab)
+{
+ size_t offset;
+ u8 bitmap_len, num_vendor;
+
+ if (!sp || sp[1] < 3)
+ return false;
+
+ bitmap_len = sp[4] & 0x0f;
+ num_vendor = (sp[4] & 0xf0) >> 4;
+ offset = 5 + bitmap_len + 4 * num_vendor;
+
+ if ((size_t) sp[1] + 2 <= offset)
+ return false;
+
+ return ieee802_11_rsnx_capab_len(sp + offset, sp[1] + 2 - offset,
+ capab);
+}
+
+
void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
int primary_channel,
struct ieee80211_edmg_config *edmg)
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 81e04a04d9a5..ed9d227bc2c2 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -388,6 +388,7 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
unsigned int capab);
bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab);
+bool ieee802_11_sec_prof_rsnx_capab(const u8 *sp, unsigned int capab);
int op_class_to_bandwidth(u8 op_class);
enum oper_chan_width op_class_to_ch_width(u8 op_class);
int chwidth_freq2_to_ch_width(int chwidth, int freq2);
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 3f8b46e1da9f..7dd3a3422924 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -583,6 +583,58 @@ static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
}
+static void wpa_bss_parse_smd_info(struct wpa_bss *bss)
+{
+ const u8 *ie, *sp;
+ const struct ieee80211_smd_info *smd;
+
+ os_memset(bss->smd_id, 0, ETH_ALEN);
+ bss->smd_per_ap_mld_ptk_mode = false;
+ bss->smd_max_prep_targets = 0;
+
+ if (!(bss->mld_capa & EHT_ML_MLD_CAPA_LINK_RECONF_OP_SUPPORT)) {
+ wpa_printf(MSG_DEBUG,
+ "BSS=" MACSTR " doesn't support Link Reconfiguration Operation. mld_capa=0x%x",
+ MAC2STR(bss->bssid), bss->mld_capa);
+ return;
+ }
+
+ /*
+ * An AP indicates SMD support only in the Extended RSN Capabilities
+ * field of the Security Profile element.
+ */
+ sp = wpa_bss_get_ie_ext(bss, WLAN_EID_EXT_SECURITY_PROFILE);
+ if (!ieee802_11_sec_prof_rsnx_capab(sp, WLAN_RSNX_CAPAB_SMD)) {
+ wpa_printf(MSG_DEBUG,
+ "BSS=" MACSTR " doesn't support SMD in Security Profile element",
+ MAC2STR(bss->bssid));
+ return;
+ }
+
+ ie = wpa_bss_get_ie_ext(bss, WLAN_EID_EXT_SMD_INFO);
+ if (!ie || ie[1] < 1 + sizeof(*smd))
+ return;
+
+ smd = (const struct ieee80211_smd_info *)(ie + 3);
+ os_memcpy(bss->smd_id, smd->smd_id, ETH_ALEN);
+ bss->smd_per_ap_mld_ptk_mode =
+ !!(smd->smd_capabilities & SMD_CAPA_PER_AP_MLD_PTK_MODE);
+
+ /* Get the maximal allowed prepared targets */
+ bss->smd_max_prep_targets =
+ ((smd->smd_capabilities &
+ SMD_CAPA_MAX_PREP_TARGET_AP_MLDS_MASK) >>
+ SMD_CAPA_MAX_PREP_TARGET_AP_MLDS_POS) + 1;
+
+ wpa_printf(MSG_DEBUG,
+ "BSS=" MACSTR " in SMD: ID=" MACSTR
+ ", PTK mode=%s, max prepared targets=%u",
+ MAC2STR(bss->bssid), MAC2STR(bss->smd_id),
+ bss->smd_per_ap_mld_ptk_mode ? "per-AP MLD" : "per-SMD",
+ bss->smd_max_prep_targets);
+}
+
+
static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
const u8 *ssid, size_t ssid_len,
struct wpa_scan_res *res,
@@ -607,6 +659,7 @@ static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
wpa_bss_set_hessid(bss);
wpa_bss_parse_basic_ml_element(wpa_s, bss);
+ wpa_bss_parse_smd_info(bss);
if (wpa_s->num_bss + 1 > wpa_s->conf->bss_max_count &&
wpa_bss_remove_oldest(wpa_s) != 0) {
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index b38b5e51a809..780ea27a9639 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -145,6 +145,15 @@ struct wpa_bss {
bool disabled;
} mld_links[MAX_NUM_MLD_LINKS];
+ /** SMD Identifier (all zeros if not part of an SMD) */
+ u8 smd_id[ETH_ALEN];
+
+ /** SMD per-AP MLD PTK mode */
+ bool smd_per_ap_mld_ptk_mode;
+
+ /** Maximum number of target AP MLDs allowed in the prepared state */
+ u8 smd_max_prep_targets;
+
/* followed by ie_len octets of IEs */
/* followed by beacon_ie_len octets of IEs */
u8 ies[];
--
2.55.0
More information about the Hostap
mailing list