mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-22 11:53:02 +00:00
125 lines
3.7 KiB
Diff
125 lines
3.7 KiB
Diff
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -3973,7 +3973,7 @@ static int nl80211_set_interface(struct
|
|
return err;
|
|
}
|
|
|
|
-static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|
+static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|
{
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
struct vif_params params;
|
|
@@ -3982,9 +3982,6 @@ static int nl80211_new_interface(struct
|
|
int err;
|
|
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
|
|
|
|
- /* to avoid failing a new interface creation due to pending removal */
|
|
- cfg80211_destroy_ifaces(rdev);
|
|
-
|
|
memset(¶ms, 0, sizeof(params));
|
|
|
|
if (!info->attrs[NL80211_ATTR_IFNAME])
|
|
@@ -4072,6 +4069,21 @@ static int nl80211_new_interface(struct
|
|
return genlmsg_reply(msg, info);
|
|
}
|
|
|
|
+static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|
+{
|
|
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
+ int ret;
|
|
+
|
|
+ /* to avoid failing a new interface creation due to pending removal */
|
|
+ cfg80211_destroy_ifaces(rdev);
|
|
+
|
|
+ wiphy_lock(&rdev->wiphy);
|
|
+ ret = _nl80211_new_interface(skb, info);
|
|
+ wiphy_unlock(&rdev->wiphy);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
|
|
{
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
@@ -15037,6 +15049,7 @@ static int nl80211_color_change(struct s
|
|
#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
|
|
NL80211_FLAG_CHECK_NETDEV_UP)
|
|
#define NL80211_FLAG_CLEAR_SKB 0x20
|
|
+#define NL80211_FLAG_NO_WIPHY_MTX 0x40
|
|
|
|
static int nl80211_pre_doit(__genl_const struct genl_ops *ops,
|
|
struct sk_buff *skb,
|
|
@@ -15089,7 +15102,7 @@ static int nl80211_pre_doit(__genl_const
|
|
info->user_ptr[0] = rdev;
|
|
}
|
|
|
|
- if (rdev) {
|
|
+ if (rdev && !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
|
|
wiphy_lock(&rdev->wiphy);
|
|
/* we keep the mutex locked until post_doit */
|
|
__release(&rdev->wiphy.mtx);
|
|
@@ -15115,7 +15128,8 @@ static void nl80211_post_doit(__genl_con
|
|
}
|
|
}
|
|
|
|
- if (info->user_ptr[0]) {
|
|
+ if (info->user_ptr[0] &&
|
|
+ !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
|
|
/* we kept the mutex locked since pre_doit */
|
|
@@ -15286,7 +15300,9 @@ static const struct genl_small_ops nl802
|
|
.doit = nl80211_new_interface,
|
|
.flags = GENL_UNS_ADMIN_PERM,
|
|
.internal_flags = NL80211_FLAG_NEED_WIPHY |
|
|
- NL80211_FLAG_NEED_RTNL,
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ /* we take the wiphy mutex later ourselves */
|
|
+ NL80211_FLAG_NO_WIPHY_MTX,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_DEL_INTERFACE,
|
|
@@ -15581,7 +15597,9 @@ static const struct genl_small_ops nl802
|
|
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
|
.doit = nl80211_wiphy_netns,
|
|
.flags = GENL_UNS_ADMIN_PERM,
|
|
- .internal_flags = NL80211_FLAG_NEED_WIPHY,
|
|
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
|
|
+ NL80211_FLAG_NEED_RTNL |
|
|
+ NL80211_FLAG_NO_WIPHY_MTX,
|
|
},
|
|
{
|
|
.cmd = NL80211_CMD_GET_SURVEY,
|
|
--- a/net/wireless/core.c
|
|
+++ b/net/wireless/core.c
|
|
@@ -334,11 +334,17 @@ void cfg80211_destroy_ifaces(struct cfg8
|
|
struct wireless_dev *wdev, *tmp;
|
|
|
|
ASSERT_RTNL();
|
|
- lockdep_assert_wiphy(&rdev->wiphy);
|
|
|
|
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
|
|
- if (wdev->nl_owner_dead)
|
|
+ if (wdev->nl_owner_dead) {
|
|
+ if (wdev->netdev)
|
|
+ dev_close(wdev->netdev);
|
|
+
|
|
+ wiphy_lock(&rdev->wiphy);
|
|
+ cfg80211_leave(rdev, wdev);
|
|
rdev_del_virtual_intf(rdev, wdev);
|
|
+ wiphy_unlock(&rdev->wiphy);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -350,9 +356,7 @@ static void cfg80211_destroy_iface_wk(st
|
|
destroy_work);
|
|
|
|
rtnl_lock();
|
|
- wiphy_lock(&rdev->wiphy);
|
|
cfg80211_destroy_ifaces(rdev);
|
|
- wiphy_unlock(&rdev->wiphy);
|
|
rtnl_unlock();
|
|
}
|
|
|