* [RFC PATCH 1/2] mac80211: store channel info in sta_bss_list
@ 2007-10-09 23:49 John W. Linville
2007-10-09 23:49 ` [RFC PATCH 2/2] mac80211: store SSID " John W. Linville
0 siblings, 1 reply; 5+ messages in thread
From: John W. Linville @ 2007-10-09 23:49 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
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 <linville@tuxdriver.com>
---
net/mac80211/ieee80211_sta.c | 34 +++++++++++++++++++---------------
1 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 7c93f29..bd11775 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,
@@ -426,7 +426,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);
@@ -571,7 +572,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;
@@ -719,6 +720,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;
@@ -726,7 +728,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
ifsta->key_management_enabled)
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;
@@ -1231,7 +1233,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;
@@ -1261,7 +1264,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;
@@ -1337,7 +1341,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;
@@ -1348,6 +1352,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? */
@@ -1359,7 +1364,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;
@@ -1367,7 +1372,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;
}
@@ -1533,9 +1539,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 {
@@ -1635,7 +1641,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 ||
@@ -2379,7 +2384,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;
@@ -2390,7 +2395,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;
@@ -2448,7 +2452,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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH 2/2] mac80211: store SSID in sta_bss_list
2007-10-09 23:49 [RFC PATCH 1/2] mac80211: store channel info in sta_bss_list John W. Linville
@ 2007-10-09 23:49 ` John W. Linville
2007-10-10 9:02 ` Johannes Berg
0 siblings, 1 reply; 5+ messages in thread
From: John W. Linville @ 2007-10-09 23:49 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
From: John W. Linville <linville@tuxdriver.com>
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 <linville@tuxdriver.com>
---
net/mac80211/ieee80211_sta.c | 53 ++++++++++++++++++++++++++---------------
1 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index bd11775..e804173 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -61,7 +61,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,
@@ -427,7 +428,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);
@@ -572,7 +574,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;
@@ -728,7 +731,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
ifsta->key_management_enabled)
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;
@@ -1234,7 +1238,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;
@@ -1265,7 +1270,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;
@@ -1341,7 +1347,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;
@@ -1353,6 +1360,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? */
@@ -1364,7 +1375,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;
@@ -1372,8 +1384,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;
}
@@ -1539,9 +1553,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 {
@@ -1567,10 +1583,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) {
@@ -2362,7 +2374,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;
@@ -2384,11 +2396,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)
@@ -2452,7 +2464,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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [RFC PATCH 2/2] mac80211: store SSID in sta_bss_list
2007-10-09 23:49 ` [RFC PATCH 2/2] mac80211: store SSID " John W. Linville
@ 2007-10-10 9:02 ` Johannes Berg
2007-10-10 14:36 ` Dan Williams
0 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2007-10-10 9:02 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
[-- Attachment #1: Type: text/plain, Size: 476 bytes --]
On Tue, 2007-10-09 at 19:49 -0400, John W. Linville wrote:
> From: John W. Linville <linville@tuxdriver.com>
>
> 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.
There's a TODO comment at the top of the file for this which you can
remove :)
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC PATCH 2/2] mac80211: store SSID in sta_bss_list
2007-10-10 9:02 ` Johannes Berg
@ 2007-10-10 14:36 ` Dan Williams
2007-10-10 15:13 ` John W. Linville
0 siblings, 1 reply; 5+ messages in thread
From: Dan Williams @ 2007-10-10 14:36 UTC (permalink / raw)
To: Johannes Berg; +Cc: John W. Linville, linux-wireless
On Wed, 2007-10-10 at 11:02 +0200, Johannes Berg wrote:
> On Tue, 2007-10-09 at 19:49 -0400, John W. Linville wrote:
> > From: John W. Linville <linville@tuxdriver.com>
> >
> > 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.
The "standard" (which is a stretch) was that only _one_ SSID can be
broadcast in beacons, and the rest of the supported SSIDs must be
hidden. Is that the case? Or is the AP you're referring to actually
pushing out multiple beacons with different not-hidden SSIDs and the
same BSSID?
Dan
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC PATCH 2/2] mac80211: store SSID in sta_bss_list
2007-10-10 14:36 ` Dan Williams
@ 2007-10-10 15:13 ` John W. Linville
0 siblings, 0 replies; 5+ messages in thread
From: John W. Linville @ 2007-10-10 15:13 UTC (permalink / raw)
To: Dan Williams; +Cc: Johannes Berg, linux-wireless
On Wed, Oct 10, 2007 at 10:36:43AM -0400, Dan Williams wrote:
> On Wed, 2007-10-10 at 11:02 +0200, Johannes Berg wrote:
> > On Tue, 2007-10-09 at 19:49 -0400, John W. Linville wrote:
> > > From: John W. Linville <linville@tuxdriver.com>
> > >
> > > 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.
>
> The "standard" (which is a stretch) was that only _one_ SSID can be
> broadcast in beacons, and the rest of the supported SSIDs must be
> hidden. Is that the case? Or is the AP you're referring to actually
> pushing out multiple beacons with different not-hidden SSIDs and the
> same BSSID?
My impression is that the standard is not particularly clear on this,
hence the variety of behaviors. Can you cite specific wording?
My research indicates the existance of both "1 beacon, N-1 hidden"
and "N beacons" behaviors. Either way, the sta_bss_list can be
populated not just from beacons but also from probe responses.
So even if N-1 SSIDs are hidden, we still need to be able to record
information about them.
Unfortunately I don't have any hardware that behaves in this fashion.
I discovered references to this behavior while researching the
preceding "same BSSID on different frequencies" patch. Having become
aware of this behavior, I figured it was worth fixing at the same
time to avoid future bug reports.
Hth!
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-10-10 15:39 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-09 23:49 [RFC PATCH 1/2] mac80211: store channel info in sta_bss_list John W. Linville
2007-10-09 23:49 ` [RFC PATCH 2/2] mac80211: store SSID " John W. Linville
2007-10-10 9:02 ` Johannes Berg
2007-10-10 14:36 ` Dan Williams
2007-10-10 15:13 ` John W. Linville
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).