diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-06 21:56:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:02:32 -0400 |
commit | 667503ddcb96f3b10211f997fe55907fa7509841 (patch) | |
tree | 5e2559e94a716bb81bfc7566e3e3a05267810c31 /net/mac80211/mlme.c | |
parent | 4f5dadcebb55fccef34722bbbf6401d39124c8a4 (diff) |
cfg80211: fix locking
Over time, a lot of locking issues have crept into
the smarts of cfg80211, so e.g. scan completion can
race against a new scan, IBSS join can race against
leaving an IBSS, etc.
Introduce a new per-interface lock that protects
most of the per-interface data that we need to keep
track of, and sprinkle assertions about that lock
everywhere. Some things now need to be offloaded to
work structs so that we don't require being able to
sleep in functions the drivers call. The exception
to that are the MLME callbacks (rx_auth etc.) that
currently only mac80211 calls because it was easier
to do that there instead of in cfg80211, and future
drivers implementing those calls will, if they ever
exist, probably need to use a similar scheme like
mac80211 anyway...
In order to be able to handle _deauth and _disassoc
properly, introduce a cookie passed to it that will
determine locking requirements.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 15dbb57ab55e..c9db9646025b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -386,7 +386,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
386 | 386 | ||
387 | 387 | ||
388 | static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | 388 | static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, |
389 | const u8 *bssid, u16 stype, u16 reason) | 389 | const u8 *bssid, u16 stype, u16 reason, |
390 | void *cookie) | ||
390 | { | 391 | { |
391 | struct ieee80211_local *local = sdata->local; | 392 | struct ieee80211_local *local = sdata->local; |
392 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 393 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
@@ -412,9 +413,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
412 | mgmt->u.deauth.reason_code = cpu_to_le16(reason); | 413 | mgmt->u.deauth.reason_code = cpu_to_le16(reason); |
413 | 414 | ||
414 | if (stype == IEEE80211_STYPE_DEAUTH) | 415 | if (stype == IEEE80211_STYPE_DEAUTH) |
415 | cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len); | 416 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie); |
416 | else | 417 | else |
417 | cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len); | 418 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie); |
418 | ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); | 419 | ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); |
419 | } | 420 | } |
420 | 421 | ||
@@ -1837,10 +1838,12 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1837 | /* no action */ | 1838 | /* no action */ |
1838 | break; | 1839 | break; |
1839 | case RX_MGMT_CFG80211_DEAUTH: | 1840 | case RX_MGMT_CFG80211_DEAUTH: |
1840 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | 1841 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, |
1842 | NULL); | ||
1841 | break; | 1843 | break; |
1842 | case RX_MGMT_CFG80211_DISASSOC: | 1844 | case RX_MGMT_CFG80211_DISASSOC: |
1843 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); | 1845 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, |
1846 | NULL); | ||
1844 | break; | 1847 | break; |
1845 | default: | 1848 | default: |
1846 | WARN(1, "unexpected: %d", rma); | 1849 | WARN(1, "unexpected: %d", rma); |
@@ -2273,7 +2276,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2273 | } | 2276 | } |
2274 | 2277 | ||
2275 | int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | 2278 | int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, |
2276 | struct cfg80211_deauth_request *req) | 2279 | struct cfg80211_deauth_request *req, |
2280 | void *cookie) | ||
2277 | { | 2281 | { |
2278 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2282 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2279 | struct ieee80211_mgd_work *wk; | 2283 | struct ieee80211_mgd_work *wk; |
@@ -2305,13 +2309,15 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2305 | mutex_unlock(&ifmgd->mtx); | 2309 | mutex_unlock(&ifmgd->mtx); |
2306 | 2310 | ||
2307 | ieee80211_send_deauth_disassoc(sdata, bssid, | 2311 | ieee80211_send_deauth_disassoc(sdata, bssid, |
2308 | IEEE80211_STYPE_DEAUTH, req->reason_code); | 2312 | IEEE80211_STYPE_DEAUTH, req->reason_code, |
2313 | cookie); | ||
2309 | 2314 | ||
2310 | return 0; | 2315 | return 0; |
2311 | } | 2316 | } |
2312 | 2317 | ||
2313 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | 2318 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, |
2314 | struct cfg80211_disassoc_request *req) | 2319 | struct cfg80211_disassoc_request *req, |
2320 | void *cookie) | ||
2315 | { | 2321 | { |
2316 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2322 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2317 | 2323 | ||
@@ -2331,6 +2337,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2331 | mutex_unlock(&ifmgd->mtx); | 2337 | mutex_unlock(&ifmgd->mtx); |
2332 | 2338 | ||
2333 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, | 2339 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, |
2334 | IEEE80211_STYPE_DISASSOC, req->reason_code); | 2340 | IEEE80211_STYPE_DISASSOC, req->reason_code, |
2341 | cookie); | ||
2335 | return 0; | 2342 | return 0; |
2336 | } | 2343 | } |