Browse Source

TDLS: Clear peer entries on association/disassociation

Since the TDLS links are allowed only to STAs that are in the same
BSS with us, clear all peer data whenever the BSS may have changed.
Jouni Malinen 14 years ago
parent
commit
40cf22e6ff
3 changed files with 45 additions and 12 deletions
  1. 35 12
      src/rsn_supp/tdls.c
  2. 7 0
      src/rsn_supp/wpa.c
  3. 3 0
      src/rsn_supp/wpa_i.h

+ 35 - 12
src/rsn_supp/tdls.c

@@ -1765,6 +1765,26 @@ int wpa_tdls_init(struct wpa_sm *sm)
 }
 
 
+static void wpa_tdls_remove_peers(struct wpa_sm *sm)
+{
+	struct wpa_tdls_peer *peer, *tmp;
+
+	peer = sm->tdls;
+	sm->tdls = NULL;
+
+	while (peer) {
+		int res;
+		tmp = peer->next;
+		res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
+		wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
+			   MAC2STR(peer->addr), res);
+		wpa_supplicant_peer_free(sm, peer);
+		os_free(peer);
+		peer = tmp;
+	}
+}
+
+
 /**
  * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
  *
@@ -1773,8 +1793,6 @@ int wpa_tdls_init(struct wpa_sm *sm)
  */
 void wpa_tdls_deinit(struct wpa_sm *sm)
 {
-	struct wpa_tdls_peer *peer;
-
 	if (sm == NULL)
 		return;
 
@@ -1782,14 +1800,19 @@ void wpa_tdls_deinit(struct wpa_sm *sm)
 		l2_packet_deinit(sm->l2_tdls);
 	sm->l2_tdls = NULL;
 
-	peer = sm->tdls;
-	while (peer) {
-		struct wpa_tdls_peer *tmp;
-		tmp = peer->next;
-		/* clear tdls sm */
-		wpa_supplicant_peer_free(sm, peer);
-		os_free(peer);
-		peer = tmp;
-	}
-	sm->tdls = NULL;
+	wpa_tdls_remove_peers(sm);
+}
+
+
+void wpa_tdls_assoc(struct wpa_sm *sm)
+{
+	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
+	wpa_tdls_remove_peers(sm);
+}
+
+
+void wpa_tdls_disassoc(struct wpa_sm *sm)
+{
+	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
+	wpa_tdls_remove_peers(sm);
 }

+ 7 - 0
src/rsn_supp/wpa.c

@@ -2128,6 +2128,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
 		sm->ptk_set = 0;
 		sm->tptk_set = 0;
 	}
+
+#ifdef CONFIG_TDLS
+	wpa_tdls_assoc(sm);
+#endif /* CONFIG_TDLS */
 }
 
 
@@ -2143,6 +2147,9 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm)
 	rsn_preauth_deinit(sm);
 	if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
 		sm->dot11RSNA4WayHandshakeFailures++;
+#ifdef CONFIG_TDLS
+	wpa_tdls_disassoc(sm);
+#endif /* CONFIG_TDLS */
 }
 
 

+ 3 - 0
src/rsn_supp/wpa_i.h

@@ -282,4 +282,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 		      const struct wpa_eapol_key *key,
 		      struct wpa_ptk *ptk, size_t ptk_len);
 
+void wpa_tdls_assoc(struct wpa_sm *sm);
+void wpa_tdls_disassoc(struct wpa_sm *sm);
+
 #endif /* WPA_I_H */