2007-10-26 21:06:42

by John W. Linville

[permalink] [raw]
Subject: [PATCH] Add get_unaligned to ieee80211_get_radiotap_len

From: warmcat <[email protected]>

ieee80211_get_radiotap_len() tries to dereference radiotap length without
taking care that it is completely unaligned and get_unaligned()
is required.

Signed-off-by: Andy Green <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index ff2172f..9b9d716 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -350,7 +350,7 @@ static int ieee80211_get_radiotap_len(struct sk_buff *skb)
struct ieee80211_radiotap_header *hdr =
(struct ieee80211_radiotap_header *) skb->data;

- return le16_to_cpu(hdr->it_len);
+ return le16_to_cpu(get_unaligned(&hdr->it_len));
}

#ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP
--
1.5.2.4



2007-10-28 08:00:50

by Michael Wu

[permalink] [raw]
Subject: Re: [PATCH] mac80211: reorder association debug output

On Saturday 27 October 2007 08:58:55 Johannes Berg wrote:
> Oops, I stand corrected. Still I don't think that the message patch is
> worth doing in stable, although the regression potential is pretty much
> nil.
>
According to the stable kernel rules, this fix doesn't look appropriate.
(though it is practically zero risk) Also, the sta_bss_list changes do not
qualify due to "It cannot be bigger than 100 lines, with context". The
radiotap get_unaligned patch doesn't qualify - it's not important enough. The
IE parsing fix is also too big. I'm not certain that the SSID scanning patch
qualifies either.. from the patch's POV, it's adding a feature. So, the way
I'm reading things, no mac80211 patches seem to qualify according to stable
kernel rules.

FWIW, I think
[PATCH] mac80211: reorder association debug output
[PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl (plus fix)
[PATCH] mac80211: make ieee802_11_parse_elems return void
do enough good that they should be pushed to stable. The IE parsing fix is a
little big but it's trivial, reordering the debug output is safe and reduces
confusion, and the SSID scanning patch makes it easier to connect to hidden
APs. In addition, the SSID len match patch should also be pushed to stable
since I think it's a one line, fairly obvious patch that fixes a problem in
auto AP selection that can prevent association.

-Michael Wu


Attachments:
(No filename) (1.37 kB)
signature.asc (194.00 B)
This is a digitally signed message part.
Download all attachments

2007-10-26 21:07:43

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl

From: Bill Moss <[email protected]>

This patch fixes the problem of associating with wpa_secured hidden
AP. Please try out.

The original author of this patch is Bill Moss <[email protected]>

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211_ioctl.c | 40 ++++++++++++++++++++++++----------------
1 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index e7904db..5bd103a 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -687,32 +687,40 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,

static int ieee80211_ioctl_siwscan(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct iw_scan_req *req = NULL;
u8 *ssid = NULL;
size_t ssid_len = 0;

if (!netif_running(dev))
return -ENETDOWN;

- switch (sdata->type) {
- case IEEE80211_IF_TYPE_STA:
- case IEEE80211_IF_TYPE_IBSS:
- if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
- ssid = sdata->u.sta.ssid;
- ssid_len = sdata->u.sta.ssid_len;
- }
- break;
- case IEEE80211_IF_TYPE_AP:
- if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
- ssid = sdata->u.ap.ssid;
- ssid_len = sdata->u.ap.ssid_len;
+ if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+ wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ req = (struct iw_scan_req *)extra;
+ ssid = req->essid;
+ ssid_len = req->essid_len;
+ } else {
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS:
+ if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
+ ssid = sdata->u.sta.ssid;
+ ssid_len = sdata->u.sta.ssid_len;
+ }
+ break;
+ case IEEE80211_IF_TYPE_AP:
+ if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
+ ssid = sdata->u.ap.ssid;
+ ssid_len = sdata->u.ap.ssid_len;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
}
- break;
- default:
- return -EOPNOTSUPP;
}

return ieee80211_sta_req_scan(dev, ssid, ssid_len);
--
1.5.2.4


2007-10-26 21:07:21

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: reorder association debug output

From: Johannes Berg <[email protected]>

There's no reason to warn about an invalid AID field when the
association was denied.

Signed-off-by: Johannes Berg <[email protected]>
Acked-by: Michael Wu <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211_sta.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 0d99b68..ae74c79 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -1174,15 +1174,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
- if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
- printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
- "set\n", dev->name, aid);
- aid &= ~(BIT(15) | BIT(14));

printk(KERN_DEBUG "%s: RX %sssocResp from " MAC_FMT " (capab=0x%x "
"status=%d aid=%d)\n",
dev->name, reassoc ? "Rea" : "A", MAC_ARG(mgmt->sa),
- capab_info, status_code, aid);
+ capab_info, status_code, aid & ~(BIT(15) | BIT(14)));

if (status_code != WLAN_STATUS_SUCCESS) {
printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -1192,6 +1188,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
return;
}

+ if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
+ printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
+ "set\n", dev->name, aid);
+ aid &= ~(BIT(15) | BIT(14));
+
pos = mgmt->u.assoc_resp.variable;
if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
== ParseFailed) {
--
1.5.2.4


2007-10-28 07:35:03

by Michael Wu

[permalink] [raw]
Subject: Re: [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl

On Sunday 28 October 2007 03:29:36 Michael Wu wrote:
> On Friday 26 October 2007 17:04:33 John W. Linville wrote:
> > From: Bill Moss <[email protected]>
> >
> > This patch fixes the problem of associating with wpa_secured hidden
> > AP. Please try out.
> >
> > The original author of this patch is Bill Moss <[email protected]>
> >
> > Signed-off-by: Abhijeet Kolekar <[email protected]>
> > Signed-off-by: John W. Linville <[email protected]>
>
> Wrong patch.
>
Er, actually nevermind. However, I'd much prefer rolling the next patch you
have in this series up into this patch.

-Michael Wu



Attachments:
(No filename) (611.00 B)
signature.asc (194.00 B)
This is a digitally signed message part.
Download all attachments

2007-10-26 21:06:04

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: store SSID in sta_bss_list

From: John W. Linville <[email protected]>

Some AP equipment "in the wild" services multiple SSIDs using the
same BSSID. This patch changes the key of sta_bss_list to include
the SSID as well as the BSSID and the channel so as to prevent one
SSID from eclipsing another SSID with the same BSSID.

Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211_sta.c | 54 +++++++++++++++++++++++++----------------
1 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 1991daa..e78b51e 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -12,7 +12,6 @@
*/

/* TODO:
- * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
* order BSS list by RSSI(?) ("quality of AP")
* scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
* SSID)
@@ -61,7 +60,8 @@
static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
u8 *ssid, size_t ssid_len);
static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel);
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+ u8 *ssid, u8 ssid_len);
static void ieee80211_rx_bss_put(struct net_device *dev,
struct ieee80211_sta_bss *bss);
static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -403,7 +403,8 @@ static void ieee80211_set_associated(struct net_device *dev,
return;

bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
- local->hw.conf.channel);
+ local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
if (bss->has_erp_value)
ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -545,7 +546,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
WLAN_CAPABILITY_SHORT_PREAMBLE;
}
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
if (bss->capability & WLAN_CAPABILITY_PRIVACY)
capab |= WLAN_CAPABILITY_PRIVACY;
@@ -705,7 +707,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE)
return 0;

- bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (!bss)
return 0;

@@ -1215,7 +1218,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
if (elems.erp_info && elems.erp_info_len >= 1) {
struct ieee80211_sta_bss *bss
= ieee80211_rx_bss_get(dev, ifsta->bssid,
- local->hw.conf.channel);
+ local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
bss->erp_value = elems.erp_info[0];
bss->has_erp_value = 1;
@@ -1246,7 +1250,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
return;
}
bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
- local->hw.conf.channel);
+ local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
sta->last_rssi = bss->rssi;
sta->last_signal = bss->signal;
@@ -1327,7 +1332,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,


static struct ieee80211_sta_bss *
-ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)
+ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
+ u8 *ssid, u8 ssid_len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
@@ -1339,6 +1345,10 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)
atomic_inc(&bss->users);
memcpy(bss->bssid, bssid, ETH_ALEN);
bss->channel = channel;
+ if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
+ memcpy(bss->ssid, ssid, ssid_len);
+ bss->ssid_len = ssid_len;
+ }

spin_lock_bh(&local->sta_bss_lock);
/* TODO: order by RSSI? */
@@ -1350,7 +1360,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)


static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel)
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+ u8 *ssid, u8 ssid_len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
@@ -1358,8 +1369,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel)
spin_lock_bh(&local->sta_bss_lock);
bss = local->sta_bss_hash[STA_HASH(bssid)];
while (bss) {
- if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
- bss->channel == channel) {
+ if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
+ bss->channel == channel &&
+ bss->ssid_len == ssid_len &&
+ (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
atomic_inc(&bss->users);
break;
}
@@ -1527,9 +1540,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
else
channel = rx_status->channel;

- bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel);
+ bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
+ elems.ssid, elems.ssid_len);
if (!bss) {
- bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel);
+ bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
+ elems.ssid, elems.ssid_len);
if (!bss)
return;
} else {
@@ -1555,10 +1570,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,

bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
- if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
- memcpy(bss->ssid, elems.ssid, elems.ssid_len);
- bss->ssid_len = elems.ssid_len;
- }

bss->supp_rates_len = 0;
if (elems.supp_rates) {
@@ -2339,7 +2350,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_hw_mode *mode;
u8 bssid[ETH_ALEN], *pos;
int i;
@@ -2361,11 +2372,11 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n",
dev->name, MAC_ARG(bssid));

- bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel);
+ bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
+ sdata->u.sta.ssid, sdata->u.sta.ssid_len);
if (!bss)
return -ENOMEM;

- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
mode = local->oper_hw_mode;

if (local->hw.conf.beacon_int == 0)
@@ -2431,7 +2442,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid));
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
- (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel))) {
+ (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len))) {
printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT
" based on configured SSID\n",
dev->name, MAC_ARG(bssid));
--
1.5.2.4


2007-10-26 21:07:28

by John W. Linville

[permalink] [raw]
Subject: [PATCH] libertas: more endianness breakage

From: Al Viro <[email protected]>

domain->header.len is le16 and has just been assigned
cpu_to_le16(arithmetical expression). And all fields of adapter->logmsg
are __le32; not a single 16-bit among them...
That's incremental to the previous one

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
drivers/net/wireless/libertas/11d.c | 2 +-
drivers/net/wireless/libertas/wext.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index 4cf0ff7..0560270 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -562,7 +562,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
nr_subband * sizeof(struct ieeetypes_subbandset));

cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
- domain->header.len +
+ le16_to_cpu(domain->header.len) +
sizeof(struct mrvlietypesheader) +
S_DS_GEN);
} else {
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 2fcc3bf..873c405 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -973,7 +973,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
/* Quality by TX errors */
priv->wstats.discard.retries = priv->stats.tx_errors;

- tx_retries = le16_to_cpu(adapter->logmsg.retry);
+ tx_retries = le32_to_cpu(adapter->logmsg.retry);

if (tx_retries > 75)
tx_qual = (90 - tx_retries) * POOR / 15;
@@ -989,10 +989,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
(PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
quality = min(quality, tx_qual);

- priv->wstats.discard.code = le16_to_cpu(adapter->logmsg.wepundecryptable);
- priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag);
+ priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable);
+ priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag);
priv->wstats.discard.retries = tx_retries;
- priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure);
+ priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure);

/* Calculate quality */
priv->wstats.qual.qual = max(quality, (u32)100);
--
1.5.2.4


2007-10-26 21:07:20

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes

From: John W. Linville <[email protected]>

The previous IW_SCAN_THIS_ESSID patch left a hole allowing scan
requests on interfaces in inappropriate modes.

Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211_ioctl.c | 37 +++++++++++++++++++------------------
1 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 5bd103a..7b5b801 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -698,29 +698,30 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
if (!netif_running(dev))
return -ENETDOWN;

+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS:
+ if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
+ ssid = sdata->u.sta.ssid;
+ ssid_len = sdata->u.sta.ssid_len;
+ }
+ break;
+ case IEEE80211_IF_TYPE_AP:
+ if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
+ ssid = sdata->u.ap.ssid;
+ ssid_len = sdata->u.ap.ssid_len;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* if SSID was specified explicitly then use that */
if (wrqu->data.length == sizeof(struct iw_scan_req) &&
wrqu->data.flags & IW_SCAN_THIS_ESSID) {
req = (struct iw_scan_req *)extra;
ssid = req->essid;
ssid_len = req->essid_len;
- } else {
- switch (sdata->type) {
- case IEEE80211_IF_TYPE_STA:
- case IEEE80211_IF_TYPE_IBSS:
- if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
- ssid = sdata->u.sta.ssid;
- ssid_len = sdata->u.sta.ssid_len;
- }
- break;
- case IEEE80211_IF_TYPE_AP:
- if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
- ssid = sdata->u.ap.ssid;
- ssid_len = sdata->u.ap.ssid_len;
- }
- break;
- default:
- return -EOPNOTSUPP;
- }
}

return ieee80211_sta_req_scan(dev, ssid, ssid_len);
--
1.5.2.4


2007-10-26 21:09:30

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] mac80211: reorder association debug output


On Fri, 2007-10-26 at 17:04 -0400, John W. Linville wrote:
> From: Johannes Berg <[email protected]>
>
> There's no reason to warn about an invalid AID field when the
> association was denied.

I don't really see a reason to have this in stable, do we really want
that? And if so, we should roll in the fix for the warning :)

johannes


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2007-10-26 21:07:24

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: make ieee802_11_parse_elems return void

From: John W. Linville <[email protected]>

Some APs send management frames with junk padding after the last IE.
We already account for a similar problem with some Apple Airport
devices, but at least one device is known to send more than a single
extra byte. The device in question is the Draytek Vigor2900:

http://www.draytek.com.au/products/Vigor2900.php

The junk in question looks like an IE that runs off the end of the
frame. This cause us to return ParseFailed. Since the frame in
question is an association response, this causes us to fail to associate
with this AP.

The return code from ieee802_11_parse_elems is superfluous.
All callers still check for the presence of the specific IEs that
interest them anyway. So, remove the return code so the parse never
"fails".

