wext: Add cfg80211-specific optimization to avoid silly behavior

If the driver is detected to use cfg80211, we can rely on it being able
to disconnect with SIOCSIWMLME commands and to use empty SSID as a way
to stop it from associating when we are in progress of configuring the
driver for association. Consequently, we can remove the hack that uses
random 32-octet SSID to force disconnection and re-order association
commands to match the expectations that cfg80211 has for WEXT ioctls.
This gets rid of extra scan rounds and attempts to associate with the
silly 32-octet SSID.
This commit is contained in:
Jouni Malinen 2010-01-12 20:01:09 +02:00
parent b0d77f43f7
commit 3145e6154c
2 changed files with 39 additions and 3 deletions

View file

@ -1,6 +1,6 @@
/* /*
* WPA Supplicant - driver interaction with generic Linux Wireless Extensions * Driver interaction with generic Linux Wireless Extensions
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2010, 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
@ -20,6 +20,7 @@
#include "includes.h" #include "includes.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include "wireless_copy.h" #include "wireless_copy.h"
@ -697,6 +698,8 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
{ {
struct wpa_driver_wext_data *drv; struct wpa_driver_wext_data *drv;
struct netlink_config *cfg; struct netlink_config *cfg;
char path[128];
struct stat buf;
drv = os_zalloc(sizeof(*drv)); drv = os_zalloc(sizeof(*drv));
if (drv == NULL) if (drv == NULL)
@ -704,6 +707,12 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
drv->ctx = ctx; drv->ctx = ctx;
os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname);
if (stat(path, &buf) == 0) {
wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected");
drv->cfg80211 = 1;
}
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (drv->ioctl_sock < 0) { if (drv->ioctl_sock < 0) {
perror("socket(PF_INET,SOCK_DGRAM)"); perror("socket(PF_INET,SOCK_DGRAM)");
@ -1709,6 +1718,19 @@ static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
} }
if (iwr.u.mode == IW_MODE_INFRA) { if (iwr.u.mode == IW_MODE_INFRA) {
if (drv->cfg80211) {
/*
* cfg80211 supports SIOCSIWMLME commands, so there is
* no need for the random SSID hack, but clear the
* BSSID and SSID.
*/
if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) {
wpa_printf(MSG_DEBUG, "WEXT: Failed to clear "
"to disconnect");
}
return;
}
/* /*
* Clear the BSSID selection and set a random SSID to make sure * Clear the BSSID selection and set a random SSID to make sure
* the driver will not be trying to associate with something * the driver will not be trying to associate with something
@ -1858,6 +1880,14 @@ int wpa_driver_wext_associate(void *priv,
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (drv->cfg80211) {
/*
* Stop cfg80211 from trying to associate before we are done
* with all parameters.
*/
wpa_driver_wext_set_ssid(drv, (u8 *) "", 0);
}
if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted) if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted)
< 0) < 0)
ret = -1; ret = -1;
@ -1945,11 +1975,15 @@ int wpa_driver_wext_associate(void *priv,
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */
if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0) if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
ret = -1; ret = -1;
if (wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0) if (!drv->cfg80211 &&
wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
ret = -1; ret = -1;
if (params->bssid && if (params->bssid &&
wpa_driver_wext_set_bssid(drv, params->bssid) < 0) wpa_driver_wext_set_bssid(drv, params->bssid) < 0)
ret = -1; ret = -1;
if (drv->cfg80211 &&
wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
ret = -1;
return ret; return ret;
} }

View file

@ -43,6 +43,8 @@ struct wpa_driver_wext_data {
char mlmedev[IFNAMSIZ + 1]; char mlmedev[IFNAMSIZ + 1];
int scan_complete_events; int scan_complete_events;
int cfg80211; /* whether driver is using cfg80211 */
}; };
int wpa_driver_wext_get_bssid(void *priv, u8 *bssid); int wpa_driver_wext_get_bssid(void *priv, u8 *bssid);