From: Daniel Gabay <daniel.gabay@xxxxxxxxx> Implement SPP (Signaling and Payload Protected) A-MSDU negotiation. Station advertise support in (Re)association RSNXE whenever: - The driver supports SPP A-MSDU. - AP advertises SPP A-MSDU support in the RSNXE. - Using CCMP/GCMP cipher in the connection. Indicate to the driver to enable SPP A-MSDU in association params when AP also advertised support in it's beacon/probe response RSNXE. Signed-off-by: Daniel Gabay <daniel.gabay@xxxxxxxxx> --- src/rsn_supp/wpa.c | 7 +++++++ src/rsn_supp/wpa.h | 7 +++++++ src/rsn_supp/wpa_i.h | 1 + src/rsn_supp/wpa_ie.c | 2 ++ wpa_supplicant/ctrl_iface.c | 2 ++ wpa_supplicant/pasn_supplicant.c | 3 +++ wpa_supplicant/sme.c | 3 +++ wpa_supplicant/wpa_supplicant.c | 10 ++++++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 9 files changed, 36 insertions(+) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 9e4b0b219e..ba576d2413 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -4953,6 +4953,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, case WPA_PARAM_USE_EXT_KEY_ID: sm->use_ext_key_id = value; break; + case WPA_PARAM_SPP_AMSDU: + sm->spp_amsdu = value; + break; #ifdef CONFIG_TESTING_OPTIONS case WPA_PARAM_FT_RSNXE_USED: sm->ft_rsnxe_used = value; @@ -7183,6 +7186,10 @@ void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm) pmksa_cache_reconfig(sm->pmksa); } +int wpa_sm_uses_spp_amsdu(struct wpa_sm *sm) +{ + return sm ? sm->spp_amsdu : 0; +} struct rsn_pmksa_cache * wpa_sm_get_pmksa_cache(struct wpa_sm *sm) { diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 9783feef2b..3f6d7e9648 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -140,6 +140,7 @@ enum wpa_sm_conf_params { WPA_PARAM_RSN_OVERRIDE, WPA_PARAM_RSN_OVERRIDE_SUPPORT, WPA_PARAM_EAPOL_2_KEY_INFO_SET_MASK, + WPA_PARAM_SPP_AMSDU, }; enum wpa_rsn_override { @@ -279,6 +280,7 @@ void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm); int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo); void wpa_sm_set_driver_bss_selection(struct wpa_sm *sm, bool driver_bss_selection); +int wpa_sm_uses_spp_amsdu(struct wpa_sm *sm); #else /* CONFIG_NO_WPA */ @@ -527,6 +529,11 @@ static inline void wpa_sm_set_driver_bss_selection(struct wpa_sm *sm, { } +static inline int wpa_sm_uses_spp_amsdu(struct wpa_sm *sm) +{ + return 0; +} + #endif /* CONFIG_NO_WPA */ #ifdef CONFIG_IEEE80211R diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 2fd08b0f23..b1b6729097 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -113,6 +113,7 @@ struct wpa_sm { unsigned int secure_rtt:1; unsigned int prot_range_neg:1; unsigned int ssid_protection:1; + unsigned int spp_amsdu:1; u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */ size_t assoc_wpa_ie_len; diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index 515f1b0275..d07f5b367f 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -394,6 +394,8 @@ int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len) capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); if (sm->ssid_protection) capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION); + if (sm->spp_amsdu) + capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU); if (!capab) return 0; /* no supported extended RSN capabilities */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 76012955be..7d5cd329cd 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -10504,6 +10504,8 @@ static int wpas_ctrl_resend_assoc(struct wpa_supplicant *wpa_s) params.key_mgmt_suite = wpa_s->key_mgmt; params.wpa_proto = wpa_s->wpa_proto; params.mgmt_frame_protection = wpa_s->sme.mfp; + params.spp_amsdu = wpa_s->sme.spp_amsdu; + params.rrm_used = wpa_s->rrm.rrm_used; if (wpa_s->sme.prev_bssid_set) params.prev_bssid = wpa_s->sme.prev_bssid; diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c index a46fe46b1f..8f095e8afd 100644 --- a/wpa_supplicant/pasn_supplicant.c +++ b/wpa_supplicant/pasn_supplicant.c @@ -583,6 +583,9 @@ static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit) capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA) capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); + if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU) + capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU); + pasn_set_rsnxe_caps(pasn, capab); pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL); ssid = wpa_config_get_network(wpa_s->conf, awork->network_id); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 2b758939d3..b74664ecbd 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -854,6 +854,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, } } + wpa_s->sme.spp_amsdu = wpa_sm_uses_spp_amsdu(wpa_s->wpa); + #ifdef CONFIG_P2P if (wpa_s->global->p2p) { u8 *pos; @@ -2660,6 +2662,7 @@ mscs_fail: #endif /* CONFIG_IEEE80211R */ params.mode = mode; params.mgmt_frame_protection = wpa_s->sme.mfp; + params.spp_amsdu = wpa_s->sme.spp_amsdu; params.rrm_used = wpa_s->rrm.rrm_used; if (wpa_s->sme.prev_bssid_set) params.prev_bssid = wpa_s->sme.prev_bssid; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 132d91598f..8f45a5c726 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2272,6 +2272,16 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION, false); } + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SPP_AMSDU, + wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU && + ieee802_11_rsnx_capab(bss_rsnx, + WLAN_RSNX_CAPAB_SPP_A_MSDU) && + wpa_s->pairwise_cipher & (WPA_CIPHER_CCMP_256 | + WPA_CIPHER_GCMP_256 | + WPA_CIPHER_CCMP | + WPA_CIPHER_GCMP) && + wpa_s->wpa_proto & WPA_PROTO_RSN); + if (!skip_default_rsne) { if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 93592a1377..9d64f12e1b 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1035,6 +1035,7 @@ struct wpa_supplicant { u8 sched_obss_scan; u16 obss_scan_int; u16 bss_max_idle_period; + unsigned int spp_amsdu:1; #ifdef CONFIG_SAE struct sae_data sae; struct wpabuf *sae_token; -- 2.43.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap