From 50baf345b4634d6c2246c8b84341943b7dd5b58d Mon Sep 17 00:00:00 2001 From: Sreeramya Soratkal Date: Wed, 6 Jan 2021 12:38:25 +0530 Subject: [PATCH] TDLS: Support TDLS operations in HE mode Determine if the TDLS peer is HE capable based on HE Capability element received in the TDLS Setup Response frame. Indicate the peer's HE capabilities to the driver through sta_add(). Signed-off-by: Sreeramya Soratkal --- src/common/ieee802_11_defs.h | 1 + src/common/wpa_common.c | 5 +++++ src/common/wpa_common.h | 2 ++ src/rsn_supp/tdls.c | 41 ++++++++++++++++++++++++++++++++---- src/rsn_supp/wpa.h | 2 ++ src/rsn_supp/wpa_i.h | 6 +++++- wpa_supplicant/wpas_glue.c | 4 ++++ 7 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 038c4ec0e..9518545c8 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2164,6 +2164,7 @@ struct ieee80211_he_capabilities { * and optional variable length PPE Thresholds field. */ u8 optional[37]; } STRUCT_PACKED; +#define IEEE80211_HE_CAPAB_MIN_LEN (6 + 11) struct ieee80211_he_operation { le32 he_oper_params; /* HE Operation Parameters[3] and diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 2b8c7f661..04d49ee4c 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -3226,6 +3226,11 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie) pos[1] >= sizeof(struct ieee80211_vht_capabilities)) { ie->vht_capabilities = pos + 2; + } else if (*pos == WLAN_EID_EXTENSION && + pos[1] >= 1 + IEEE80211_HE_CAPAB_MIN_LEN && + pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) { + ie->he_capabilities = pos + 3; + ie->he_capab_len = pos[1] - 1; } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) { ie->qosinfo = pos[2]; } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) { diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index c31e1a0fa..0e9f252ad 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -592,6 +592,8 @@ struct wpa_eapol_ie_parse { size_t ext_supp_rates_len; const u8 *ht_capabilities; const u8 *vht_capabilities; + const u8 *he_capabilities; + size_t he_capab_len; const u8 *supp_channels; size_t supp_channels_len; const u8 *supp_oper_classes; diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 7c4ef191c..af692680c 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -136,6 +136,8 @@ struct wpa_tdls_peer { struct ieee80211_ht_capabilities *ht_capabilities; struct ieee80211_vht_capabilities *vht_capabilities; + struct ieee80211_he_capabilities *he_capabilities; + size_t he_capab_len; u8 qos_info; @@ -703,6 +705,8 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) peer->ht_capabilities = NULL; os_free(peer->vht_capabilities); peer->vht_capabilities = NULL; + os_free(peer->he_capabilities); + peer->he_capabilities = NULL; os_free(peer->ext_capab); peer->ext_capab = NULL; os_free(peer->supp_channels); @@ -1652,6 +1656,29 @@ static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde, } +static int copy_peer_he_capab(const struct wpa_eapol_ie_parse *kde, + struct wpa_tdls_peer *peer) +{ + if (!kde->he_capabilities) { + wpa_printf(MSG_DEBUG, "TDLS: No HE capabilities received"); + return 0; + } + + os_free(peer->he_capabilities); + peer->he_capab_len = 0; + peer->he_capabilities = os_memdup(kde->he_capabilities, + kde->he_capab_len); + if (!peer->he_capabilities) + return -1; + + peer->he_capab_len = kde->he_capab_len; + wpa_hexdump(MSG_DEBUG, "TDLS: Peer HE capabilities", + peer->he_capabilities, peer->he_capab_len); + + return 0; +} + + static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde, struct wpa_tdls_peer *peer) { @@ -1761,6 +1788,8 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, peer->supp_rates, peer->supp_rates_len, peer->ht_capabilities, peer->vht_capabilities, + peer->he_capabilities, + peer->he_capab_len, peer->qos_info, peer->wmm_capable, peer->ext_capab, peer->ext_capab_len, peer->supp_channels, @@ -1896,7 +1925,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, if (copy_peer_ht_capab(&kde, peer) < 0) goto error; - if (copy_peer_vht_capab(&kde, peer) < 0) + if (copy_peer_vht_capab(&kde, peer) < 0 || + copy_peer_he_capab(&kde, peer) < 0) goto error; if (copy_peer_ext_capab(&kde, peer) < 0) @@ -1925,7 +1955,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, "TDLS setup - send own request"); peer->initiator = 1; wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, - NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0); + NULL, NULL, 0, 0, 0, NULL, 0, NULL, 0, + NULL, 0); if (wpa_tdls_send_tpk_m1(sm, peer) == -2) { peer = NULL; goto error; @@ -2303,7 +2334,8 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr, if (copy_peer_ht_capab(&kde, peer) < 0) goto error; - if (copy_peer_vht_capab(&kde, peer) < 0) + if (copy_peer_vht_capab(&kde, peer) < 0 || + copy_peer_he_capab(&kde, peer) < 0) goto error; if (copy_peer_ext_capab(&kde, peer) < 0) @@ -2690,7 +2722,8 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr) /* add the peer to the driver as a "setup in progress" peer */ if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, - NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0)) { + NULL, NULL, 0, 0, 0, NULL, 0, NULL, 0, + NULL, 0)) { wpa_tdls_disable_peer_link(sm, peer); return -1; } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 8e4533e45..f377acba2 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -69,6 +69,8 @@ struct wpa_sm_ctx { size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_vht_capabilities *vht_capab, + const struct ieee80211_he_capabilities *he_capab, + size_t he_capab_len, u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, const u8 *supp_channels, size_t supp_channels_len, diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 1dc963963..e7281bf3b 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -398,6 +398,8 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_vht_capabilities *vht_capab, + const struct ieee80211_he_capabilities *he_capab, + size_t he_capab_len, u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, const u8 *supp_channels, size_t supp_channels_len, const u8 *supp_oper_classes, @@ -407,7 +409,9 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add, aid, capability, supp_rates, supp_rates_len, ht_capab, - vht_capab, qosinfo, wmm, + vht_capab, + he_capab, he_capab_len, + qosinfo, wmm, ext_capab, ext_capab_len, supp_channels, supp_channels_len, diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 345c87d35..240e3d2d9 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -778,6 +778,8 @@ static int wpa_supplicant_tdls_peer_addset( const u8 *supp_rates, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_vht_capabilities *vht_capab, + const struct ieee80211_he_capabilities *he_capab, + size_t he_capab_len, u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len, const u8 *supp_channels, size_t supp_channels_len, const u8 *supp_oper_classes, size_t supp_oper_classes_len) @@ -801,6 +803,8 @@ static int wpa_supplicant_tdls_peer_addset( params.ht_capabilities = ht_capab; params.vht_capabilities = vht_capab; + params.he_capab = he_capab; + params.he_capab_len = he_capab_len; params.qosinfo = qosinfo; params.listen_interval = 0; params.supp_rates = supp_rates;