summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2018-03-26 13:52:45 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-03-29 04:36:22 -0400
commitf8d16d3edb4dbae080df04318423c360de3c594d (patch)
treeb110456d132b2538a6533e3b249a8e5fa1b157b3 /net/wireless
parent37b1c004685a3cea420dd96aa3803da627359f60 (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.h8
-rw-r--r--net/wireless/ibss.c27
-rw-r--r--net/wireless/nl80211.c7
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 */
285int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 285int __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);
289void cfg80211_clear_ibss(struct net_device *dev, bool nowext); 289void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
290int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 290int __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}
85EXPORT_SYMBOL(cfg80211_ibss_joined); 85EXPORT_SYMBOL(cfg80211_ibss_joined);
86 86
87static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 87int __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
149int 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
166static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) 150static 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