diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-06-19 07:21:15 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-06-19 12:55:39 -0400 |
commit | f1940c5730f0f0555e42afbcf629be7f7fbbce8e (patch) | |
tree | 0e85c3b6f57bbb8e9f2640c28d0e98e0bdf55765 /net | |
parent | 959867fa55d0cb55fb3d08656e5e62607167617f (diff) |
cfg80211: hold BSS over association process
This fixes the potential issue that the BSS struct that we use
and later assign to wdev->current_bss is removed from the scan
list while associating.
Also warn when we don't have a BSS struct in connect_result
unless it's from a driver that only has the connect() API.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/mlme.c | 4 | ||||
-rw-r--r-- | net/wireless/sme.c | 15 |
2 files changed, 14 insertions, 5 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index dd6f79d7bd2e..bfac5e186f57 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | |||
38 | * frame instead of reassoc. | 38 | * frame instead of reassoc. |
39 | */ | 39 | */ |
40 | if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { | 40 | if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { |
41 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
41 | cfg80211_put_bss(wiphy, bss); | 42 | cfg80211_put_bss(wiphy, bss); |
42 | return; | 43 | return; |
43 | } | 44 | } |
@@ -142,6 +143,7 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss) | |||
142 | nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL); | 143 | nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL); |
143 | cfg80211_sme_assoc_timeout(wdev); | 144 | cfg80211_sme_assoc_timeout(wdev); |
144 | 145 | ||
146 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
145 | cfg80211_put_bss(wiphy, bss); | 147 | cfg80211_put_bss(wiphy, bss); |
146 | } | 148 | } |
147 | EXPORT_SYMBOL(cfg80211_assoc_timeout); | 149 | EXPORT_SYMBOL(cfg80211_assoc_timeout); |
@@ -309,6 +311,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
309 | goto out; | 311 | goto out; |
310 | 312 | ||
311 | err = rdev_assoc(rdev, dev, req); | 313 | err = rdev_assoc(rdev, dev, req); |
314 | if (!err) | ||
315 | cfg80211_hold_bss(bss_from_pub(req->bss)); | ||
312 | 316 | ||
313 | out: | 317 | out: |
314 | if (err) | 318 | if (err) |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index ae7e2cbf45cb..c0bf781d4fbe 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -615,19 +615,24 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
615 | kfree(wdev->connect_keys); | 615 | kfree(wdev->connect_keys); |
616 | wdev->connect_keys = NULL; | 616 | wdev->connect_keys = NULL; |
617 | wdev->ssid_len = 0; | 617 | wdev->ssid_len = 0; |
618 | cfg80211_put_bss(wdev->wiphy, bss); | 618 | if (bss) { |
619 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
620 | cfg80211_put_bss(wdev->wiphy, bss); | ||
621 | } | ||
619 | return; | 622 | return; |
620 | } | 623 | } |
621 | 624 | ||
622 | if (!bss) | 625 | if (!bss) { |
626 | WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect); | ||
623 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 627 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, |
624 | wdev->ssid, wdev->ssid_len, | 628 | wdev->ssid, wdev->ssid_len, |
625 | WLAN_CAPABILITY_ESS, | 629 | WLAN_CAPABILITY_ESS, |
626 | WLAN_CAPABILITY_ESS); | 630 | WLAN_CAPABILITY_ESS); |
627 | if (WARN_ON(!bss)) | 631 | if (WARN_ON(!bss)) |
628 | return; | 632 | return; |
633 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
634 | } | ||
629 | 635 | ||
630 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
631 | wdev->current_bss = bss_from_pub(bss); | 636 | wdev->current_bss = bss_from_pub(bss); |
632 | 637 | ||
633 | cfg80211_upload_connect_keys(wdev); | 638 | cfg80211_upload_connect_keys(wdev); |