TDLS: Pass peer's Capability and Ext Capability info during sta_add
The contents of the peer's capability and extended capability information is required for the driver to perform TDLS P-UAPSD and Off Channel operations. Pass this information to the driver when the peer station is getting added. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
189206dddb
commit
d16531c40c
5 changed files with 52 additions and 8 deletions
|
@ -911,6 +911,8 @@ struct hostapd_sta_add_params {
|
||||||
u32 flags; /* bitmask of WPA_STA_* flags */
|
u32 flags; /* bitmask of WPA_STA_* flags */
|
||||||
int set; /* Set STA parameters instead of add */
|
int set; /* Set STA parameters instead of add */
|
||||||
u8 qosinfo;
|
u8 qosinfo;
|
||||||
|
const u8 *ext_capab;
|
||||||
|
size_t ext_capab_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hostapd_freq_params {
|
struct hostapd_freq_params {
|
||||||
|
|
|
@ -124,6 +124,9 @@ struct wpa_tdls_peer {
|
||||||
struct ieee80211_ht_capabilities *ht_capabilities;
|
struct ieee80211_ht_capabilities *ht_capabilities;
|
||||||
|
|
||||||
u8 qos_info;
|
u8 qos_info;
|
||||||
|
|
||||||
|
u8 *ext_capab;
|
||||||
|
size_t ext_capab_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -617,6 +620,8 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
||||||
peer->sm_tmr.buf = NULL;
|
peer->sm_tmr.buf = NULL;
|
||||||
os_free(peer->ht_capabilities);
|
os_free(peer->ht_capabilities);
|
||||||
peer->ht_capabilities = NULL;
|
peer->ht_capabilities = NULL;
|
||||||
|
os_free(peer->ext_capab);
|
||||||
|
peer->ext_capab = NULL;
|
||||||
peer->rsnie_i_len = peer->rsnie_p_len = 0;
|
peer->rsnie_i_len = peer->rsnie_p_len = 0;
|
||||||
peer->cipher = 0;
|
peer->cipher = 0;
|
||||||
peer->tpk_set = peer->tpk_success = 0;
|
peer->tpk_set = peer->tpk_success = 0;
|
||||||
|
@ -1365,6 +1370,30 @@ static int copy_peer_ht_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)
|
||||||
|
{
|
||||||
|
if (!kde->ext_capab) {
|
||||||
|
wpa_printf(MSG_DEBUG, "TDLS: No extended capabilities "
|
||||||
|
"received");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!peer->ext_capab || peer->ext_capab_len < kde->ext_capab_len - 2) {
|
||||||
|
/* Need to allocate buffer to fit the new information */
|
||||||
|
os_free(peer->ext_capab);
|
||||||
|
peer->ext_capab = os_zalloc(kde->ext_capab_len - 2);
|
||||||
|
if (peer->ext_capab == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
peer->ext_capab_len = kde->ext_capab_len - 2;
|
||||||
|
os_memcpy(peer->ext_capab, kde->ext_capab + 2, peer->ext_capab_len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
|
static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
|
||||||
const u8 *buf, size_t len)
|
const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -1437,6 +1466,9 @@ 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_ext_capab(&kde, peer) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
peer->qos_info = kde.qosinfo;
|
peer->qos_info = kde.qosinfo;
|
||||||
|
|
||||||
#ifdef CONFIG_TDLS_TESTING
|
#ifdef CONFIG_TDLS_TESTING
|
||||||
|
@ -1662,7 +1694,8 @@ skip_rsn:
|
||||||
|
|
||||||
skip_rsn_check:
|
skip_rsn_check:
|
||||||
/* add the peer to the driver as a "setup in progress" peer */
|
/* add the peer to the driver as a "setup in progress" peer */
|
||||||
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0);
|
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0,
|
||||||
|
NULL, 0);
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
|
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
|
||||||
if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
|
if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
|
||||||
|
@ -1702,10 +1735,11 @@ static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
||||||
#endif /* CONFIG_TDLS_TESTING */
|
#endif /* CONFIG_TDLS_TESTING */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add supported rates and capabilities to the TDLS peer */
|
/* add supported rates, capabilities, and qos_info to the TDLS peer */
|
||||||
wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
|
wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
|
||||||
peer->supp_rates, peer->supp_rates_len,
|
peer->supp_rates, peer->supp_rates_len,
|
||||||
peer->ht_capabilities, peer->qos_info);
|
peer->ht_capabilities, peer->qos_info,
|
||||||
|
peer->ext_capab, peer->ext_capab_len);
|
||||||
|
|
||||||
wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
|
wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
|
||||||
}
|
}
|
||||||
|
@ -1804,6 +1838,9 @@ 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_ext_capab(&kde, peer) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
peer->qos_info = kde.qosinfo;
|
peer->qos_info = kde.qosinfo;
|
||||||
|
|
||||||
if (!wpa_tdls_get_privacy(sm)) {
|
if (!wpa_tdls_get_privacy(sm)) {
|
||||||
|
@ -2109,7 +2146,8 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
|
||||||
peer->initiator = 1;
|
peer->initiator = 1;
|
||||||
|
|
||||||
/* add the peer to the driver as a "setup in progress" peer */
|
/* add the peer to the driver as a "setup in progress" peer */
|
||||||
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0);
|
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0,
|
||||||
|
NULL, 0);
|
||||||
|
|
||||||
if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
|
if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
|
||||||
wpa_tdls_disable_link(sm, peer->addr);
|
wpa_tdls_disable_link(sm, peer->addr);
|
||||||
|
|
|
@ -60,7 +60,8 @@ struct wpa_sm_ctx {
|
||||||
u16 capability, const u8 *supp_rates,
|
u16 capability, const u8 *supp_rates,
|
||||||
size_t supp_rates_len,
|
size_t supp_rates_len,
|
||||||
const struct ieee80211_ht_capabilities *ht_capab,
|
const struct ieee80211_ht_capabilities *ht_capab,
|
||||||
u8 qosinfo);
|
u8 qosinfo, const u8 *ext_capab,
|
||||||
|
size_t ext_capab_len);
|
||||||
#endif /* CONFIG_TDLS */
|
#endif /* CONFIG_TDLS */
|
||||||
void (*set_rekey_offload)(void *ctx, const u8 *kek, const u8 *kck,
|
void (*set_rekey_offload)(void *ctx, const u8 *kek, const u8 *kck,
|
||||||
const u8 *replay_ctr);
|
const u8 *replay_ctr);
|
||||||
|
|
|
@ -285,13 +285,14 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
|
||||||
u16 capability, const u8 *supp_rates,
|
u16 capability, const u8 *supp_rates,
|
||||||
size_t supp_rates_len,
|
size_t supp_rates_len,
|
||||||
const struct ieee80211_ht_capabilities *ht_capab,
|
const struct ieee80211_ht_capabilities *ht_capab,
|
||||||
u8 qosinfo)
|
u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
|
||||||
{
|
{
|
||||||
if (sm->ctx->tdls_peer_addset)
|
if (sm->ctx->tdls_peer_addset)
|
||||||
return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
|
return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
|
||||||
capability, supp_rates,
|
capability, supp_rates,
|
||||||
supp_rates_len, ht_capab,
|
supp_rates_len, ht_capab,
|
||||||
qosinfo);
|
qosinfo, ext_capab,
|
||||||
|
ext_capab_len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TDLS */
|
#endif /* CONFIG_TDLS */
|
||||||
|
|
|
@ -554,7 +554,7 @@ static int wpa_supplicant_tdls_peer_addset(
|
||||||
void *ctx, const u8 *peer, int add, u16 capability,
|
void *ctx, const u8 *peer, int add, u16 capability,
|
||||||
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,
|
||||||
u8 qosinfo)
|
u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
struct hostapd_sta_add_params params;
|
struct hostapd_sta_add_params params;
|
||||||
|
@ -579,6 +579,8 @@ static int wpa_supplicant_tdls_peer_addset(
|
||||||
params.supp_rates = supp_rates;
|
params.supp_rates = supp_rates;
|
||||||
params.supp_rates_len = supp_rates_len;
|
params.supp_rates_len = supp_rates_len;
|
||||||
params.set = !add;
|
params.set = !add;
|
||||||
|
params.ext_capab = ext_capab;
|
||||||
|
params.ext_capab_len = ext_capab_len;
|
||||||
|
|
||||||
return wpa_drv_sta_add(wpa_s, ¶ms);
|
return wpa_drv_sta_add(wpa_s, ¶ms);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue