summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2006-04-20 20:02:03 +0200
committerJohn W. Linville <linville@tuxdriver.com>2006-04-24 15:20:23 -0400
commit818667f7c40dd0bd14029b5ac1d0f5282e12310e (patch)
treef270cfb4caeb26bceec7ea61ba93e268eae57324
parentdac322e39a2b82871cf514c9a533f24a1b4c7e19 (diff)
downloadlinux-3.10-818667f7c40dd0bd14029b5ac1d0f5282e12310e.tar.gz
linux-3.10-818667f7c40dd0bd14029b5ac1d0f5282e12310e.tar.bz2
linux-3.10-818667f7c40dd0bd14029b5ac1d0f5282e12310e.zip
[PATCH] softmac: fix SIOCSIWAP
There are some bugs in the current implementation of the SIOCSIWAP wext, for example that when you do it twice and it fails, it may still try another access point for some reason. This patch fixes this by introducing a new flag that tells the association code that the bssid that is in use was fixed by the user and shouldn't be deviated from. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/ieee80211softmac.h5
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c20
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c2
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c27
4 files changed, 39 insertions, 15 deletions
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
index 6b3693f05ca..b1ebfbae397 100644
--- a/include/net/ieee80211softmac.h
+++ b/include/net/ieee80211softmac.h
@@ -96,10 +96,13 @@ struct ieee80211softmac_assoc_info {
*
* bssvalid is true if we found a matching network
* and saved it's BSSID into the bssid above.
+ *
+ * bssfixed is used for SIOCSIWAP.
*/
u8 static_essid:1,
associating:1,
- bssvalid:1;
+ bssvalid:1,
+ bssfixed:1;
/* Scan retries remaining */
int scan_retry;
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 4498023841d..fb79ce7d643 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -144,6 +144,12 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne
if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len))
return 0;
+ /* assume that users know what they're doing ...
+ * (note we don't let them select a net we're incompatible with) */
+ if (mac->associnfo.bssfixed) {
+ return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN);
+ }
+
/* if 'ANY' network requested, take any that doesn't have privacy enabled */
if (mac->associnfo.req_essid.len == 0
&& !(net->capability & WLAN_CAPABILITY_PRIVACY))
@@ -176,7 +182,7 @@ ieee80211softmac_assoc_work(void *d)
ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
/* try to find the requested network in our list, if we found one already */
- if (mac->associnfo.bssvalid)
+ if (mac->associnfo.bssvalid || mac->associnfo.bssfixed)
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
/* Search the ieee80211 networks for this network if we didn't find it by bssid,
@@ -241,19 +247,25 @@ ieee80211softmac_assoc_work(void *d)
if (ieee80211softmac_start_scan(mac))
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
return;
- }
- else {
+ } else {
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.associating = 0;
mac->associated = 0;
spin_unlock_irqrestore(&mac->lock, flags);
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;
}
}
-
+
+ /* reset the retry counter for the next user request since we
+ * now found a net and will try to associate to it, but not
+ * schedule this function again. */
+ mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
mac->associnfo.bssvalid = 1;
memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN);
/* copy the ESSID for displaying it */
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index 60f06a31f0d..be83bdc1644 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -45,6 +45,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
softmac->scaninfo = NULL;
+ softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
+
/* TODO: initialise all the other callbacks in the ieee struct
* (once they're written)
*/
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 00f0d4f7189..27edb2b5581 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -27,7 +27,8 @@
#include "ieee80211softmac_priv.h"
#include <net/iw_handler.h>
-
+/* for is_broadcast_ether_addr and is_zero_ether_addr */
+#include <linux/etherdevice.h>
int
ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
@@ -83,7 +84,6 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
sm->associnfo.static_essid = 1;
}
}
- sm->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
/* set our requested ESSID length.
* If applicable, we have already copied the data in */
@@ -310,8 +310,6 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
char *extra)
{
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- static const unsigned char any[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- static const unsigned char off[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned long flags;
/* sanity check */
@@ -320,10 +318,17 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
}
spin_lock_irqsave(&mac->lock, flags);
- if (!memcmp(any, data->ap_addr.sa_data, ETH_ALEN) ||
- !memcmp(off, data->ap_addr.sa_data, ETH_ALEN)) {
- schedule_work(&mac->associnfo.work);
- goto out;
+ 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)
+ 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) {
@@ -333,12 +338,14 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
} else {
/* copy new value in data->ap_addr.sa_data to bssid */
memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN);
- }
+ }
+ /* tell the other code that this bssid should be used no matter what */
+ mac->associnfo.bssfixed = 1;
/* queue associate if new bssid or (old one again and not associated) */
schedule_work(&mac->associnfo.work);
}
-out:
+ out:
spin_unlock_irqrestore(&mac->lock, flags);
return 0;
}