diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-10-04 15:14:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-05 13:37:51 -0400 |
commit | 6774889314ba507483e63c014fcb81adfc127202 (patch) | |
tree | 698dcdc2e1d26b3bd5595bba2a553b6107ee1a07 /net/wireless/nl80211.c | |
parent | 41265714810e20d91ddd7aaca30043b0f12190ad (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.c | 151 |
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 | ||
201 | static 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 | |||
236 | static 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 */ |
202 | static bool is_valid_ie_attr(const struct nlattr *attr) | 243 | static 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 | ||
3088 | static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, | 3075 | 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, | |||
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 | ||