Simon Wunderlich wrote: > we have found a regression in the IBSS creation/joining part of mac80211 which > is appearently connected to the TSF-syncing patches introduced last year[1]. > It prevents beaconing of an adhoc member after rejoining a cell when this cell > is currently empty. The problem is present in at least 3.10 and 3.13. > > To reproduce, use two adhoc peers and let them join/leave in the following > order: > > station 1: join > station 2: join > station 2: leave > station 1: leave > station 1: join > > now we would expect that station 1 sends beacons, but it doesn't. After > inspecting the code, station 1 actually selected the "old" ibss network and > waits for a beacon to sync the tsf which is never received, as all members > already left the network. An easy workaround is to set the IBSS creator always > to true. The race condition is that station-1 (the creator) removes station-2 only after a while, based on the expiration/inactive timer. The small window that IEEE80211_IBSS_MERGE_INTERVAL introduces when ieee80211_ibss_disconnect() is called causes the race, since we assume that station-2 is still active and do not remove the BSS from cfg80211. I am not sure why we have to keep the BSS around when we are leaving the network. Is this patch the right approach ? diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 771080e..e1688cd 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -688,17 +688,18 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata) return active; } -static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) +static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata, bool leave) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct cfg80211_bss *cbss; struct beacon_data *presp; struct sta_info *sta; - int active_ibss; + int active_ibss = 0; u16 capability; - active_ibss = ieee80211_sta_active_ibss(sdata); + if (!leave) + active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { capability = WLAN_CAPABILITY_IBSS; @@ -765,7 +766,7 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work) sdata_lock(sdata); - ieee80211_ibss_disconnect(sdata); + ieee80211_ibss_disconnect(sdata, false); synchronize_rcu(); skb_queue_purge(&sdata->skb_queue); @@ -1721,7 +1722,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - ieee80211_ibss_disconnect(sdata); + ieee80211_ibss_disconnect(sdata, true); ifibss->ssid_len = 0; memset(ifibss->bssid, 0, ETH_ALEN); Sujith -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html