From 84b3de8095ca34ea756e412fac5ee1e6f7b62f88 Mon Sep 17 00:00:00 2001 From: Utkarsh Bhatnagar Date: Mon, 19 Jul 2021 13:42:05 +0530 Subject: [PATCH] TDLS: Support TDLS operations in HE mode for 6 GHz Determine if the TDLS peer supports TDLS in 6 GHz band based on the HE 6 GHz Band Capabilities element received in the TDLS Setup Response frame. Indicate the peer's HE 6 GHz capabilities to the driver through sta_add(). Signed-off-by: Jouni Malinen --- src/common/wpa_common.c | 5 +++++ src/common/wpa_common.h | 1 + src/rsn_supp/tdls.c | 43 +++++++++++++++++++++++++++++++++----- src/rsn_supp/wpa.h | 1 + src/rsn_supp/wpa_i.h | 3 ++- wpa_supplicant/wpas_glue.c | 2 ++ 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 04461516f..b78db05a1 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -3231,6 +3231,11 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie) pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) { ie->he_capabilities = pos + 3; ie->he_capab_len = pos[1] - 1; + } else if (*pos == WLAN_EID_EXTENSION && + pos[1] >= 1 + + sizeof(struct ieee80211_he_6ghz_band_cap) && + pos[2] == WLAN_EID_EXT_HE_6GHZ_BAND_CAP) { + ie->he_6ghz_capabilities = pos + 3; } 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 a1ff89565..c28c55d3a 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -599,6 +599,7 @@ struct wpa_eapol_ie_parse { const u8 *vht_capabilities; const u8 *he_capabilities; size_t he_capab_len; + const u8 *he_6ghz_capabilities; 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 411cbf46a..c26a63d82 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -138,6 +138,7 @@ struct wpa_tdls_peer { struct ieee80211_vht_capabilities *vht_capabilities; struct ieee80211_he_capabilities *he_capabilities; size_t he_capab_len; + struct ieee80211_he_6ghz_band_cap *he_6ghz_band_capabilities; u8 qos_info; @@ -707,6 +708,8 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) peer->vht_capabilities = NULL; os_free(peer->he_capabilities); peer->he_capabilities = NULL; + os_free(peer->he_6ghz_band_capabilities); + peer->he_6ghz_band_capabilities = NULL; os_free(peer->ext_capab); peer->ext_capab = NULL; os_free(peer->supp_channels); @@ -1681,6 +1684,33 @@ static int copy_peer_he_capab(const struct wpa_eapol_ie_parse *kde, } +static int copy_peer_he_6ghz_band_capab(const struct wpa_eapol_ie_parse *kde, + struct wpa_tdls_peer *peer) +{ + if (!kde->he_6ghz_capabilities) { + wpa_printf(MSG_DEBUG, + "TDLS: No HE 6 GHz band capabilities received"); + return 0; + } + + if (!peer->he_6ghz_band_capabilities) { + peer->he_6ghz_band_capabilities = + os_zalloc(sizeof(struct ieee80211_he_6ghz_band_cap)); + if (peer->he_6ghz_band_capabilities == NULL) + return -1; + } + + os_memcpy(peer->he_6ghz_band_capabilities, kde->he_6ghz_capabilities, + sizeof(struct ieee80211_he_6ghz_band_cap)); + + wpa_hexdump(MSG_DEBUG, "TDLS: Peer 6 GHz band HE capabilities", + peer->he_6ghz_band_capabilities, + sizeof(struct ieee80211_he_6ghz_band_cap)); + + return 0; +} + + static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde, struct wpa_tdls_peer *peer) { @@ -1792,6 +1822,7 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, peer->vht_capabilities, peer->he_capabilities, peer->he_capab_len, + peer->he_6ghz_band_capabilities, peer->qos_info, peer->wmm_capable, peer->ext_capab, peer->ext_capab_len, peer->supp_channels, @@ -1928,7 +1959,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, goto error; if (copy_peer_vht_capab(&kde, peer) < 0 || - copy_peer_he_capab(&kde, peer) < 0) + copy_peer_he_capab(&kde, peer) < 0 || + copy_peer_he_6ghz_band_capab(&kde, peer) < 0) goto error; if (copy_peer_ext_capab(&kde, peer) < 0) @@ -1957,8 +1989,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, NULL, 0, 0, 0, NULL, 0, NULL, 0, - NULL, 0); + NULL, NULL, 0, NULL, 0, 0, NULL, 0, + NULL, 0, NULL, 0); if (wpa_tdls_send_tpk_m1(sm, peer) == -2) { peer = NULL; goto error; @@ -2337,7 +2369,8 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr, goto error; if (copy_peer_vht_capab(&kde, peer) < 0 || - copy_peer_he_capab(&kde, peer) < 0) + copy_peer_he_capab(&kde, peer) < 0 || + copy_peer_he_6ghz_band_capab(&kde, peer) < 0) goto error; if (copy_peer_ext_capab(&kde, peer) < 0) @@ -2724,7 +2757,7 @@ 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, NULL, 0, 0, 0, NULL, 0, NULL, 0, + NULL, NULL, 0, NULL, 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 ff8a85b6e..c98377bf6 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -71,6 +71,7 @@ struct wpa_sm_ctx { const struct ieee80211_vht_capabilities *vht_capab, const struct ieee80211_he_capabilities *he_capab, size_t he_capab_len, + const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab, 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 e7281bf3b..6cdce321d 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -400,6 +400,7 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, const struct ieee80211_vht_capabilities *vht_capab, const struct ieee80211_he_capabilities *he_capab, size_t he_capab_len, + const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab, 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, @@ -411,7 +412,7 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, supp_rates_len, ht_capab, vht_capab, he_capab, he_capab_len, - qosinfo, wmm, + he_6ghz_capab, 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 968186978..17fc05bcb 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -780,6 +780,7 @@ static int wpa_supplicant_tdls_peer_addset( const struct ieee80211_vht_capabilities *vht_capab, const struct ieee80211_he_capabilities *he_capab, size_t he_capab_len, + const struct ieee80211_he_6ghz_band_cap *he_6ghz_he_capab, 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) @@ -805,6 +806,7 @@ static int wpa_supplicant_tdls_peer_addset( params.vht_capabilities = vht_capab; params.he_capab = he_capab; params.he_capab_len = he_capab_len; + params.he_6ghz_capab = he_6ghz_he_capab; params.qosinfo = qosinfo; params.listen_interval = 0; params.supp_rates = supp_rates;