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 <ssramya@codeaurora.org>
This commit is contained in:
Sreeramya Soratkal 2021-01-06 12:38:25 +05:30 committed by Jouni Malinen
parent 184c824689
commit 50baf345b4
7 changed files with 56 additions and 5 deletions

View file

@ -2164,6 +2164,7 @@ struct ieee80211_he_capabilities {
* and optional variable length PPE Thresholds field. */ * and optional variable length PPE Thresholds field. */
u8 optional[37]; u8 optional[37];
} STRUCT_PACKED; } STRUCT_PACKED;
#define IEEE80211_HE_CAPAB_MIN_LEN (6 + 11)
struct ieee80211_he_operation { struct ieee80211_he_operation {
le32 he_oper_params; /* HE Operation Parameters[3] and le32 he_oper_params; /* HE Operation Parameters[3] and

View file

@ -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)) pos[1] >= sizeof(struct ieee80211_vht_capabilities))
{ {
ie->vht_capabilities = pos + 2; 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) { } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
ie->qosinfo = pos[2]; ie->qosinfo = pos[2];
} else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) { } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {

View file

@ -592,6 +592,8 @@ struct wpa_eapol_ie_parse {
size_t ext_supp_rates_len; size_t ext_supp_rates_len;
const u8 *ht_capabilities; const u8 *ht_capabilities;
const u8 *vht_capabilities; const u8 *vht_capabilities;
const u8 *he_capabilities;
size_t he_capab_len;
const u8 *supp_channels; const u8 *supp_channels;
size_t supp_channels_len; size_t supp_channels_len;
const u8 *supp_oper_classes; const u8 *supp_oper_classes;

View file

@ -136,6 +136,8 @@ struct wpa_tdls_peer {
struct ieee80211_ht_capabilities *ht_capabilities; struct ieee80211_ht_capabilities *ht_capabilities;
struct ieee80211_vht_capabilities *vht_capabilities; struct ieee80211_vht_capabilities *vht_capabilities;
struct ieee80211_he_capabilities *he_capabilities;
size_t he_capab_len;
u8 qos_info; 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; peer->ht_capabilities = NULL;
os_free(peer->vht_capabilities); os_free(peer->vht_capabilities);
peer->vht_capabilities = NULL; peer->vht_capabilities = NULL;
os_free(peer->he_capabilities);
peer->he_capabilities = NULL;
os_free(peer->ext_capab); os_free(peer->ext_capab);
peer->ext_capab = NULL; peer->ext_capab = NULL;
os_free(peer->supp_channels); 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, static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
struct wpa_tdls_peer *peer) 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->supp_rates, peer->supp_rates_len,
peer->ht_capabilities, peer->ht_capabilities,
peer->vht_capabilities, peer->vht_capabilities,
peer->he_capabilities,
peer->he_capab_len,
peer->qos_info, peer->wmm_capable, peer->qos_info, peer->wmm_capable,
peer->ext_capab, peer->ext_capab_len, peer->ext_capab, peer->ext_capab_len,
peer->supp_channels, 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) if (copy_peer_ht_capab(&kde, peer) < 0)
goto error; 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; goto error;
if (copy_peer_ext_capab(&kde, peer) < 0) 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"); "TDLS setup - send own request");
peer->initiator = 1; peer->initiator = 1;
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, 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) { if (wpa_tdls_send_tpk_m1(sm, peer) == -2) {
peer = NULL; peer = NULL;
goto error; 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) if (copy_peer_ht_capab(&kde, peer) < 0)
goto error; 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; goto error;
if (copy_peer_ext_capab(&kde, peer) < 0) 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 */ /* 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, 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); wpa_tdls_disable_peer_link(sm, peer);
return -1; return -1;
} }

View file

@ -69,6 +69,8 @@ struct wpa_sm_ctx {
size_t supp_rates_len, size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_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, u8 qosinfo, int wmm, const u8 *ext_capab,
size_t ext_capab_len, const u8 *supp_channels, size_t ext_capab_len, const u8 *supp_channels,
size_t supp_channels_len, size_t supp_channels_len,

View file

@ -398,6 +398,8 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
size_t supp_rates_len, size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_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, u8 qosinfo, int wmm, const u8 *ext_capab,
size_t ext_capab_len, const u8 *supp_channels, size_t ext_capab_len, const u8 *supp_channels,
size_t supp_channels_len, const u8 *supp_oper_classes, 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, return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
aid, capability, supp_rates, aid, capability, supp_rates,
supp_rates_len, ht_capab, supp_rates_len, ht_capab,
vht_capab, qosinfo, wmm, vht_capab,
he_capab, he_capab_len,
qosinfo, wmm,
ext_capab, ext_capab_len, ext_capab, ext_capab_len,
supp_channels, supp_channels,
supp_channels_len, supp_channels_len,

View file

@ -778,6 +778,8 @@ static int wpa_supplicant_tdls_peer_addset(
const u8 *supp_rates, size_t supp_rates_len, const u8 *supp_rates, size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab, const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_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, 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_channels, size_t supp_channels_len,
const u8 *supp_oper_classes, size_t supp_oper_classes_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.ht_capabilities = ht_capab;
params.vht_capabilities = vht_capab; params.vht_capabilities = vht_capab;
params.he_capab = he_capab;
params.he_capab_len = he_capab_len;
params.qosinfo = qosinfo; params.qosinfo = qosinfo;
params.listen_interval = 0; params.listen_interval = 0;
params.supp_rates = supp_rates; params.supp_rates = supp_rates;