aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-06-08 07:27:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-06-08 14:19:05 -0400
commitf3209bea110cade12e2b133da8b8499689cb0e2e (patch)
tree27346021a1b6a50b49a6a27696a1f01f18655f7c /net
parent43e4e0b94984b45d52048e3ac027cac15c718b65 (diff)
mac80211: fix IBSS teardown race
Ignacy reports that sometimes after leaving an IBSS joining a new one didn't work because there still were stations on the list. He fixed it by flushing stations when attempting to join a new IBSS, but this shouldn't be happening in the first case. When I looked into it I saw a race condition in teardown that could cause stations to be added after flush, and thus cause this situation. Ignacy confirms that after applying my patch he hasn't seen this happen again. Reported-by: Ignacy Gawedzki <i@lri.fr> Debugged-by: Ignacy Gawedzki <i@lri.fr> Tested-by: Ignacy Gawedzki <i@lri.fr> Cc: stable@kernel.org Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ibss.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 421eaa6b0c2b..56c24cabf26d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -965,6 +965,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
965 965
966 mutex_lock(&sdata->u.ibss.mtx); 966 mutex_lock(&sdata->u.ibss.mtx);
967 967
968 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
969 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
970 sdata->u.ibss.ssid_len = 0;
971
968 active_ibss = ieee80211_sta_active_ibss(sdata); 972 active_ibss = ieee80211_sta_active_ibss(sdata);
969 973
970 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { 974 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
@@ -999,8 +1003,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
999 kfree_skb(skb); 1003 kfree_skb(skb);
1000 1004
1001 skb_queue_purge(&sdata->skb_queue); 1005 skb_queue_purge(&sdata->skb_queue);
1002 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
1003 sdata->u.ibss.ssid_len = 0;
1004 1006
1005 del_timer_sync(&sdata->u.ibss.timer); 1007 del_timer_sync(&sdata->u.ibss.timer);
1006 1008