Do not trigger fast reconnection on locally generated deauth/disassoc
The deauthentication and disassociation events from nl80211 were being processed identically regardless of whether the frame was generated by the local STA or the AP. This resulted in fast reconnection mechanism getting triggered even in the case where the disconnection was detected locally (e.g., due to beacon loss) while this was supposed to happen only in the case where the AP is sending an explicit Deauthentication or Disassociation frame with a specific reason code. Fix this by adding a new deauth/disassoc event variable to indicate whether the event was generated locally. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
0be3542338
commit
3d9975d5b0
3 changed files with 40 additions and 11 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Driver interface definition
|
* Driver interface definition
|
||||||
* Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -3028,6 +3028,11 @@ union wpa_event_data {
|
||||||
* ie_len - Length of ie buffer in octets
|
* ie_len - Length of ie buffer in octets
|
||||||
*/
|
*/
|
||||||
size_t ie_len;
|
size_t ie_len;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* locally_generated - Whether the frame was locally generated
|
||||||
|
*/
|
||||||
|
int locally_generated;
|
||||||
} disassoc_info;
|
} disassoc_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3054,6 +3059,11 @@ union wpa_event_data {
|
||||||
* ie_len - Length of ie buffer in octets
|
* ie_len - Length of ie buffer in octets
|
||||||
*/
|
*/
|
||||||
size_t ie_len;
|
size_t ie_len;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* locally_generated - Whether the frame was locally generated
|
||||||
|
*/
|
||||||
|
int locally_generated;
|
||||||
} deauth_info;
|
} deauth_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Driver interaction with Linux nl80211/cfg80211
|
* Driver interaction with Linux nl80211/cfg80211
|
||||||
* Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
||||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
||||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
||||||
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
|
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
@ -1151,7 +1151,8 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
|
||||||
|
|
||||||
|
|
||||||
static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
|
static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
|
||||||
struct nlattr *reason, struct nlattr *addr)
|
struct nlattr *reason, struct nlattr *addr,
|
||||||
|
struct nlattr *by_ap)
|
||||||
{
|
{
|
||||||
union wpa_event_data data;
|
union wpa_event_data data;
|
||||||
|
|
||||||
|
@ -1169,6 +1170,7 @@ static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
|
||||||
os_memset(&data, 0, sizeof(data));
|
os_memset(&data, 0, sizeof(data));
|
||||||
if (reason)
|
if (reason)
|
||||||
data.disassoc_info.reason_code = nla_get_u16(reason);
|
data.disassoc_info.reason_code = nla_get_u16(reason);
|
||||||
|
data.disassoc_info.locally_generated = by_ap == NULL;
|
||||||
wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
|
wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,6 +1311,8 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
|
||||||
reason_code = le_to_host16(mgmt->u.deauth.reason_code);
|
reason_code = le_to_host16(mgmt->u.deauth.reason_code);
|
||||||
|
|
||||||
if (type == EVENT_DISASSOC) {
|
if (type == EVENT_DISASSOC) {
|
||||||
|
event.disassoc_info.locally_generated =
|
||||||
|
!os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
|
||||||
event.disassoc_info.addr = bssid;
|
event.disassoc_info.addr = bssid;
|
||||||
event.disassoc_info.reason_code = reason_code;
|
event.disassoc_info.reason_code = reason_code;
|
||||||
if (frame + len > mgmt->u.disassoc.variable) {
|
if (frame + len > mgmt->u.disassoc.variable) {
|
||||||
|
@ -1317,6 +1321,8 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
|
||||||
mgmt->u.disassoc.variable;
|
mgmt->u.disassoc.variable;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
event.deauth_info.locally_generated =
|
||||||
|
!os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
|
||||||
event.deauth_info.addr = bssid;
|
event.deauth_info.addr = bssid;
|
||||||
event.deauth_info.reason_code = reason_code;
|
event.deauth_info.reason_code = reason_code;
|
||||||
if (frame + len > mgmt->u.deauth.variable) {
|
if (frame + len > mgmt->u.deauth.variable) {
|
||||||
|
@ -2083,7 +2089,8 @@ static void do_process_drv_event(struct wpa_driver_nl80211_data *drv,
|
||||||
break;
|
break;
|
||||||
case NL80211_CMD_DISCONNECT:
|
case NL80211_CMD_DISCONNECT:
|
||||||
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
|
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
|
||||||
tb[NL80211_ATTR_MAC]);
|
tb[NL80211_ATTR_MAC],
|
||||||
|
tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
|
||||||
break;
|
break;
|
||||||
case NL80211_CMD_MICHAEL_MIC_FAILURE:
|
case NL80211_CMD_MICHAEL_MIC_FAILURE:
|
||||||
mlme_event_michael_mic_failure(drv, tb);
|
mlme_event_michael_mic_failure(drv, tb);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - Driver event processing
|
* WPA Supplicant - Driver event processing
|
||||||
* Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -1543,7 +1543,8 @@ static int disconnect_reason_recoverable(u16 reason_code)
|
||||||
|
|
||||||
|
|
||||||
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
|
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
|
||||||
u16 reason_code)
|
u16 reason_code,
|
||||||
|
int locally_generated)
|
||||||
{
|
{
|
||||||
const u8 *bssid;
|
const u8 *bssid;
|
||||||
int authenticating;
|
int authenticating;
|
||||||
|
@ -1579,6 +1580,7 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->wpa_state == WPA_COMPLETED &&
|
if (wpa_s->wpa_state == WPA_COMPLETED &&
|
||||||
wpa_s->current_ssid &&
|
wpa_s->current_ssid &&
|
||||||
wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
|
wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
|
||||||
|
!locally_generated &&
|
||||||
disconnect_reason_recoverable(reason_code)) {
|
disconnect_reason_recoverable(reason_code)) {
|
||||||
/*
|
/*
|
||||||
* It looks like the AP has dropped association with
|
* It looks like the AP has dropped association with
|
||||||
|
@ -1991,6 +1993,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
u16 reason_code = 0;
|
u16 reason_code = 0;
|
||||||
|
int locally_generated = 0;
|
||||||
|
|
||||||
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
|
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
|
||||||
event != EVENT_INTERFACE_ENABLED &&
|
event != EVENT_INTERFACE_ENABLED &&
|
||||||
|
@ -2032,8 +2035,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
case EVENT_DISASSOC:
|
case EVENT_DISASSOC:
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
|
wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
|
||||||
if (data) {
|
if (data) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u",
|
wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
|
||||||
data->disassoc_info.reason_code);
|
data->disassoc_info.reason_code,
|
||||||
|
data->disassoc_info.locally_generated ?
|
||||||
|
" (locally generated)" : "");
|
||||||
if (data->disassoc_info.addr)
|
if (data->disassoc_info.addr)
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
|
wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
|
||||||
MAC2STR(data->disassoc_info.addr));
|
MAC2STR(data->disassoc_info.addr));
|
||||||
|
@ -2052,6 +2057,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
if (data) {
|
if (data) {
|
||||||
reason_code = data->disassoc_info.reason_code;
|
reason_code = data->disassoc_info.reason_code;
|
||||||
|
locally_generated =
|
||||||
|
data->disassoc_info.locally_generated;
|
||||||
wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
|
wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
|
||||||
data->disassoc_info.ie,
|
data->disassoc_info.ie,
|
||||||
data->disassoc_info.ie_len);
|
data->disassoc_info.ie_len);
|
||||||
|
@ -2071,8 +2078,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
"Deauthentication notification");
|
"Deauthentication notification");
|
||||||
if (data) {
|
if (data) {
|
||||||
reason_code = data->deauth_info.reason_code;
|
reason_code = data->deauth_info.reason_code;
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u",
|
locally_generated =
|
||||||
data->deauth_info.reason_code);
|
data->deauth_info.locally_generated;
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
|
||||||
|
data->deauth_info.reason_code,
|
||||||
|
data->deauth_info.locally_generated ?
|
||||||
|
" (locally generated)" : "");
|
||||||
if (data->deauth_info.addr) {
|
if (data->deauth_info.addr) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, " * address "
|
wpa_dbg(wpa_s, MSG_DEBUG, " * address "
|
||||||
MACSTR,
|
MACSTR,
|
||||||
|
@ -2104,7 +2115,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_AP */
|
#endif /* CONFIG_AP */
|
||||||
wpa_supplicant_event_disassoc(wpa_s, reason_code);
|
wpa_supplicant_event_disassoc(wpa_s, reason_code,
|
||||||
|
locally_generated);
|
||||||
break;
|
break;
|
||||||
case EVENT_MICHAEL_MIC_FAILURE:
|
case EVENT_MICHAEL_MIC_FAILURE:
|
||||||
wpa_supplicant_event_michael_mic_failure(wpa_s, data);
|
wpa_supplicant_event_michael_mic_failure(wpa_s, data);
|
||||||
|
|
Loading…
Reference in a new issue