Cumulative patch from commit c2db79f2376c61c21918162fb2222a66c029fa48

c2db79f VLAN: Remove vlan_tail
f7b4ef2 TDLS: Handle transmission failures of TPK Handshake messages
a2ea8d6 P2P: Fix invalid remain-on-channel duration for frame TX
cbf41ca P2P: Do not delay retries on failure during group formation
dc01de8 nl80211: Fix TDLS key configuration to not set TX key index

Change-Id: Id2418699c3ce49a7e198ab9c0d718ab4a713df62
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index c9b2599..b340c1e 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -327,7 +327,7 @@
 	int wmm_enabled;
 	int wmm_uapsd;
 
-	struct hostapd_vlan *vlan, *vlan_tail;
+	struct hostapd_vlan *vlan;
 
 	macaddr bssid;
 
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 21235f2..d38330f 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -689,15 +689,19 @@
 	if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
 		sta->vlan_id = 0;
 	else if (sta->vlan_id > 0) {
+		struct hostapd_vlan *wildcard_vlan = NULL;
 		vlan = hapd->conf->vlan;
 		while (vlan) {
-			if (vlan->vlan_id == sta->vlan_id ||
-			    vlan->vlan_id == VLAN_ID_WILDCARD) {
-				iface = vlan->ifname;
+			if (vlan->vlan_id == sta->vlan_id)
 				break;
-			}
+			if (vlan->vlan_id == VLAN_ID_WILDCARD)
+				wildcard_vlan = vlan;
 			vlan = vlan->next;
 		}
+		if (!vlan)
+			vlan = wildcard_vlan;
+		if (vlan)
+			iface = vlan->ifname;
 	}
 
 	if (sta->vlan_id > 0 && vlan == NULL) {
diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c
index 70affda..746af40 100644
--- a/src/ap/vlan_init.c
+++ b/src/ap/vlan_init.c
@@ -1004,11 +1004,8 @@
 		vlan->vlan_id = VLAN_ID_WILDCARD;
 		os_snprintf(vlan->ifname, sizeof(vlan->ifname), "%s.#",
 			    hapd->conf->iface);
-		if (hapd->conf->vlan_tail)
-			hapd->conf->vlan_tail->next = vlan;
-		else
-			hapd->conf->vlan = vlan;
-		hapd->conf->vlan_tail = vlan;
+		vlan->next = hapd->conf->vlan;
+		hapd->conf->vlan = vlan;
 	}
 
 	if (vlan_dynamic_add(hapd, hapd->conf->vlan))
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index eaecc36..9b0e6d7 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4893,6 +4893,7 @@
 	int ifindex;
 	struct nl_msg *msg;
 	int ret;
+	int tdls = 0;
 
 	/* Ignore for P2P Device */
 	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -4904,8 +4905,10 @@
 		   __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
 		   (unsigned long) seq_len, (unsigned long) key_len);
 #ifdef CONFIG_TDLS
-	if (key_idx == -1)
+	if (key_idx == -1) {
 		key_idx = 0;
+		tdls = 1;
+	}
 #endif /* CONFIG_TDLS */
 
 	msg = nlmsg_alloc();
@@ -4995,7 +4998,7 @@
 	 * If we failed or don't need to set the default TX key (below),
 	 * we're done here.
 	 */
-	if (ret || !set_tx || alg == WPA_ALG_NONE)
+	if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
 		return ret;
 	if (is_ap_interface(drv->nlmode) && addr &&
 	    !is_broadcast_ether_addr(addr))
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 539aa25..b7ca075 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -932,6 +932,7 @@
 	u8 *rbuf, *pos, *count_pos;
 	u16 count;
 	struct rsn_ie_hdr *hdr;
+	int status;
 
 	if (!wpa_tdls_get_privacy(sm)) {
 		wpa_printf(MSG_DEBUG, "TDLS: No security used on the link");
@@ -1092,11 +1093,11 @@
 		   "Handshake Message 1 (peer " MACSTR ")",
 		   MAC2STR(peer->addr));
 
-	wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, 1, 0,
-			  rbuf, pos - rbuf);
+	status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST,
+				   1, 0, rbuf, pos - rbuf);
 	os_free(rbuf);
 
-	return 0;
+	return status;
 }
 
 
@@ -1110,6 +1111,7 @@
 	u32 lifetime;
 	struct wpa_tdls_timeoutie timeoutie;
 	struct wpa_tdls_ftie *ftie;
+	int status;
 
 	buf_len = 0;
 	if (wpa_tdls_get_privacy(sm)) {
@@ -1175,11 +1177,11 @@
 			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
 
 skip_ies:
-	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
-			  rbuf, pos - rbuf);
+	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
+				   dtoken, 0, rbuf, pos - rbuf);
 	os_free(rbuf);
 
-	return 0;
+	return status;
 }
 
 
@@ -1193,6 +1195,7 @@
 	struct wpa_tdls_ftie *ftie;
 	struct wpa_tdls_timeoutie timeoutie;
 	u32 lifetime;
+	int status;
 
 	buf_len = 0;
 	if (wpa_tdls_get_privacy(sm)) {
@@ -1256,11 +1259,11 @@
 			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);
 
 skip_ies:
-	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 0,
-			  rbuf, pos - rbuf);
+	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
+				   dtoken, 0, rbuf, pos - rbuf);
 	os_free(rbuf);
 
-	return 0;
+	return status;
 }
 
 
@@ -2030,7 +2033,10 @@
 
 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
 		   "TPK Handshake Message 3");
-	wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);
+	if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0) {
+		wpa_tdls_disable_link(sm, peer->addr);
+		return -1;
+	}
 
 	ret = wpa_tdls_enable_link(sm, peer);
 	if (ret < 0) {
@@ -2043,8 +2049,7 @@
 error:
 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
 			    status);
-	if (sm->tdls_external_setup)
-		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
+	wpa_tdls_disable_link(sm, peer->addr);
 	return -1;
 }