nl80211: reduce dumping boilerplate
authorJohannes Berg <johannes.berg@intel.com>
Mon, 4 Oct 2010 19:14:06 +0000 (21:14 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 5 Oct 2010 17:37:51 +0000 (13:37 -0400)
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>
net/wireless/nl80211.c

index ca8d04c..0c94971 100644 (file)
@@ -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;
 }