]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
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 9a79d28ce0e37d1e58d2f9d7205c08aebe3df387..59929b518bd3ce604734e06c4c91b4927f65ea0f 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 2c989b72f74dbe360927eb8930cf6cb15a22ab9d..eedbb2d9559704b6011157faffb2456093928652 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 ae4f22f4e03fa28dd06778574e55d01c56a4e660..ef7a6f0698470dee714edd6a92e912b80a5ccb68 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));