Acked-by: Michael Wu <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211_sta.c | 56 ++++++-----------------------------------
1 files changed, 9 insertions(+), 47 deletions(-)

diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index e78b51e..73d39e1 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -108,15 +108,11 @@ struct ieee802_11_elems {
u8 wmm_param_len;
};

-typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
-
-
-static ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
- struct ieee802_11_elems *elems)
+static void ieee802_11_parse_elems(u8 *start, size_t len,
+ struct ieee802_11_elems *elems)
{
size_t left = len;
u8 *pos = start;
- int unknown = 0;

memset(elems, 0, sizeof(*elems));

@@ -127,15 +123,8 @@ static ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
elen = *pos++;
left -= 2;

- if (elen > left) {
-#if 0
- if (net_ratelimit())
- printk(KERN_DEBUG "IEEE 802.11 element parse "
- "failed (id=%d elen=%d left=%d)\n",
- id, elen, left);
-#endif
- return ParseFailed;
- }
+ if (elen > left)
+ return;

switch (id) {
case WLAN_EID_SSID:
@@ -202,28 +191,15 @@ static ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
elems->ext_supp_rates_len = elen;
break;
default:
-#if 0
- printk(KERN_DEBUG "IEEE 802.11 element parse ignored "
- "unknown element (id=%d elen=%d)\n",
- id, elen);
-#endif
- unknown++;
break;
}

left -= elen;
pos += elen;
}
-
- /* Do not trigger error if left == 1 as Apple Airport base stations
- * send AssocResps that are one spurious byte too long. */
-
- return unknown ? ParseUnknown : ParseOK;
}


-
-
static int ecw2cw(int ecw)
{
int cw = 1;
@@ -907,12 +883,7 @@ static void ieee80211_auth_challenge(struct net_device *dev,

printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name);
pos = mgmt->u.auth.variable;
- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
- == ParseFailed) {
- printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n",
- dev->name);
- return;
- }
+ ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
if (!elems.challenge) {
printk(KERN_DEBUG "%s: no challenge IE in shared key auth "
"frame\n", dev->name);
@@ -1200,12 +1171,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
aid &= ~(BIT(15) | BIT(14));

pos = mgmt->u.assoc_resp.variable;
- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
- == ParseFailed) {
- printk(KERN_DEBUG "%s: failed to parse AssocResp\n",
- dev->name);
- return;
- }
+ ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);

if (!elems.supp_rates) {
printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
@@ -1434,7 +1400,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee802_11_elems elems;
size_t baselen;
- int channel, invalid = 0, clen;
+ int channel, clen;
struct ieee80211_sta_bss *bss;
struct sta_info *sta;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1478,9 +1444,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
}

- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
- &elems) == ParseFailed)
- invalid = 1;
+ ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);

if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
@@ -1699,9 +1663,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
if (baselen > len)
return;

- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
- &elems) == ParseFailed)
- return;
+ ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);

if (elems.erp_info && elems.erp_info_len >= 1)
ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
--
1.5.2.4


2007-10-26 21:07:30

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: store channel info in sta_bss_list

From: John W. Linville <[email protected]>

