nl80211: reduce dumping boilerplate
Consolidate boilerplate code needed for .dumpit calls operating on netdevs. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
4126571481
commit
6774889314
|
@ -198,6 +198,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb)
|
|||
return res;
|
||||
}
|
||||
|
||||
static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
|
||||
struct netlink_callback *cb,
|
||||
struct cfg80211_registered_device **rdev,
|
||||
struct net_device **dev)
|
||||
{
|
||||
int ifidx = cb->args[0];
|
||||
int err;
|
||||
|
||||
if (!ifidx)
|
||||
ifidx = nl80211_get_ifidx(cb);
|
||||
if (ifidx < 0)
|
||||
return ifidx;
|
||||
|
||||
cb->args[0] = ifidx;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
*dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
|
||||
if (!*dev) {
|
||||
err = -ENODEV;
|
||||
goto out_rtnl;
|
||||
}
|
||||
|
||||
*rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
|
||||
if (IS_ERR(dev)) {
|
||||
err = PTR_ERR(dev);
|
||||
goto out_rtnl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out_rtnl:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
cfg80211_unlock_rdev(rdev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
/* IE validation */
|
||||
static bool is_valid_ie_attr(const struct nlattr *attr)
|
||||
{
|
||||
|
@ -1796,28 +1837,12 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
|||
struct cfg80211_registered_device *dev;
|
||||
struct net_device *netdev;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
int ifidx = cb->args[0];
|
||||
int sta_idx = cb->args[1];
|
||||
int err;
|
||||
|
||||
if (!ifidx)
|
||||
ifidx = nl80211_get_ifidx(cb);
|
||||
if (ifidx < 0)
|
||||
return ifidx;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
|
||||
if (!netdev) {
|
||||
err = -ENODEV;
|
||||
goto out_rtnl;
|
||||
}
|
||||
|
||||
dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
|
||||
if (IS_ERR(dev)) {
|
||||
err = PTR_ERR(dev);
|
||||
goto out_rtnl;
|
||||
}
|
||||
err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!dev->ops->dump_station) {
|
||||
err = -EOPNOTSUPP;
|
||||
|
@ -1847,9 +1872,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
|
|||
cb->args[1] = sta_idx;
|
||||
err = skb->len;
|
||||
out_err:
|
||||
cfg80211_unlock_rdev(dev);
|
||||
out_rtnl:
|
||||
rtnl_unlock();
|
||||
nl80211_finish_netdev_dump(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -2169,28 +2192,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
|||
struct net_device *netdev;
|
||||
u8 dst[ETH_ALEN];
|
||||
u8 next_hop[ETH_ALEN];
|
||||
int ifidx = cb->args[0];
|
||||
int path_idx = cb->args[1];
|
||||
int err;
|
||||
|
||||
if (!ifidx)
|
||||
ifidx = nl80211_get_ifidx(cb);
|
||||
if (ifidx < 0)
|
||||
return ifidx;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
|
||||
if (!netdev) {
|
||||
err = -ENODEV;
|
||||
goto out_rtnl;
|
||||
}
|
||||
|
||||
dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
|
||||
if (IS_ERR(dev)) {
|
||||
err = PTR_ERR(dev);
|
||||
goto out_rtnl;
|
||||
}
|
||||
err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!dev->ops->dump_mpath) {
|
||||
err = -EOPNOTSUPP;
|
||||
|
@ -2224,10 +2231,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
|
|||
cb->args[1] = path_idx;
|
||||
err = skb->len;
|
||||
out_err:
|
||||
cfg80211_unlock_rdev(dev);
|
||||
out_rtnl:
|
||||
rtnl_unlock();
|
||||
|
||||
nl80211_finish_netdev_dump(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -3034,25 +3038,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
|
|||
struct net_device *dev;
|
||||
struct cfg80211_internal_bss *scan;
|
||||
struct wireless_dev *wdev;
|
||||
int ifidx = cb->args[0];
|
||||
int start = cb->args[1], idx = 0;
|
||||
int err;
|
||||
|
||||
if (!ifidx)
|
||||
ifidx = nl80211_get_ifidx(cb);
|
||||
if (ifidx < 0)
|
||||
return ifidx;
|
||||
cb->args[0] = ifidx;
|
||||
|
||||
dev = dev_get_by_index(sock_net(skb->sk), ifidx);
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
|
||||
if (IS_ERR(rdev)) {
|
||||
err = PTR_ERR(rdev);
|
||||
goto out_put_netdev;
|
||||
}
|
||||
err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
wdev = dev->ieee80211_ptr;
|
||||
|
||||
|
@ -3068,21 +3059,17 @@ static int nl80211_dump_scan(struct sk_buff *skb,
|
|||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||
rdev, wdev, scan) < 0) {
|
||||
idx--;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&rdev->bss_lock);
|
||||
wdev_unlock(wdev);
|
||||
|
||||
cb->args[1] = idx;
|
||||
err = skb->len;
|
||||
cfg80211_unlock_rdev(rdev);
|
||||
out_put_netdev:
|
||||
dev_put(dev);
|
||||
nl80211_finish_netdev_dump(rdev);
|
||||
|
||||
return err;
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
|
||||
|
@ -3130,29 +3117,12 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|||
struct survey_info survey;
|
||||
struct cfg80211_registered_device *dev;
|
||||
struct net_device *netdev;
|
||||
int ifidx = cb->args[0];
|
||||
int survey_idx = cb->args[1];
|
||||
int res;
|
||||
|
||||
if (!ifidx)
|
||||
ifidx = nl80211_get_ifidx(cb);
|
||||
if (ifidx < 0)
|
||||
return ifidx;
|
||||
cb->args[0] = ifidx;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
|
||||
if (!netdev) {
|
||||
res = -ENODEV;
|
||||
goto out_rtnl;
|
||||
}
|
||||
|
||||
dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto out_rtnl;
|
||||
}
|
||||
res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (!dev->ops->dump_survey) {
|
||||
res = -EOPNOTSUPP;
|
||||
|
@ -3180,10 +3150,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
|
|||
cb->args[1] = survey_idx;
|
||||
res = skb->len;
|
||||
out_err:
|
||||
cfg80211_unlock_rdev(dev);
|
||||
out_rtnl:
|
||||
rtnl_unlock();
|
||||
|
||||
nl80211_finish_netdev_dump(dev);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue