Accumulative patch from commit 97279d8d1ad40bd7d884af8e2fc26dff0163331a

97279d8 nl80211: Drop frame events that are for foreign address
cc2ada8 nl80211: Reduce debug on Probe Request frames
63a965c P2P: Fix after_scan_tx processing during ongoing operations
06b7f58 RSN: Update preauth scan results only based on new scan results
18e00b5 Move wpa_s freeing into wpa_supplicant_deinit_iface()
754632c dbus_new: Add EAP logon/logoff
c2aff6b hostapd: Add some testing options
adc96dc nl80211: Fix nla_nest_start conversion
0606052 wpa_supplicant: Add get_capability freq
c7a39ba Provide TLS alerts to CLI/UI over control interface
2a07a27 P2P: Increase GTK rekeying period to 24 hours
75fa7d1 TDLS: Fix key configuration with current mac80211
8970bae nl80211: Use nla_nest_start/end instead of nla_put_nested

Change-Id: Ic4b568c341657d266b7759513230d4ef206d75b1
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 8ceaf6c..069e22b 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -86,6 +86,7 @@
 
 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 @@
 		   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 @@
 }
 
 
-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 @@
 	}
 
 	/* 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 @@
 	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 @@
 		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 @@
 		   "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 @@
 	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 @@
 		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;
 }