TDLS: Tear down peers when disconnecting from the AP
authorSunil Dutt <duttus@codeaurora.org>
Tue, 12 Feb 2013 21:25:21 +0000 (23:25 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 12 Feb 2013 23:19:44 +0000 (01:19 +0200)
A TDLS Teardown frame with Reason Code 3 (Deauthenticated because
sending STA is leaving (or has left) IBSS or ESS) shall be transmitted
to all TDLS peer STAs (via the AP or via the direct path) prior to
transmitting a Disassociation frame or a Deauthentication frame to the
AP.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/rsn_supp/tdls.c
src/rsn_supp/wpa.h
wpa_supplicant/wpa_supplicant.c

index 9a79d28..59929b5 100644 (file)
@@ -681,8 +681,10 @@ int wpa_tdls_send_teardown(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
        pos = rbuf;
 
        if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success) {
-               /* Overwrite the reason code */
-               reason_code = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
+               if (reason_code != WLAN_REASON_DEAUTH_LEAVING) {
+                       /* Overwrite the reason code */
+                       reason_code = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
+               }
                goto skip_ies;
        }
 
@@ -2207,6 +2209,28 @@ int wpa_tdls_init(struct wpa_sm *sm)
 }
 
 
+void wpa_tdls_teardown_peers(struct wpa_sm *sm)
+{
+       struct wpa_tdls_peer *peer;
+
+       peer = sm->tdls;
+
+       wpa_printf(MSG_DEBUG, "TDLS: Tear down peers");
+
+       while (peer) {
+               wpa_printf(MSG_DEBUG, "TDLS: Tear down peer " MACSTR,
+                          MAC2STR(peer->addr));
+               if (sm->tdls_external_setup)
+                       wpa_tdls_send_teardown(sm, peer->addr,
+                                              WLAN_REASON_DEAUTH_LEAVING);
+               else
+                       wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);
+
+               peer = peer->next;
+       }
+}
+
+
 static void wpa_tdls_remove_peers(struct wpa_sm *sm)
 {
        struct wpa_tdls_peer *peer, *tmp;
index 2c989b7..eedbb2d 100644 (file)
@@ -360,6 +360,7 @@ int wpa_tdls_send_teardown(struct wpa_sm *sm, const u8 *addr, u16 reason_code);
 int wpa_tdls_teardown_link(struct wpa_sm *sm, const u8 *addr, u16 reason_code);
 int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr);
 int wpa_tdls_init(struct wpa_sm *sm);
+void wpa_tdls_teardown_peers(struct wpa_sm *sm);
 void wpa_tdls_deinit(struct wpa_sm *sm);
 void wpa_tdls_enable(struct wpa_sm *sm, int enabled);
 void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr);
index ae4f22f..ef7a6f0 100644 (file)
@@ -1709,6 +1709,10 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
                zero_addr = 1;
        }
 
+#ifdef CONFIG_TDLS
+       wpa_tdls_teardown_peers(wpa_s->wpa);
+#endif /* CONFIG_TDLS */
+
        if (addr) {
                wpa_drv_deauthenticate(wpa_s, addr, reason_code);
                os_memset(&event, 0, sizeof(event));