aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-10-04 15:14:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-05 13:37:51 -0400
commit6774889314ba507483e63c014fcb81adfc127202 (patch)
tree698dcdc2e1d26b3bd5595bba2a553b6107ee1a07 /net/wireless/nl80211.c
parent41265714810e20d91ddd7aaca30043b0f12190ad (diff)
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>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c151
1 files changed, 59 insertions, 92 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ca8d04cb172f..0c9497170f1f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -198,6 +198,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb)
198 return res; 198 return res;
199} 199}
200 200
201static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
202 struct netlink_callback *cb,
203 struct cfg80211_registered_device **rdev,
204 struct net_device **dev)
205{
206 int ifidx = cb->args[0];
207 int err;
208
209 if (!ifidx)
210 ifidx = nl80211_get_ifidx(cb);
211 if (ifidx < 0)
212 return ifidx;
213
214 cb->args[0] = ifidx;
215
216 rtnl_lock();
217
218 *dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
219 if (!*dev) {
220 err = -ENODEV;
221 goto out_rtnl;
222 }
223
224 *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
225 if (IS_ERR(dev)) {
226 err = PTR_ERR(dev);
227 goto out_rtnl;
228 }
229
230 return 0;
231 out_rtnl:
232 rtnl_unlock();
233 return err;
234}
235
236static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
237{
238 cfg80211_unlock_rdev(rdev);
239 rtnl_unlock();
240}
241
201/* IE validation */ 242/* IE validation */
202static bool is_valid_ie_attr(const struct nlattr *attr) 243static bool is_valid_ie_attr(const struct nlattr *attr)
203{ 244{
@@ -1796,28 +1837,12 @@ static int nl80211_dump_station(struct sk_buff *skb,
1796 struct cfg80211_registered_device *dev; 1837 struct cfg80211_registered_device *dev;
1797 struct net_device *netdev; 1838 struct net_device *netdev;
1798 u8 mac_addr[ETH_ALEN]; 1839 u8 mac_addr[ETH_ALEN];
1799 int ifidx = cb->args[0];
1800 int sta_idx = cb->args[1]; 1840 int sta_idx = cb->args[1];
1801 int err; 1841 int err;
1802 1842
1803 if (!ifidx) 1843 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
1804 ifidx = nl80211_get_ifidx(cb); 1844 if (err)
1805 if (ifidx < 0) 1845 return err;
1806 return ifidx;
1807
1808 rtnl_lock();
1809
1810 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
1811 if (!netdev) {
1812 err = -ENODEV;
1813 goto out_rtnl;
1814 }
1815
1816 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
1817 if (IS_ERR(dev)) {
1818 err = PTR_ERR(dev);
1819 goto out_rtnl;
1820 }
1821 1846
1822 if (!dev->ops->dump_station) { 1847 if (!dev->ops->dump_station) {
1823 err = -EOPNOTSUPP; 1848 err = -EOPNOTSUPP;
@@ -1847,9 +1872,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
1847 cb->args[1] = sta_idx; 1872 cb->args[1] = sta_idx;
1848 err = skb->len; 1873 err = skb->len;
1849 out_err: 1874 out_err:
1850 cfg80211_unlock_rdev(dev); 1875 nl80211_finish_netdev_dump(dev);
1851 out_rtnl:
1852 rtnl_unlock();
1853 1876
1854 return err; 1877 return err;
1855} 1878}
@@ -2169,28 +2192,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2169 struct net_device *netdev; 2192 struct net_device *netdev;
2170 u8 dst[ETH_ALEN]; 2193 u8 dst[ETH_ALEN];
2171 u8 next_hop[ETH_ALEN]; 2194 u8 next_hop[ETH_ALEN];
2172 int ifidx = cb->args[0];
2173 int path_idx = cb->args[1]; 2195 int path_idx = cb->args[1];
2174 int err; 2196 int err;
2175 2197
2176 if (!ifidx) 2198 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
2177 ifidx = nl80211_get_ifidx(cb); 2199 if (err)
2178 if (ifidx < 0) 2200 return err;
2179 return ifidx;
2180
2181 rtnl_lock();
2182
2183 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
2184 if (!netdev) {
2185 err = -ENODEV;
2186 goto out_rtnl;
2187 }
2188
2189 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
2190 if (IS_ERR(dev)) {
2191 err = PTR_ERR(dev);
2192 goto out_rtnl;
2193 }
2194 2201
2195 if (!dev->ops->dump_mpath) { 2202 if (!dev->ops->dump_mpath) {
2196 err = -EOPNOTSUPP; 2203 err = -EOPNOTSUPP;
@@ -2224,10 +2231,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2224 cb->args[1] = path_idx; 2231 cb->args[1] = path_idx;
2225 err = skb->len; 2232 err = skb->len;
2226 out_err: 2233 out_err:
2227 cfg80211_unlock_rdev(dev); 2234 nl80211_finish_netdev_dump(dev);
2228 out_rtnl:
2229 rtnl_unlock();
2230
2231 return err; 2235 return err;
2232} 2236}
2233 2237
@@ -3034,25 +3038,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3034 struct net_device *dev; 3038 struct net_device *dev;
3035 struct cfg80211_internal_bss *scan; 3039 struct cfg80211_internal_bss *scan;
3036 struct wireless_dev *wdev; 3040 struct wireless_dev *wdev;
3037 int ifidx = cb->args[0];
3038 int start = cb->args[1], idx = 0; 3041 int start = cb->args[1], idx = 0;
3039 int err; 3042 int err;
3040 3043
3041 if (!ifidx) 3044 err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
3042 ifidx = nl80211_get_ifidx(cb); 3045 if (err)
3043 if (ifidx < 0) 3046 return err;
3044 return ifidx;
3045 cb->args[0] = ifidx;
3046
3047 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3048 if (!dev)
3049 return -ENODEV;
3050
3051 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3052 if (IS_ERR(rdev)) {
3053 err = PTR_ERR(rdev);
3054 goto out_put_netdev;
3055 }
3056 3047
3057 wdev = dev->ieee80211_ptr; 3048 wdev = dev->ieee80211_ptr;
3058 3049
@@ -3068,21 +3059,17 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3068 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3059 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3069 rdev, wdev, scan) < 0) { 3060 rdev, wdev, scan) < 0) {
3070 idx--; 3061 idx--;
3071 goto out; 3062 break;
3072 } 3063 }
3073 } 3064 }
3074 3065
3075 out:
3076 spin_unlock_bh(&rdev->bss_lock); 3066 spin_unlock_bh(&rdev->bss_lock);
3077 wdev_unlock(wdev); 3067 wdev_unlock(wdev);
3078 3068
3079 cb->args[1] = idx; 3069 cb->args[1] = idx;
3080 err = skb->len; 3070 nl80211_finish_netdev_dump(rdev);
3081 cfg80211_unlock_rdev(rdev);
3082 out_put_netdev:
3083 dev_put(dev);
3084 3071
3085 return err; 3072 return skb->len;
3086} 3073}
3087 3074
3088static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, 3075static 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,
3130 struct survey_info survey; 3117 struct survey_info survey;
3131 struct cfg80211_registered_device *dev; 3118 struct cfg80211_registered_device *dev;
3132 struct net_device *netdev; 3119 struct net_device *netdev;
3133 int ifidx = cb->args[0];
3134 int survey_idx = cb->args[1]; 3120 int survey_idx = cb->args[1];
3135 int res; 3121 int res;
3136 3122
3137 if (!ifidx) 3123 res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
3138 ifidx = nl80211_get_ifidx(cb); 3124 if (res)
3139 if (ifidx < 0) 3125 return res;
3140 return ifidx;
3141 cb->args[0] = ifidx;
3142
3143 rtnl_lock();
3144
3145 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3146 if (!netdev) {
3147 res = -ENODEV;
3148 goto out_rtnl;
3149 }
3150
3151 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3152 if (IS_ERR(dev)) {
3153 res = PTR_ERR(dev);
3154 goto out_rtnl;
3155 }
3156 3126
3157 if (!dev->ops->dump_survey) { 3127 if (!dev->ops->dump_survey) {
3158 res = -EOPNOTSUPP; 3128 res = -EOPNOTSUPP;
@@ -3180,10 +3150,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3180 cb->args[1] = survey_idx; 3150 cb->args[1] = survey_idx;
3181 res = skb->len; 3151 res = skb->len;
3182 out_err: 3152 out_err:
3183 cfg80211_unlock_rdev(dev); 3153 nl80211_finish_netdev_dump(dev);
3184 out_rtnl:
3185 rtnl_unlock();
3186
3187 return res; 3154 return res;
3188} 3155}
3189 3156