Some AP equipment "in the wild" uses the same BSSID on multiple channels
(particularly "a" vs. "b/g"). This patch changes the key of sta_bss_list
to include both the BSSID and the channel so as to prevent a BSSID on
one channel from eclipsing the same BSSID on another channel.

Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211_sta.c | 35 ++++++++++++++++++++---------------
1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index ae74c79..1991daa 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -61,7 +61,7 @@
static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
u8 *ssid, size_t ssid_len);
static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid);
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel);
static void ieee80211_rx_bss_put(struct net_device *dev,
struct ieee80211_sta_bss *bss);
static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -387,6 +387,7 @@ static void ieee80211_set_associated(struct net_device *dev,
struct ieee80211_if_sta *ifsta, int assoc)
{
union iwreq_data wrqu;
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

if (ifsta->associated == assoc)
@@ -401,7 +402,8 @@ static void ieee80211_set_associated(struct net_device *dev,
if (sdata->type != IEEE80211_IF_TYPE_STA)
return;

- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+ local->hw.conf.channel);
if (bss) {
if (bss->has_erp_value)
ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -543,7 +545,7 @@ static void ieee80211_send_assoc(struct net_device *dev,
capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
WLAN_CAPABILITY_SHORT_PREAMBLE;
}
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel);
if (bss) {
if (bss->capability & WLAN_CAPABILITY_PRIVACY)
capab |= WLAN_CAPABILITY_PRIVACY;
@@ -695,6 +697,7 @@ static void ieee80211_send_disassoc(struct net_device *dev,
static int ieee80211_privacy_mismatch(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
int res = 0;

@@ -702,7 +705,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE)
return 0;

- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel);
if (!bss)
return 0;

@@ -1211,7 +1214,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
* update our stored copy */
if (elems.erp_info && elems.erp_info_len >= 1) {
struct ieee80211_sta_bss *bss
- = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ = ieee80211_rx_bss_get(dev, ifsta->bssid,
+ local->hw.conf.channel);
if (bss) {
bss->erp_value = elems.erp_info[0];
bss->has_erp_value = 1;
@@ -1241,7 +1245,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
" AP\n", dev->name);
return;
}
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+ local->hw.conf.channel);
if (bss) {
sta->last_rssi = bss->rssi;
sta->last_signal = bss->signal;
@@ -1322,7 +1327,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,


static struct ieee80211_sta_bss *
-ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
@@ -1333,6 +1338,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
atomic_inc(&bss->users);
atomic_inc(&bss->users);
memcpy(bss->bssid, bssid, ETH_ALEN);
+ bss->channel = channel;

spin_lock_bh(&local->sta_bss_lock);
/* TODO: order by RSSI? */
@@ -1344,7 +1350,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)


static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
@@ -1352,7 +1358,8 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
spin_lock_bh(&local->sta_bss_lock);
bss = local->sta_bss_hash[STA_HASH(bssid)];
while (bss) {
- if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
+ if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
+ bss->channel == channel) {
atomic_inc(&bss->users);
break;
}
@@ -1520,9 +1527,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
else
channel = rx_status->channel;

- bss = ieee80211_rx_bss_get(dev, mgmt->bssid);
+ bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel);
if (!bss) {
- bss = ieee80211_rx_bss_add(dev, mgmt->bssid);
+ bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel);
if (!bss)
return;
} else {
@@ -1622,7 +1629,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,


bss->hw_mode = rx_status->phymode;
- bss->channel = channel;
bss->freq = rx_status->freq;
if (channel != rx_status->channel &&
(bss->hw_mode == MODE_IEEE80211G ||
@@ -2355,7 +2361,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n",
dev->name, MAC_ARG(bssid));

- bss = ieee80211_rx_bss_add(dev, bssid);
+ bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel);
if (!bss)
return -ENOMEM;

@@ -2366,7 +2372,6 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
local->hw.conf.beacon_int = 100;
bss->beacon_int = local->hw.conf.beacon_int;
bss->hw_mode = local->hw.conf.phymode;
- bss->channel = local->hw.conf.channel;
bss->freq = local->hw.conf.freq;
bss->last_update = jiffies;
bss->capability = WLAN_CAPABILITY_IBSS;
@@ -2426,7 +2431,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid));
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
- (bss = ieee80211_rx_bss_get(dev, bssid))) {
+ (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel))) {
printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT
" based on configured SSID\n",
dev->name, MAC_ARG(bssid));
--
1.5.2.4


2007-10-26 21:06:46

by John W. Linville

[permalink] [raw]
Subject: [PATCH] Improve sanity checks on injected packets

From: warmcat <[email protected]>

Michael Wu noticed that the skb length checking is not taken care of enough when
a packet is presented on the Monitor interface for injection.

This patch improves the sanity checking and removes fake offsets placed
into the skb network and transport header.

Signed-off-by: Andy Green <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211.c | 48 ++++++++++++++++++++++++++-------------------
1 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 9b9d716..ad73a40 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1680,46 +1680,54 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
struct ieee80211_tx_packet_data *pkt_data;
struct ieee80211_radiotap_header *prthdr =
(struct ieee80211_radiotap_header *)skb->data;
- u16 len;
+ u16 len_rthdr;

- /*
- * there must be a radiotap header at the
- * start in this case
- */
- if (unlikely(prthdr->it_version)) {
- /* only version 0 is supported */
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
+ /* check for not even having the fixed radiotap header part */
+ if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
+ goto fail; /* too short to be possibly valid */
+
+ /* is it a header version we can trust to find length from? */
+ if (unlikely(prthdr->it_version))
+ goto fail; /* only version 0 is supported */
+
+ /* then there must be a radiotap header with a length we can use */
+ len_rthdr = ieee80211_get_radiotap_len(skb);
+
+ /* does the skb contain enough to deliver on the alleged length? */
+ if (unlikely(skb->len < len_rthdr))
+ goto fail; /* skb too short for claimed rt header extent */

skb->dev = local->mdev;

pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
memset(pkt_data, 0, sizeof(*pkt_data));
+ /* needed because we set skb device to master */
pkt_data->ifindex = dev->ifindex;
+
pkt_data->mgmt_iface = 0;
pkt_data->do_not_encrypt = 1;

- /* above needed because we set skb device to master */
-
/*
* fix up the pointers accounting for the radiotap
* header still being in there. We are being given
* a precooked IEEE80211 header so no need for
* normal processing
*/
- len = le16_to_cpu(get_unaligned(&prthdr->it_len));
- skb_set_mac_header(skb, len);
- skb_set_network_header(skb, len + sizeof(struct ieee80211_hdr));
- skb_set_transport_header(skb, len + sizeof(struct ieee80211_hdr));
-
+ skb_set_mac_header(skb, len_rthdr);
/*
- * pass the radiotap header up to
- * the next stage intact
+ * these are just fixed to the end of the rt area since we
+ * don't have any better information and at this point, nobody cares
*/
- dev_queue_xmit(skb);
+ skb_set_network_header(skb, len_rthdr);
+ skb_set_transport_header(skb, len_rthdr);

+ /* pass the radiotap header up to the next stage intact */
+ dev_queue_xmit(skb);
return NETDEV_TX_OK;
+
+fail:
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK; /* meaning, we dealt with the skb */
}


--
1.5.2.4


2007-10-28 07:33:12

by Michael Wu

[permalink] [raw]
Subject: Re: [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl

On Friday 26 October 2007 17:04:33 John W. Linville wrote:
> From: Bill Moss <[email protected]>
>
> This patch fixes the problem of associating with wpa_secured hidden
> AP. Please try out.
>
> The original author of this patch is Bill Moss <[email protected]>
>
> Signed-off-by: Abhijeet Kolekar <[email protected]>
> Signed-off-by: John W. Linville <[email protected]>
Wrong patch.

-Michael Wu


Attachments:
(No filename) (413.00 B)
signature.asc (194.00 B)
This is a digitally signed message part.
Download all attachments

2007-10-26 21:06:04

by John W. Linville

[permalink] [raw]
Subject: [PATCH] mac80211: filter locally-originated multicast frames

From: John W. Linville <[email protected]>

In STA mode, the AP will echo our traffic. This includes multicast
traffic.

Receiving these frames confuses some protocols and applications,
notably IPv6 Duplicate Address Detection.

Signed-off-by: John W. Linville <[email protected]>
---
net/mac80211/ieee80211.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index ad73a40..9e0da6e 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -2844,9 +2844,10 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr3, ETH_ALEN);

- if (sdata->type != IEEE80211_IF_TYPE_STA) {
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
+ (is_multicast_ether_addr(dst) &&
+ !compare_ether_addr(src, dev->dev_addr)))
return TXRX_DROP;
- }
break;
case 0:
/* DA SA BSSID */
--
1.5.2.4


2007-10-27 12:50:43

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH] mac80211: reorder association debug output

On Fri, Oct 26, 2007 at 11:44:38PM +0200, Johannes Berg wrote:
>
> > Anyway, this probably got caught-up in a "what recent fixes still
> > apply to 2.6.23" sweep. Still, I don't see why this wouldn't be
> > desirable for someone running 2.6.23?
>
> No drivers in 2.6.23 anyway and Intel ships their own mac80211. Why
> should we care at all?

rtl8187 is in 2.6.23.

--
John W. Linville
[email protected]

2007-10-26 21:07:14

by John W. Linville

[permalink] [raw]
Subject: [PATCH] ieee80211: fix TKIP QoS bug

From: Johannes Berg <[email protected]>

The commit 65b6a277 titled "ieee80211: Fix header->qos_ctl endian issue"
*introduced* an endianness bug. Partially revert it.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
net/ieee80211/ieee80211_crypt_tkip.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 5a48d8e..7f11dd9 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -584,7 +584,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
if (stype & IEEE80211_STYPE_QOS_DATA) {
const struct ieee80211_hdr_3addrqos *qoshdr =
(struct ieee80211_hdr_3addrqos *)skb->data;
- hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
+ hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
} else
hdr[12] = 0; /* priority */

--
1.5.2.4


2007-10-26 21:43:29

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] mac80211: reorder association debug output


> Anyway, this probably got caught-up in a "what recent fixes still
> apply to 2.6.23" sweep. Still, I don't see why this wouldn't be
> desirable for someone running 2.6.23?

No drivers in 2.6.23 anyway and Intel ships their own mac80211. Why
should we care at all?

johannes


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2007-10-26 21:07:22

by John W. Linville

[permalink] [raw]
Subject: [PATCH] ipw2100: send WEXT scan events

From: Dan Williams <[email protected]>

ipw2100 wasn't sending WEXT scan events at all on scan completion. And
like ipw2200, the driver aggressively auto-scans, requiring
non-user-requested scan events to be batched together and sent at
specific intervals instead of many times per seconds.

Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
drivers/net/wireless/ipw2100.c | 39 +++++++++++++++++++++++++++++++++++++++
drivers/net/wireless/ipw2100.h | 4 ++++
2 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 8990585..e690609 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2102,12 +2102,46 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
}

