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));