diff options
author | Eliad Peller <eliad@wizery.com> | 2014-01-12 04:06:37 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-02-06 03:55:17 -0500 |
commit | 2f617435c3a6fe3f39efb9ae2baa77de2d6c97b8 (patch) | |
tree | 5838cbb3374a7c5121b613ce9e0602c014b918dc /net/mac80211/cfg.c | |
parent | 53d8ab29f8f6d67e37857b68189b38fa3d87dd8e (diff) |
mac80211: move roc cookie assignment earlier
ieee80211_start_roc_work() might add a new roc
to existing roc, and tell cfg80211 it has already
started.
However, this might happen before the roc cookie
was set, resulting in REMAIN_ON_CHANNEL (started)
event with null cookie. Consequently, it can make
wpa_supplicant go out of sync.
Fix it by setting the roc cookie earlier.
Cc: stable@vger.kernel.org
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f9ae9b85d4c1..94b4acb5aabb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2638,6 +2638,24 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2638 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); | 2638 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); |
2639 | INIT_LIST_HEAD(&roc->dependents); | 2639 | INIT_LIST_HEAD(&roc->dependents); |
2640 | 2640 | ||
2641 | /* | ||
2642 | * cookie is either the roc cookie (for normal roc) | ||
2643 | * or the SKB (for mgmt TX) | ||
2644 | */ | ||
2645 | if (!txskb) { | ||
2646 | /* local->mtx protects this */ | ||
2647 | local->roc_cookie_counter++; | ||
2648 | roc->cookie = local->roc_cookie_counter; | ||
2649 | /* wow, you wrapped 64 bits ... more likely a bug */ | ||
2650 | if (WARN_ON(roc->cookie == 0)) { | ||
2651 | roc->cookie = 1; | ||
2652 | local->roc_cookie_counter++; | ||
2653 | } | ||
2654 | *cookie = roc->cookie; | ||
2655 | } else { | ||
2656 | *cookie = (unsigned long)txskb; | ||
2657 | } | ||
2658 | |||
2641 | /* if there's one pending or we're scanning, queue this one */ | 2659 | /* if there's one pending or we're scanning, queue this one */ |
2642 | if (!list_empty(&local->roc_list) || | 2660 | if (!list_empty(&local->roc_list) || |
2643 | local->scanning || local->radar_detect_enabled) | 2661 | local->scanning || local->radar_detect_enabled) |
@@ -2772,24 +2790,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2772 | if (!queued) | 2790 | if (!queued) |
2773 | list_add_tail(&roc->list, &local->roc_list); | 2791 | list_add_tail(&roc->list, &local->roc_list); |
2774 | 2792 | ||
2775 | /* | ||
2776 | * cookie is either the roc cookie (for normal roc) | ||
2777 | * or the SKB (for mgmt TX) | ||
2778 | */ | ||
2779 | if (!txskb) { | ||
2780 | /* local->mtx protects this */ | ||
2781 | local->roc_cookie_counter++; | ||
2782 | roc->cookie = local->roc_cookie_counter; | ||
2783 | /* wow, you wrapped 64 bits ... more likely a bug */ | ||
2784 | if (WARN_ON(roc->cookie == 0)) { | ||
2785 | roc->cookie = 1; | ||
2786 | local->roc_cookie_counter++; | ||
2787 | } | ||
2788 | *cookie = roc->cookie; | ||
2789 | } else { | ||
2790 | *cookie = (unsigned long)txskb; | ||
2791 | } | ||
2792 | |||
2793 | return 0; | 2793 | return 0; |
2794 | } | 2794 | } |
2795 | 2795 | ||