diff options
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index a3e96eb59eb0..892b5f96a427 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -1454,7 +1454,7 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1454 | { | 1454 | { |
1455 | /* not an elegant detour, but there is no choice as the timer passes | 1455 | /* not an elegant detour, but there is no choice as the timer passes |
1456 | * only one argument, and both sta_info and TID are needed, so init | 1456 | * only one argument, and both sta_info and TID are needed, so init |
1457 | * flow in sta_info_add gives the TID as data, while the timer_to_id | 1457 | * flow in sta_info_create gives the TID as data, while the timer_to_id |
1458 | * array gives the sta through container_of */ | 1458 | * array gives the sta through container_of */ |
1459 | u16 tid = *(int *)data; | 1459 | u16 tid = *(int *)data; |
1460 | struct sta_info *temp_sta = container_of((void *)data, | 1460 | struct sta_info *temp_sta = container_of((void *)data, |
@@ -1505,7 +1505,7 @@ void sta_rx_agg_session_timer_expired(unsigned long data) | |||
1505 | { | 1505 | { |
1506 | /* not an elegant detour, but there is no choice as the timer passes | 1506 | /* not an elegant detour, but there is no choice as the timer passes |
1507 | * only one argument, and verious sta_info are needed here, so init | 1507 | * only one argument, and verious sta_info are needed here, so init |
1508 | * flow in sta_info_add gives the TID as data, while the timer_to_id | 1508 | * flow in sta_info_create gives the TID as data, while the timer_to_id |
1509 | * array gives the sta through container_of */ | 1509 | * array gives the sta through container_of */ |
1510 | u8 *ptid = (u8 *)data; | 1510 | u8 *ptid = (u8 *)data; |
1511 | u8 *timer_to_id = ptid - *ptid; | 1511 | u8 *timer_to_id = ptid - *ptid; |
@@ -1829,11 +1829,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1829 | sta = sta_info_get(local, ifsta->bssid); | 1829 | sta = sta_info_get(local, ifsta->bssid); |
1830 | if (!sta) { | 1830 | if (!sta) { |
1831 | struct ieee80211_sta_bss *bss; | 1831 | struct ieee80211_sta_bss *bss; |
1832 | int err; | ||
1832 | 1833 | ||
1833 | sta = sta_info_add(sdata, ifsta->bssid); | 1834 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); |
1834 | if (IS_ERR(sta)) { | 1835 | if (!sta) { |
1835 | printk(KERN_DEBUG "%s: failed to add STA entry for the" | 1836 | printk(KERN_DEBUG "%s: failed to alloc STA entry for" |
1836 | " AP (error %ld)\n", dev->name, PTR_ERR(sta)); | 1837 | " the AP\n", dev->name); |
1837 | rcu_read_unlock(); | 1838 | rcu_read_unlock(); |
1838 | return; | 1839 | return; |
1839 | } | 1840 | } |
@@ -1846,8 +1847,27 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1846 | sta->last_noise = bss->noise; | 1847 | sta->last_noise = bss->noise; |
1847 | ieee80211_rx_bss_put(dev, bss); | 1848 | ieee80211_rx_bss_put(dev, bss); |
1848 | } | 1849 | } |
1850 | |||
1851 | err = sta_info_insert(sta); | ||
1852 | if (err) { | ||
1853 | printk(KERN_DEBUG "%s: failed to insert STA entry for" | ||
1854 | " the AP (error %d)\n", dev->name, err); | ||
1855 | sta_info_destroy(sta); | ||
1856 | rcu_read_unlock(); | ||
1857 | return; | ||
1858 | } | ||
1849 | } | 1859 | } |
1850 | 1860 | ||
1861 | /* | ||
1862 | * FIXME: Do we really need to update the sta_info's information here? | ||
1863 | * We already know about the AP (we found it in our list) so it | ||
1864 | * should already be filled with the right info, no? | ||
1865 | * As is stands, all this is racy because typically we assume | ||
1866 | * the information that is filled in here (except flags) doesn't | ||
1867 | * change while a STA structure is alive. As such, it should move | ||
1868 | * to between the sta_info_alloc() and sta_info_insert() above. | ||
1869 | */ | ||
1870 | |||
1851 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | | 1871 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | |
1852 | WLAN_STA_AUTHORIZED; | 1872 | WLAN_STA_AUTHORIZED; |
1853 | 1873 | ||
@@ -2588,10 +2608,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2588 | "local TSF - IBSS merge with BSSID %s\n", | 2608 | "local TSF - IBSS merge with BSSID %s\n", |
2589 | dev->name, print_mac(mac, mgmt->bssid)); | 2609 | dev->name, print_mac(mac, mgmt->bssid)); |
2590 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); | 2610 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); |
2591 | rcu_read_lock(); | ||
2592 | ieee80211_ibss_add_sta(dev, NULL, | 2611 | ieee80211_ibss_add_sta(dev, NULL, |
2593 | mgmt->bssid, mgmt->sa); | 2612 | mgmt->bssid, mgmt->sa); |
2594 | rcu_read_unlock(); | ||
2595 | } | 2613 | } |
2596 | } | 2614 | } |
2597 | 2615 | ||
@@ -4023,7 +4041,6 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) | |||
4023 | } | 4041 | } |
4024 | 4042 | ||
4025 | 4043 | ||
4026 | /* must be called under RCU read lock */ | ||
4027 | struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | 4044 | struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, |
4028 | struct sk_buff *skb, u8 *bssid, | 4045 | struct sk_buff *skb, u8 *bssid, |
4029 | u8 *addr) | 4046 | u8 *addr) |
@@ -4046,8 +4063,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
4046 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 4063 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", |
4047 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); | 4064 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); |
4048 | 4065 | ||
4049 | sta = sta_info_add(sdata, addr); | 4066 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
4050 | if (IS_ERR(sta)) | 4067 | if (!sta) |
4051 | return NULL; | 4068 | return NULL; |
4052 | 4069 | ||
4053 | sta->flags |= WLAN_STA_AUTHORIZED; | 4070 | sta->flags |= WLAN_STA_AUTHORIZED; |
@@ -4057,6 +4074,11 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
4057 | 4074 | ||
4058 | rate_control_rate_init(sta, local); | 4075 | rate_control_rate_init(sta, local); |
4059 | 4076 | ||
4077 | if (sta_info_insert(sta)) { | ||
4078 | sta_info_destroy(sta); | ||
4079 | return NULL; | ||
4080 | } | ||
4081 | |||
4060 | return sta; | 4082 | return sta; |
4061 | } | 4083 | } |
4062 | 4084 | ||