diff options
author | Jouni Malinen <jouni@qca.qualcomm.com> | 2012-08-31 22:04:41 +0300 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2012-09-09 13:06:48 -0700 |
commit | 2b89da85b8cfe9bb862e8dd334855263c3522c00 (patch) | |
tree | ea0e7f7039b8be2a2c9d5d4e9069d5cdfb057732 | |
parent | a831d78b5fb6af549533456cda57f88d73f6d153 (diff) | |
download | external_wpa_supplicant_8-2b89da85b8cfe9bb862e8dd334855263c3522c00.zip external_wpa_supplicant_8-2b89da85b8cfe9bb862e8dd334855263c3522c00.tar.gz external_wpa_supplicant_8-2b89da85b8cfe9bb862e8dd334855263c3522c00.tar.bz2 |
Fix disconnection event processing
Commit 0d30cc240fa36905b034dc9676f9d8da0ac18e56 forced
wpa_s->current_ssid and wpa_s->key_mgmt to be cleared in
wpa_supplicant_mark_disassoc() which gets called from
wpa_supplicant_event_disassoc(). This broke IEEE 802.1X authentication
failure processing and P2P deauthentication notification (group
termination).
Fix this by splitting wpa_supplicant_event_disassoc() into two parts and
make wpas_p2p_deauth_notif() indicate whether the interface was removed.
If so, the last part of disassocition event processing is skipped. Since
the wpa_supplicant_mark_disassoc() call is in the second part, the above
mentioned issues are resolved. In addition, this cleans up the P2P group
interface removal case by not trying to use fast reconnection mechanism
just before the interface gets removed.
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
-rw-r--r-- | wpa_supplicant/events.c | 56 | ||||
-rw-r--r-- | wpa_supplicant/p2p_supplicant.c | 24 | ||||
-rw-r--r-- | wpa_supplicant/p2p_supplicant.h | 6 |
3 files changed, 62 insertions, 24 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index a610008..48faff2 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1809,6 +1809,35 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, int locally_generated) { const u8 *bssid; + + if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { + /* + * At least Host AP driver and a Prism3 card seemed to be + * generating streams of disconnected events when configuring + * IBSS for WPA-None. Ignore them for now. + */ + return; + } + + bssid = wpa_s->bssid; + if (is_zero_ether_addr(bssid)) + bssid = wpa_s->pending_bssid; + + if (!is_zero_ether_addr(bssid) || + wpa_s->wpa_state >= WPA_AUTHENTICATING) { + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR + " reason=%d%s", + MAC2STR(bssid), reason_code, + locally_generated ? " locally_generated=1" : ""); + } +} + + +static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, + u16 reason_code, + int locally_generated) +{ + const u8 *bssid; int authenticating; u8 prev_pending_bssid[ETH_ALEN]; struct wpa_bss *fast_reconnect = NULL; @@ -1880,13 +1909,6 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, else wpa_s->disconnect_reason = reason_code; wpas_notify_disconnect_reason(wpa_s); - if (!is_zero_ether_addr(bssid) || - wpa_s->wpa_state >= WPA_AUTHENTICATING) { - wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR - " reason=%d%s", - MAC2STR(bssid), reason_code, - locally_generated ? " locally_generated=1" : ""); - } if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; @@ -2415,13 +2437,23 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpas_auth_failed(wpa_s); #ifdef CONFIG_P2P if (event == EVENT_DEAUTH && data) { - wpas_p2p_deauth_notif(wpa_s, data->deauth_info.addr, - reason_code, - data->deauth_info.ie, - data->deauth_info.ie_len, - locally_generated); + if (wpas_p2p_deauth_notif(wpa_s, + data->deauth_info.addr, + reason_code, + data->deauth_info.ie, + data->deauth_info.ie_len, + locally_generated) > 0) { + /* + * The interface was removed, so cannot + * continue processing any additional + * operations after this. + */ + break; + } } #endif /* CONFIG_P2P */ + wpa_supplicant_event_disassoc_finish(wpa_s, reason_code, + locally_generated); break; case EVENT_MICHAEL_MIC_FAILURE: wpa_supplicant_event_michael_mic_failure(wpa_s, data); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index cfe0433..94a8658 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -374,7 +374,7 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, if (wpa_s && ifname) wpa_drv_if_remove(wpa_s, type, ifname); os_free(ifname); - return 0; + return 1; } wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network"); @@ -4709,14 +4709,15 @@ static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s) } -void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, - u16 reason_code, const u8 *ie, size_t ie_len, - int locally_generated) +/* Returns 1 if the interface was removed */ +int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, + u16 reason_code, const u8 *ie, size_t ie_len, + int locally_generated) { if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) - return; + return 0; if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) - return; + return 0; if (!locally_generated) p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, @@ -4728,9 +4729,13 @@ void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, wpa_s->current_ssid->mode == WPAS_MODE_INFRA) { wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group " "session is ending"); - wpas_p2p_group_delete(wpa_s, - P2P_GROUP_REMOVAL_GO_ENDING_SESSION); + if (wpas_p2p_group_delete(wpa_s, + P2P_GROUP_REMOVAL_GO_ENDING_SESSION) + > 0) + return 1; } + + return 0; } @@ -5165,7 +5170,8 @@ int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s) if (wpa_s == NULL) return -1; - return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED); + return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ? + -1 : 0; } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index bbdd83e..dfa39f2 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -120,9 +120,9 @@ int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, u32 interval1, u32 duration2, u32 interval2); int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period, unsigned int interval); -void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, - u16 reason_code, const u8 *ie, size_t ie_len, - int locally_generated); +int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, + u16 reason_code, const u8 *ie, size_t ie_len, + int locally_generated); void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, u16 reason_code, const u8 *ie, size_t ie_len, int locally_generated); |