diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-29 05:23:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:43:24 -0400 |
commit | df7fc0f9735085bb617fff774bfd71465edb448c (patch) | |
tree | 2b47f3823a8aee6c13e86aa3dedc06bda9ebae38 /net/wireless/sme.c | |
parent | 97af743207466ff8b477e14bfb7af0ba2c93375b (diff) |
cfg80211: keep track of current_bss for userspace SME
When a userspace SME is active, we're currently not
keeping track of the BSS properly for reporting the
current link and for internal use. Additionally, it
looks like there is a possible BSS leak in that the
BSS never gets removed from auth_bsses[]. To fix it,
pass the BSS struct to __cfg80211_connect_result in
this case.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r-- | net/wireless/sme.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index d2b5d4ce0a00..3728d2b88b25 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -182,7 +182,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
182 | wdev->conn->params.bssid, | 182 | wdev->conn->params.bssid, |
183 | NULL, 0, NULL, 0, | 183 | NULL, 0, NULL, 0, |
184 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 184 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
185 | false); | 185 | false, NULL); |
186 | wdev_unlock(wdev); | 186 | wdev_unlock(wdev); |
187 | } | 187 | } |
188 | 188 | ||
@@ -247,7 +247,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev) | |||
247 | wdev->conn->params.bssid, | 247 | wdev->conn->params.bssid, |
248 | NULL, 0, NULL, 0, | 248 | NULL, 0, NULL, 0, |
249 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 249 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
250 | false); | 250 | false, NULL); |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
@@ -305,7 +305,7 @@ void cfg80211_sme_rx_auth(struct net_device *dev, | |||
305 | schedule_work(&rdev->conn_work); | 305 | schedule_work(&rdev->conn_work); |
306 | } else if (status_code != WLAN_STATUS_SUCCESS) { | 306 | } else if (status_code != WLAN_STATUS_SUCCESS) { |
307 | __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, | 307 | __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, |
308 | status_code, false); | 308 | status_code, false, NULL); |
309 | } else if (wdev->sme_state == CFG80211_SME_CONNECTING && | 309 | } else if (wdev->sme_state == CFG80211_SME_CONNECTING && |
310 | wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { | 310 | wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { |
311 | wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; | 311 | wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; |
@@ -316,10 +316,10 @@ void cfg80211_sme_rx_auth(struct net_device *dev, | |||
316 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 316 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
317 | const u8 *req_ie, size_t req_ie_len, | 317 | const u8 *req_ie, size_t req_ie_len, |
318 | const u8 *resp_ie, size_t resp_ie_len, | 318 | const u8 *resp_ie, size_t resp_ie_len, |
319 | u16 status, bool wextev) | 319 | u16 status, bool wextev, |
320 | struct cfg80211_bss *bss) | ||
320 | { | 321 | { |
321 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 322 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
322 | struct cfg80211_bss *bss; | ||
323 | #ifdef CONFIG_WIRELESS_EXT | 323 | #ifdef CONFIG_WIRELESS_EXT |
324 | union iwreq_data wrqu; | 324 | union iwreq_data wrqu; |
325 | #endif | 325 | #endif |
@@ -361,6 +361,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
361 | } | 361 | } |
362 | #endif | 362 | #endif |
363 | 363 | ||
364 | if (wdev->current_bss) { | ||
365 | cfg80211_unhold_bss(wdev->current_bss); | ||
366 | cfg80211_put_bss(&wdev->current_bss->pub); | ||
367 | wdev->current_bss = NULL; | ||
368 | } | ||
369 | |||
364 | if (status == WLAN_STATUS_SUCCESS && | 370 | if (status == WLAN_STATUS_SUCCESS && |
365 | wdev->sme_state == CFG80211_SME_IDLE) | 371 | wdev->sme_state == CFG80211_SME_IDLE) |
366 | goto success; | 372 | goto success; |
@@ -368,12 +374,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
368 | if (wdev->sme_state != CFG80211_SME_CONNECTING) | 374 | if (wdev->sme_state != CFG80211_SME_CONNECTING) |
369 | return; | 375 | return; |
370 | 376 | ||
371 | if (wdev->current_bss) { | ||
372 | cfg80211_unhold_bss(wdev->current_bss); | ||
373 | cfg80211_put_bss(&wdev->current_bss->pub); | ||
374 | wdev->current_bss = NULL; | ||
375 | } | ||
376 | |||
377 | if (wdev->conn) | 377 | if (wdev->conn) |
378 | wdev->conn->state = CFG80211_CONN_IDLE; | 378 | wdev->conn->state = CFG80211_CONN_IDLE; |
379 | 379 | ||
@@ -386,10 +386,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
386 | return; | 386 | return; |
387 | } | 387 | } |
388 | 388 | ||
389 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 389 | success: |
390 | wdev->ssid, wdev->ssid_len, | 390 | if (!bss) |
391 | WLAN_CAPABILITY_ESS, | 391 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, |
392 | WLAN_CAPABILITY_ESS); | 392 | wdev->ssid, wdev->ssid_len, |
393 | WLAN_CAPABILITY_ESS, | ||
394 | WLAN_CAPABILITY_ESS); | ||
393 | 395 | ||
394 | if (WARN_ON(!bss)) | 396 | if (WARN_ON(!bss)) |
395 | return; | 397 | return; |
@@ -397,7 +399,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
397 | cfg80211_hold_bss(bss_from_pub(bss)); | 399 | cfg80211_hold_bss(bss_from_pub(bss)); |
398 | wdev->current_bss = bss_from_pub(bss); | 400 | wdev->current_bss = bss_from_pub(bss); |
399 | 401 | ||
400 | success: | ||
401 | wdev->sme_state = CFG80211_SME_CONNECTED; | 402 | wdev->sme_state = CFG80211_SME_CONNECTED; |
402 | cfg80211_upload_connect_keys(wdev); | 403 | cfg80211_upload_connect_keys(wdev); |
403 | } | 404 | } |
@@ -788,7 +789,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
788 | else if (wdev->sme_state == CFG80211_SME_CONNECTING) | 789 | else if (wdev->sme_state == CFG80211_SME_CONNECTING) |
789 | __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, | 790 | __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, |
790 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 791 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
791 | wextev); | 792 | wextev, NULL); |
792 | 793 | ||
793 | return 0; | 794 | return 0; |
794 | } | 795 | } |