summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2018-03-26 13:52:46 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-03-29 04:38:24 -0400
commit188c1b3c04d69e842122daf201f07a34fcfad039 (patch)
tree515707f3b46c7f98a0fb85fdabf2ef36e008b688
parentf8d16d3edb4dbae080df04318423c360de3c594d (diff)
nl80211: Add SOCKET_OWNER support to JOIN_MESH
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>
-rw-r--r--include/uapi/linux/nl80211.h2
-rw-r--r--net/wireless/core.h4
-rw-r--r--net/wireless/mesh.c16
-rw-r--r--net/wireless/nl80211.c10
4 files changed, 11 insertions, 21 deletions
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 266b43c4f6e1..98eb37def37d 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1964,6 +1964,8 @@ enum nl80211_commands {
1964 * station will deauthenticate when the socket is closed. 1964 * station will deauthenticate when the socket is closed.
1965 * If set during %NL80211_CMD_JOIN_IBSS the IBSS will be automatically 1965 * If set during %NL80211_CMD_JOIN_IBSS the IBSS will be automatically
1966 * torn down when the socket is closed. 1966 * torn down when the socket is closed.
1967 * If set during %NL80211_CMD_JOIN_MESH the mesh setup will be
1968 * automatically torn down when the socket is closed.
1967 * 1969 *
1968 * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is 1970 * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
1969 * the TDLS link initiator. 1971 * the TDLS link initiator.
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b5cf3ea8d4df..63eb1b5fdd04 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -303,10 +303,6 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
303 struct net_device *dev, 303 struct net_device *dev,
304 struct mesh_setup *setup, 304 struct mesh_setup *setup,
305 const struct mesh_config *conf); 305 const struct mesh_config *conf);
306int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
307 struct net_device *dev,
308 struct mesh_setup *setup,
309 const struct mesh_config *conf);
310int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 306int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
311 struct net_device *dev); 307 struct net_device *dev);
312int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 308int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index b12da6ef3c12..eac5aa1419fc 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -217,21 +217,6 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
217 return err; 217 return err;
218} 218}
219 219
220int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
221 struct net_device *dev,
222 struct mesh_setup *setup,
223 const struct mesh_config *conf)
224{
225 struct wireless_dev *wdev = dev->ieee80211_ptr;
226 int err;
227
228 wdev_lock(wdev);
229 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
230 wdev_unlock(wdev);
231
232 return err;
233}
234
235int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, 220int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
236 struct wireless_dev *wdev, 221 struct wireless_dev *wdev,
237 struct cfg80211_chan_def *chandef) 222 struct cfg80211_chan_def *chandef)
@@ -286,6 +271,7 @@ int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
286 271
287 err = rdev_leave_mesh(rdev, dev); 272 err = rdev_leave_mesh(rdev, dev);
288 if (!err) { 273 if (!err) {
274 wdev->conn_owner_nlportid = 0;
289 wdev->mesh_id_len = 0; 275 wdev->mesh_id_len = 0;
290 wdev->beacon_interval = 0; 276 wdev->beacon_interval = 0;
291 memset(&wdev->chandef, 0, sizeof(wdev->chandef)); 277 memset(&wdev->chandef, 0, sizeof(wdev->chandef));
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 13f7c002f562..1d6e81e5b2c8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10092,7 +10092,7 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
10092 if (err) 10092 if (err)
10093 return err; 10093 return err;
10094 } else { 10094 } else {
10095 /* cfg80211_join_mesh() will sort it out */ 10095 /* __cfg80211_join_mesh() will sort it out */
10096 setup.chandef.chan = NULL; 10096 setup.chandef.chan = NULL;
10097 } 10097 }
10098 10098
@@ -10130,7 +10130,13 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
10130 setup.userspace_handles_dfs = 10130 setup.userspace_handles_dfs =
10131 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]); 10131 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10132 10132
10133 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 10133 wdev_lock(dev->ieee80211_ptr);
10134 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
10135 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
10136 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10137 wdev_unlock(dev->ieee80211_ptr);
10138
10139 return err;
10134} 10140}
10135 10141
10136static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) 10142static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)