+static void send_scan_event(void *data)
+{
+ struct ipw2100_priv *priv = data;
+ union iwreq_data wrqu;
+
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
+}
+
+static void ipw2100_scan_event_later(struct work_struct *work)
+{
+ send_scan_event(container_of(work, struct ipw2100_priv,
+ scan_event_later.work));
+}
+
+static void ipw2100_scan_event_now(struct work_struct *work)
+{
+ send_scan_event(container_of(work, struct ipw2100_priv,
+ scan_event_now));
+}
+
static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
{
IPW_DEBUG_SCAN("scan complete\n");
/* Age the scan results... */
priv->ieee->scans++;
priv->status &= ~STATUS_SCANNING;
+
+ /* Only userspace-requested scan completion events go out immediately */
+ if (!priv->user_requested_scan) {
+ if (!delayed_work_pending(&priv->scan_event_later))
+ queue_delayed_work(priv->workqueue,
+ &priv->scan_event_later,
+ round_jiffies(msecs_to_jiffies(4000)));
+ } else {
+ priv->user_requested_scan = 0;
+ cancel_delayed_work(&priv->scan_event_later);
+ queue_work(priv->workqueue, &priv->scan_event_now);
+ }
}

#ifdef CONFIG_IPW2100_DEBUG
@@ -4376,6 +4410,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
cancel_delayed_work(&priv->wx_event_work);
cancel_delayed_work(&priv->hang_check);
cancel_delayed_work(&priv->rf_kill);
+ cancel_delayed_work(&priv->scan_event_later);
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
}
@@ -6118,6 +6153,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
+ INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
+ INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);

tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
ipw2100_irq_tasklet, (unsigned long)priv);
@@ -7427,6 +7464,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
}

IPW_DEBUG_WX("Initiating scan...\n");
+
+ priv->user_requested_scan = 1;
if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
IPW_DEBUG_WX("Start scan failed.\n");

diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index de7d384..1ee3348 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -588,6 +588,10 @@ struct ipw2100_priv {
struct delayed_work wx_event_work;
struct delayed_work hang_check;
struct delayed_work rf_kill;
+ struct work_struct scan_event_now;
+ struct delayed_work scan_event_later;
+
+ int user_requested_scan;

u32 interrupts;
int tx_interrupts;
--
1.5.2.4


2007-10-27 12:57:42

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] mac80211: reorder association debug output



> > No drivers in 2.6.23 anyway and Intel ships their own mac80211. Why
> > should we care at all?
>
> rtl8187 is in 2.6.23.

Oops, I stand corrected. Still I don't think that the message patch is
worth doing in stable, although the regression potential is pretty much
nil.

johannes


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2007-10-26 21:23:36

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH] mac80211: reorder association debug output

On Fri, Oct 26, 2007 at 11:10:39PM +0200, Johannes Berg wrote:
>
> On Fri, 2007-10-26 at 17:04 -0400, John W. Linville wrote:
> > From: Johannes Berg <[email protected]>
> >
> > There's no reason to warn about an invalid AID field when the
> > association was denied.
>
> I don't really see a reason to have this in stable, do we really want

Perhaps not. I'm still not totally clear on the "stable" criteria
(probably my own fault).

Anyway, this probably got caught-up in a "what recent fixes still
apply to 2.6.23" sweep. Still, I don't see why this wouldn't be
desirable for someone running 2.6.23?

> that? And if so, we should roll in the fix for the warning :)

I was trying to "clear the baffles" before rolling-out the more
recent fixes. If this patch isn't rejected for stable then it might
be worth waiting for the warning fix patch pushed yesterday.

John
--
John W. Linville
[email protected]

2007-10-26 21:07:49

by John W. Linville

[permalink] [raw]
Subject: [PATCH] libertas: fix endianness breakage

From: Al Viro <[email protected]>

wep->keytype[] is u8

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
drivers/net/wireless/libertas/cmd.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 4a8f5dc..86fff8d 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -185,14 +185,12 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,

switch (pkey->len) {
case KEY_LEN_WEP_40:
- wep->keytype[i] =
- cpu_to_le16(cmd_type_wep_40_bit);
+ wep->keytype[i] = cmd_type_wep_40_bit;
memmove(&wep->keymaterial[i], pkey->key,
pkey->len);
break;
case KEY_LEN_WEP_104:
- wep->keytype[i] =
- cpu_to_le16(cmd_type_wep_104_bit);
+ wep->keytype[i] = cmd_type_wep_104_bit;
memmove(&wep->keymaterial[i], pkey->key,
pkey->len);
break;
--
1.5.2.4


2007-10-26 21:06:51

by John W. Linville

[permalink] [raw]
Subject: [PATCH] zd1201: avoid null ptr access of skb->dev

From: John W. Linville <[email protected]>

skb->dev is not set until eth_type_trans is called...

Signed-off-by: John W. Linville <[email protected]>
---
drivers/net/wireless/zd1201.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 935b144..d5c0c66 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -327,8 +327,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, 6), &data[datalen-8], 6);
memcpy(skb_put(skb, 2), &data[datalen-24], 2);
memcpy(skb_put(skb, len), data, len);
- skb->dev->last_rx = jiffies;
skb->protocol = eth_type_trans(skb, zd->dev);
+ skb->dev->last_rx = jiffies;
zd->stats.rx_packets++;
zd->stats.rx_bytes += skb->len;
netif_rx(skb);
@@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, 2), &data[6], 2);
memcpy(skb_put(skb, len), data+8, len);
}
- skb->dev->last_rx = jiffies;
skb->protocol = eth_type_trans(skb, zd->dev);
+ skb->dev->last_rx = jiffies;
zd->stats.rx_packets++;
zd->stats.rx_bytes += skb->len;
netif_rx(skb);
--
1.5.2.4


2007-10-26 21:05:48

by John W. Linville

[permalink] [raw]
Subject: [PATCH] zd1211rw, fix oops when ejecting install media

From: Marc Pignat <[email protected]>

The disconnect function can dereference the net_device structure when it
is never allocated. This is the case when ejecting the device installer.

Signed-off-by: Marc Pignat <[email protected]>
Acked-by: Daniel Drake <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
drivers/net/wireless/zd1211rw/zd_usb.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index a9c339e..5326301 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1041,14 +1041,17 @@ error:
static void disconnect(struct usb_interface *intf)
{
struct net_device *netdev = zd_intf_to_netdev(intf);
- struct zd_mac *mac = zd_netdev_mac(netdev);
- struct zd_usb *usb = &mac->chip.usb;
+ struct zd_mac *mac;
+ struct zd_usb *usb;

/* Either something really bad happened, or we're just dealing with
* a DEVICE_INSTALLER. */
if (netdev == NULL)
return;

+ mac = zd_netdev_mac(netdev);
+ usb = &mac->chip.usb;
+
dev_dbg_f(zd_usb_dev(usb), "\n");

zd_netdev_disconnect(netdev);
--
1.5.2.4


2007-10-26 21:07:29

by John W. Linville

[permalink] [raw]
Subject: [PATCH] rtl8187: Fix more frag bit checking, rts duration calc

From: Michael Wu <[email protected]>

The wrong pointer is passed to ieee80211_get_morefrag. Fix this.

While we're at it, reorder things so they look better and the rts duration
calculation is done with the right length.

Thanks to Christoph Hellwig for finding the ieee80211_get_morefrag issue.

Signed-off-by: Michael Wu <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
---
drivers/net/wireless/rtl8187_dev.c | 31 ++++++++++++++++---------------
1 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index e61c6d5..66704b8 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -78,7 +78,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
struct rtl8187_tx_hdr *hdr;
struct rtl8187_tx_info *info;
struct urb *urb;
- u32 tmp;
+ __le16 rts_dur = 0;
+ u32 flags;

urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
@@ -86,24 +87,24 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0;
}

- hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
- tmp = skb->len - sizeof(*hdr);
- tmp |= RTL8187_TX_FLAG_NO_ENCRYPT;
- tmp |= control->rts_cts_rate << 19;
- tmp |= control->tx_rate << 24;
- if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb))
- tmp |= RTL8187_TX_FLAG_MORE_FRAG;
+ flags = skb->len;
+ flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
+ flags |= control->rts_cts_rate << 19;
+ flags |= control->tx_rate << 24;
+ if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
+ flags |= RTL8187_TX_FLAG_MORE_FRAG;
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- tmp |= RTL8187_TX_FLAG_RTS;
- hdr->rts_duration =
- ieee80211_rts_duration(dev, skb->len, control);
+ flags |= RTL8187_TX_FLAG_RTS;
+ rts_dur = ieee80211_rts_duration(dev, skb->len, control);
}
if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
- tmp |= RTL8187_TX_FLAG_CTS;
- hdr->flags = cpu_to_le32(tmp);
+ flags |= RTL8187_TX_FLAG_CTS;
+
+ hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
+ hdr->flags = cpu_to_le32(flags);
hdr->len = 0;
- tmp = control->retry_limit << 8;
- hdr->retry = cpu_to_le32(tmp);
+ hdr->rts_duration = rts_dur;
+ hdr->retry = cpu_to_le32(control->retry_limit << 8);

info = (struct rtl8187_tx_info *)skb->cb;
info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
--
1.5.2.4


2007-10-26 21:32:00

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [PATCH] mac80211: reorder association debug output

On Fri, Oct 26, 2007 at 05:23:03PM -0400, John W. Linville wrote:
> On Fri, Oct 26, 2007 at 11:10:39PM +0200, Johannes Berg wrote:
> >
> > On Fri, 2007-10-26 at 17:04 -0400, John W. Linville wrote:
> > > From: Johannes Berg <[email protected]>
> > >
> > > There's no reason to warn about an invalid AID field when the
> > > association was denied.
> >
> > I don't really see a reason to have this in stable, do we really want
>
> Perhaps not. I'm still not totally clear on the "stable" criteria
> (probably my own fault).

See Documentation/stable_kernel_rules.txt for what the "criteria" is.

thanks,

greg k-h