* [PATCH] softmac: Fix WX and association related races
@ 2006-09-27 15:26 Michael Buesch
2006-09-27 16:18 ` Larry Finger
2006-09-27 22:20 ` Benjamin Herrenschmidt
0 siblings, 2 replies; 27+ messages in thread
From: Michael Buesch @ 2006-09-27 15:26 UTC (permalink / raw)
To: linville; +Cc: Larry Finger, Benjamin Herrenschmidt, Christian, netdev
This fixes some race conditions in the WirelessExtension
handling and association handling code.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
---
Hi John,
Please apply this fo wireless-2.6 and push it with your
next push of bugfixes.
There are other theoretical raceconditions possible in softmac
related to scanning and assoc code. But I don't really want to fix
these, as I think they:
1) are not triggerable in real world conditions.
2) are not exploitable to do some bad attacks, etc...
3) require _huge_ changes to softmac, and I don't really
want to spend more effort into softmac any longer.
This patch fixes some real-world exploitable bugs, so better
fix them to have working wireless until d80211 is ready for
prime-time.
btw: d80211 might have similiar race conditions like this.
Larry, once this patch settled a little bit and enough people
tested it, you might want to try pushing it into -stable (although
it's big...)
Index: wireless-2.6/include/net/ieee80211softmac.h
===================================================================
--- wireless-2.6.orig/include/net/ieee80211softmac.h 2006-09-25 17:02:08.000000000 +0200
+++ wireless-2.6/include/net/ieee80211softmac.h 2006-09-27 16:39:17.000000000 +0200
@@ -63,13 +63,11 @@ struct ieee80211softmac_wpa {
/*
* Information about association
- *
- * Do we need a lock for this?
- * We only ever use this structure inlined
- * into our global struct. I've used its lock,
- * but maybe we need a local one here?
*/
struct ieee80211softmac_assoc_info {
+
+ struct mutex mutex;
+
/*
* This is the requested ESSID. It is written
* only by the WX handlers.
@@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info {
*
* bssfixed is used for SIOCSIWAP.
*/
- u8 static_essid:1,
- short_preamble_available:1,
- associating:1,
- assoc_wait:1,
- bssvalid:1,
- bssfixed:1;
+ u8 static_essid;
+ u8 short_preamble_available;
+ u8 associating;
+ u8 associated;
+ u8 assoc_wait;
+ u8 bssvalid;
+ u8 bssfixed;
/* Scan retries remaining */
int scan_retry;
@@ -229,12 +228,10 @@ struct ieee80211softmac_device {
/* private stuff follows */
/* this lock protects this structure */
spinlock_t lock;
-
- /* couple of flags */
- u8 scanning:1, /* protects scanning from being done multiple times at once */
- associated:1,
- running:1;
-
+
+ u8 running; /* SoftMAC started? */
+ u8 scanning;
+
struct ieee80211softmac_scaninfo *scaninfo;
struct ieee80211softmac_assoc_info associnfo;
struct ieee80211softmac_bss_info bssinfo;
@@ -250,7 +247,7 @@ struct ieee80211softmac_device {
/* we need to keep a list of network structs we copied */
struct list_head network_list;
-
+
/* This must be the last item so that it points to the data
* allocated beyond this structure by alloc_ieee80211 */
u8 priv[0];
@@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_sugges
{
struct ieee80211softmac_txrates *txrates = &mac->txrates;
- if (!mac->associated)
+ if (!mac->associnfo.associated)
return txrates->mgt_mcast_rate;
/* We are associated, sending unicast frame */
Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-17 15:21:53.000000000 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 17:10:08.000000000 +0200
@@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211s
dprintk(KERN_INFO PFX "sent association request!\n");
spin_lock_irqsave(&mac->lock, flags);
- mac->associated = 0; /* just to make sure */
+ mac->associnfo.associated = 0; /* just to make sure */
/* Set a timer for timeout */
/* FIXME: make timeout configurable */
@@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d)
{
struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
struct ieee80211softmac_network *n;
- unsigned long flags;
- spin_lock_irqsave(&mac->lock, flags);
+ mutex_lock(&mac->associnfo.mutex);
/* we might race against ieee80211softmac_handle_assoc_response,
* so make sure only one of us does something */
- if (!mac->associnfo.associating) {
- spin_unlock_irqrestore(&mac->lock, flags);
- return;
- }
+ if (!mac->associnfo.associating)
+ goto out;
mac->associnfo.associating = 0;
mac->associnfo.bssvalid = 0;
- mac->associated = 0;
+ mac->associnfo.associated = 0;
n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
- spin_unlock_irqrestore(&mac->lock, flags);
dprintk(KERN_INFO PFX "assoc request timed out!\n");
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
+out:
+ mutex_unlock(&mac->associnfo.mutex);
}
void
@@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee802
netif_carrier_off(mac->dev);
- mac->associated = 0;
+ mac->associnfo.associated = 0;
mac->associnfo.bssvalid = 0;
mac->associnfo.associating = 0;
ieee80211softmac_init_bss(mac);
@@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struc
{
struct ieee80211softmac_network *found;
- if (mac->associnfo.bssvalid && mac->associated) {
+ if (mac->associnfo.bssvalid && mac->associnfo.associated) {
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
if (found)
ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
@@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d)
int bssvalid;
unsigned long flags;
+ mutex_lock(&mac->associnfo.mutex);
+
+ if (!mac->associnfo.associating)
+ goto out;
+
/* ieee80211_disassoc might clear this */
bssvalid = mac->associnfo.bssvalid;
/* meh */
- if (mac->associated)
+ if (mac->associnfo.associated)
ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
- spin_lock_irqsave(&mac->lock, flags);
- mac->associnfo.associating = 1;
- spin_unlock_irqrestore(&mac->lock, flags);
-
/* try to find the requested network in our list, if we found one already */
if (bssvalid || mac->associnfo.bssfixed)
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
@@ -260,10 +259,8 @@ ieee80211softmac_assoc_work(void *d)
if (!found) {
if (mac->associnfo.scan_retry > 0) {
- spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.scan_retry--;
- spin_unlock_irqrestore(&mac->lock, flags);
-
+
/* We know of no such network. Let's scan.
* NB: this also happens if we had no memory to copy the network info...
* Maybe we can hope to have more memory after scanning finishes ;)
@@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d)
ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
if (ieee80211softmac_start_scan(mac))
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
- return;
+ goto out;
} else {
- spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.associating = 0;
- mac->associated = 0;
- spin_unlock_irqrestore(&mac->lock, flags);
+ mac->associnfo.associated = 0;
dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
/* reset the retry counter for the next user request since we
* break out and don't reschedule ourselves after this point. */
mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
- return;
+ goto out;
}
}
@@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d)
/* copy the ESSID for displaying it */
mac->associnfo.associate_essid.len = found->essid.len;
memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
-
+
/* we found a network! authenticate (if necessary) and associate to it. */
if (found->authenticating) {
dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
@@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
mac->associnfo.assoc_wait = 1;
ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
}
- return;
+ goto out;
}
if (!found->authenticated && !found->authenticating) {
/* This relies on the fact that _auth_req only queues the work,
@@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d)
mac->associnfo.assoc_wait = 0;
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
}
- return;
+ goto out;
}
/* finally! now we can start associating */
mac->associnfo.assoc_wait = 0;
ieee80211softmac_assoc(mac, found);
+
+out:
+ mutex_unlock(&mac->associnfo.mutex);
}
/* call this to do whatever is necessary when we're associated */
@@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee8
mac->bssinfo.supported_rates = net->supported_rates;
ieee80211softmac_recalc_txrates(mac);
- mac->associated = 1;
+ mac->associnfo.associated = 1;
mac->associnfo.short_preamble_available =
(cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
@@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(s
dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status);
mac->associnfo.associating = 0;
mac->associnfo.bssvalid = 0;
- mac->associated = 0;
+ mac->associnfo.associated = 0;
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network);
}
Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-17 15:21:52.000000000 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-27 16:30:07.000000000 +0200
@@ -57,6 +57,7 @@ struct net_device *alloc_ieee80211softma
INIT_LIST_HEAD(&softmac->network_list);
INIT_LIST_HEAD(&softmac->events);
+ mutex_init(&softmac->associnfo.mutex);
INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac);
INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac);
softmac->start_scan = ieee80211softmac_start_scan_implementation;
Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-17 15:21:53.000000000 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 16:49:25.000000000 +0200
@@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net
struct ieee80211softmac_network *n;
struct ieee80211softmac_auth_queue_item *authptr;
int length = 0;
- unsigned long flags;
+
+ mutex_lock(&sm->associnfo.mutex);
/* Check if we're already associating to this or another network
* If it's another network, cancel and start over with our new network
* If it's our network, ignore the change, we're already doing it!
*/
- if((sm->associnfo.associating || sm->associated) &&
+ if((sm->associnfo.associating || sm->associnfo.associated) &&
(data->essid.flags && data->essid.length && extra)) {
/* Get the associating network */
n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
@@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net
!memcmp(n->essid.data, extra, n->essid.len)) {
dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
MAC_ARG(sm->associnfo.bssid));
- return 0;
+ goto out;
} else {
dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
- spin_lock_irqsave(&sm->lock,flags);
/* Cancel assoc work */
cancel_delayed_work(&sm->associnfo.work);
/* We don't have to do this, but it's a little cleaner */
@@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net
cancel_delayed_work(&authptr->work);
sm->associnfo.bssvalid = 0;
sm->associnfo.bssfixed = 0;
- spin_unlock_irqrestore(&sm->lock,flags);
flush_scheduled_work();
+ sm->associnfo.associating = 0;
+ sm->associnfo.associated = 0;
}
}
- spin_lock_irqsave(&sm->lock, flags);
-
sm->associnfo.static_essid = 0;
sm->associnfo.assoc_wait = 0;
@@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net
* If applicable, we have already copied the data in */
sm->associnfo.req_essid.len = length;
+ sm->associnfo.associating = 1;
/* queue lower level code to do work (if necessary) */
schedule_work(&sm->associnfo.work);
+out:
+ mutex_unlock(&sm->associnfo.mutex);
- spin_unlock_irqrestore(&sm->lock, flags);
return 0;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
@@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net
char *extra)
{
struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
- unsigned long flags;
- /* avoid getting inconsistent information */
- spin_lock_irqsave(&sm->lock, flags);
+ mutex_lock(&sm->associnfo.mutex);
/* If all fails, return ANY (empty) */
data->essid.length = 0;
data->essid.flags = 0; /* active */
@@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net
}
/* If we're associating/associated, return that */
- if (sm->associated || sm->associnfo.associating) {
+ if (sm->associnfo.associated || sm->associnfo.associating) {
data->essid.length = sm->associnfo.associate_essid.len;
data->essid.flags = 1; /* active */
memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
}
- spin_unlock_irqrestore(&sm->lock, flags);
+ mutex_unlock(&sm->associnfo.mutex);
+
return 0;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
@@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_d
{
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
int err = 0;
- unsigned long flags;
- spin_lock_irqsave(&mac->lock, flags);
+ mutex_lock(&mac->associnfo.mutex);
if (mac->associnfo.bssvalid)
memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
else
memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
data->ap_addr.sa_family = ARPHRD_ETHER;
- spin_unlock_irqrestore(&mac->lock, flags);
+ mutex_unlock(&mac->associnfo.mutex);
+
return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
@@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_d
char *extra)
{
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- unsigned long flags;
/* sanity check */
if (data->ap_addr.sa_family != ARPHRD_ETHER) {
return -EINVAL;
}
- spin_lock_irqsave(&mac->lock, flags);
+ mutex_lock(&mac->associnfo.mutex);
if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
/* the bssid we have is not to be fixed any longer,
* and we should reassociate to the best AP. */
mac->associnfo.bssfixed = 0;
/* force reassociation */
mac->associnfo.bssvalid = 0;
- if (mac->associated)
+ if (mac->associnfo.associated)
schedule_work(&mac->associnfo.work);
} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
/* the bssid we have is no longer fixed */
mac->associnfo.bssfixed = 0;
} else {
if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
- if (mac->associnfo.associating || mac->associated) {
+ if (mac->associnfo.associating || mac->associnfo.associated) {
/* bssid unchanged and associated or associating - just return */
goto out;
}
@@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_d
}
out:
- spin_unlock_irqrestore(&mac->lock, flags);
+ mutex_unlock(&mac->associnfo.mutex);
+
return 0;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
@@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net
int err = 0;
char *buf;
int i;
-
+
+ mutex_lock(&mac->associnfo.mutex);
spin_lock_irqsave(&mac->lock, flags);
/* bleh. shouldn't be locked for that kmalloc... */
@@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net
out:
spin_unlock_irqrestore(&mac->lock, flags);
+ mutex_unlock(&mac->associnfo.mutex);
+
return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
@@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net
unsigned long flags;
int err = 0;
int space = wrqu->data.length;
-
+
+ mutex_lock(&mac->associnfo.mutex);
spin_lock_irqsave(&mac->lock, flags);
wrqu->data.length = 0;
@@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net
err = -E2BIG;
}
spin_unlock_irqrestore(&mac->lock, flags);
+ mutex_lock(&mac->associnfo.mutex);
+
return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
@@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_
struct iw_mlme *mlme = (struct iw_mlme *)extra;
u16 reason = cpu_to_le16(mlme->reason_code);
struct ieee80211softmac_network *net;
+ int err = -EINVAL;
+
+ mutex_lock(&mac->associnfo.mutex);
if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
- return -EINVAL;
+ goto out;
}
switch (mlme->cmd) {
@@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_
net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
if (!net) {
printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
- return -EINVAL;
+ goto out;
}
return ieee80211softmac_deauth_req(mac, net, reason);
case IW_MLME_DISASSOC:
ieee80211softmac_send_disassoc_req(mac, reason);
- return 0;
+ mac->associnfo.associated = 0;
+ mac->associnfo.associating = 0;
+ err = 0;
+ goto out;
default:
- return -EOPNOTSUPP;
+ err = -EOPNOTSUPP;
}
+
+out:
+ mutex_unlock(&mac->associnfo.mutex);
+
+ return err;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
===================================================================
--- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-17 15:24:29.000000000 +0200
+++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 15:29:01.000000000 +0200
@@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_
//TODO
break;
case BCM43xx_LED_ASSOC:
- if (bcm->softmac->associated)
+ if (bcm->softmac->associnfo.associated)
turn_on = 1;
break;
#ifdef CONFIG_BCM43XX_DEBUG
Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
===================================================================
--- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-24 18:34:58.000000000 +0200
+++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 15:28:36.000000000 +0200
@@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get
unsigned long flags;
wstats = &bcm->stats.wstats;
- if (!mac->associated) {
+ if (!mac->associnfo.associated) {
wstats->miss.beacon = 0;
// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
wstats->discard.retries = 0;
Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-17 15:21:53.000000000 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 16:33:18.000000000 +0200
@@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struc
{
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
- ieee80211softmac_process_erp(mac, network->erp_value);
+ /* This might race, but we don't really care and it's not worth
+ * adding heavyweight locking in this fastpath.
+ */
+ if (mac->associnfo.associated) {
+ if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
+ ieee80211softmac_process_erp(mac, network->erp_value);
+ }
return 0;
}
--
Greetings Michael.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 15:26 [PATCH] softmac: Fix WX and association related races Michael Buesch @ 2006-09-27 16:18 ` Larry Finger 2006-09-27 17:50 ` Michael Buesch 2006-09-27 22:20 ` Benjamin Herrenschmidt 1 sibling, 1 reply; 27+ messages in thread From: Larry Finger @ 2006-09-27 16:18 UTC (permalink / raw) To: Michael Buesch; +Cc: linville, Benjamin Herrenschmidt, Christian, netdev Michael Buesch wrote: > This fixes some race conditions in the WirelessExtension > handling and association handling code. > > Signed-off-by: Michael Buesch <mb@bu3sch.de> > > --- This patch doesn't apply. > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c > =================================================================== > --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-17 15:21:53.000000000 +0200 > +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 16:49:25.000000000 +0200 > @@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net > struct ieee80211softmac_network *n; > struct ieee80211softmac_auth_queue_item *authptr; > int length = 0; > - unsigned long flags; > + > + mutex_lock(&sm->associnfo.mutex); > > /* Check if we're already associating to this or another network > * If it's another network, cancel and start over with our new network > * If it's our network, ignore the change, we're already doing it! > */ > - if((sm->associnfo.associating || sm->associated) && > + if((sm->associnfo.associating || sm->associnfo.associated) && > (data->essid.flags && data->essid.length && extra)) { ^^^^^^^^^ The marked stuff is not in my copy of wireless-2.6. Is mine hosed? Larry > /* Get the associating network */ > n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); > @@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net > !memcmp(n->essid.data, extra, n->essid.len)) { > dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", > MAC_ARG(sm->associnfo.bssid)); > - return 0; > + goto out; > } else { > dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); > - spin_lock_irqsave(&sm->lock,flags); > /* Cancel assoc work */ > cancel_delayed_work(&sm->associnfo.work); > /* We don't have to do this, but it's a little cleaner */ > @@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net > cancel_delayed_work(&authptr->work); > sm->associnfo.bssvalid = 0; > sm->associnfo.bssfixed = 0; > - spin_unlock_irqrestore(&sm->lock,flags); > flush_scheduled_work(); > + sm->associnfo.associating = 0; > + sm->associnfo.associated = 0; > } > } > > > - spin_lock_irqsave(&sm->lock, flags); > - > sm->associnfo.static_essid = 0; > sm->associnfo.assoc_wait = 0; > > @@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net > * If applicable, we have already copied the data in */ > sm->associnfo.req_essid.len = length; > > + sm->associnfo.associating = 1; > /* queue lower level code to do work (if necessary) */ > schedule_work(&sm->associnfo.work); > +out: > + mutex_unlock(&sm->associnfo.mutex); > > - spin_unlock_irqrestore(&sm->lock, flags); > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); > @@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net > char *extra) > { > struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); > - unsigned long flags; > > - /* avoid getting inconsistent information */ > - spin_lock_irqsave(&sm->lock, flags); > + mutex_lock(&sm->associnfo.mutex); > /* If all fails, return ANY (empty) */ > data->essid.length = 0; > data->essid.flags = 0; /* active */ > @@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net > } > > /* If we're associating/associated, return that */ > - if (sm->associated || sm->associnfo.associating) { > + if (sm->associnfo.associated || sm->associnfo.associating) { > data->essid.length = sm->associnfo.associate_essid.len; > data->essid.flags = 1; /* active */ > memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); > } > - spin_unlock_irqrestore(&sm->lock, flags); > + mutex_unlock(&sm->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); > @@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_d > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > int err = 0; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (mac->associnfo.bssvalid) > memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); > else > memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); > data->ap_addr.sa_family = ARPHRD_ETHER; > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); > @@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_d > char *extra) > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > - unsigned long flags; > > /* sanity check */ > if (data->ap_addr.sa_family != ARPHRD_ETHER) { > return -EINVAL; > } > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is not to be fixed any longer, > * and we should reassociate to the best AP. */ > mac->associnfo.bssfixed = 0; > /* force reassociation */ > mac->associnfo.bssvalid = 0; > - if (mac->associated) > + if (mac->associnfo.associated) > schedule_work(&mac->associnfo.work); > } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is no longer fixed */ > mac->associnfo.bssfixed = 0; > } else { > if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { > - if (mac->associnfo.associating || mac->associated) { > + if (mac->associnfo.associating || mac->associnfo.associated) { > /* bssid unchanged and associated or associating - just return */ > goto out; > } > @@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_d > } > > out: > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); > @@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net > int err = 0; > char *buf; > int i; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > /* bleh. shouldn't be locked for that kmalloc... */ > > @@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net > > out: > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); > @@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net > unsigned long flags; > int err = 0; > int space = wrqu->data.length; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > > wrqu->data.length = 0; > @@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net > err = -E2BIG; > } > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); > @@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_ > struct iw_mlme *mlme = (struct iw_mlme *)extra; > u16 reason = cpu_to_le16(mlme->reason_code); > struct ieee80211softmac_network *net; > + int err = -EINVAL; > + > + mutex_lock(&mac->associnfo.mutex); > > if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { > printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); > - return -EINVAL; > + goto out; > } > > switch (mlme->cmd) { > @@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_ > net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); > if (!net) { > printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); > - return -EINVAL; > + goto out; > } > return ieee80211softmac_deauth_req(mac, net, reason); > case IW_MLME_DISASSOC: > ieee80211softmac_send_disassoc_req(mac, reason); > - return 0; > + mac->associnfo.associated = 0; > + mac->associnfo.associating = 0; > + err = 0; > + goto out; > default: > - return -EOPNOTSUPP; > + err = -EOPNOTSUPP; > } > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > + > + return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c > =================================================================== > --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-17 15:24:29.000000000 +0200 > +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 15:29:01.000000000 +0200 > @@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_ > //TODO > break; > case BCM43xx_LED_ASSOC: > - if (bcm->softmac->associated) > + if (bcm->softmac->associnfo.associated) > turn_on = 1; > break; > #ifdef CONFIG_BCM43XX_DEBUG > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c > =================================================================== > --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-24 18:34:58.000000000 +0200 > +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 15:28:36.000000000 +0200 > @@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get > unsigned long flags; > > wstats = &bcm->stats.wstats; > - if (!mac->associated) { > + if (!mac->associnfo.associated) { > wstats->miss.beacon = 0; > // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? > wstats->discard.retries = 0; > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c > =================================================================== > --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-17 15:21:53.000000000 +0200 > +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 16:33:18.000000000 +0200 > @@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struc > { > struct ieee80211softmac_device *mac = ieee80211_priv(dev); > > - if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) > - ieee80211softmac_process_erp(mac, network->erp_value); > + /* This might race, but we don't really care and it's not worth > + * adding heavyweight locking in this fastpath. > + */ > + if (mac->associnfo.associated) { > + if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) > + ieee80211softmac_process_erp(mac, network->erp_value); > + } > > return 0; > } > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 16:18 ` Larry Finger @ 2006-09-27 17:50 ` Michael Buesch 2006-09-27 21:11 ` Christian ` (3 more replies) 0 siblings, 4 replies; 27+ messages in thread From: Michael Buesch @ 2006-09-27 17:50 UTC (permalink / raw) To: linville; +Cc: Larry Finger, Benjamin Herrenschmidt, Christian, netdev On Wednesday 27 September 2006 18:18, Larry Finger wrote: > Michael Buesch wrote: > > This fixes some race conditions in the WirelessExtension > > handling and association handling code. > > > > Signed-off-by: Michael Buesch <mb@bu3sch.de> > > > > --- > > This patch doesn't apply. Oh, linville merged stuff on the 25th. That's the day I updated my tree to do this patch. But seems like I did it just before the merge. Who could suspect that linville merges something. :D *me runs away* Anyway. Here's an updated patch. Index: wireless-2.6/include/net/ieee80211softmac.h =================================================================== --- wireless-2.6.orig/include/net/ieee80211softmac.h 2006-09-27 19:34:20.000000000 +0200 +++ wireless-2.6/include/net/ieee80211softmac.h 2006-09-27 19:36:39.000000000 +0200 @@ -63,13 +63,11 @@ struct ieee80211softmac_wpa { /* * Information about association - * - * Do we need a lock for this? - * We only ever use this structure inlined - * into our global struct. I've used its lock, - * but maybe we need a local one here? */ struct ieee80211softmac_assoc_info { + + struct mutex mutex; + /* * This is the requested ESSID. It is written * only by the WX handlers. @@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info { * * bssfixed is used for SIOCSIWAP. */ - u8 static_essid:1, - short_preamble_available:1, - associating:1, - assoc_wait:1, - bssvalid:1, - bssfixed:1; + u8 static_essid; + u8 short_preamble_available; + u8 associating; + u8 associated; + u8 assoc_wait; + u8 bssvalid; + u8 bssfixed; /* Scan retries remaining */ int scan_retry; @@ -229,12 +228,10 @@ struct ieee80211softmac_device { /* private stuff follows */ /* this lock protects this structure */ spinlock_t lock; - - /* couple of flags */ - u8 scanning:1, /* protects scanning from being done multiple times at once */ - associated:1, - running:1; - + + u8 running; /* SoftMAC started? */ + u8 scanning; + struct ieee80211softmac_scaninfo *scaninfo; struct ieee80211softmac_assoc_info associnfo; struct ieee80211softmac_bss_info bssinfo; @@ -250,7 +247,7 @@ struct ieee80211softmac_device { /* we need to keep a list of network structs we copied */ struct list_head network_list; - + /* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ u8 priv[0]; @@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_sugges { struct ieee80211softmac_txrates *txrates = &mac->txrates; - if (!mac->associated) + if (!mac->associnfo.associated) return txrates->mgt_mcast_rate; /* We are associated, sending unicast frame */ Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c =================================================================== --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 19:34:20.000000000 +0200 +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 19:36:39.000000000 +0200 @@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211s dprintk(KERN_INFO PFX "sent association request!\n"); spin_lock_irqsave(&mac->lock, flags); - mac->associated = 0; /* just to make sure */ + mac->associnfo.associated = 0; /* just to make sure */ /* Set a timer for timeout */ /* FIXME: make timeout configurable */ @@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d) { struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_network *n; - unsigned long flags; - spin_lock_irqsave(&mac->lock, flags); + mutex_lock(&mac->associnfo.mutex); /* we might race against ieee80211softmac_handle_assoc_response, * so make sure only one of us does something */ - if (!mac->associnfo.associating) { - spin_unlock_irqrestore(&mac->lock, flags); - return; - } + if (!mac->associnfo.associating) + goto out; mac->associnfo.associating = 0; mac->associnfo.bssvalid = 0; - mac->associated = 0; + mac->associnfo.associated = 0; n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); - spin_unlock_irqrestore(&mac->lock, flags); dprintk(KERN_INFO PFX "assoc request timed out!\n"); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); +out: + mutex_unlock(&mac->associnfo.mutex); } void @@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee802 netif_carrier_off(mac->dev); - mac->associated = 0; + mac->associnfo.associated = 0; mac->associnfo.bssvalid = 0; mac->associnfo.associating = 0; ieee80211softmac_init_bss(mac); @@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struc { struct ieee80211softmac_network *found; - if (mac->associnfo.bssvalid && mac->associated) { + if (mac->associnfo.bssvalid && mac->associnfo.associated) { found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); if (found) ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); @@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d) int bssvalid; unsigned long flags; + mutex_lock(&mac->associnfo.mutex); + + if (!mac->associnfo.associating) + goto out; + /* ieee80211_disassoc might clear this */ bssvalid = mac->associnfo.bssvalid; /* meh */ - if (mac->associated) + if (mac->associnfo.associated) ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); - spin_lock_irqsave(&mac->lock, flags); - mac->associnfo.associating = 1; - spin_unlock_irqrestore(&mac->lock, flags); - /* try to find the requested network in our list, if we found one already */ if (bssvalid || mac->associnfo.bssfixed) found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); @@ -260,10 +259,8 @@ ieee80211softmac_assoc_work(void *d) if (!found) { if (mac->associnfo.scan_retry > 0) { - spin_lock_irqsave(&mac->lock, flags); mac->associnfo.scan_retry--; - spin_unlock_irqrestore(&mac->lock, flags); - + /* We know of no such network. Let's scan. * NB: this also happens if we had no memory to copy the network info... * Maybe we can hope to have more memory after scanning finishes ;) @@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d) ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); if (ieee80211softmac_start_scan(mac)) dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); - return; + goto out; } else { - spin_lock_irqsave(&mac->lock, flags); mac->associnfo.associating = 0; - mac->associated = 0; - spin_unlock_irqrestore(&mac->lock, flags); + mac->associnfo.associated = 0; dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); /* reset the retry counter for the next user request since we * break out and don't reschedule ourselves after this point. */ mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); - return; + goto out; } } @@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d) /* copy the ESSID for displaying it */ mac->associnfo.associate_essid.len = found->essid.len; memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); - + /* we found a network! authenticate (if necessary) and associate to it. */ if (found->authenticating) { dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); @@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d) mac->associnfo.assoc_wait = 1; ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); } - return; + goto out; } if (!found->authenticated && !found->authenticating) { /* This relies on the fact that _auth_req only queues the work, @@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d) mac->associnfo.assoc_wait = 0; ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); } - return; + goto out; } /* finally! now we can start associating */ mac->associnfo.assoc_wait = 0; ieee80211softmac_assoc(mac, found); + +out: + mutex_unlock(&mac->associnfo.mutex); } /* call this to do whatever is necessary when we're associated */ @@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee8 mac->bssinfo.supported_rates = net->supported_rates; ieee80211softmac_recalc_txrates(mac); - mac->associated = 1; + mac->associnfo.associated = 1; mac->associnfo.short_preamble_available = (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; @@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(s dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); mac->associnfo.associating = 0; mac->associnfo.bssvalid = 0; - mac->associated = 0; + mac->associnfo.associated = 0; ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); } Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c =================================================================== --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-27 19:34:20.000000000 +0200 +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-27 19:36:39.000000000 +0200 @@ -57,6 +57,7 @@ struct net_device *alloc_ieee80211softma INIT_LIST_HEAD(&softmac->network_list); INIT_LIST_HEAD(&softmac->events); + mutex_init(&softmac->associnfo.mutex); INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); softmac->start_scan = ieee80211softmac_start_scan_implementation; Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c =================================================================== --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 19:33:27.000000000 +0200 +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 19:37:16.000000000 +0200 @@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net struct ieee80211softmac_network *n; struct ieee80211softmac_auth_queue_item *authptr; int length = 0; - unsigned long flags; + + mutex_lock(&sm->associnfo.mutex); /* Check if we're already associating to this or another network * If it's another network, cancel and start over with our new network * If it's our network, ignore the change, we're already doing it! */ - if((sm->associnfo.associating || sm->associated) && + if((sm->associnfo.associating || sm->associnfo.associated) && (data->essid.flags && data->essid.length)) { /* Get the associating network */ n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); @@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net !memcmp(n->essid.data, extra, n->essid.len)) { dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", MAC_ARG(sm->associnfo.bssid)); - return 0; + goto out; } else { dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); - spin_lock_irqsave(&sm->lock,flags); /* Cancel assoc work */ cancel_delayed_work(&sm->associnfo.work); /* We don't have to do this, but it's a little cleaner */ @@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net cancel_delayed_work(&authptr->work); sm->associnfo.bssvalid = 0; sm->associnfo.bssfixed = 0; - spin_unlock_irqrestore(&sm->lock,flags); flush_scheduled_work(); + sm->associnfo.associating = 0; + sm->associnfo.associated = 0; } } - spin_lock_irqsave(&sm->lock, flags); - sm->associnfo.static_essid = 0; sm->associnfo.assoc_wait = 0; @@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net * If applicable, we have already copied the data in */ sm->associnfo.req_essid.len = length; + sm->associnfo.associating = 1; /* queue lower level code to do work (if necessary) */ schedule_work(&sm->associnfo.work); +out: + mutex_unlock(&sm->associnfo.mutex); - spin_unlock_irqrestore(&sm->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); @@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net char *extra) { struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); - unsigned long flags; - /* avoid getting inconsistent information */ - spin_lock_irqsave(&sm->lock, flags); + mutex_lock(&sm->associnfo.mutex); /* If all fails, return ANY (empty) */ data->essid.length = 0; data->essid.flags = 0; /* active */ @@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net } /* If we're associating/associated, return that */ - if (sm->associated || sm->associnfo.associating) { + if (sm->associnfo.associated || sm->associnfo.associating) { data->essid.length = sm->associnfo.associate_essid.len; data->essid.flags = 1; /* active */ memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); } - spin_unlock_irqrestore(&sm->lock, flags); + mutex_unlock(&sm->associnfo.mutex); + return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); @@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_d { struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); int err = 0; - unsigned long flags; - spin_lock_irqsave(&mac->lock, flags); + mutex_lock(&mac->associnfo.mutex); if (mac->associnfo.bssvalid) memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); else memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); data->ap_addr.sa_family = ARPHRD_ETHER; - spin_unlock_irqrestore(&mac->lock, flags); + mutex_unlock(&mac->associnfo.mutex); + return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); @@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_d char *extra) { struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); - unsigned long flags; /* sanity check */ if (data->ap_addr.sa_family != ARPHRD_ETHER) { return -EINVAL; } - spin_lock_irqsave(&mac->lock, flags); + mutex_lock(&mac->associnfo.mutex); if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { /* the bssid we have is not to be fixed any longer, * and we should reassociate to the best AP. */ mac->associnfo.bssfixed = 0; /* force reassociation */ mac->associnfo.bssvalid = 0; - if (mac->associated) + if (mac->associnfo.associated) schedule_work(&mac->associnfo.work); } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { /* the bssid we have is no longer fixed */ mac->associnfo.bssfixed = 0; } else { if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { - if (mac->associnfo.associating || mac->associated) { + if (mac->associnfo.associating || mac->associnfo.associated) { /* bssid unchanged and associated or associating - just return */ goto out; } @@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_d } out: - spin_unlock_irqrestore(&mac->lock, flags); + mutex_unlock(&mac->associnfo.mutex); + return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); @@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net int err = 0; char *buf; int i; - + + mutex_lock(&mac->associnfo.mutex); spin_lock_irqsave(&mac->lock, flags); /* bleh. shouldn't be locked for that kmalloc... */ @@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net out: spin_unlock_irqrestore(&mac->lock, flags); + mutex_unlock(&mac->associnfo.mutex); + return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); @@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net unsigned long flags; int err = 0; int space = wrqu->data.length; - + + mutex_lock(&mac->associnfo.mutex); spin_lock_irqsave(&mac->lock, flags); wrqu->data.length = 0; @@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net err = -E2BIG; } spin_unlock_irqrestore(&mac->lock, flags); + mutex_lock(&mac->associnfo.mutex); + return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); @@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_ struct iw_mlme *mlme = (struct iw_mlme *)extra; u16 reason = cpu_to_le16(mlme->reason_code); struct ieee80211softmac_network *net; + int err = -EINVAL; + + mutex_lock(&mac->associnfo.mutex); if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); - return -EINVAL; + goto out; } switch (mlme->cmd) { @@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_ net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); if (!net) { printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); - return -EINVAL; + goto out; } return ieee80211softmac_deauth_req(mac, net, reason); case IW_MLME_DISASSOC: ieee80211softmac_send_disassoc_req(mac, reason); - return 0; + mac->associnfo.associated = 0; + mac->associnfo.associating = 0; + err = 0; + goto out; default: - return -EOPNOTSUPP; + err = -EOPNOTSUPP; } + +out: + mutex_unlock(&mac->associnfo.mutex); + + return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c =================================================================== --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 19:34:10.000000000 +0200 +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 19:36:39.000000000 +0200 @@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_ //TODO break; case BCM43xx_LED_ASSOC: - if (bcm->softmac->associated) + if (bcm->softmac->associnfo.associated) turn_on = 1; break; #ifdef CONFIG_BCM43XX_DEBUG Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c =================================================================== --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 19:33:27.000000000 +0200 +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 19:36:39.000000000 +0200 @@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get unsigned long flags; wstats = &bcm->stats.wstats; - if (!mac->associated) { + if (!mac->associnfo.associated) { wstats->miss.beacon = 0; // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? wstats->discard.retries = 0; Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c =================================================================== --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 19:34:20.000000000 +0200 +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 19:36:39.000000000 +0200 @@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struc { struct ieee80211softmac_device *mac = ieee80211_priv(dev); - if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) - ieee80211softmac_process_erp(mac, network->erp_value); + /* This might race, but we don't really care and it's not worth + * adding heavyweight locking in this fastpath. + */ + if (mac->associnfo.associated) { + if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) + ieee80211softmac_process_erp(mac, network->erp_value); + } return 0; } -- Greetings Michael. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 17:50 ` Michael Buesch @ 2006-09-27 21:11 ` Christian 2006-09-27 21:21 ` Christian ` (2 subsequent siblings) 3 siblings, 0 replies; 27+ messages in thread From: Christian @ 2006-09-27 21:11 UTC (permalink / raw) To: Michael Buesch; +Cc: linville, Larry Finger, Benjamin Herrenschmidt, netdev And a second try seems to hint at some acpi problems on the acer: bcm43xx: Device resumed. PM: Writing back config space on device 0000:06:09.0 at offset f (was 34001ff, writing 5c0010b) PM: Writing back config space on device 0000:06:09.0 at offset e (was 0, writing 24fc) PM: Writing back config space on device 0000:06:09.0 at offset d (was 0, writing 2400) PM: Writing back config space on device 0000:06:09.0 at offset c (was 0, writing 20fc) PM: Writing back config space on device 0000:06:09.0 at offset b (was 0, writing 2000) PM: Writing back config space on device 0000:06:09.0 at offset a (was 0, writing 53fff000) PM: Writing back config space on device 0000:06:09.0 at offset 9 (was 0, writing 52000000) PM: Writing back config space on device 0000:06:09.0 at offset 8 (was 0, writing 51fff000) PM: Writing back config space on device 0000:06:09.0 at offset 7 (was 0, writing 50000000) PM: Writing back config space on device 0000:06:09.0 at offset 6 (was 0, writing b00a0706) PM: Writing back config space on device 0000:06:09.0 at offset 4 (was 0, writing c0308000) PM: Writing back config space on device 0000:06:09.0 at offset 3 (was 820000, writing 82a810) PM: Writing back config space on device 0000:06:09.0 at offset 1 (was 2100000, writing 2100007) ACPI: PCI Interrupt 0000:06:09.0[A] -> Link [LNKH] -> GSI 11 (level, low) -> IRQ 11 PM: Writing back config space on device 0000:06:09.2 at offset f (was 4030300, writing 403030b) PM: Writing back config space on device 0000:06:09.2 at offset 5 (was 0, writing c0300000) PM: Writing back config space on device 0000:06:09.2 at offset 4 (was 0, writing c0309000) PM: Writing back config space on device 0000:06:09.2 at offset 3 (was 800000, writing 804008) PM: Writing back config space on device 0000:06:09.2 at offset 1 (was 2100000, writing 2100016) PM: Writing back config space on device 0000:06:09.3 at offset f (was 40701ff, writing 407010b) PM: Writing back config space on device 0000:06:09.3 at offset 4 (was 0, writing c0306000) PM: Writing back config space on device 0000:06:09.3 at offset 3 (was 800000, writing 804008) PM: Writing back config space on device 0000:06:09.3 at offset 1 (was 2100000, writing 2100002) ACPI: PCI Interrupt 0000:06:09.3[A] -> Link [LNKH] -> GSI 11 (level, low) -> IRQ 11 Restarting tasks...<7>ACPI: read EC, OB not full ACPI Exception (evregion-0424): AE_TIME, Returned by Handler for [EmbeddedControl] [20060707] ACPI Exception (dswexec-0458): AE_TIME, While resolving operands for [OpcodeName unavailable] [20060707] ACPI Error (psparse-0537): Method parse/execution failed [\_SB_.ACAD._PSR] (Node ffff810001fba690), AE_TIME ACPI Exception (acpi_ac-0096): AE_TIME, Error reading AC Adapter state [20060707] done ohci_hcd: 2005 April 22 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI) ACPI: PCI Interrupt 0000:00:13.0[A] -> Link [LNKD] -> GSI 10 (level, low) -> IRQ 10 ohci_hcd 0000:00:13.0: OHCI Host Controller ohci_hcd 0000:00:13.0: new USB bus registered, assigned bus number 2 ohci_hcd 0000:00:13.0: irq 10, io mem 0xc0000000 usb usb2: configuration #1 chosen from 1 choice hub 2-0:1.0: USB hub found hub 2-0:1.0: 4 ports detected ACPI: PCI Interrupt 0000:00:13.1[A] -> Link [LNKD] -> GSI 10 (level, low) -> IRQ 10 ohci_hcd 0000:00:13.1: OHCI Host Controller ohci_hcd 0000:00:13.1: new USB bus registered, assigned bus number 3 ohci_hcd 0000:00:13.1: irq 10, io mem 0xc0001000 usb usb3: configuration #1 chosen from 1 choice hub 3-0:1.0: USB hub found hub 3-0:1.0: 4 ports detected Synaptics Touchpad, model: 1, fw: 5.9, id: 0x126eb1, caps: 0xa04713/0x4000 input: SynPS/2 Synaptics TouchPad as /class/input/input8 tg3.c:v3.65 (August 07, 2006) ACPI: PCI Interrupt 0000:05:00.0[A] -> Link [LNKC] -> GSI 10 (level, low) -> IRQ 10 PCI: Setting latency timer of device 0000:05:00.0 to 64 eth0: Tigon3 [partno(BCM95789) rev 4101 PHY(5750)] (PCI Express) 10/100/1000BaseT Ethernet 00:c0:9f:b7:77:f3 eth0: RXcsums[1] LinkChgREG[0] MIirq[0] ASF[0] Split[0] WireSpeed[1] TSOcap[1] eth0: dma_rwctrl[76180000] dma_mask[64-bit] usb 3-2: new full speed USB device using ohci_hcd and address 2 usb 3-2: configuration #1 chosen from 1 choice input: Bluetooth HID Boot Protocol Device as /class/input/input9 bcm43xx: Radio turned off bcm43xx: DMA-32 0x0200 (RX) max used slots: 0/64 bcm43xx: DMA-32 0x02A0 (TX) max used slots: 0/512 bcm43xx: DMA-32 0x0280 (TX) max used slots: 0/512 bcm43xx: DMA-32 0x0260 (TX) max used slots: 0/512 bcm43xx: DMA-32 0x0240 (TX) max used slots: 0/512 bcm43xx: DMA-32 0x0220 (TX) max used slots: 2/512 bcm43xx: ASSERTION FAILED (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) at: drivers/net/wireless/bcm43xx/bcm43xx_main.c:1848:bcm43xx_interrupt_handler() bcm43xx: DMA-32 0x0200 (TX) max used slots: 0/512 bcm43xx driver ACPI: PCI Interrupt 0000:06:02.0[A] -> Link [LNKF] -> GSI 11 (level, low) -> IRQ 11 bcm43xx: Chip ID 0x4318, rev 0x2 bcm43xx: Number of cores: 4 bcm43xx: Core 0: ID 0x800, rev 0xd, vendor 0x4243, enabled bcm43xx: Core 1: ID 0x812, rev 0x9, vendor 0x4243, enabled bcm43xx: Core 2: ID 0x804, rev 0xc, vendor 0x4243, enabled bcm43xx: Core 3: ID 0x80d, rev 0x7, vendor 0x4243, enabled bcm43xx: PHY connected bcm43xx: Detected PHY: Version: 3, Type 2, Revision 7 bcm43xx: Detected Radio: ID: 8205017f (Manuf: 17f Ver: 2050 Rev: 8) bcm43xx: Radio turned off bcm43xx: Radio turned off ieee80211softmac_wx_set_wap 00:00:00:00:00:00 ieee80211softmac_wx_set_rate SoftMAC: empty ratesinfo? SoftMAC: empty ratesinfo? ieee80211softmac_wx_set_wap 00:00:00:00:00:00 ieee80211softmac_wx_set_essid SoftMAC: Associate: Scanning for networks first. SoftMAC: Associate: failed to initiate scan. Is device up? bcm43xx: PHY connected bcm43xx: Microcode rev 0x123, pl 0x21 (2005-01-22 19:48:06) bcm43xx: Radio turned on bcm43xx: ASSERTION FAILED (radio_attenuation < 10) at: drivers/net/wireless/bcm43xx/bcm43xx_phy.c:1496:bcm43xx_find_lopair() bcm43xx: ASSERTION FAILED (radio_attenuation < 10) at: drivers/net/wireless/bcm43xx/bcm43xx_phy.c:1496:bcm43xx_find_lopair() bcm43xx: ASSERTION FAILED (radio_attenuation < 10) at: drivers/net/wireless/bcm43xx/bcm43xx_phy.c:1496:bcm43xx_find_lopair() bcm43xx: Chip initialized bcm43xx: 32-bit DMA initialized bcm43xx: Keys cleared bcm43xx: Selected 802.11 core (phytype 2) bcm43xx: ASSERTION FAILED (radio_attenuation < 10) at: drivers/net/wireless/bcm43xx/bcm43xx_phy.c:1496:bcm43xx_find_lopair() SoftMAC: Associate: Scanning for networks first. SoftMAC: Associate: failed to initiate scan. Is device up? ADDRCONF(NETDEV_UP): eth1: link is not ready ieee80211softmac_wx_set_rate SoftMAC: empty ratesinfo? SoftMAC: empty ratesinfo? ieee80211softmac_wx_set_wap 00:00:00:00:00:00 ieee80211softmac_wx_set_essid SoftMAC: Associate: Scanning for networks first. SoftMAC: Start scanning with channel: 1 SoftMAC: Scanning 14 channels bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 ieee80211softmac_wx_get_scan_results ieee80211softmac_wx_trigger_scan SoftMAC: Scanning finished SoftMAC: Unable to find matching network after scan! ieee80211softmac_wx_get_scan_results ieee80211softmac_wx_set_genie SoftMAC: generic IE set to dd160050f20101000050f20201000050f20201000050f202 ieee80211softmac_wx_set_essid SoftMAC: Associate: Scanning for networks first. SoftMAC: Start scanning with channel: 1 SoftMAC: Scanning 14 channels ieee80211softmac_wx_set_wap 00:13:10:2f:98:3e SoftMAC: Queueing Authentication Request to 00:13:10:2f:98:3e SoftMAC: Cannot associate without being authenticated, requested authentication SoftMAC: Sent Authentication Request to 00:13:10:2f:98:3e. SoftMAC: Open Authentication completed with 00:13:10:2f:98:3e SoftMAC: sent association request! SoftMAC: Scanning finished SoftMAC: sent association request! ieee80211softmac_wx_get_scan_results SoftMAC: associated! ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready ieee80211softmac_wx_get_wap ieee80211softmac_wx_get_essid ieee80211softmac_wx_get_wap bcm43xx: set security called, .active_key = 0, .level = 2, .enabled = 1, .encrypt = 1 bcm43xx: set security called, .enabled = 1, .encrypt = 1 r2d2 ~ # ping www.christianhoffmann.info PING www.christianhoffmann.info (82.165.77.52) 56(84) bytes of data. 64 bytes from 82.165.77.52: icmp_seq=1 ttl=52 time=95.1 ms 64 bytes from 82.165.77.52: icmp_seq=2 ttl=52 time=94.9 ms 64 bytes from 82.165.77.52: icmp_seq=3 ttl=52 time=95.1 ms --- www.christianhoffmann.info ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 94.928/95.096/95.190/0.375 ms r2d2 ~ # Chris On Wednesday 27 September 2006 19:50, Michael Buesch wrote: > On Wednesday 27 September 2006 18:18, Larry Finger wrote: > > Michael Buesch wrote: > > > This fixes some race conditions in the WirelessExtension > > > handling and association handling code. > > > > > > Signed-off-by: Michael Buesch <mb@bu3sch.de> > > > > > > --- > > > > This patch doesn't apply. > > Oh, linville merged stuff on the 25th. That's the day I updated > my tree to do this patch. But seems like I did it just before > the merge. > Who could suspect that linville merges something. :D > *me runs away* > > Anyway. Here's an updated patch. > > > Index: wireless-2.6/include/net/ieee80211softmac.h > =================================================================== > --- wireless-2.6.orig/include/net/ieee80211softmac.h 2006-09-27 > 19:34:20.000000000 +0200 +++ > wireless-2.6/include/net/ieee80211softmac.h 2006-09-27 19:36:39.000000000 > +0200 @@ -63,13 +63,11 @@ struct ieee80211softmac_wpa { > > /* > * Information about association > - * > - * Do we need a lock for this? > - * We only ever use this structure inlined > - * into our global struct. I've used its lock, > - * but maybe we need a local one here? > */ > struct ieee80211softmac_assoc_info { > + > + struct mutex mutex; > + > /* > * This is the requested ESSID. It is written > * only by the WX handlers. > @@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info { > * > * bssfixed is used for SIOCSIWAP. > */ > - u8 static_essid:1, > - short_preamble_available:1, > - associating:1, > - assoc_wait:1, > - bssvalid:1, > - bssfixed:1; > + u8 static_essid; > + u8 short_preamble_available; > + u8 associating; > + u8 associated; > + u8 assoc_wait; > + u8 bssvalid; > + u8 bssfixed; > > /* Scan retries remaining */ > int scan_retry; > @@ -229,12 +228,10 @@ struct ieee80211softmac_device { > /* private stuff follows */ > /* this lock protects this structure */ > spinlock_t lock; > - > - /* couple of flags */ > - u8 scanning:1, /* protects scanning from being done multiple times at > once */ - associated:1, > - running:1; > - > + > + u8 running; /* SoftMAC started? */ > + u8 scanning; > + > struct ieee80211softmac_scaninfo *scaninfo; > struct ieee80211softmac_assoc_info associnfo; > struct ieee80211softmac_bss_info bssinfo; > @@ -250,7 +247,7 @@ struct ieee80211softmac_device { > > /* we need to keep a list of network structs we copied */ > struct list_head network_list; > - > + > /* This must be the last item so that it points to the data > * allocated beyond this structure by alloc_ieee80211 */ > u8 priv[0]; > @@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_sugges > { > struct ieee80211softmac_txrates *txrates = &mac->txrates; > > - if (!mac->associated) > + if (!mac->associnfo.associated) > return txrates->mgt_mcast_rate; > > /* We are associated, sending unicast frame */ > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 > 19:34:20.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct > ieee80211s > dprintk(KERN_INFO PFX "sent association request!\n"); > > spin_lock_irqsave(&mac->lock, flags); > - mac->associated = 0; /* just to make sure */ > + mac->associnfo.associated = 0; /* just to make sure */ > > /* Set a timer for timeout */ > /* FIXME: make timeout configurable */ > @@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d) > { > struct ieee80211softmac_device *mac = (struct ieee80211softmac_device > *)d; struct ieee80211softmac_network *n; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > /* we might race against ieee80211softmac_handle_assoc_response, > * so make sure only one of us does something */ > - if (!mac->associnfo.associating) { > - spin_unlock_irqrestore(&mac->lock, flags); > - return; > - } > + if (!mac->associnfo.associating) > + goto out; > mac->associnfo.associating = 0; > mac->associnfo.bssvalid = 0; > - mac->associated = 0; > + mac->associnfo.associated = 0; > > n = ieee80211softmac_get_network_by_bssid_locked(mac, > mac->associnfo.bssid); - spin_unlock_irqrestore(&mac->lock, flags); > > dprintk(KERN_INFO PFX "assoc request timed out!\n"); > ieee80211softmac_call_events(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); +out: > + mutex_unlock(&mac->associnfo.mutex); > } > > void > @@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee802 > > netif_carrier_off(mac->dev); > > - mac->associated = 0; > + mac->associnfo.associated = 0; > mac->associnfo.bssvalid = 0; > mac->associnfo.associating = 0; > ieee80211softmac_init_bss(mac); > @@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struc > { > struct ieee80211softmac_network *found; > > - if (mac->associnfo.bssvalid && mac->associated) { > + if (mac->associnfo.bssvalid && mac->associnfo.associated) { > found = ieee80211softmac_get_network_by_bssid(mac, > mac->associnfo.bssid); if (found) > ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, > reason); @@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d) > int bssvalid; > unsigned long flags; > > + mutex_lock(&mac->associnfo.mutex); > + > + if (!mac->associnfo.associating) > + goto out; > + > /* ieee80211_disassoc might clear this */ > bssvalid = mac->associnfo.bssvalid; > > /* meh */ > - if (mac->associated) > + if (mac->associnfo.associated) > ieee80211softmac_send_disassoc_req(mac, > WLAN_REASON_DISASSOC_STA_HAS_LEFT); > > - spin_lock_irqsave(&mac->lock, flags); > - mac->associnfo.associating = 1; > - spin_unlock_irqrestore(&mac->lock, flags); > - > /* try to find the requested network in our list, if we found one already > */ if (bssvalid || mac->associnfo.bssfixed) > found = ieee80211softmac_get_network_by_bssid(mac, > mac->associnfo.bssid); @@ -260,10 +259,8 @@ > ieee80211softmac_assoc_work(void *d) > > if (!found) { > if (mac->associnfo.scan_retry > 0) { > - spin_lock_irqsave(&mac->lock, flags); > mac->associnfo.scan_retry--; > - spin_unlock_irqrestore(&mac->lock, flags); > - > + > /* We know of no such network. Let's scan. > * NB: this also happens if we had no memory to copy the network > info... * Maybe we can hope to have more memory after scanning finishes ;) > @@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d) > ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, > ieee80211softmac_assoc_notify_scan, NULL); if > (ieee80211softmac_start_scan(mac)) > dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device > up?\n"); - return; > + goto out; > } else { > - spin_lock_irqsave(&mac->lock, flags); > mac->associnfo.associating = 0; > - mac->associated = 0; > - spin_unlock_irqrestore(&mac->lock, flags); > + mac->associnfo.associated = 0; > > dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); > /* reset the retry counter for the next user request since we > * break out and don't reschedule ourselves after this point. */ > mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; > ieee80211softmac_call_events(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); - return; > + goto out; > } > } > > @@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d) > /* copy the ESSID for displaying it */ > mac->associnfo.associate_essid.len = found->essid.len; > memcpy(mac->associnfo.associate_essid.data, found->essid.data, > IW_ESSID_MAX_SIZE + 1); - > + > /* we found a network! authenticate (if necessary) and associate to it. > */ if (found->authenticating) { > dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); > @@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d) > mac->associnfo.assoc_wait = 1; > ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, > found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); } > - return; > + goto out; > } > if (!found->authenticated && !found->authenticating) { > /* This relies on the fact that _auth_req only queues the work, > @@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d) > mac->associnfo.assoc_wait = 0; > ieee80211softmac_call_events(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); } > - return; > + goto out; > } > /* finally! now we can start associating */ > mac->associnfo.assoc_wait = 0; > ieee80211softmac_assoc(mac, found); > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > } > > /* call this to do whatever is necessary when we're associated */ > @@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee8 > mac->bssinfo.supported_rates = net->supported_rates; > ieee80211softmac_recalc_txrates(mac); > > - mac->associated = 1; > + mac->associnfo.associated = 1; > > mac->associnfo.short_preamble_available = > (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; > @@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(s > dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); > mac->associnfo.associating = 0; > mac->associnfo.bssvalid = 0; > - mac->associated = 0; > + mac->associnfo.associated = 0; > ieee80211softmac_call_events_locked(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); } > > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-2 >7 19:34:20.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -57,6 +57,7 @@ struct net_device > *alloc_ieee80211softma > INIT_LIST_HEAD(&softmac->network_list); > INIT_LIST_HEAD(&softmac->events); > > + mutex_init(&softmac->associnfo.mutex); > INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, > softmac); INIT_WORK(&softmac->associnfo.timeout, > ieee80211softmac_assoc_timeout, softmac); softmac->start_scan = > ieee80211softmac_start_scan_implementation; Index: > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 > 19:33:27.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 > 19:37:16.000000000 +0200 @@ -73,13 +73,14 @@ > ieee80211softmac_wx_set_essid(struct net > struct ieee80211softmac_network *n; > struct ieee80211softmac_auth_queue_item *authptr; > int length = 0; > - unsigned long flags; > + > + mutex_lock(&sm->associnfo.mutex); > > /* Check if we're already associating to this or another network > * If it's another network, cancel and start over with our new network > * If it's our network, ignore the change, we're already doing it! > */ > - if((sm->associnfo.associating || sm->associated) && > + if((sm->associnfo.associating || sm->associnfo.associated) && > (data->essid.flags && data->essid.length)) { > /* Get the associating network */ > n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); > @@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net > !memcmp(n->essid.data, extra, n->essid.len)) { > dprintk(KERN_INFO PFX "Already associating or associated to > "MAC_FMT"\n", MAC_ARG(sm->associnfo.bssid)); > - return 0; > + goto out; > } else { > dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); > - spin_lock_irqsave(&sm->lock,flags); > /* Cancel assoc work */ > cancel_delayed_work(&sm->associnfo.work); > /* We don't have to do this, but it's a little cleaner */ > @@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net > cancel_delayed_work(&authptr->work); > sm->associnfo.bssvalid = 0; > sm->associnfo.bssfixed = 0; > - spin_unlock_irqrestore(&sm->lock,flags); > flush_scheduled_work(); > + sm->associnfo.associating = 0; > + sm->associnfo.associated = 0; > } > } > > > - spin_lock_irqsave(&sm->lock, flags); > - > sm->associnfo.static_essid = 0; > sm->associnfo.assoc_wait = 0; > > @@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net > * If applicable, we have already copied the data in */ > sm->associnfo.req_essid.len = length; > > + sm->associnfo.associating = 1; > /* queue lower level code to do work (if necessary) */ > schedule_work(&sm->associnfo.work); > +out: > + mutex_unlock(&sm->associnfo.mutex); > > - spin_unlock_irqrestore(&sm->lock, flags); > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); > @@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net > char *extra) > { > struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); > - unsigned long flags; > > - /* avoid getting inconsistent information */ > - spin_lock_irqsave(&sm->lock, flags); > + mutex_lock(&sm->associnfo.mutex); > /* If all fails, return ANY (empty) */ > data->essid.length = 0; > data->essid.flags = 0; /* active */ > @@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net > } > > /* If we're associating/associated, return that */ > - if (sm->associated || sm->associnfo.associating) { > + if (sm->associnfo.associated || sm->associnfo.associating) { > data->essid.length = sm->associnfo.associate_essid.len; > data->essid.flags = 1; /* active */ > memcpy(extra, sm->associnfo.associate_essid.data, > sm->associnfo.associate_essid.len); } > - spin_unlock_irqrestore(&sm->lock, flags); > + mutex_unlock(&sm->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); > @@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_d > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > int err = 0; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (mac->associnfo.bssvalid) > memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); > else > memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); > data->ap_addr.sa_family = ARPHRD_ETHER; > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); > @@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_d > char *extra) > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > - unsigned long flags; > > /* sanity check */ > if (data->ap_addr.sa_family != ARPHRD_ETHER) { > return -EINVAL; > } > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is not to be fixed any longer, > * and we should reassociate to the best AP. */ > mac->associnfo.bssfixed = 0; > /* force reassociation */ > mac->associnfo.bssvalid = 0; > - if (mac->associated) > + if (mac->associnfo.associated) > schedule_work(&mac->associnfo.work); > } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is no longer fixed */ > mac->associnfo.bssfixed = 0; > } else { > if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { > - if (mac->associnfo.associating || mac->associated) { > + if (mac->associnfo.associating || mac->associnfo.associated) { > /* bssid unchanged and associated or associating - just return */ > goto out; > } > @@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_d > } > > out: > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); > @@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net > int err = 0; > char *buf; > int i; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > /* bleh. shouldn't be locked for that kmalloc... */ > > @@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net > > out: > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); > @@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net > unsigned long flags; > int err = 0; > int space = wrqu->data.length; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > > wrqu->data.length = 0; > @@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net > err = -E2BIG; > } > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); > @@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_ > struct iw_mlme *mlme = (struct iw_mlme *)extra; > u16 reason = cpu_to_le16(mlme->reason_code); > struct ieee80211softmac_network *net; > + int err = -EINVAL; > + > + mutex_lock(&mac->associnfo.mutex); > > if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { > printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't > use\n"); - return -EINVAL; > + goto out; > } > > switch (mlme->cmd) { > @@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_ > net = ieee80211softmac_get_network_by_bssid_locked(mac, > mlme->addr.sa_data); if (!net) { > printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); > - return -EINVAL; > + goto out; > } > return ieee80211softmac_deauth_req(mac, net, reason); > case IW_MLME_DISASSOC: > ieee80211softmac_send_disassoc_req(mac, reason); > - return 0; > + mac->associnfo.associated = 0; > + mac->associnfo.associating = 0; > + err = 0; > + goto out; > default: > - return -EOPNOTSUPP; > + err = -EOPNOTSUPP; > } > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > + > + return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c > =================================================================== > --- > wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 > 19:34:10.000000000 +0200 +++ > wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -242,7 +242,7 @@ void > bcm43xx_leds_update(struct bcm43xx_ > //TODO > break; > case BCM43xx_LED_ASSOC: > - if (bcm->softmac->associated) > + if (bcm->softmac->associnfo.associated) > turn_on = 1; > break; > #ifdef CONFIG_BCM43XX_DEBUG > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c > =================================================================== > --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 > 19:33:27.000000000 +0200 +++ > wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -847,7 +847,7 @@ static struct iw_statistics > *bcm43xx_get > unsigned long flags; > > wstats = &bcm->stats.wstats; > - if (!mac->associated) { > + if (!mac->associnfo.associated) { > wstats->miss.beacon = 0; > // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should > this be cleared here? wstats->discard.retries = 0; > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 > 19:34:20.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -475,8 +475,13 @@ int > ieee80211softmac_handle_beacon(struc > { > struct ieee80211softmac_device *mac = ieee80211_priv(dev); > > - if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, > ETH_ALEN) == 0) - ieee80211softmac_process_erp(mac, network->erp_value); > + /* This might race, but we don't really care and it's not worth > + * adding heavyweight locking in this fastpath. > + */ > + if (mac->associnfo.associated) { > + if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) > + ieee80211softmac_process_erp(mac, network->erp_value); > + } > > return 0; > } ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 17:50 ` Michael Buesch 2006-09-27 21:11 ` Christian @ 2006-09-27 21:21 ` Christian 2006-09-27 22:23 ` Benjamin Herrenschmidt 2006-09-28 4:09 ` Larry Finger 3 siblings, 0 replies; 27+ messages in thread From: Christian @ 2006-09-27 21:21 UTC (permalink / raw) To: Michael Buesch; +Cc: linville, Larry Finger, Benjamin Herrenschmidt, netdev Actually, I dont need the rmmod/modprobe of the module, I just need to do a /et c/init.d/net.eth1 restart. So maybe just an isssue with wpa_supplicant or a missing ifconfig eth1 up? Chris On Wednesday 27 September 2006 19:50, Michael Buesch wrote: > On Wednesday 27 September 2006 18:18, Larry Finger wrote: > > Michael Buesch wrote: > > > This fixes some race conditions in the WirelessExtension > > > handling and association handling code. > > > > > > Signed-off-by: Michael Buesch <mb@bu3sch.de> > > > > > > --- > > > > This patch doesn't apply. > > Oh, linville merged stuff on the 25th. That's the day I updated > my tree to do this patch. But seems like I did it just before > the merge. > Who could suspect that linville merges something. :D > *me runs away* > > Anyway. Here's an updated patch. > > > Index: wireless-2.6/include/net/ieee80211softmac.h > =================================================================== > --- wireless-2.6.orig/include/net/ieee80211softmac.h 2006-09-27 > 19:34:20.000000000 +0200 +++ > wireless-2.6/include/net/ieee80211softmac.h 2006-09-27 19:36:39.000000000 > +0200 @@ -63,13 +63,11 @@ struct ieee80211softmac_wpa { > > /* > * Information about association > - * > - * Do we need a lock for this? > - * We only ever use this structure inlined > - * into our global struct. I've used its lock, > - * but maybe we need a local one here? > */ > struct ieee80211softmac_assoc_info { > + > + struct mutex mutex; > + > /* > * This is the requested ESSID. It is written > * only by the WX handlers. > @@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info { > * > * bssfixed is used for SIOCSIWAP. > */ > - u8 static_essid:1, > - short_preamble_available:1, > - associating:1, > - assoc_wait:1, > - bssvalid:1, > - bssfixed:1; > + u8 static_essid; > + u8 short_preamble_available; > + u8 associating; > + u8 associated; > + u8 assoc_wait; > + u8 bssvalid; > + u8 bssfixed; > > /* Scan retries remaining */ > int scan_retry; > @@ -229,12 +228,10 @@ struct ieee80211softmac_device { > /* private stuff follows */ > /* this lock protects this structure */ > spinlock_t lock; > - > - /* couple of flags */ > - u8 scanning:1, /* protects scanning from being done multiple times at > once */ - associated:1, > - running:1; > - > + > + u8 running; /* SoftMAC started? */ > + u8 scanning; > + > struct ieee80211softmac_scaninfo *scaninfo; > struct ieee80211softmac_assoc_info associnfo; > struct ieee80211softmac_bss_info bssinfo; > @@ -250,7 +247,7 @@ struct ieee80211softmac_device { > > /* we need to keep a list of network structs we copied */ > struct list_head network_list; > - > + > /* This must be the last item so that it points to the data > * allocated beyond this structure by alloc_ieee80211 */ > u8 priv[0]; > @@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_sugges > { > struct ieee80211softmac_txrates *txrates = &mac->txrates; > > - if (!mac->associated) > + if (!mac->associnfo.associated) > return txrates->mgt_mcast_rate; > > /* We are associated, sending unicast frame */ > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 > 19:34:20.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct > ieee80211s > dprintk(KERN_INFO PFX "sent association request!\n"); > > spin_lock_irqsave(&mac->lock, flags); > - mac->associated = 0; /* just to make sure */ > + mac->associnfo.associated = 0; /* just to make sure */ > > /* Set a timer for timeout */ > /* FIXME: make timeout configurable */ > @@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d) > { > struct ieee80211softmac_device *mac = (struct ieee80211softmac_device > *)d; struct ieee80211softmac_network *n; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > /* we might race against ieee80211softmac_handle_assoc_response, > * so make sure only one of us does something */ > - if (!mac->associnfo.associating) { > - spin_unlock_irqrestore(&mac->lock, flags); > - return; > - } > + if (!mac->associnfo.associating) > + goto out; > mac->associnfo.associating = 0; > mac->associnfo.bssvalid = 0; > - mac->associated = 0; > + mac->associnfo.associated = 0; > > n = ieee80211softmac_get_network_by_bssid_locked(mac, > mac->associnfo.bssid); - spin_unlock_irqrestore(&mac->lock, flags); > > dprintk(KERN_INFO PFX "assoc request timed out!\n"); > ieee80211softmac_call_events(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); +out: > + mutex_unlock(&mac->associnfo.mutex); > } > > void > @@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee802 > > netif_carrier_off(mac->dev); > > - mac->associated = 0; > + mac->associnfo.associated = 0; > mac->associnfo.bssvalid = 0; > mac->associnfo.associating = 0; > ieee80211softmac_init_bss(mac); > @@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struc > { > struct ieee80211softmac_network *found; > > - if (mac->associnfo.bssvalid && mac->associated) { > + if (mac->associnfo.bssvalid && mac->associnfo.associated) { > found = ieee80211softmac_get_network_by_bssid(mac, > mac->associnfo.bssid); if (found) > ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, > reason); @@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d) > int bssvalid; > unsigned long flags; > > + mutex_lock(&mac->associnfo.mutex); > + > + if (!mac->associnfo.associating) > + goto out; > + > /* ieee80211_disassoc might clear this */ > bssvalid = mac->associnfo.bssvalid; > > /* meh */ > - if (mac->associated) > + if (mac->associnfo.associated) > ieee80211softmac_send_disassoc_req(mac, > WLAN_REASON_DISASSOC_STA_HAS_LEFT); > > - spin_lock_irqsave(&mac->lock, flags); > - mac->associnfo.associating = 1; > - spin_unlock_irqrestore(&mac->lock, flags); > - > /* try to find the requested network in our list, if we found one already > */ if (bssvalid || mac->associnfo.bssfixed) > found = ieee80211softmac_get_network_by_bssid(mac, > mac->associnfo.bssid); @@ -260,10 +259,8 @@ > ieee80211softmac_assoc_work(void *d) > > if (!found) { > if (mac->associnfo.scan_retry > 0) { > - spin_lock_irqsave(&mac->lock, flags); > mac->associnfo.scan_retry--; > - spin_unlock_irqrestore(&mac->lock, flags); > - > + > /* We know of no such network. Let's scan. > * NB: this also happens if we had no memory to copy the network > info... * Maybe we can hope to have more memory after scanning finishes ;) > @@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d) > ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, > ieee80211softmac_assoc_notify_scan, NULL); if > (ieee80211softmac_start_scan(mac)) > dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device > up?\n"); - return; > + goto out; > } else { > - spin_lock_irqsave(&mac->lock, flags); > mac->associnfo.associating = 0; > - mac->associated = 0; > - spin_unlock_irqrestore(&mac->lock, flags); > + mac->associnfo.associated = 0; > > dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); > /* reset the retry counter for the next user request since we > * break out and don't reschedule ourselves after this point. */ > mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; > ieee80211softmac_call_events(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); - return; > + goto out; > } > } > > @@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d) > /* copy the ESSID for displaying it */ > mac->associnfo.associate_essid.len = found->essid.len; > memcpy(mac->associnfo.associate_essid.data, found->essid.data, > IW_ESSID_MAX_SIZE + 1); - > + > /* we found a network! authenticate (if necessary) and associate to it. > */ if (found->authenticating) { > dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); > @@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d) > mac->associnfo.assoc_wait = 1; > ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, > found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); } > - return; > + goto out; > } > if (!found->authenticated && !found->authenticating) { > /* This relies on the fact that _auth_req only queues the work, > @@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d) > mac->associnfo.assoc_wait = 0; > ieee80211softmac_call_events(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); } > - return; > + goto out; > } > /* finally! now we can start associating */ > mac->associnfo.assoc_wait = 0; > ieee80211softmac_assoc(mac, found); > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > } > > /* call this to do whatever is necessary when we're associated */ > @@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee8 > mac->bssinfo.supported_rates = net->supported_rates; > ieee80211softmac_recalc_txrates(mac); > > - mac->associated = 1; > + mac->associnfo.associated = 1; > > mac->associnfo.short_preamble_available = > (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; > @@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(s > dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); > mac->associnfo.associating = 0; > mac->associnfo.bssvalid = 0; > - mac->associated = 0; > + mac->associnfo.associated = 0; > ieee80211softmac_call_events_locked(mac, > IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); } > > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-2 >7 19:34:20.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -57,6 +57,7 @@ struct net_device > *alloc_ieee80211softma > INIT_LIST_HEAD(&softmac->network_list); > INIT_LIST_HEAD(&softmac->events); > > + mutex_init(&softmac->associnfo.mutex); > INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, > softmac); INIT_WORK(&softmac->associnfo.timeout, > ieee80211softmac_assoc_timeout, softmac); softmac->start_scan = > ieee80211softmac_start_scan_implementation; Index: > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 > 19:33:27.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 > 19:37:16.000000000 +0200 @@ -73,13 +73,14 @@ > ieee80211softmac_wx_set_essid(struct net > struct ieee80211softmac_network *n; > struct ieee80211softmac_auth_queue_item *authptr; > int length = 0; > - unsigned long flags; > + > + mutex_lock(&sm->associnfo.mutex); > > /* Check if we're already associating to this or another network > * If it's another network, cancel and start over with our new network > * If it's our network, ignore the change, we're already doing it! > */ > - if((sm->associnfo.associating || sm->associated) && > + if((sm->associnfo.associating || sm->associnfo.associated) && > (data->essid.flags && data->essid.length)) { > /* Get the associating network */ > n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); > @@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net > !memcmp(n->essid.data, extra, n->essid.len)) { > dprintk(KERN_INFO PFX "Already associating or associated to > "MAC_FMT"\n", MAC_ARG(sm->associnfo.bssid)); > - return 0; > + goto out; > } else { > dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); > - spin_lock_irqsave(&sm->lock,flags); > /* Cancel assoc work */ > cancel_delayed_work(&sm->associnfo.work); > /* We don't have to do this, but it's a little cleaner */ > @@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net > cancel_delayed_work(&authptr->work); > sm->associnfo.bssvalid = 0; > sm->associnfo.bssfixed = 0; > - spin_unlock_irqrestore(&sm->lock,flags); > flush_scheduled_work(); > + sm->associnfo.associating = 0; > + sm->associnfo.associated = 0; > } > } > > > - spin_lock_irqsave(&sm->lock, flags); > - > sm->associnfo.static_essid = 0; > sm->associnfo.assoc_wait = 0; > > @@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net > * If applicable, we have already copied the data in */ > sm->associnfo.req_essid.len = length; > > + sm->associnfo.associating = 1; > /* queue lower level code to do work (if necessary) */ > schedule_work(&sm->associnfo.work); > +out: > + mutex_unlock(&sm->associnfo.mutex); > > - spin_unlock_irqrestore(&sm->lock, flags); > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); > @@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net > char *extra) > { > struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); > - unsigned long flags; > > - /* avoid getting inconsistent information */ > - spin_lock_irqsave(&sm->lock, flags); > + mutex_lock(&sm->associnfo.mutex); > /* If all fails, return ANY (empty) */ > data->essid.length = 0; > data->essid.flags = 0; /* active */ > @@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net > } > > /* If we're associating/associated, return that */ > - if (sm->associated || sm->associnfo.associating) { > + if (sm->associnfo.associated || sm->associnfo.associating) { > data->essid.length = sm->associnfo.associate_essid.len; > data->essid.flags = 1; /* active */ > memcpy(extra, sm->associnfo.associate_essid.data, > sm->associnfo.associate_essid.len); } > - spin_unlock_irqrestore(&sm->lock, flags); > + mutex_unlock(&sm->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); > @@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_d > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > int err = 0; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (mac->associnfo.bssvalid) > memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); > else > memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); > data->ap_addr.sa_family = ARPHRD_ETHER; > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); > @@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_d > char *extra) > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > - unsigned long flags; > > /* sanity check */ > if (data->ap_addr.sa_family != ARPHRD_ETHER) { > return -EINVAL; > } > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is not to be fixed any longer, > * and we should reassociate to the best AP. */ > mac->associnfo.bssfixed = 0; > /* force reassociation */ > mac->associnfo.bssvalid = 0; > - if (mac->associated) > + if (mac->associnfo.associated) > schedule_work(&mac->associnfo.work); > } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is no longer fixed */ > mac->associnfo.bssfixed = 0; > } else { > if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { > - if (mac->associnfo.associating || mac->associated) { > + if (mac->associnfo.associating || mac->associnfo.associated) { > /* bssid unchanged and associated or associating - just return */ > goto out; > } > @@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_d > } > > out: > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); > @@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net > int err = 0; > char *buf; > int i; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > /* bleh. shouldn't be locked for that kmalloc... */ > > @@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net > > out: > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); > @@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net > unsigned long flags; > int err = 0; > int space = wrqu->data.length; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > > wrqu->data.length = 0; > @@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net > err = -E2BIG; > } > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); > @@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_ > struct iw_mlme *mlme = (struct iw_mlme *)extra; > u16 reason = cpu_to_le16(mlme->reason_code); > struct ieee80211softmac_network *net; > + int err = -EINVAL; > + > + mutex_lock(&mac->associnfo.mutex); > > if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { > printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't > use\n"); - return -EINVAL; > + goto out; > } > > switch (mlme->cmd) { > @@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_ > net = ieee80211softmac_get_network_by_bssid_locked(mac, > mlme->addr.sa_data); if (!net) { > printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); > - return -EINVAL; > + goto out; > } > return ieee80211softmac_deauth_req(mac, net, reason); > case IW_MLME_DISASSOC: > ieee80211softmac_send_disassoc_req(mac, reason); > - return 0; > + mac->associnfo.associated = 0; > + mac->associnfo.associating = 0; > + err = 0; > + goto out; > default: > - return -EOPNOTSUPP; > + err = -EOPNOTSUPP; > } > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > + > + return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c > =================================================================== > --- > wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 > 19:34:10.000000000 +0200 +++ > wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -242,7 +242,7 @@ void > bcm43xx_leds_update(struct bcm43xx_ > //TODO > break; > case BCM43xx_LED_ASSOC: > - if (bcm->softmac->associated) > + if (bcm->softmac->associnfo.associated) > turn_on = 1; > break; > #ifdef CONFIG_BCM43XX_DEBUG > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c > =================================================================== > --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 > 19:33:27.000000000 +0200 +++ > wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -847,7 +847,7 @@ static struct iw_statistics > *bcm43xx_get > unsigned long flags; > > wstats = &bcm->stats.wstats; > - if (!mac->associated) { > + if (!mac->associnfo.associated) { > wstats->miss.beacon = 0; > // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should > this be cleared here? wstats->discard.retries = 0; > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c > =================================================================== > --- > wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 > 19:34:20.000000000 +0200 +++ > wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 > 19:36:39.000000000 +0200 @@ -475,8 +475,13 @@ int > ieee80211softmac_handle_beacon(struc > { > struct ieee80211softmac_device *mac = ieee80211_priv(dev); > > - if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, > ETH_ALEN) == 0) - ieee80211softmac_process_erp(mac, network->erp_value); > + /* This might race, but we don't really care and it's not worth > + * adding heavyweight locking in this fastpath. > + */ > + if (mac->associnfo.associated) { > + if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) > + ieee80211softmac_process_erp(mac, network->erp_value); > + } > > return 0; > } ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 17:50 ` Michael Buesch 2006-09-27 21:11 ` Christian 2006-09-27 21:21 ` Christian @ 2006-09-27 22:23 ` Benjamin Herrenschmidt 2006-09-28 0:43 ` Larry Finger 2006-09-28 4:09 ` Larry Finger 3 siblings, 1 reply; 27+ messages in thread From: Benjamin Herrenschmidt @ 2006-09-27 22:23 UTC (permalink / raw) To: Michael Buesch; +Cc: linville, Larry Finger, Christian, netdev On Wed, 2006-09-27 at 19:50 +0200, Michael Buesch wrote: > On Wednesday 27 September 2006 18:18, Larry Finger wrote: > > Michael Buesch wrote: > > > This fixes some race conditions in the WirelessExtension > > > handling and association handling code. > > > > > > Signed-off-by: Michael Buesch <mb@bu3sch.de> > > > > > > --- > > > > This patch doesn't apply. > > Oh, linville merged stuff on the 25th. That's the day I updated > my tree to do this patch. But seems like I did it just before > the merge. > Who could suspect that linville merges something. :D > *me runs away* > > Anyway. Here's an updated patch. Which still doesn't apply to 2.6.18. I won't try some random other git tree to test things, it's simply not feasible for me and we need something we can give to distros to backport so they have something remotely stable (I'm thinking for example about the upcoming ubuntu edgy which is coming out soon an a 2.6.17 base). Ben. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 22:23 ` Benjamin Herrenschmidt @ 2006-09-28 0:43 ` Larry Finger 2006-09-28 1:04 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 27+ messages in thread From: Larry Finger @ 2006-09-28 0:43 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: Michael Buesch, linville, Christian, netdev Benjamin Herrenschmidt wrote: >> > I won't try some random other git tree to test things, it's simply not > feasible for me and we need something we can give to distros to backport > so they have something remotely stable (I'm thinking for example about > the upcoming ubuntu edgy which is coming out soon an a 2.6.17 base). I don't know what your problem is! Despite your negative attitude, I have tried to accommodate you, but obviously you do not appreciate my efforts. My big patch for 2.6.18 concentrated on bcm43xx. Yes there were changes in softmac, but they had no major effect until Michael's fix of the race condition. The bottom line is that I have had it with you! You had best go back to some mainline kernel as you will get no further help from me. There are lots of folks that need help _AND_ are appreciative of that help. My time will be spent on them. Larry ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 0:43 ` Larry Finger @ 2006-09-28 1:04 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 27+ messages in thread From: Benjamin Herrenschmidt @ 2006-09-28 1:04 UTC (permalink / raw) To: Larry Finger; +Cc: Michael Buesch, linville, Christian, netdev On Wed, 2006-09-27 at 19:43 -0500, Larry Finger wrote: > Benjamin Herrenschmidt wrote: > >> > > I won't try some random other git tree to test things, it's simply not > > feasible for me and we need something we can give to distros to backport > > so they have something remotely stable (I'm thinking for example about > > the upcoming ubuntu edgy which is coming out soon an a 2.6.17 base). > > I don't know what your problem is! Despite your negative attitude, I have tried to accommodate you, > but obviously you do not appreciate my efforts. My big patch for 2.6.18 concentrated on bcm43xx. Yes > there were changes in softmac, but they had no major effect until Michael's fix of the race condition. > > The bottom line is that I have had it with you! You had best go back to some mainline kernel as you > will get no further help from me. There are lots of folks that need help _AND_ are appreciative of > that help. My time will be spent on them. Maybe because I'm a hot blooded asshole :) Note that I wasn't complaining about your patch (which is a bit huge tho for a stable release, but it did make a difference here along with Michael debug one). I just noticed that none of Michael last "final" patches would apply on 2.6.18 + your patch, and went into my usual rant in case they were supposed to apply to the wireless tree. There is a number of reasons why people can't just use a wireless-git or whatever else tree, and having something against mainline is the only way I see to get something to distros now, which is the way to fix the most people problems rather than only the ones finding this mailing list. Ben. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 17:50 ` Michael Buesch ` (2 preceding siblings ...) 2006-09-27 22:23 ` Benjamin Herrenschmidt @ 2006-09-28 4:09 ` Larry Finger 2006-09-28 12:55 ` Michael Buesch 3 siblings, 1 reply; 27+ messages in thread From: Larry Finger @ 2006-09-28 4:09 UTC (permalink / raw) To: Michael Buesch; +Cc: linville, netdev Michael Buesch wrote: > On Wednesday 27 September 2006 18:18, Larry Finger wrote: >> Michael Buesch wrote: >>> This fixes some race conditions in the WirelessExtension >>> handling and association handling code. >>> >>> Signed-off-by: Michael Buesch <mb@bu3sch.de> >>> >>> --- >> This patch doesn't apply. > > Oh, linville merged stuff on the 25th. That's the day I updated > my tree to do this patch. But seems like I did it just before > the merge. > Who could suspect that linville merges something. :D > *me runs away* > > Anyway. Here's an updated patch. NACK this version. It applied correctly, but introduced a new problem. My device occasionally gets deauthentication messages from my AP.Preciously, it would do a scan or two, and then reauthenticate. After your patch was applied, it never stops scanning. The "normal" sequence is kernel: SoftMAC: Received deauthentication packet from 00:14:bf:85:49:fa, but that network is unknown. kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: bcm43xx: set security called, .enabled = 0, .encrypt = 0 kernel: bcm43xx: set security called, .enabled = 0, .encrypt = 0 kernel: bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 kernel: bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 kernel: bcm43xx: set security called, .level = 0, .enabled = 0, .encrypt = 0 kernel: SoftMAC: Scanning finished kernel: SoftMAC: Queueing Authentication Request to 00:14:bf:85:49:fa kernel: SoftMAC: Cannot associate without being authenticated, requested authentication kernel: SoftMAC: Sent Authentication Request to 00:14:bf:85:49:fa. kernel: SoftMAC: Open Authentication completed with 00:14:bf:85:49:fa kernel: SoftMAC: sent association request! kernel: SoftMAC: generic IE set to dd160050f20101000050f20201000050f20201000050f202 kernel: SoftMAC: Already associating or associated to 00:14:bf:85:49:fa kernel: SoftMAC: associated! kernel: bcm43xx: set security called, .active_key = 0, .level = 2, .enabled = 1, With your patch: kernel: SoftMAC: Received deauthentication packet from 00:14:bf:85:49:fa, but that network is unknown. kernel: SoftMAC: Scanning finished kernel: SoftMAC: Unable to find matching network after scan! kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: SoftMAC: Scanning finished kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: SoftMAC: Scanning finished kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: SoftMAC: Scanning finished kernel: SoftMAC: Unable to find matching network after scan! kernel: SoftMAC: generic IE set to dd160050f20101000050f20201000050f20201000050f202 kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: SoftMAC: Scanning finished kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: SoftMAC: Scanning finished kernel: SoftMAC: Associate: Scanning for networks first. kernel: SoftMAC: Start scanning with channel: 1 kernel: SoftMAC: Scanning 14 channels kernel: SoftMAC: Scanning finished kernel: SoftMAC: Unable to find matching network after scan! kernel: SoftMAC: generic IE set to dd160050f20101000050f20201000050f20201000050f202 This pattern repeats until the network is brought down and back up. Larry ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 4:09 ` Larry Finger @ 2006-09-28 12:55 ` Michael Buesch 2006-09-28 14:19 ` Dan Williams 0 siblings, 1 reply; 27+ messages in thread From: Michael Buesch @ 2006-09-28 12:55 UTC (permalink / raw) To: Larry Finger; +Cc: linville, netdev On Thursday 28 September 2006 06:09, Larry Finger wrote: > Michael Buesch wrote: > > On Wednesday 27 September 2006 18:18, Larry Finger wrote: > >> Michael Buesch wrote: > >>> This fixes some race conditions in the WirelessExtension > >>> handling and association handling code. > >>> > >>> Signed-off-by: Michael Buesch <mb@bu3sch.de> > >>> > >>> --- > >> This patch doesn't apply. > > > > Oh, linville merged stuff on the 25th. That's the day I updated > > my tree to do this patch. But seems like I did it just before > > the merge. > > Who could suspect that linville merges something. :D > > *me runs away* > > > > Anyway. Here's an updated patch. > > NACK this version. It applied correctly, but introduced a new problem. My device occasionally gets > deauthentication messages from my AP.Preciously, it would do a scan or two, and then reauthenticate. > After your patch was applied, it never stops scanning. Oh, well... It's impossible to completely fix softmac race issues. I am _not_ going to rewrite huge parts of softmac to get locking working. If you want this to be fixed, please hack up a solution by yourself. I'm really not going to do more work on softmac. This has various reasons. 1) I cannot reproduce all these bugs I'm hunting 2) Time is spent better at d80211 or other projects. But to debug the problem: Why do you get deauth messages? Broken AP? I'd say that it's _correct_ behaviour to stop working after getting a deauth ;). wpa_supplicant is responsible to re-auth. Why doesn't it re-auth? Or does it do and it just doesn't work as expected? -- Greetings Michael. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 12:55 ` Michael Buesch @ 2006-09-28 14:19 ` Dan Williams 2006-09-28 14:27 ` Johannes Berg 0 siblings, 1 reply; 27+ messages in thread From: Dan Williams @ 2006-09-28 14:19 UTC (permalink / raw) To: Michael Buesch; +Cc: Larry Finger, linville, netdev On Thu, 2006-09-28 at 14:55 +0200, Michael Buesch wrote: > On Thursday 28 September 2006 06:09, Larry Finger wrote: > > Michael Buesch wrote: > > > On Wednesday 27 September 2006 18:18, Larry Finger wrote: > > >> Michael Buesch wrote: > > >>> This fixes some race conditions in the WirelessExtension > > >>> handling and association handling code. > > >>> > > >>> Signed-off-by: Michael Buesch <mb@bu3sch.de> > > >>> > > >>> --- > > >> This patch doesn't apply. > > > > > > Oh, linville merged stuff on the 25th. That's the day I updated > > > my tree to do this patch. But seems like I did it just before > > > the merge. > > > Who could suspect that linville merges something. :D > > > *me runs away* > > > > > > Anyway. Here's an updated patch. > > > > NACK this version. It applied correctly, but introduced a new problem. My device occasionally gets > > deauthentication messages from my AP.Preciously, it would do a scan or two, and then reauthenticate. > > After your patch was applied, it never stops scanning. > > Oh, well... It's impossible to completely fix softmac race issues. > I am _not_ going to rewrite huge parts of softmac to get locking > working. If you want this to be fixed, please hack up a solution by > yourself. I'm really not going to do more work on softmac. This > has various reasons. 1) I cannot reproduce all these bugs I'm hunting > 2) Time is spent better at d80211 or other projects. > > But to debug the problem: > Why do you get deauth messages? Broken AP? > I'd say that it's _correct_ behaviour to stop working > after getting a deauth ;). wpa_supplicant is responsible to re-auth. I'd buy that argument. When the driver gets the deauth message, shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to userspace? That would cause a tool like wpa_supplicant (or NM) to attempt reauth/reassoc anyway, based on their own policy. "Stations may send Disassociation or Deauthentication frames in response to traffic when the sender has not properly joined the network." (802.11 Wireless Networks) What's the value of the Reason Code received in the deauth frame? That will give a clue as to why the AP is rejecting you: 0 Reserved; unused 1 Unspecified 2 Prior authentication is not valid 3 Station has left the basic service area or extended service area and is deauthenticated 4 Inactivity timer expired and station was disassociated 5 Disassociated due to insufficient resources at the access point 6 Incorrect frame type or subtype received from unauthenticated station 7 Incorrect frame type or subtype received from unassociated station 8 Station has left the basic service area or extended service area and is disassociated 9 Association or reassociation requested before authentication is complete 10 Reserved; unused > Why doesn't it re-auth? Or does it do and it just doesn't work as > expected? It would be interesting to know what state the driver's state machine is in when it gets this message. Does the driver think it's authenticated? Does the AP think the same thing? Dan ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:19 ` Dan Williams @ 2006-09-28 14:27 ` Johannes Berg 2006-09-28 14:37 ` Dan Williams 0 siblings, 1 reply; 27+ messages in thread From: Johannes Berg @ 2006-09-28 14:27 UTC (permalink / raw) To: Dan Williams; +Cc: Michael Buesch, Larry Finger, linville, netdev On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: > I'd buy that argument. When the driver gets the deauth message, > shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to > userspace? I thought we did that since a long time now, didn't you actually develop the initial patch? johannes ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:27 ` Johannes Berg @ 2006-09-28 14:37 ` Dan Williams 2006-09-28 14:43 ` Michael Buesch 2006-09-28 14:43 ` Johannes Berg 0 siblings, 2 replies; 27+ messages in thread From: Dan Williams @ 2006-09-28 14:37 UTC (permalink / raw) To: Johannes Berg; +Cc: Michael Buesch, Larry Finger, linville, netdev On Thu, 2006-09-28 at 16:27 +0200, Johannes Berg wrote: > On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: > > > I'd buy that argument. When the driver gets the deauth message, > > shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to > > userspace? > > I thought we did that since a long time now, didn't you actually develop > the initial patch? Yes, I think I did. My point here wasn't that the driver is _not_ sending those messages (it almost certainly is), but what's _implied_ by those messages. Namely that, if you're using a tool like wpa_supplicant and/or NM, when you get a deauth from the AP and send the IWAP event, all bets are off because the tool will likely override whatever the driver thinks its doing. I'm somewhat ambiguous on just how much policy a driver should try to enforce. I guess I'm OK with reassociation with the _same_ credentials. But what airo does with "auto_wep" is very nearly, if not completely, crossing the line [1]. The real question is, how much should drivers really do, and how much should they leave to userspace? Dan [1] if the auth mode (open or shared-key) doesn't work, airo schedules a timer and bumps the auth mode to the other one automatically, and tries reassociation. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:37 ` Dan Williams @ 2006-09-28 14:43 ` Michael Buesch 2006-09-28 14:52 ` Dan Williams 2006-09-28 14:43 ` Johannes Berg 1 sibling, 1 reply; 27+ messages in thread From: Michael Buesch @ 2006-09-28 14:43 UTC (permalink / raw) To: Dan Williams; +Cc: Larry Finger, linville, netdev, Johannes Berg On Thursday 28 September 2006 16:37, Dan Williams wrote: > On Thu, 2006-09-28 at 16:27 +0200, Johannes Berg wrote: > > On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: > > > > > I'd buy that argument. When the driver gets the deauth message, > > > shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to > > > userspace? > > > > I thought we did that since a long time now, didn't you actually develop > > the initial patch? > > Yes, I think I did. My point here wasn't that the driver is _not_ > sending those messages (it almost certainly is), but what's _implied_ by > those messages. Namely that, if you're using a tool like wpa_supplicant > and/or NM, when you get a deauth from the AP and send the IWAP event, > all bets are off because the tool will likely override whatever the > driver thinks its doing. > > I'm somewhat ambiguous on just how much policy a driver should try to > enforce. I guess I'm OK with reassociation with the _same_ credentials. > But what airo does with "auto_wep" is very nearly, if not completely, > crossing the line [1]. The real question is, how much should drivers > really do, and how much should they leave to userspace? IMO a driver should implement absolutely _zero_ policy, as this is the only way to get the same (default) policy for different cards. A driver should _only_ provide generic events for userspace tools to make decisions. A "I got a deauth" event is really enough for userspace to know what to do. > Dan > > [1] if the auth mode (open or shared-key) doesn't work, airo schedules a > timer and bumps the auth mode to the other one automatically, and tries > reassociation. > > > -- Greetings Michael. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:43 ` Michael Buesch @ 2006-09-28 14:52 ` Dan Williams 2006-09-28 15:13 ` Michael Buesch 2006-09-28 15:16 ` Larry Finger 0 siblings, 2 replies; 27+ messages in thread From: Dan Williams @ 2006-09-28 14:52 UTC (permalink / raw) To: Michael Buesch; +Cc: Larry Finger, linville, netdev, Johannes Berg On Thu, 2006-09-28 at 16:43 +0200, Michael Buesch wrote: > On Thursday 28 September 2006 16:37, Dan Williams wrote: > > On Thu, 2006-09-28 at 16:27 +0200, Johannes Berg wrote: > > > On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: > > > > > > > I'd buy that argument. When the driver gets the deauth message, > > > > shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to > > > > userspace? > > > > > > I thought we did that since a long time now, didn't you actually develop > > > the initial patch? > > > > Yes, I think I did. My point here wasn't that the driver is _not_ > > sending those messages (it almost certainly is), but what's _implied_ by > > those messages. Namely that, if you're using a tool like wpa_supplicant > > and/or NM, when you get a deauth from the AP and send the IWAP event, > > all bets are off because the tool will likely override whatever the > > driver thinks its doing. > > > > I'm somewhat ambiguous on just how much policy a driver should try to > > enforce. I guess I'm OK with reassociation with the _same_ credentials. > > But what airo does with "auto_wep" is very nearly, if not completely, > > crossing the line [1]. The real question is, how much should drivers > > really do, and how much should they leave to userspace? > > IMO a driver should implement absolutely _zero_ policy, as this > is the only way to get the same (default) policy for different > cards. A driver should _only_ provide generic events for > userspace tools to make decisions. > A "I got a deauth" event is really enough for userspace to > know what to do. As a counterpoint, does every developer _really_ want to run wpa_supplicant just to use a WEP-encrypted connection where you may occasionally get kicked off? I think it's clear that with WPA, it's pretty nearly impossible to do reauth/reassoc because you need a user-space supplicant, right? But WEP doesn't require any interaction other than the 2- or 4-stage handshake for open or shared key, and that's already done in the driver. I'd say that handling WEP reauth/reassoc in the driver is probably fine [1] since many drivers already try to do this, but I believe it's probably inappropriate for anything more than WEP. It's probably also impossible to do with any sort of more-than-WEP roaming, maybe even WEP roaming. Dan [1] with a suitable timeout or #tries clamp so it doesn't try forever. airo does the auto_wep thing twice before failing and sending IWAP 00:00:... I believe. > > Dan > > > > [1] if the auth mode (open or shared-key) doesn't work, airo schedules a > > timer and bumps the auth mode to the other one automatically, and tries > > reassociation. > > > > > > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:52 ` Dan Williams @ 2006-09-28 15:13 ` Michael Buesch 2006-09-28 17:33 ` Jouni Malinen 2006-09-28 15:16 ` Larry Finger 1 sibling, 1 reply; 27+ messages in thread From: Michael Buesch @ 2006-09-28 15:13 UTC (permalink / raw) To: Dan Williams, Larry Finger, linville, netdev, Johannes Berg On Thursday 28 September 2006 16:52, Dan Williams wrote: > On Thu, 2006-09-28 at 16:43 +0200, Michael Buesch wrote: > > On Thursday 28 September 2006 16:37, Dan Williams wrote: > > > On Thu, 2006-09-28 at 16:27 +0200, Johannes Berg wrote: > > > > On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: > > > > > > > > > I'd buy that argument. When the driver gets the deauth message, > > > > > shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to > > > > > userspace? > > > > > > > > I thought we did that since a long time now, didn't you actually develop > > > > the initial patch? > > > > > > Yes, I think I did. My point here wasn't that the driver is _not_ > > > sending those messages (it almost certainly is), but what's _implied_ by > > > those messages. Namely that, if you're using a tool like wpa_supplicant > > > and/or NM, when you get a deauth from the AP and send the IWAP event, > > > all bets are off because the tool will likely override whatever the > > > driver thinks its doing. > > > > > > I'm somewhat ambiguous on just how much policy a driver should try to > > > enforce. I guess I'm OK with reassociation with the _same_ credentials. > > > But what airo does with "auto_wep" is very nearly, if not completely, > > > crossing the line [1]. The real question is, how much should drivers > > > really do, and how much should they leave to userspace? > > > > IMO a driver should implement absolutely _zero_ policy, as this > > is the only way to get the same (default) policy for different > > cards. A driver should _only_ provide generic events for > > userspace tools to make decisions. > > A "I got a deauth" event is really enough for userspace to > > know what to do. > > As a counterpoint, does every developer _really_ want to run > wpa_supplicant just to use a WEP-encrypted connection where you may > occasionally get kicked off? I think that's the way we want to take. Even for unencrypted networks, probably. We want as much as possible of the high level MAC implementation in userspace. Remember the summit and Simon's talk? It was a good talk and made a lot of sense. This userspace implementation should probably renamed from wpa_supplicant to wireless_supplicant or whatever. -- Greetings Michael. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 15:13 ` Michael Buesch @ 2006-09-28 17:33 ` Jouni Malinen 0 siblings, 0 replies; 27+ messages in thread From: Jouni Malinen @ 2006-09-28 17:33 UTC (permalink / raw) To: Michael Buesch Cc: Dan Williams, Larry Finger, linville, netdev, Johannes Berg On Thu, Sep 28, 2006 at 05:13:20PM +0200, Michael Buesch wrote: > On Thursday 28 September 2006 16:52, Dan Williams wrote: > > As a counterpoint, does every developer _really_ want to run > > wpa_supplicant just to use a WEP-encrypted connection where you may > > occasionally get kicked off? > > I think that's the way we want to take. Even for unencrypted networks, > probably. We want as much as possible of the high level MAC > implementation in userspace. Remember the summit and Simon's talk? > It was a good talk and made a lot of sense. I don't know whether every developer wants to run a userspace tool for that, but taken into account that I'm planning on focusing on the MLME code in wpa_supplicant instead of fine tuning similar code in kernel, it should be quite obvious what I would be voting for ;-). > This userspace implementation should probably renamed from wpa_supplicant > to wireless_supplicant or whatever. Yeah.. wpa_supplicant does not really describe the exact set of functionality in the program. Though, I'm not planning on renaming it just for the sake of having a better name. Then again, there are plans on merging (with build time options) wpa_supplicant and hostapd functionality, so there is a good point for renaming the end result to something else. At this point, it shouldn't have "supplicant" in the name either since it will be possible to include both supplicant and authenticator functionality into the same program (e.g., for IEEE 802.11i IBSS). -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:52 ` Dan Williams 2006-09-28 15:13 ` Michael Buesch @ 2006-09-28 15:16 ` Larry Finger 2006-09-28 15:29 ` Michael Buesch 2006-09-28 15:35 ` Michael Wu 1 sibling, 2 replies; 27+ messages in thread From: Larry Finger @ 2006-09-28 15:16 UTC (permalink / raw) To: Dan Williams; +Cc: Michael Buesch, linville, netdev, Johannes Berg Dan Williams wrote: > On Thu, 2006-09-28 at 16:43 +0200, Michael Buesch wrote: >> On Thursday 28 September 2006 16:37, Dan Williams wrote: >>> On Thu, 2006-09-28 at 16:27 +0200, Johannes Berg wrote: >>>> On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: >>>> >>>>> I'd buy that argument. When the driver gets the deauth message, >>>>> shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to >>>>> userspace? >>>> I thought we did that since a long time now, didn't you actually develop >>>> the initial patch? >>> Yes, I think I did. My point here wasn't that the driver is _not_ >>> sending those messages (it almost certainly is), but what's _implied_ by >>> those messages. Namely that, if you're using a tool like wpa_supplicant >>> and/or NM, when you get a deauth from the AP and send the IWAP event, >>> all bets are off because the tool will likely override whatever the >>> driver thinks its doing. >>> >>> I'm somewhat ambiguous on just how much policy a driver should try to >>> enforce. I guess I'm OK with reassociation with the _same_ credentials. >>> But what airo does with "auto_wep" is very nearly, if not completely, >>> crossing the line [1]. The real question is, how much should drivers >>> really do, and how much should they leave to userspace? >> IMO a driver should implement absolutely _zero_ policy, as this >> is the only way to get the same (default) policy for different >> cards. A driver should _only_ provide generic events for >> userspace tools to make decisions. >> A "I got a deauth" event is really enough for userspace to >> know what to do. > > As a counterpoint, does every developer _really_ want to run > wpa_supplicant just to use a WEP-encrypted connection where you may > occasionally get kicked off? > > I think it's clear that with WPA, it's pretty nearly impossible to do > reauth/reassoc because you need a user-space supplicant, right? But WEP > doesn't require any interaction other than the 2- or 4-stage handshake > for open or shared key, and that's already done in the driver. > > I'd say that handling WEP reauth/reassoc in the driver is probably fine > [1] since many drivers already try to do this, but I believe it's > probably inappropriate for anything more than WEP. It's probably also > impossible to do with any sort of more-than-WEP roaming, maybe even WEP > roaming. > > Dan > > [1] with a suitable timeout or #tries clamp so it doesn't try forever. > airo does the auto_wep thing twice before failing and sending IWAP > 00:00:... I believe. > >>> Dan >>> >>> [1] if the auth mode (open or shared-key) doesn't work, airo schedules a >>> timer and bumps the auth mode to the other one automatically, and tries >>> reassociation. Thanks for the educational discourse here. I have quite a bit of food for thought. First of all, my problem is quite likely caused by a buggy AP. It is a Linksys WRT54G V5, which is one of those with a VxWorks kernel, not Linux. I have already reported one bug to Linksys, which they have neither acknowledged nor fixed! In that case, SoftMAC had to be modified as a work-around. I don't know why the deauthentication is being sent. The reason is not logged, which will be my first change in the code. The second place to look is why SoftMAC reports the network is unknown when the MAC printed is that of my AP. Once I know more about the above points, I'll likely be back with more questions. Once I get the response to the deauthentication to be better behaved, I will retry Michael's patch. The main difficulty in all of this is that it happens even less frequently than the NETDEV WATCHDOG timeouts, which were bad enough to troubleshoot. Thanks again, Larry ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 15:16 ` Larry Finger @ 2006-09-28 15:29 ` Michael Buesch 2006-09-28 15:35 ` Michael Wu 1 sibling, 0 replies; 27+ messages in thread From: Michael Buesch @ 2006-09-28 15:29 UTC (permalink / raw) To: Larry Finger; +Cc: linville, netdev, Johannes Berg, Dan Williams On Thursday 28 September 2006 17:16, Larry Finger wrote: > Dan Williams wrote: > > On Thu, 2006-09-28 at 16:43 +0200, Michael Buesch wrote: > >> On Thursday 28 September 2006 16:37, Dan Williams wrote: > >>> On Thu, 2006-09-28 at 16:27 +0200, Johannes Berg wrote: > >>>> On Thu, 2006-09-28 at 10:19 -0400, Dan Williams wrote: > >>>> > >>>>> I'd buy that argument. When the driver gets the deauth message, > >>>>> shouldn't it be sending an IWAP 00:00:00:00:00:00 wireless event to > >>>>> userspace? > >>>> I thought we did that since a long time now, didn't you actually develop > >>>> the initial patch? > >>> Yes, I think I did. My point here wasn't that the driver is _not_ > >>> sending those messages (it almost certainly is), but what's _implied_ by > >>> those messages. Namely that, if you're using a tool like wpa_supplicant > >>> and/or NM, when you get a deauth from the AP and send the IWAP event, > >>> all bets are off because the tool will likely override whatever the > >>> driver thinks its doing. > >>> > >>> I'm somewhat ambiguous on just how much policy a driver should try to > >>> enforce. I guess I'm OK with reassociation with the _same_ credentials. > >>> But what airo does with "auto_wep" is very nearly, if not completely, > >>> crossing the line [1]. The real question is, how much should drivers > >>> really do, and how much should they leave to userspace? > >> IMO a driver should implement absolutely _zero_ policy, as this > >> is the only way to get the same (default) policy for different > >> cards. A driver should _only_ provide generic events for > >> userspace tools to make decisions. > >> A "I got a deauth" event is really enough for userspace to > >> know what to do. > > > > As a counterpoint, does every developer _really_ want to run > > wpa_supplicant just to use a WEP-encrypted connection where you may > > occasionally get kicked off? > > > > I think it's clear that with WPA, it's pretty nearly impossible to do > > reauth/reassoc because you need a user-space supplicant, right? But WEP > > doesn't require any interaction other than the 2- or 4-stage handshake > > for open or shared key, and that's already done in the driver. > > > > I'd say that handling WEP reauth/reassoc in the driver is probably fine > > [1] since many drivers already try to do this, but I believe it's > > probably inappropriate for anything more than WEP. It's probably also > > impossible to do with any sort of more-than-WEP roaming, maybe even WEP > > roaming. > > > > Dan > > > > [1] with a suitable timeout or #tries clamp so it doesn't try forever. > > airo does the auto_wep thing twice before failing and sending IWAP > > 00:00:... I believe. > > > >>> Dan > >>> > >>> [1] if the auth mode (open or shared-key) doesn't work, airo schedules a > >>> timer and bumps the auth mode to the other one automatically, and tries > >>> reassociation. > > Thanks for the educational discourse here. I have quite a bit of food for thought. > > First of all, my problem is quite likely caused by a buggy AP. It is a Linksys WRT54G V5, which is > one of those with a VxWorks kernel, not Linux. I have already reported one bug to Linksys, which > they have neither acknowledged nor fixed! In that case, SoftMAC had to be modified as a work-around. > > I don't know why the deauthentication is being sent. The reason is not logged, which will be my > first change in the code. The second place to look is why SoftMAC reports the network is unknown > when the MAC printed is that of my AP. > > Once I know more about the above points, I'll likely be back with more questions. Once I get the > response to the deauthentication to be better behaved, I will retry Michael's patch. The main > difficulty in all of this is that it happens even less frequently than the NETDEV WATCHDOG timeouts, > which were bad enough to troubleshoot. You could try to capture such a deauth packet once you got one from the AP and inject it for testing from another machine. Injecting can be done with my crappy sysfs interface (search archives) or with nl80211. My sysfs patch is probably easier to use, for now. But you could also patch the driver and hardcode the packet into some routine that executes on some user triggered event (Some private WX, some sysfs file, etc...) Modifying the driver to inject the frame is probably easiest. -- Greetings Michael. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 15:16 ` Larry Finger 2006-09-28 15:29 ` Michael Buesch @ 2006-09-28 15:35 ` Michael Wu 2006-09-28 15:52 ` Larry Finger 1 sibling, 1 reply; 27+ messages in thread From: Michael Wu @ 2006-09-28 15:35 UTC (permalink / raw) To: Larry Finger Cc: Dan Williams, Michael Buesch, linville, netdev, Johannes Berg [-- Attachment #1: Type: text/plain, Size: 1104 bytes --] On Thursday 28 September 2006 11:16, Larry Finger wrote: > First of all, my problem is quite likely caused by a buggy AP. It is a > Linksys WRT54G V5, which is one of those with a VxWorks kernel, not Linux. > I have already reported one bug to Linksys, which they have neither > acknowledged nor fixed! In that case, SoftMAC had to be modified as a > work-around. > These APs are truly bad. Hacking linux into it (DD-WRT) helps a bit, but wireless often seems to fail *completely* at times. > I don't know why the deauthentication is being sent. The reason is not > logged, which will be my first change in the code. The second place to look > is why SoftMAC reports the network is unknown when the MAC printed is that > of my AP. > The deauth reason code is usually 6 or 7.. IIRC, it is 6: Class 2 Frame from Non Authenticated STA. The AP just forgets you're associated. However, I think that was from when I had a v3 WRT54G. I made sure the old adm8211 softmac stack had a very good set of printks to report these sort of things. :) Many APs do funny things.. -Michael Wu [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 15:35 ` Michael Wu @ 2006-09-28 15:52 ` Larry Finger 2006-09-28 16:31 ` Jason Lunz 0 siblings, 1 reply; 27+ messages in thread From: Larry Finger @ 2006-09-28 15:52 UTC (permalink / raw) To: Michael Wu; +Cc: Dan Williams, Michael Buesch, linville, netdev, Johannes Berg Michael Wu wrote: > On Thursday 28 September 2006 11:16, Larry Finger wrote: >> First of all, my problem is quite likely caused by a buggy AP. It is a >> Linksys WRT54G V5, which is one of those with a VxWorks kernel, not Linux. >> I have already reported one bug to Linksys, which they have neither >> acknowledged nor fixed! In that case, SoftMAC had to be modified as a >> work-around. >> > These APs are truly bad. Hacking linux into it (DD-WRT) helps a bit, but > wireless often seems to fail *completely* at times. I had very good luck with my first AP, a Linksys WRT54G V1, that I bought a second when the power supply failed in the first. Little did I know that a VxWorks license costs less than the extra memory needed to run Linux. Or was it to defeat the open-source alternatives for the AP? >> I don't know why the deauthentication is being sent. The reason is not >> logged, which will be my first change in the code. The second place to look >> is why SoftMAC reports the network is unknown when the MAC printed is that >> of my AP. >> > The deauth reason code is usually 6 or 7.. IIRC, it is 6: Class 2 Frame from > Non Authenticated STA. The AP just forgets you're associated. However, I > think that was from when I had a v3 WRT54G. I already have modified SoftMAC to log the reason. Now I have to wait for the event to happen. > I made sure the old adm8211 softmac stack had a very good set of printks to > report these sort of things. :) Many APs do funny things.. Thanks for the tip. It is unfortunate that the Linux code has to work around all the closed-source other stuff! Larry ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 15:52 ` Larry Finger @ 2006-09-28 16:31 ` Jason Lunz 2006-09-28 17:04 ` Larry Finger 0 siblings, 1 reply; 27+ messages in thread From: Jason Lunz @ 2006-09-28 16:31 UTC (permalink / raw) To: Larry Finger Cc: Dan Williams, Michael Buesch, linville, netdev, Johannes Berg On Thu, Sep 28, 2006 at 10:52:24AM -0500, Larry Finger wrote: > I had very good luck with my first AP, a Linksys WRT54G V1, that I > bought a second when the power supply failed in the first. Little did > I know that a VxWorks license costs less than the extra memory needed > to run Linux. Or was it to defeat the open-source alternatives for the > AP? last I checked, linksys (cisco?) still sells the linux-compatible version as the WRT54GL. <- note the extra 'L'. Jason ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 16:31 ` Jason Lunz @ 2006-09-28 17:04 ` Larry Finger 2006-09-28 17:14 ` Michael Buesch 0 siblings, 1 reply; 27+ messages in thread From: Larry Finger @ 2006-09-28 17:04 UTC (permalink / raw) To: Jason Lunz; +Cc: Dan Williams, Michael Buesch, linville, netdev, Johannes Berg Jason Lunz wrote: > On Thu, Sep 28, 2006 at 10:52:24AM -0500, Larry Finger wrote: >> I had very good luck with my first AP, a Linksys WRT54G V1, that I >> bought a second when the power supply failed in the first. Little did >> I know that a VxWorks license costs less than the extra memory needed >> to run Linux. Or was it to defeat the open-source alternatives for the >> AP? > > last I checked, linksys (cisco?) still sells the linux-compatible > version as the WRT54GL. <- note the extra 'L'. I know, but have decided to stay with V5 (and bitch a lot) as others are likely to suffer from the same problems as I do. As many of them would never try alternate firmware, we need to provide the workarounds. If I'm using one of the brain-dead APs, I get the symptoms first hand and can tell when they are fixed. Larry ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 17:04 ` Larry Finger @ 2006-09-28 17:14 ` Michael Buesch 2006-09-28 17:40 ` Larry Finger 0 siblings, 1 reply; 27+ messages in thread From: Michael Buesch @ 2006-09-28 17:14 UTC (permalink / raw) To: Larry Finger; +Cc: Dan Williams, linville, netdev, Johannes Berg, Jason Lunz On Thursday 28 September 2006 19:04, Larry Finger wrote: > Jason Lunz wrote: > > On Thu, Sep 28, 2006 at 10:52:24AM -0500, Larry Finger wrote: > >> I had very good luck with my first AP, a Linksys WRT54G V1, that I > >> bought a second when the power supply failed in the first. Little did > >> I know that a VxWorks license costs less than the extra memory needed > >> to run Linux. Or was it to defeat the open-source alternatives for the > >> AP? > > > > last I checked, linksys (cisco?) still sells the linux-compatible > > version as the WRT54GL. <- note the extra 'L'. > > I know, but have decided to stay with V5 (and bitch a lot) as others are likely to suffer from the > same problems as I do. As many of them would never try alternate firmware, we need to provide the > workarounds. If I'm using one of the brain-dead APs, I get the symptoms first hand and can tell when > they are fixed. Well. You say that it works with your AP and without my patch, but not with the patch. I'd say it works by pure luck. I don't think my patch changes any semantics. It just properly protects some parts from racing. Maybe you actually benefit from these races and softmac magically "races you the correct result" ;) Or do you notice something that changes semantics? -- Greetings Michael. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 17:14 ` Michael Buesch @ 2006-09-28 17:40 ` Larry Finger 0 siblings, 0 replies; 27+ messages in thread From: Larry Finger @ 2006-09-28 17:40 UTC (permalink / raw) To: Michael Buesch; +Cc: Dan Williams, linville, netdev, Johannes Berg, Jason Lunz Michael Buesch wrote: > On Thursday 28 September 2006 19:04, Larry Finger wrote: >> Jason Lunz wrote: >>> On Thu, Sep 28, 2006 at 10:52:24AM -0500, Larry Finger wrote: >>>> I had very good luck with my first AP, a Linksys WRT54G V1, that I >>>> bought a second when the power supply failed in the first. Little did >>>> I know that a VxWorks license costs less than the extra memory needed >>>> to run Linux. Or was it to defeat the open-source alternatives for the >>>> AP? >>> last I checked, linksys (cisco?) still sells the linux-compatible >>> version as the WRT54GL. <- note the extra 'L'. >> I know, but have decided to stay with V5 (and bitch a lot) as others are likely to suffer from the >> same problems as I do. As many of them would never try alternate firmware, we need to provide the >> workarounds. If I'm using one of the brain-dead APs, I get the symptoms first hand and can tell when >> they are fixed. > > Well. You say that it works with your AP and without my patch, but > not with the patch. I'd say it works by pure luck. I don't think > my patch changes any semantics. It just properly protects some > parts from racing. Maybe you actually benefit from these races > and softmac magically "races you the correct result" ;) > > Or do you notice something that changes semantics? > No, only that the system recovers w/o your patch, and not with it. It could very well race to the correct point. ATM, I have your patch back in and I'm trying to get more diagnostics in the logs. I'll let you know. Larry ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-28 14:37 ` Dan Williams 2006-09-28 14:43 ` Michael Buesch @ 2006-09-28 14:43 ` Johannes Berg 1 sibling, 0 replies; 27+ messages in thread From: Johannes Berg @ 2006-09-28 14:43 UTC (permalink / raw) To: Dan Williams; +Cc: Michael Buesch, Larry Finger, linville, netdev On Thu, 2006-09-28 at 10:37 -0400, Dan Williams wrote: > Yes, I think I did. My point here wasn't that the driver is _not_ > sending those messages (it almost certainly is), but what's _implied_ by > those messages. Namely that, if you're using a tool like wpa_supplicant > and/or NM, when you get a deauth from the AP and send the IWAP event, > all bets are off because the tool will likely override whatever the > driver thinks its doing. Ah ok. But I suppose the actual problem is that different drivers do it differently and hence wpa_supplicant or similar simply cannot react properly. That said, I do believe softmac tries reauth or did at some point, I remember implementing that because the net at uni kept kicking me out. johannes ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] softmac: Fix WX and association related races 2006-09-27 15:26 [PATCH] softmac: Fix WX and association related races Michael Buesch 2006-09-27 16:18 ` Larry Finger @ 2006-09-27 22:20 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 27+ messages in thread From: Benjamin Herrenschmidt @ 2006-09-27 22:20 UTC (permalink / raw) To: Michael Buesch; +Cc: linville, Larry Finger, Christian, netdev On Wed, 2006-09-27 at 17:26 +0200, Michael Buesch wrote: > This fixes some race conditions in the WirelessExtension > handling and association handling code. Unlike the previous patch, this one doesn't apply on top of 2.6.18 (which I'm using as a basis for testing, along with Larry big bcm43xx patch). Ben. > Signed-off-by: Michael Buesch <mb@bu3sch.de> > > --- > > Hi John, > > Please apply this fo wireless-2.6 and push it with your > next push of bugfixes. > There are other theoretical raceconditions possible in softmac > related to scanning and assoc code. But I don't really want to fix > these, as I think they: > 1) are not triggerable in real world conditions. > 2) are not exploitable to do some bad attacks, etc... > 3) require _huge_ changes to softmac, and I don't really > want to spend more effort into softmac any longer. > This patch fixes some real-world exploitable bugs, so better > fix them to have working wireless until d80211 is ready for > prime-time. > > btw: d80211 might have similiar race conditions like this. > > Larry, once this patch settled a little bit and enough people > tested it, you might want to try pushing it into -stable (although > it's big...) > > > Index: wireless-2.6/include/net/ieee80211softmac.h > =================================================================== > --- wireless-2.6.orig/include/net/ieee80211softmac.h 2006-09-25 17:02:08.000000000 +0200 > +++ wireless-2.6/include/net/ieee80211softmac.h 2006-09-27 16:39:17.000000000 +0200 > @@ -63,13 +63,11 @@ struct ieee80211softmac_wpa { > > /* > * Information about association > - * > - * Do we need a lock for this? > - * We only ever use this structure inlined > - * into our global struct. I've used its lock, > - * but maybe we need a local one here? > */ > struct ieee80211softmac_assoc_info { > + > + struct mutex mutex; > + > /* > * This is the requested ESSID. It is written > * only by the WX handlers. > @@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info { > * > * bssfixed is used for SIOCSIWAP. > */ > - u8 static_essid:1, > - short_preamble_available:1, > - associating:1, > - assoc_wait:1, > - bssvalid:1, > - bssfixed:1; > + u8 static_essid; > + u8 short_preamble_available; > + u8 associating; > + u8 associated; > + u8 assoc_wait; > + u8 bssvalid; > + u8 bssfixed; > > /* Scan retries remaining */ > int scan_retry; > @@ -229,12 +228,10 @@ struct ieee80211softmac_device { > /* private stuff follows */ > /* this lock protects this structure */ > spinlock_t lock; > - > - /* couple of flags */ > - u8 scanning:1, /* protects scanning from being done multiple times at once */ > - associated:1, > - running:1; > - > + > + u8 running; /* SoftMAC started? */ > + u8 scanning; > + > struct ieee80211softmac_scaninfo *scaninfo; > struct ieee80211softmac_assoc_info associnfo; > struct ieee80211softmac_bss_info bssinfo; > @@ -250,7 +247,7 @@ struct ieee80211softmac_device { > > /* we need to keep a list of network structs we copied */ > struct list_head network_list; > - > + > /* This must be the last item so that it points to the data > * allocated beyond this structure by alloc_ieee80211 */ > u8 priv[0]; > @@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_sugges > { > struct ieee80211softmac_txrates *txrates = &mac->txrates; > > - if (!mac->associated) > + if (!mac->associnfo.associated) > return txrates->mgt_mcast_rate; > > /* We are associated, sending unicast frame */ > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c > =================================================================== > --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-17 15:21:53.000000000 +0200 > +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-09-27 17:10:08.000000000 +0200 > @@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211s > dprintk(KERN_INFO PFX "sent association request!\n"); > > spin_lock_irqsave(&mac->lock, flags); > - mac->associated = 0; /* just to make sure */ > + mac->associnfo.associated = 0; /* just to make sure */ > > /* Set a timer for timeout */ > /* FIXME: make timeout configurable */ > @@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d) > { > struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; > struct ieee80211softmac_network *n; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > /* we might race against ieee80211softmac_handle_assoc_response, > * so make sure only one of us does something */ > - if (!mac->associnfo.associating) { > - spin_unlock_irqrestore(&mac->lock, flags); > - return; > - } > + if (!mac->associnfo.associating) > + goto out; > mac->associnfo.associating = 0; > mac->associnfo.bssvalid = 0; > - mac->associated = 0; > + mac->associnfo.associated = 0; > > n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); > - spin_unlock_irqrestore(&mac->lock, flags); > > dprintk(KERN_INFO PFX "assoc request timed out!\n"); > ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); > +out: > + mutex_unlock(&mac->associnfo.mutex); > } > > void > @@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee802 > > netif_carrier_off(mac->dev); > > - mac->associated = 0; > + mac->associnfo.associated = 0; > mac->associnfo.bssvalid = 0; > mac->associnfo.associating = 0; > ieee80211softmac_init_bss(mac); > @@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struc > { > struct ieee80211softmac_network *found; > > - if (mac->associnfo.bssvalid && mac->associated) { > + if (mac->associnfo.bssvalid && mac->associnfo.associated) { > found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); > if (found) > ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); > @@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d) > int bssvalid; > unsigned long flags; > > + mutex_lock(&mac->associnfo.mutex); > + > + if (!mac->associnfo.associating) > + goto out; > + > /* ieee80211_disassoc might clear this */ > bssvalid = mac->associnfo.bssvalid; > > /* meh */ > - if (mac->associated) > + if (mac->associnfo.associated) > ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); > > - spin_lock_irqsave(&mac->lock, flags); > - mac->associnfo.associating = 1; > - spin_unlock_irqrestore(&mac->lock, flags); > - > /* try to find the requested network in our list, if we found one already */ > if (bssvalid || mac->associnfo.bssfixed) > found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); > @@ -260,10 +259,8 @@ ieee80211softmac_assoc_work(void *d) > > if (!found) { > if (mac->associnfo.scan_retry > 0) { > - spin_lock_irqsave(&mac->lock, flags); > mac->associnfo.scan_retry--; > - spin_unlock_irqrestore(&mac->lock, flags); > - > + > /* We know of no such network. Let's scan. > * NB: this also happens if we had no memory to copy the network info... > * Maybe we can hope to have more memory after scanning finishes ;) > @@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d) > ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); > if (ieee80211softmac_start_scan(mac)) > dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); > - return; > + goto out; > } else { > - spin_lock_irqsave(&mac->lock, flags); > mac->associnfo.associating = 0; > - mac->associated = 0; > - spin_unlock_irqrestore(&mac->lock, flags); > + mac->associnfo.associated = 0; > > dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); > /* reset the retry counter for the next user request since we > * break out and don't reschedule ourselves after this point. */ > mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; > ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); > - return; > + goto out; > } > } > > @@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d) > /* copy the ESSID for displaying it */ > mac->associnfo.associate_essid.len = found->essid.len; > memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); > - > + > /* we found a network! authenticate (if necessary) and associate to it. */ > if (found->authenticating) { > dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); > @@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d) > mac->associnfo.assoc_wait = 1; > ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); > } > - return; > + goto out; > } > if (!found->authenticated && !found->authenticating) { > /* This relies on the fact that _auth_req only queues the work, > @@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d) > mac->associnfo.assoc_wait = 0; > ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); > } > - return; > + goto out; > } > /* finally! now we can start associating */ > mac->associnfo.assoc_wait = 0; > ieee80211softmac_assoc(mac, found); > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > } > > /* call this to do whatever is necessary when we're associated */ > @@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee8 > mac->bssinfo.supported_rates = net->supported_rates; > ieee80211softmac_recalc_txrates(mac); > > - mac->associated = 1; > + mac->associnfo.associated = 1; > > mac->associnfo.short_preamble_available = > (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; > @@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(s > dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); > mac->associnfo.associating = 0; > mac->associnfo.bssvalid = 0; > - mac->associated = 0; > + mac->associnfo.associated = 0; > ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); > } > > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c > =================================================================== > --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-17 15:21:52.000000000 +0200 > +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_module.c 2006-09-27 16:30:07.000000000 +0200 > @@ -57,6 +57,7 @@ struct net_device *alloc_ieee80211softma > INIT_LIST_HEAD(&softmac->network_list); > INIT_LIST_HEAD(&softmac->events); > > + mutex_init(&softmac->associnfo.mutex); > INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); > INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); > softmac->start_scan = ieee80211softmac_start_scan_implementation; > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c > =================================================================== > --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-17 15:21:53.000000000 +0200 > +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_wx.c 2006-09-27 16:49:25.000000000 +0200 > @@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net > struct ieee80211softmac_network *n; > struct ieee80211softmac_auth_queue_item *authptr; > int length = 0; > - unsigned long flags; > + > + mutex_lock(&sm->associnfo.mutex); > > /* Check if we're already associating to this or another network > * If it's another network, cancel and start over with our new network > * If it's our network, ignore the change, we're already doing it! > */ > - if((sm->associnfo.associating || sm->associated) && > + if((sm->associnfo.associating || sm->associnfo.associated) && > (data->essid.flags && data->essid.length && extra)) { > /* Get the associating network */ > n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); > @@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net > !memcmp(n->essid.data, extra, n->essid.len)) { > dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", > MAC_ARG(sm->associnfo.bssid)); > - return 0; > + goto out; > } else { > dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); > - spin_lock_irqsave(&sm->lock,flags); > /* Cancel assoc work */ > cancel_delayed_work(&sm->associnfo.work); > /* We don't have to do this, but it's a little cleaner */ > @@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net > cancel_delayed_work(&authptr->work); > sm->associnfo.bssvalid = 0; > sm->associnfo.bssfixed = 0; > - spin_unlock_irqrestore(&sm->lock,flags); > flush_scheduled_work(); > + sm->associnfo.associating = 0; > + sm->associnfo.associated = 0; > } > } > > > - spin_lock_irqsave(&sm->lock, flags); > - > sm->associnfo.static_essid = 0; > sm->associnfo.assoc_wait = 0; > > @@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net > * If applicable, we have already copied the data in */ > sm->associnfo.req_essid.len = length; > > + sm->associnfo.associating = 1; > /* queue lower level code to do work (if necessary) */ > schedule_work(&sm->associnfo.work); > +out: > + mutex_unlock(&sm->associnfo.mutex); > > - spin_unlock_irqrestore(&sm->lock, flags); > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); > @@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net > char *extra) > { > struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); > - unsigned long flags; > > - /* avoid getting inconsistent information */ > - spin_lock_irqsave(&sm->lock, flags); > + mutex_lock(&sm->associnfo.mutex); > /* If all fails, return ANY (empty) */ > data->essid.length = 0; > data->essid.flags = 0; /* active */ > @@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net > } > > /* If we're associating/associated, return that */ > - if (sm->associated || sm->associnfo.associating) { > + if (sm->associnfo.associated || sm->associnfo.associating) { > data->essid.length = sm->associnfo.associate_essid.len; > data->essid.flags = 1; /* active */ > memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); > } > - spin_unlock_irqrestore(&sm->lock, flags); > + mutex_unlock(&sm->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); > @@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_d > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > int err = 0; > - unsigned long flags; > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (mac->associnfo.bssvalid) > memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); > else > memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); > data->ap_addr.sa_family = ARPHRD_ETHER; > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); > @@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_d > char *extra) > { > struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); > - unsigned long flags; > > /* sanity check */ > if (data->ap_addr.sa_family != ARPHRD_ETHER) { > return -EINVAL; > } > > - spin_lock_irqsave(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is not to be fixed any longer, > * and we should reassociate to the best AP. */ > mac->associnfo.bssfixed = 0; > /* force reassociation */ > mac->associnfo.bssvalid = 0; > - if (mac->associated) > + if (mac->associnfo.associated) > schedule_work(&mac->associnfo.work); > } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { > /* the bssid we have is no longer fixed */ > mac->associnfo.bssfixed = 0; > } else { > if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { > - if (mac->associnfo.associating || mac->associated) { > + if (mac->associnfo.associating || mac->associnfo.associated) { > /* bssid unchanged and associated or associating - just return */ > goto out; > } > @@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_d > } > > out: > - spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return 0; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); > @@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net > int err = 0; > char *buf; > int i; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > /* bleh. shouldn't be locked for that kmalloc... */ > > @@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net > > out: > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_unlock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); > @@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net > unsigned long flags; > int err = 0; > int space = wrqu->data.length; > - > + > + mutex_lock(&mac->associnfo.mutex); > spin_lock_irqsave(&mac->lock, flags); > > wrqu->data.length = 0; > @@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net > err = -E2BIG; > } > spin_unlock_irqrestore(&mac->lock, flags); > + mutex_lock(&mac->associnfo.mutex); > + > return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); > @@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_ > struct iw_mlme *mlme = (struct iw_mlme *)extra; > u16 reason = cpu_to_le16(mlme->reason_code); > struct ieee80211softmac_network *net; > + int err = -EINVAL; > + > + mutex_lock(&mac->associnfo.mutex); > > if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { > printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); > - return -EINVAL; > + goto out; > } > > switch (mlme->cmd) { > @@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_ > net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); > if (!net) { > printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); > - return -EINVAL; > + goto out; > } > return ieee80211softmac_deauth_req(mac, net, reason); > case IW_MLME_DISASSOC: > ieee80211softmac_send_disassoc_req(mac, reason); > - return 0; > + mac->associnfo.associated = 0; > + mac->associnfo.associating = 0; > + err = 0; > + goto out; > default: > - return -EOPNOTSUPP; > + err = -EOPNOTSUPP; > } > + > +out: > + mutex_unlock(&mac->associnfo.mutex); > + > + return err; > } > EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c > =================================================================== > --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-17 15:24:29.000000000 +0200 > +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_leds.c 2006-09-27 15:29:01.000000000 +0200 > @@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_ > //TODO > break; > case BCM43xx_LED_ASSOC: > - if (bcm->softmac->associated) > + if (bcm->softmac->associnfo.associated) > turn_on = 1; > break; > #ifdef CONFIG_BCM43XX_DEBUG > Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c > =================================================================== > --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-24 18:34:58.000000000 +0200 > +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c 2006-09-27 15:28:36.000000000 +0200 > @@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get > unsigned long flags; > > wstats = &bcm->stats.wstats; > - if (!mac->associated) { > + if (!mac->associnfo.associated) { > wstats->miss.beacon = 0; > // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? > wstats->discard.retries = 0; > Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c > =================================================================== > --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-17 15:21:53.000000000 +0200 > +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_io.c 2006-09-27 16:33:18.000000000 +0200 > @@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struc > { > struct ieee80211softmac_device *mac = ieee80211_priv(dev); > > - if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) > - ieee80211softmac_process_erp(mac, network->erp_value); > + /* This might race, but we don't really care and it's not worth > + * adding heavyweight locking in this fastpath. > + */ > + if (mac->associnfo.associated) { > + if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) > + ieee80211softmac_process_erp(mac, network->erp_value); > + } > > return 0; > } > > ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2006-09-28 17:40 UTC | newest] Thread overview: 27+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-09-27 15:26 [PATCH] softmac: Fix WX and association related races Michael Buesch 2006-09-27 16:18 ` Larry Finger 2006-09-27 17:50 ` Michael Buesch 2006-09-27 21:11 ` Christian 2006-09-27 21:21 ` Christian 2006-09-27 22:23 ` Benjamin Herrenschmidt 2006-09-28 0:43 ` Larry Finger 2006-09-28 1:04 ` Benjamin Herrenschmidt 2006-09-28 4:09 ` Larry Finger 2006-09-28 12:55 ` Michael Buesch 2006-09-28 14:19 ` Dan Williams 2006-09-28 14:27 ` Johannes Berg 2006-09-28 14:37 ` Dan Williams 2006-09-28 14:43 ` Michael Buesch 2006-09-28 14:52 ` Dan Williams 2006-09-28 15:13 ` Michael Buesch 2006-09-28 17:33 ` Jouni Malinen 2006-09-28 15:16 ` Larry Finger 2006-09-28 15:29 ` Michael Buesch 2006-09-28 15:35 ` Michael Wu 2006-09-28 15:52 ` Larry Finger 2006-09-28 16:31 ` Jason Lunz 2006-09-28 17:04 ` Larry Finger 2006-09-28 17:14 ` Michael Buesch 2006-09-28 17:40 ` Larry Finger 2006-09-28 14:43 ` Johannes Berg 2006-09-27 22:20 ` Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).