From 7b44ff2c21f588d6d042809ef4cc2c7f47974735 Mon Sep 17 00:00:00 2001 From: Sunil Dutt Date: Tue, 12 Feb 2013 23:25:21 +0200 Subject: [PATCH] TDLS: Tear down peers when disconnecting from the AP 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 --- src/rsn_supp/tdls.c | 28 ++++++++++++++++++++++++++-- src/rsn_supp/wpa.h | 1 + wpa_supplicant/wpa_supplicant.c | 4 ++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 9a79d28ce..59929b518 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -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; diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 2c989b72f..eedbb2d95 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -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); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index ae4f22f4e..ef7a6f069 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -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));