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 <jouni@qca.qualcomm.com>
This commit is contained in:
Sunil Dutt 2013-02-12 23:25:21 +02:00 committed by Jouni Malinen
parent a5b5e830a0
commit 7b44ff2c21
3 changed files with 31 additions and 2 deletions

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

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

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