TDLS: Handle unreachable link teardown for external setup

If a link is unreachable, the specification mandates we should send a
teardown packet via the AP with a specific teardown reason. Force this
by first disabling the link and only then sending the teardown packet
for the LOW_ACK event.

Rename the TDLS LOW_ACK event handler to better reflect its purpose.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
This commit is contained in:
Arik Nemtsov 2014-06-10 21:19:04 +03:00 committed by Jouni Malinen
parent 7eb33a8f99
commit 947f900fb8
3 changed files with 22 additions and 4 deletions

View file

@ -802,7 +802,7 @@ static void wpa_tdls_disable_peer_link(struct wpa_sm *sm,
} }
void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr) void wpa_tdls_disable_unreachable_link(struct wpa_sm *sm, const u8 *addr)
{ {
struct wpa_tdls_peer *peer; struct wpa_tdls_peer *peer;
@ -811,8 +811,25 @@ void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
break; break;
} }
if (peer) if (!peer || !peer->tpk_success) {
wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
" not connected - cannot teardown unreachable link",
MAC2STR(addr));
return;
}
if (wpa_tdls_is_external_setup(sm)) {
/*
* Disable the link, send a teardown packet through the
* AP, and then reset link data.
*/
wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
wpa_tdls_send_teardown(sm, addr,
WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE);
wpa_tdls_peer_free(sm, peer);
} else {
wpa_tdls_disable_peer_link(sm, peer); wpa_tdls_disable_peer_link(sm, peer);
}
} }

View file

@ -385,7 +385,7 @@ int wpa_tdls_init(struct wpa_sm *sm);
void wpa_tdls_teardown_peers(struct wpa_sm *sm); void wpa_tdls_teardown_peers(struct wpa_sm *sm);
void wpa_tdls_deinit(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_enable(struct wpa_sm *sm, int enabled);
void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr); void wpa_tdls_disable_unreachable_link(struct wpa_sm *sm, const u8 *addr);
const char * wpa_tdls_get_link_status(struct wpa_sm *sm, const u8 *addr); const char * wpa_tdls_get_link_status(struct wpa_sm *sm, const u8 *addr);
int wpa_tdls_is_external_setup(struct wpa_sm *sm); int wpa_tdls_is_external_setup(struct wpa_sm *sm);

View file

@ -3402,7 +3402,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#endif /* CONFIG_AP */ #endif /* CONFIG_AP */
#ifdef CONFIG_TDLS #ifdef CONFIG_TDLS
if (data) if (data)
wpa_tdls_disable_link(wpa_s->wpa, data->low_ack.addr); wpa_tdls_disable_unreachable_link(wpa_s->wpa,
data->low_ack.addr);
#endif /* CONFIG_TDLS */ #endif /* CONFIG_TDLS */
break; break;
case EVENT_IBSS_PEER_LOST: case EVENT_IBSS_PEER_LOST: