Commit 67748893 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

nl80211: reduce dumping boilerplate

Consolidate boilerplate code needed for .dumpit
calls operating on netdevs.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 41265714
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment