aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2007-10-05 14:23:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-10-16 21:19:18 -0400
commitcffdd30d20d163343b1c6de25bcb0cc978a1ebf9 (patch)
treedfdf21df7e580c1098e13708a1ae6f0b581ed0fa /net
parent65c107ab3befc37b21d1c970a6159525bc0121b8 (diff)
[PATCH] mac80211: store SSID in sta_bss_list
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>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_sta.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index c1cc79e9f1f7..db81aef6177a 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14/* TODO: 14/* TODO:
15 * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
16 * order BSS list by RSSI(?) ("quality of AP") 15 * order BSS list by RSSI(?) ("quality of AP")
17 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, 16 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
18 * SSID) 17 * SSID)
@@ -61,7 +60,8 @@
61static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, 60static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
62 u8 *ssid, size_t ssid_len); 61 u8 *ssid, size_t ssid_len);
63static struct ieee80211_sta_bss * 62static struct ieee80211_sta_bss *
64ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel); 63ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
64 u8 *ssid, u8 ssid_len);
65static void ieee80211_rx_bss_put(struct net_device *dev, 65static void ieee80211_rx_bss_put(struct net_device *dev,
66 struct ieee80211_sta_bss *bss); 66 struct ieee80211_sta_bss *bss);
67static int ieee80211_sta_find_ibss(struct net_device *dev, 67static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -428,7 +428,8 @@ static void ieee80211_set_associated(struct net_device *dev,
428 return; 428 return;
429 429
430 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 430 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
431 local->hw.conf.channel); 431 local->hw.conf.channel,
432 ifsta->ssid, ifsta->ssid_len);
432 if (bss) { 433 if (bss) {
433 if (bss->has_erp_value) 434 if (bss->has_erp_value)
434 ieee80211_handle_erp_ie(dev, bss->erp_value); 435 ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -575,7 +576,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
575 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | 576 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
576 WLAN_CAPABILITY_SHORT_PREAMBLE; 577 WLAN_CAPABILITY_SHORT_PREAMBLE;
577 } 578 }
578 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel); 579 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
580 ifsta->ssid, ifsta->ssid_len);
579 if (bss) { 581 if (bss) {
580 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 582 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
581 capab |= WLAN_CAPABILITY_PRIVACY; 583 capab |= WLAN_CAPABILITY_PRIVACY;
@@ -731,7 +733,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
731 ifsta->key_management_enabled) 733 ifsta->key_management_enabled)
732 return 0; 734 return 0;
733 735
734 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel); 736 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
737 ifsta->ssid, ifsta->ssid_len);
735 if (!bss) 738 if (!bss)
736 return 0; 739 return 0;
737 740
@@ -1245,7 +1248,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1245 if (elems.erp_info && elems.erp_info_len >= 1) { 1248 if (elems.erp_info && elems.erp_info_len >= 1) {
1246 struct ieee80211_sta_bss *bss 1249 struct ieee80211_sta_bss *bss
1247 = ieee80211_rx_bss_get(dev, ifsta->bssid, 1250 = ieee80211_rx_bss_get(dev, ifsta->bssid,
1248 local->hw.conf.channel); 1251 local->hw.conf.channel,
1252 ifsta->ssid, ifsta->ssid_len);
1249 if (bss) { 1253 if (bss) {
1250 bss->erp_value = elems.erp_info[0]; 1254 bss->erp_value = elems.erp_info[0];
1251 bss->has_erp_value = 1; 1255 bss->has_erp_value = 1;
@@ -1276,7 +1280,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1276 return; 1280 return;
1277 } 1281 }
1278 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 1282 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
1279 local->hw.conf.channel); 1283 local->hw.conf.channel,
1284 ifsta->ssid, ifsta->ssid_len);
1280 if (bss) { 1285 if (bss) {
1281 sta->last_rssi = bss->rssi; 1286 sta->last_rssi = bss->rssi;
1282 sta->last_signal = bss->signal; 1287 sta->last_signal = bss->signal;
@@ -1352,7 +1357,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
1352 1357
1353 1358
1354static struct ieee80211_sta_bss * 1359static struct ieee80211_sta_bss *
1355ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel) 1360ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
1361 u8 *ssid, u8 ssid_len)
1356{ 1362{
1357 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1363 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1358 struct ieee80211_sta_bss *bss; 1364 struct ieee80211_sta_bss *bss;
@@ -1364,6 +1370,10 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)
1364 atomic_inc(&bss->users); 1370 atomic_inc(&bss->users);
1365 memcpy(bss->bssid, bssid, ETH_ALEN); 1371 memcpy(bss->bssid, bssid, ETH_ALEN);
1366 bss->channel = channel; 1372 bss->channel = channel;
1373 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
1374 memcpy(bss->ssid, ssid, ssid_len);
1375 bss->ssid_len = ssid_len;
1376 }
1367 1377
1368 spin_lock_bh(&local->sta_bss_lock); 1378 spin_lock_bh(&local->sta_bss_lock);
1369 /* TODO: order by RSSI? */ 1379 /* TODO: order by RSSI? */
@@ -1375,7 +1385,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel)
1375 1385
1376 1386
1377static struct ieee80211_sta_bss * 1387static struct ieee80211_sta_bss *
1378ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel) 1388ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
1389 u8 *ssid, u8 ssid_len)
1379{ 1390{
1380 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1391 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1381 struct ieee80211_sta_bss *bss; 1392 struct ieee80211_sta_bss *bss;
@@ -1383,8 +1394,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel)
1383 spin_lock_bh(&local->sta_bss_lock); 1394 spin_lock_bh(&local->sta_bss_lock);
1384 bss = local->sta_bss_hash[STA_HASH(bssid)]; 1395 bss = local->sta_bss_hash[STA_HASH(bssid)];
1385 while (bss) { 1396 while (bss) {
1386 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 && 1397 if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
1387 bss->channel == channel) { 1398 bss->channel == channel &&
1399 bss->ssid_len == ssid_len &&
1400 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
1388 atomic_inc(&bss->users); 1401 atomic_inc(&bss->users);
1389 break; 1402 break;
1390 } 1403 }
@@ -1552,9 +1565,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1552 else 1565 else
1553 channel = rx_status->channel; 1566 channel = rx_status->channel;
1554 1567
1555 bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel); 1568 bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
1569 elems.ssid, elems.ssid_len);
1556 if (!bss) { 1570 if (!bss) {
1557 bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel); 1571 bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
1572 elems.ssid, elems.ssid_len);
1558 if (!bss) 1573 if (!bss)
1559 return; 1574 return;
1560 } else { 1575 } else {
@@ -1580,10 +1595,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1580 1595
1581 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 1596 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
1582 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 1597 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
1583 if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
1584 memcpy(bss->ssid, elems.ssid, elems.ssid_len);
1585 bss->ssid_len = elems.ssid_len;
1586 }
1587 1598
1588 bss->supp_rates_len = 0; 1599 bss->supp_rates_len = 0;
1589 if (elems.supp_rates) { 1600 if (elems.supp_rates) {
@@ -2381,7 +2392,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
2381{ 2392{
2382 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2393 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2383 struct ieee80211_sta_bss *bss; 2394 struct ieee80211_sta_bss *bss;
2384 struct ieee80211_sub_if_data *sdata; 2395 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2385 struct ieee80211_hw_mode *mode; 2396 struct ieee80211_hw_mode *mode;
2386 u8 bssid[ETH_ALEN], *pos; 2397 u8 bssid[ETH_ALEN], *pos;
2387 int i; 2398 int i;
@@ -2404,11 +2415,11 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
2404 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", 2415 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
2405 dev->name, print_mac(mac, bssid)); 2416 dev->name, print_mac(mac, bssid));
2406 2417
2407 bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel); 2418 bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
2419 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
2408 if (!bss) 2420 if (!bss)
2409 return -ENOMEM; 2421 return -ENOMEM;
2410 2422
2411 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2412 mode = local->oper_hw_mode; 2423 mode = local->oper_hw_mode;
2413 2424
2414 if (local->hw.conf.beacon_int == 0) 2425 if (local->hw.conf.beacon_int == 0)
@@ -2474,7 +2485,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
2474 "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); 2485 "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
2475#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2486#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2476 if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && 2487 if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
2477 (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel))) { 2488 (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
2489 ifsta->ssid, ifsta->ssid_len))) {
2478 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" 2490 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
2479 " based on configured SSID\n", 2491 " based on configured SSID\n",
2480 dev->name, print_mac(mac, bssid)); 2492 dev->name, print_mac(mac, bssid));