nl80211: add NL80211_FLAG_NEED_WDEV
Some nl80211 callbacks will soon need the wdev instead of the netdev, so add NL80211_FLAG_NEED_WDEV to allow them to request that. Add NL80211_FLAG_NEED_WDEV_UP as well which checks the netdev is UP if one exists. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
89a54e48b9
commit
1bf614ef79
|
@ -6718,6 +6718,10 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
|
||||||
#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
|
#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
|
||||||
#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
|
#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
|
||||||
NL80211_FLAG_CHECK_NETDEV_UP)
|
NL80211_FLAG_CHECK_NETDEV_UP)
|
||||||
|
#define NL80211_FLAG_NEED_WDEV 0x10
|
||||||
|
/* If a netdev is associated, it must be UP */
|
||||||
|
#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
|
||||||
|
NL80211_FLAG_CHECK_NETDEV_UP)
|
||||||
|
|
||||||
static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
|
static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
|
||||||
struct genl_info *info)
|
struct genl_info *info)
|
||||||
|
@ -6738,7 +6742,8 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
|
||||||
return PTR_ERR(rdev);
|
return PTR_ERR(rdev);
|
||||||
}
|
}
|
||||||
info->user_ptr[0] = rdev;
|
info->user_ptr[0] = rdev;
|
||||||
} else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
|
} else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
|
||||||
|
ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
|
||||||
mutex_lock(&cfg80211_mutex);
|
mutex_lock(&cfg80211_mutex);
|
||||||
wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
|
wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
|
||||||
info->attrs);
|
info->attrs);
|
||||||
|
@ -6749,31 +6754,39 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
|
||||||
return PTR_ERR(wdev);
|
return PTR_ERR(wdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wdev->netdev) {
|
|
||||||
mutex_unlock(&cfg80211_mutex);
|
|
||||||
if (rtnl)
|
|
||||||
rtnl_unlock();
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev = wdev->netdev;
|
dev = wdev->netdev;
|
||||||
rdev = wiphy_to_dev(wdev->wiphy);
|
rdev = wiphy_to_dev(wdev->wiphy);
|
||||||
|
|
||||||
if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
|
if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
|
||||||
!netif_running(dev)) {
|
if (!dev) {
|
||||||
mutex_unlock(&cfg80211_mutex);
|
mutex_unlock(&cfg80211_mutex);
|
||||||
if (rtnl)
|
if (rtnl)
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
return -ENETDOWN;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->user_ptr[1] = dev;
|
||||||
|
} else {
|
||||||
|
info->user_ptr[1] = wdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
|
||||||
|
!netif_running(dev)) {
|
||||||
|
mutex_unlock(&cfg80211_mutex);
|
||||||
|
if (rtnl)
|
||||||
|
rtnl_unlock();
|
||||||
|
return -ENETDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_hold(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_hold(dev);
|
|
||||||
cfg80211_lock_rdev(rdev);
|
cfg80211_lock_rdev(rdev);
|
||||||
|
|
||||||
mutex_unlock(&cfg80211_mutex);
|
mutex_unlock(&cfg80211_mutex);
|
||||||
|
|
||||||
info->user_ptr[0] = rdev;
|
info->user_ptr[0] = rdev;
|
||||||
info->user_ptr[1] = dev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6784,8 +6797,16 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
if (info->user_ptr[0])
|
if (info->user_ptr[0])
|
||||||
cfg80211_unlock_rdev(info->user_ptr[0]);
|
cfg80211_unlock_rdev(info->user_ptr[0]);
|
||||||
if (info->user_ptr[1])
|
if (info->user_ptr[1]) {
|
||||||
dev_put(info->user_ptr[1]);
|
if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
|
||||||
|
struct wireless_dev *wdev = info->user_ptr[1];
|
||||||
|
|
||||||
|
if (wdev->netdev)
|
||||||
|
dev_put(wdev->netdev);
|
||||||
|
} else {
|
||||||
|
dev_put(info->user_ptr[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
|
if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue