Failed to connect an AP vai WPS on kernel >= 3.11

Jouni Malinen j
Wed Aug 26 03:06:04 PDT 2015

On Wed, Aug 26, 2015 at 09:54:54AM +0000, Vinayak Kamath wrote:
> We are facing WPS issue due to NL80211_CMD_DISCONNECT received from cfg80211 when supplicant initiate a disconnect after success WPS handshake. As a result supplicant does not attempt to associate with AP and connection fails. 

Would you be able to share a debug log showing this?

> Could you please review the patch shared below.
> Patch  ignores NL80211_CMD_DISCONNECT from cfg80211 if it is indication for local initiated disconnect.

Locally initiated? The place in which this new code is added is
immediately after "if (locally_generated) { ... return; }" and as such,
it is quite difficult to understand how it would do what you describe

> Subject: [PATCH 1/1] nl80211: Ignore NL80211_CMD_DISCONNECT after WPS
> Linux kernel >= 3.11 expects wlan driver to indicate disconnect event
> to cfg80211 even in case of disconnect initiated by wpa_supplicant
> (i.e locally generated). Hence cfg80211 sends NL80211_CMD_DISCONNECT
> to wpa_supplicant which leads to failure of WPS process and STA avoids
> connect attempt with AP even after successful WPS handshake.

I do not see this in my tests which is why I'd need to see a detailed
wpa_supplicant debug log showing the issue so that I can figure out why
this happens. Please note that wpa_supplicant already has code for
ignoring the local-disconnect event (drv->ignore_next_local_disconnect).

> diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
> @@ -394,6 +394,11 @@ static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,

This is missing the key part in context here:
		  if (locally_generated) {
>                         wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
>                                    "event triggered during reassociation");
>                         return;
> +               } else if ((nla_get_u16(reason) ==  WLAN_REASON_DEAUTH_LEAVING) &&
> +                               !(drv->associated)) {
> +                       wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
> +                               "resulted part of local disconnection");
> +                       return;
>                 }

How would this be "local disconnect" if the only way of getting there is
if !locally_generated... (locally_generated = by_ap == NULL)

This new check would require NL80211_ATTR_DISCONNECT_BY_AP to be present
and that does not sound at all correct.. I guess that !drv->associated
would remove some cases, but this is just way to confusing to be
acceptable without additional comments describing the logic here.

Jouni Malinen                                            PGP id EFC895FA

More information about the Hostap mailing list