[PATCH 5/8] AP: Support SPP A-MSDU negotiation
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Jan 7 04:51:46 PST 2025
From: Daniel Gabay <daniel.gabay at intel.com>
Implement SPP (Signaling and Payload Protected) A-MSDU negotiation.
AP advertise support in beacon/probe response RSNXE whenever:
- The driver supports SPP A-MSDU.
- Advertising CCMP/GCMP ciphers in RSN element.
- The spp_amsdu conf option is not explicitly disabled (if the above
is true, it is enabled by default).
Indicate to the driver to enable SPP A-MSDU when associating station
advertised SPP A-MSDU support in association request RSNXE.
Signed-off-by: Daniel Gabay <daniel.gabay at intel.com>
---
src/ap/ap_drv_ops.c | 2 ++
src/ap/drv_callbacks.c | 5 +++++
src/ap/ieee802_11.c | 5 +++++
src/ap/ieee802_11_shared.c | 3 +++
src/ap/sta_info.c | 5 +++--
src/ap/sta_info.h | 1 +
src/ap/wpa_auth.h | 3 +++
src/ap/wpa_auth_glue.c | 3 +++
src/ap/wpa_auth_i.h | 1 +
src/ap/wpa_auth_ie.c | 15 +++++++++++++++
10 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 65e83f468b..8e9c41e41d 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -39,6 +39,8 @@ u32 hostapd_sta_flags_to_drv(u32 flags)
res |= WPA_STA_AUTHENTICATED;
if (flags & WLAN_STA_ASSOC)
res |= WPA_STA_ASSOCIATED;
+ if (flags & WLAN_STA_SPP_AMSDU)
+ res |= WPA_STA_SPP_AMSDU;
return res;
}
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index d660beefcf..7234a3b478 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -649,6 +649,11 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
else
sta->flags &= ~WLAN_STA_MFP;
+ if (wpa_auth_uses_spp_amsdu(sta->wpa_sm))
+ sta->flags |= WLAN_STA_SPP_AMSDU;
+ else
+ sta->flags &= ~WLAN_STA_SPP_AMSDU;
+
#ifdef CONFIG_IEEE80211R_AP
if (sta->auth_alg == WLAN_AUTH_FT) {
status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index a9ed6eb0fa..73e92e408c 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -4222,6 +4222,11 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
else
sta->flags &= ~WLAN_STA_MFP;
+ if (wpa_auth_uses_spp_amsdu(sta->wpa_sm))
+ sta->flags |= WLAN_STA_SPP_AMSDU;
+ else
+ sta->flags &= ~WLAN_STA_SPP_AMSDU;
+
#ifdef CONFIG_IEEE80211R_AP
if (sta->auth_alg == WLAN_AUTH_FT) {
if (!reassoc) {
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index 5e67216de6..32bdd49742 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -1136,6 +1136,9 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
if (hapd->conf->ssid_protection)
capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
+ if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU &&
+ hapd->conf->spp_amsdu)
+ capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU);
if (!capab)
return eid; /* no supported extended RSN capabilities */
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 5a7677905d..4023b75708 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -1766,7 +1766,7 @@ int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
buf[0] = '\0';
res = os_snprintf(buf, buflen,
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
(flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
(flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : ""),
@@ -1790,7 +1790,8 @@ int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
(flags & WLAN_STA_6GHZ ? "[6GHZ]" : ""),
(flags & WLAN_STA_VENDOR_VHT ? "[VENDOR_VHT]" : ""),
(flags & WLAN_STA_WNM_SLEEP_MODE ?
- "[WNM_SLEEP_MODE]" : ""));
+ "[WNM_SLEEP_MODE]" : ""),
+ (flags & WLAN_STA_SPP_AMSDU ? "[SPP-A-MSDU]" : ""));
if (os_snprintf_error(buflen, res))
res = -1;
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index d22e86d451..0bcb1d17f9 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -22,6 +22,7 @@
/* STA flags */
#define WLAN_STA_AUTH BIT(0)
#define WLAN_STA_ASSOC BIT(1)
+#define WLAN_STA_SPP_AMSDU BIT(2)
#define WLAN_STA_AUTHORIZED BIT(5)
#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
#define WLAN_STA_SHORT_PREAMBLE BIT(7)
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 9514e55b7f..7354314b81 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -319,6 +319,8 @@ struct wpa_auth_config {
bool ssid_protection;
int rsn_override_omit_rsnxe;
+
+ bool spp_amsdu;
};
typedef enum {
@@ -459,6 +461,7 @@ int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm,
const u8 *osen_ie, size_t osen_ie_len);
int wpa_auth_uses_mfp(struct wpa_state_machine *sm);
+int wpa_auth_uses_spp_amsdu(struct wpa_state_machine *sm);
void wpa_auth_set_ocv(struct wpa_state_machine *sm, int ocv);
int wpa_auth_uses_ocv(struct wpa_state_machine *sm);
struct wpa_state_machine *
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 9fa9f19b7b..6b66f38188 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -277,6 +277,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
conf->no_disconnect_on_group_keyerror;
wconf->rsn_override_omit_rsnxe = conf->rsn_override_omit_rsnxe;
+ wconf->spp_amsdu = conf->spp_amsdu;
}
@@ -1755,6 +1756,8 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
_conf.prot_range_neg =
!!(hapd->iface->drv_flags2 &
WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP);
+ _conf.spp_amsdu = hapd->conf->spp_amsdu &&
+ hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU;
#ifdef CONFIG_IEEE80211BE
_conf.mld_addr = NULL;
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index cb902e42b9..188f51eb84 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -97,6 +97,7 @@ struct wpa_state_machine {
#endif /* CONFIG_IEEE80211R_AP */
unsigned int is_wnmsleep:1;
unsigned int pmkid_set:1;
+ unsigned int spp_amsdu:1;
unsigned int ptkstart_without_success;
diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
index ce7f90aff2..3e7a08421a 100644
--- a/src/ap/wpa_auth_ie.c
+++ b/src/ap/wpa_auth_ie.c
@@ -507,6 +507,8 @@ static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt)
capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
if (conf->ssid_protection)
capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
+ if (conf->spp_amsdu)
+ capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU);
return capab;
}
@@ -1169,6 +1171,14 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
}
+ if (wpa_auth->conf.spp_amsdu &&
+ ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SPP_A_MSDU) &&
+ (ciphers & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
+ WPA_CIPHER_GCMP_256 | WPA_CIPHER_GCMP)))
+ sm->spp_amsdu = 1;
+ else
+ sm->spp_amsdu = 0;
+
#ifdef CONFIG_IEEE80211R_AP
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) {
@@ -1412,6 +1422,11 @@ int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
}
+int wpa_auth_uses_spp_amsdu(struct wpa_state_machine *sm)
+{
+ return sm ? sm->spp_amsdu : 0;
+}
+
#ifdef CONFIG_OCV
void wpa_auth_set_ocv(struct wpa_state_machine *sm, int ocv)
--
2.43.0
More information about the Hostap
mailing list