Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+59 −92
Original line number Original line Diff line number Diff line
@@ -198,6 +198,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb)
	return res;
	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 */
/* IE validation */
static bool is_valid_ie_attr(const struct nlattr *attr)
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 cfg80211_registered_device *dev;
	struct net_device *netdev;
	struct net_device *netdev;
	u8 mac_addr[ETH_ALEN];
	u8 mac_addr[ETH_ALEN];
	int ifidx = cb->args[0];
	int sta_idx = cb->args[1];
	int sta_idx = cb->args[1];
	int err;
	int err;


	if (!ifidx)
	err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
		ifidx = nl80211_get_ifidx(cb);
	if (err)
	if (ifidx < 0)
		return err;
		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;
	}


	if (!dev->ops->dump_station) {
	if (!dev->ops->dump_station) {
		err = -EOPNOTSUPP;
		err = -EOPNOTSUPP;
@@ -1847,9 +1872,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
	cb->args[1] = sta_idx;
	cb->args[1] = sta_idx;
	err = skb->len;
	err = skb->len;
 out_err:
 out_err:
	cfg80211_unlock_rdev(dev);
	nl80211_finish_netdev_dump(dev);
 out_rtnl:
	rtnl_unlock();


	return err;
	return err;
}
}
@@ -2169,28 +2192,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
	struct net_device *netdev;
	struct net_device *netdev;
	u8 dst[ETH_ALEN];
	u8 dst[ETH_ALEN];
	u8 next_hop[ETH_ALEN];
	u8 next_hop[ETH_ALEN];
	int ifidx = cb->args[0];
	int path_idx = cb->args[1];
	int path_idx = cb->args[1];
	int err;
	int err;


	if (!ifidx)
	err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
		ifidx = nl80211_get_ifidx(cb);
	if (err)
	if (ifidx < 0)
		return err;
		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;
	}


	if (!dev->ops->dump_mpath) {
	if (!dev->ops->dump_mpath) {
		err = -EOPNOTSUPP;
		err = -EOPNOTSUPP;
@@ -2224,10 +2231,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
	cb->args[1] = path_idx;
	cb->args[1] = path_idx;
	err = skb->len;
	err = skb->len;
 out_err:
 out_err:
	cfg80211_unlock_rdev(dev);
	nl80211_finish_netdev_dump(dev);
 out_rtnl:
	rtnl_unlock();

	return err;
	return err;
}
}


@@ -3034,25 +3038,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
	struct net_device *dev;
	struct net_device *dev;
	struct cfg80211_internal_bss *scan;
	struct cfg80211_internal_bss *scan;
	struct wireless_dev *wdev;
	struct wireless_dev *wdev;
	int ifidx = cb->args[0];
	int start = cb->args[1], idx = 0;
	int start = cb->args[1], idx = 0;
	int err;
	int err;


	if (!ifidx)
	err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
		ifidx = nl80211_get_ifidx(cb);
	if (err)
	if (ifidx < 0)
		return err;
		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;
	}


	wdev = dev->ieee80211_ptr;
	wdev = dev->ieee80211_ptr;


@@ -3068,21 +3059,17 @@ static int nl80211_dump_scan(struct sk_buff *skb,
				cb->nlh->nlmsg_seq, NLM_F_MULTI,
				cb->nlh->nlmsg_seq, NLM_F_MULTI,
				rdev, wdev, scan) < 0) {
				rdev, wdev, scan) < 0) {
			idx--;
			idx--;
			goto out;
			break;
		}
		}
	}
	}


 out:
	spin_unlock_bh(&rdev->bss_lock);
	spin_unlock_bh(&rdev->bss_lock);
	wdev_unlock(wdev);
	wdev_unlock(wdev);


	cb->args[1] = idx;
	cb->args[1] = idx;
	err = skb->len;
	nl80211_finish_netdev_dump(rdev);
	cfg80211_unlock_rdev(rdev);
 out_put_netdev:
	dev_put(dev);


	return err;
	return skb->len;
}
}


static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
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 survey_info survey;
	struct cfg80211_registered_device *dev;
	struct cfg80211_registered_device *dev;
	struct net_device *netdev;
	struct net_device *netdev;
	int ifidx = cb->args[0];
	int survey_idx = cb->args[1];
	int survey_idx = cb->args[1];
	int res;
	int res;


	if (!ifidx)
	res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
		ifidx = nl80211_get_ifidx(cb);
	if (res)
	if (ifidx < 0)
		return res;
		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;
	}


	if (!dev->ops->dump_survey) {
	if (!dev->ops->dump_survey) {
		res = -EOPNOTSUPP;
		res = -EOPNOTSUPP;
@@ -3180,10 +3150,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
	cb->args[1] = survey_idx;
	cb->args[1] = survey_idx;
	res = skb->len;
	res = skb->len;
 out_err:
 out_err:
	cfg80211_unlock_rdev(dev);
	nl80211_finish_netdev_dump(dev);
 out_rtnl:
	rtnl_unlock();

	return res;
	return res;
}
}