diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-12-02 06:43:43 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-22 13:31:18 -0500 |
commit | 5d1ec85f00e999dba61bdcbd959d62439d418e56 (patch) | |
tree | ca83faa924349b915ba10b6373154fe0e6b5f81b /net/mac80211/mlme.c | |
parent | 5fba4af32ceeb935b3926714df9a64a33c2c9cf5 (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.c | 57 |
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 | } |