diff options
author | Denis Kenzior <denkenz@gmail.com> | 2018-03-26 13:52:45 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2018-03-29 04:36:22 -0400 |
commit | f8d16d3edb4dbae080df04318423c360de3c594d (patch) | |
tree | b110456d132b2538a6533e3b249a8e5fa1b157b3 /net/wireless | |
parent | 37b1c004685a3cea420dd96aa3803da627359f60 (diff) |
nl80211: Add SOCKET_OWNER support to JOIN_IBSS
Signed-off-by: Denis Kenzior <denkenz@gmail.com>
[johannes: fix race with wdev lock/unlock by just acquiring once]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.h | 8 | ||||
-rw-r--r-- | net/wireless/ibss.c | 27 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 7 |
3 files changed, 16 insertions, 26 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index eaff636169c2..b5cf3ea8d4df 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -282,10 +282,10 @@ void cfg80211_bss_age(struct cfg80211_registered_device *rdev, | |||
282 | unsigned long age_secs); | 282 | unsigned long age_secs); |
283 | 283 | ||
284 | /* IBSS */ | 284 | /* IBSS */ |
285 | int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | 285 | int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, |
286 | struct net_device *dev, | 286 | struct net_device *dev, |
287 | struct cfg80211_ibss_params *params, | 287 | struct cfg80211_ibss_params *params, |
288 | struct cfg80211_cached_keys *connkeys); | 288 | struct cfg80211_cached_keys *connkeys); |
289 | void cfg80211_clear_ibss(struct net_device *dev, bool nowext); | 289 | void cfg80211_clear_ibss(struct net_device *dev, bool nowext); |
290 | int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | 290 | int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, |
291 | struct net_device *dev, bool nowext); | 291 | struct net_device *dev, bool nowext); |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index a1d10993d08a..d1743e6abc34 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -84,14 +84,15 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, | |||
84 | } | 84 | } |
85 | EXPORT_SYMBOL(cfg80211_ibss_joined); | 85 | EXPORT_SYMBOL(cfg80211_ibss_joined); |
86 | 86 | ||
87 | static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | 87 | int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, |
88 | struct net_device *dev, | 88 | struct net_device *dev, |
89 | struct cfg80211_ibss_params *params, | 89 | struct cfg80211_ibss_params *params, |
90 | struct cfg80211_cached_keys *connkeys) | 90 | struct cfg80211_cached_keys *connkeys) |
91 | { | 91 | { |
92 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 92 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
93 | int err; | 93 | int err; |
94 | 94 | ||
95 | ASSERT_RTNL(); | ||
95 | ASSERT_WDEV_LOCK(wdev); | 96 | ASSERT_WDEV_LOCK(wdev); |
96 | 97 | ||
97 | if (wdev->ssid_len) | 98 | if (wdev->ssid_len) |
@@ -146,23 +147,6 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
148 | 149 | ||
149 | int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | ||
150 | struct net_device *dev, | ||
151 | struct cfg80211_ibss_params *params, | ||
152 | struct cfg80211_cached_keys *connkeys) | ||
153 | { | ||
154 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
155 | int err; | ||
156 | |||
157 | ASSERT_RTNL(); | ||
158 | |||
159 | wdev_lock(wdev); | ||
160 | err = __cfg80211_join_ibss(rdev, dev, params, connkeys); | ||
161 | wdev_unlock(wdev); | ||
162 | |||
163 | return err; | ||
164 | } | ||
165 | |||
166 | static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | 150 | static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) |
167 | { | 151 | { |
168 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 152 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
@@ -224,6 +208,7 @@ int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | |||
224 | if (err) | 208 | if (err) |
225 | return err; | 209 | return err; |
226 | 210 | ||
211 | wdev->conn_owner_nlportid = 0; | ||
227 | __cfg80211_clear_ibss(dev, nowext); | 212 | __cfg80211_clear_ibss(dev, nowext); |
228 | 213 | ||
229 | return 0; | 214 | return 0; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index fe27ab443d01..13f7c002f562 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -8679,9 +8679,14 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
8679 | ibss.userspace_handles_dfs = | 8679 | ibss.userspace_handles_dfs = |
8680 | nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]); | 8680 | nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]); |
8681 | 8681 | ||
8682 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 8682 | wdev_lock(dev->ieee80211_ptr); |
8683 | err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | ||
8683 | if (err) | 8684 | if (err) |
8684 | kzfree(connkeys); | 8685 | kzfree(connkeys); |
8686 | else if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) | ||
8687 | dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid; | ||
8688 | wdev_unlock(dev->ieee80211_ptr); | ||
8689 | |||
8685 | return err; | 8690 | return err; |
8686 | } | 8691 | } |
8687 | 8692 | ||