|
@@ -86,6 +86,7 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);
|
|
|
|
|
|
struct wpa_tdls_peer {
|
|
|
struct wpa_tdls_peer *next;
|
|
|
+ unsigned int reconfig_key:1;
|
|
|
int initiator; /* whether this end was initiator for TDLS setup */
|
|
|
u8 addr[ETH_ALEN]; /* other end MAC address */
|
|
|
u8 inonce[WPA_NONCE_LEN]; /* Initiator Nonce */
|
|
@@ -616,6 +617,7 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
|
|
MAC2STR(peer->addr));
|
|
|
eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
|
|
|
eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
|
|
|
+ peer->reconfig_key = 0;
|
|
|
peer->initiator = 0;
|
|
|
os_free(peer->sm_tmr.buf);
|
|
|
peer->sm_tmr.buf = NULL;
|
|
@@ -1751,7 +1753,7 @@ error:
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
|
|
+static int wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
|
|
{
|
|
|
peer->tpk_success = 1;
|
|
|
eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
|
|
@@ -1775,13 +1777,22 @@ static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
|
|
}
|
|
|
|
|
|
/* add supported rates, capabilities, and qos_info to the TDLS peer */
|
|
|
- wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
|
|
|
- peer->supp_rates, peer->supp_rates_len,
|
|
|
- peer->ht_capabilities, peer->vht_capabilities,
|
|
|
- peer->qos_info, peer->ext_capab,
|
|
|
- peer->ext_capab_len);
|
|
|
+ if (wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
|
|
|
+ peer->supp_rates, peer->supp_rates_len,
|
|
|
+ peer->ht_capabilities,
|
|
|
+ peer->vht_capabilities,
|
|
|
+ peer->qos_info, peer->ext_capab,
|
|
|
+ peer->ext_capab_len) < 0)
|
|
|
+ return -1;
|
|
|
|
|
|
- wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
|
|
|
+ if (peer->reconfig_key && wpa_tdls_set_key(sm, peer) < 0) {
|
|
|
+ wpa_printf(MSG_INFO, "TDLS: Could not configure key to the "
|
|
|
+ "driver");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ peer->reconfig_key = 0;
|
|
|
+
|
|
|
+ return wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1800,6 +1811,7 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
|
|
|
int ielen;
|
|
|
u16 status;
|
|
|
const u8 *pos;
|
|
|
+ int ret;
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
|
|
|
"(Peer " MACSTR ")", MAC2STR(src_addr));
|
|
@@ -1992,7 +2004,15 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- wpa_tdls_set_key(sm, peer);
|
|
|
+ if (wpa_tdls_set_key(sm, peer) < 0) {
|
|
|
+ /*
|
|
|
+ * Some drivers may not be able to config the key prior to full
|
|
|
+ * STA entry having been configured.
|
|
|
+ */
|
|
|
+ wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
|
|
|
+ "STA entry is complete");
|
|
|
+ peer->reconfig_key = 1;
|
|
|
+ }
|
|
|
|
|
|
skip_rsn:
|
|
|
peer->dtoken = dtoken;
|
|
@@ -2001,9 +2021,13 @@ skip_rsn:
|
|
|
"TPK Handshake Message 3");
|
|
|
wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);
|
|
|
|
|
|
- wpa_tdls_enable_link(sm, peer);
|
|
|
-
|
|
|
- return 0;
|
|
|
+ ret = wpa_tdls_enable_link(sm, peer);
|
|
|
+ if (ret < 0) {
|
|
|
+ wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
|
|
|
+ wpa_tdls_do_teardown(sm, peer,
|
|
|
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
|
|
|
error:
|
|
|
wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
|
|
@@ -2026,6 +2050,7 @@ static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
|
|
|
u16 status;
|
|
|
const u8 *pos;
|
|
|
u32 lifetime;
|
|
|
+ int ret;
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
|
|
|
"(Peer " MACSTR ")", MAC2STR(src_addr));
|
|
@@ -2136,13 +2161,24 @@ static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- if (wpa_tdls_set_key(sm, peer) < 0)
|
|
|
- return -1;
|
|
|
+ if (wpa_tdls_set_key(sm, peer) < 0) {
|
|
|
+ /*
|
|
|
+ * Some drivers may not be able to config the key prior to full
|
|
|
+ * STA entry having been configured.
|
|
|
+ */
|
|
|
+ wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
|
|
|
+ "STA entry is complete");
|
|
|
+ peer->reconfig_key = 1;
|
|
|
+ }
|
|
|
|
|
|
skip_rsn:
|
|
|
- wpa_tdls_enable_link(sm, peer);
|
|
|
-
|
|
|
- return 0;
|
|
|
+ ret = wpa_tdls_enable_link(sm, peer);
|
|
|
+ if (ret < 0) {
|
|
|
+ wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
|
|
|
+ wpa_tdls_do_teardown(sm, peer,
|
|
|
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
|