aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-12-02 06:43:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-22 13:31:18 -0500
commit5d1ec85f00e999dba61bdcbd959d62439d418e56 (patch)
treeca83faa924349b915ba10b6373154fe0e6b5f81b /net/mac80211/mlme.c
parent5fba4af32ceeb935b3926714df9a64a33c2c9cf5 (diff)
mac80211: dont try to use existing sta for AP
Clean out some cruft that could use an already existing sta_info struct -- that case cannot happen. Also, there's a bug there -- if allocation/insertion fails then it is possible that we are left in a lingering state where mac80211 waits for the AP, cfg80211 waits for mac80211, but the AP has already replied. Since there's no way to indicate an internal error, pretend there was a timeout, i.e. that the AP never responded. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a7472c979c63..5174bfc5710d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -75,6 +75,9 @@ enum rx_mgmt_action {
75 /* caller must call cfg80211_send_disassoc() */ 75 /* caller must call cfg80211_send_disassoc() */
76 RX_MGMT_CFG80211_DISASSOC, 76 RX_MGMT_CFG80211_DISASSOC,
77 77
78 /* caller must tell cfg80211 about internal error */
79 RX_MGMT_CFG80211_ASSOC_ERROR,
80
78 /* caller must call cfg80211_auth_timeout() & free work */ 81 /* caller must call cfg80211_auth_timeout() & free work */
79 RX_MGMT_CFG80211_AUTH_TO, 82 RX_MGMT_CFG80211_AUTH_TO,
80 83
@@ -1479,8 +1482,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1479 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 1482 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1480 u8 *pos; 1483 u8 *pos;
1481 u32 changed = 0; 1484 u32 changed = 0;
1482 int i, j; 1485 int i, j, err;
1483 bool have_higher_than_11mbit = false, newsta = false; 1486 bool have_higher_than_11mbit = false;
1484 u16 ap_ht_cap_flags; 1487 u16 ap_ht_cap_flags;
1485 1488
1486 /* 1489 /*
@@ -1542,30 +1545,18 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1542 printk(KERN_DEBUG "%s: associated\n", sdata->name); 1545 printk(KERN_DEBUG "%s: associated\n", sdata->name);
1543 ifmgd->aid = aid; 1546 ifmgd->aid = aid;
1544 1547
1545 rcu_read_lock(); 1548 sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL);
1546
1547 /* Add STA entry for the AP */
1548 sta = sta_info_get(sdata, wk->bss->cbss.bssid);
1549 if (!sta) { 1549 if (!sta) {
1550 newsta = true; 1550 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1551 1551 " the AP\n", sdata->name);
1552 rcu_read_unlock(); 1552 return RX_MGMT_CFG80211_ASSOC_ERROR;
1553
1554 sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL);
1555 if (!sta) {
1556 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1557 " the AP\n", sdata->name);
1558 return RX_MGMT_NONE;
1559 }
1560
1561 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1562 WLAN_STA_ASSOC_AP);
1563 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1564 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1565
1566 rcu_read_lock();
1567 } 1553 }
1568 1554
1555 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1556 WLAN_STA_ASSOC_AP);
1557 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1558 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1559
1569 rates = 0; 1560 rates = 0;
1570 basic_rates = 0; 1561 basic_rates = 0;
1571 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1562 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
@@ -1628,18 +1619,14 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1628 if (elems.wmm_param) 1619 if (elems.wmm_param)
1629 set_sta_flags(sta, WLAN_STA_WME); 1620 set_sta_flags(sta, WLAN_STA_WME);
1630 1621
1631 if (newsta) { 1622 err = sta_info_insert(sta);
1632 int err = sta_info_insert(sta); 1623 sta = NULL;
1633 if (err) { 1624 if (err) {
1634 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1625 printk(KERN_DEBUG "%s: failed to insert STA entry for"
1635 " the AP (error %d)\n", sdata->name, err); 1626 " the AP (error %d)\n", sdata->name, err);
1636 rcu_read_unlock(); 1627 return RX_MGMT_CFG80211_ASSOC_ERROR;
1637 return RX_MGMT_NONE;
1638 }
1639 } 1628 }
1640 1629
1641 rcu_read_unlock();
1642
1643 if (elems.wmm_param) 1630 if (elems.wmm_param)
1644 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1631 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
1645 elems.wmm_param_len); 1632 elems.wmm_param_len);
@@ -2084,6 +2071,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2084 case RX_MGMT_CFG80211_DEAUTH: 2071 case RX_MGMT_CFG80211_DEAUTH:
2085 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 2072 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
2086 break; 2073 break;
2074 case RX_MGMT_CFG80211_ASSOC_ERROR:
2075 /* an internal error -- pretend timeout for now */
2076 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2077 break;
2087 default: 2078 default:
2088 WARN(1, "unexpected: %d", rma); 2079 WARN(1, "unexpected: %d", rma);
2089 } 2080 }