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 /include | |
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 'include')
-rw-r--r-- | include/net/cfg80211.h | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 60c1f11da45f..83c2c727d71e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -555,6 +555,7 @@ struct cfg80211_scan_request { | |||
555 | /* internal */ | 555 | /* internal */ |
556 | struct wiphy *wiphy; | 556 | struct wiphy *wiphy; |
557 | int ifidx; | 557 | int ifidx; |
558 | bool aborted; | ||
558 | }; | 559 | }; |
559 | 560 | ||
560 | /** | 561 | /** |
@@ -998,9 +999,11 @@ struct cfg80211_ops { | |||
998 | int (*assoc)(struct wiphy *wiphy, struct net_device *dev, | 999 | int (*assoc)(struct wiphy *wiphy, struct net_device *dev, |
999 | struct cfg80211_assoc_request *req); | 1000 | struct cfg80211_assoc_request *req); |
1000 | int (*deauth)(struct wiphy *wiphy, struct net_device *dev, | 1001 | int (*deauth)(struct wiphy *wiphy, struct net_device *dev, |
1001 | struct cfg80211_deauth_request *req); | 1002 | struct cfg80211_deauth_request *req, |
1003 | void *cookie); | ||
1002 | int (*disassoc)(struct wiphy *wiphy, struct net_device *dev, | 1004 | int (*disassoc)(struct wiphy *wiphy, struct net_device *dev, |
1003 | struct cfg80211_disassoc_request *req); | 1005 | struct cfg80211_disassoc_request *req, |
1006 | void *cookie); | ||
1004 | 1007 | ||
1005 | int (*connect)(struct wiphy *wiphy, struct net_device *dev, | 1008 | int (*connect)(struct wiphy *wiphy, struct net_device *dev, |
1006 | struct cfg80211_connect_params *sme); | 1009 | struct cfg80211_connect_params *sme); |
@@ -1249,10 +1252,12 @@ struct wireless_dev { | |||
1249 | struct wiphy *wiphy; | 1252 | struct wiphy *wiphy; |
1250 | enum nl80211_iftype iftype; | 1253 | enum nl80211_iftype iftype; |
1251 | 1254 | ||
1252 | /* private to the generic wireless code */ | 1255 | /* the remainder of this struct should be private to cfg80211 */ |
1253 | struct list_head list; | 1256 | struct list_head list; |
1254 | struct net_device *netdev; | 1257 | struct net_device *netdev; |
1255 | 1258 | ||
1259 | struct mutex mtx; | ||
1260 | |||
1256 | /* currently used for IBSS and SME - might be rearranged later */ | 1261 | /* currently used for IBSS and SME - might be rearranged later */ |
1257 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 1262 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
1258 | u8 ssid_len; | 1263 | u8 ssid_len; |
@@ -1263,6 +1268,9 @@ struct wireless_dev { | |||
1263 | } sme_state; | 1268 | } sme_state; |
1264 | struct cfg80211_conn *conn; | 1269 | struct cfg80211_conn *conn; |
1265 | 1270 | ||
1271 | struct list_head event_list; | ||
1272 | spinlock_t event_lock; | ||
1273 | |||
1266 | struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES]; | 1274 | struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES]; |
1267 | struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES]; | 1275 | struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES]; |
1268 | struct cfg80211_internal_bss *current_bss; /* associated / joined */ | 1276 | struct cfg80211_internal_bss *current_bss; /* associated / joined */ |
@@ -1765,24 +1773,30 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); | |||
1765 | * @dev: network device | 1773 | * @dev: network device |
1766 | * @buf: deauthentication frame (header + body) | 1774 | * @buf: deauthentication frame (header + body) |
1767 | * @len: length of the frame data | 1775 | * @len: length of the frame data |
1776 | * @cookie: cookie from ->deauth if called within that callback, | ||
1777 | * %NULL otherwise | ||
1768 | * | 1778 | * |
1769 | * This function is called whenever deauthentication has been processed in | 1779 | * This function is called whenever deauthentication has been processed in |
1770 | * station mode. This includes both received deauthentication frames and | 1780 | * station mode. This includes both received deauthentication frames and |
1771 | * locally generated ones. This function may sleep. | 1781 | * locally generated ones. This function may sleep. |
1772 | */ | 1782 | */ |
1773 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); | 1783 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, |
1784 | void *cookie); | ||
1774 | 1785 | ||
1775 | /** | 1786 | /** |
1776 | * cfg80211_send_disassoc - notification of processed disassociation | 1787 | * cfg80211_send_disassoc - notification of processed disassociation |
1777 | * @dev: network device | 1788 | * @dev: network device |
1778 | * @buf: disassociation response frame (header + body) | 1789 | * @buf: disassociation response frame (header + body) |
1779 | * @len: length of the frame data | 1790 | * @len: length of the frame data |
1791 | * @cookie: cookie from ->disassoc if called within that callback, | ||
1792 | * %NULL otherwise | ||
1780 | * | 1793 | * |
1781 | * This function is called whenever disassociation has been processed in | 1794 | * This function is called whenever disassociation has been processed in |
1782 | * station mode. This includes both received disassociation frames and locally | 1795 | * station mode. This includes both received disassociation frames and locally |
1783 | * generated ones. This function may sleep. | 1796 | * generated ones. This function may sleep. |
1784 | */ | 1797 | */ |
1785 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); | 1798 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, |
1799 | void *cookie); | ||
1786 | 1800 | ||
1787 | /** | 1801 | /** |
1788 | * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) | 1802 | * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) |