diff options
author | Johannes Berg <johannes.berg@intel.com> | 2015-01-19 06:15:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-19 16:20:17 -0500 |
commit | 926e9878a360fc57112259949c44c74c31709cc6 (patch) | |
tree | 156970a8248c5512200df2718c242bb3535d74ef /net | |
parent | fc83477780174dc6aa673e644428b1d2f3894e7a (diff) |
phonet netlink: allow multiple messages per skb in route dump
My previous patch to this file changed the code to be bug-compatible
towards userspace. Unless userspace (which I wasn't able to find)
implements the dump reader by hand in a wrong way, this isn't needed.
If it uses libnl or similar code putting multiple messages into a
single SKB is far more efficient.
Change the code to do this. While at it, also clean it up and don't
use so many variables - just store the address in the callback args
directly.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/phonet/pn_netlink.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index 54d766842c2b..bc5ee5fbe6ae 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -272,31 +272,23 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
272 | static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb) | 272 | static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb) |
273 | { | 273 | { |
274 | struct net *net = sock_net(skb->sk); | 274 | struct net *net = sock_net(skb->sk); |
275 | u8 addr, addr_idx = 0, addr_start_idx = cb->args[0]; | 275 | u8 addr; |
276 | 276 | ||
277 | rcu_read_lock(); | 277 | rcu_read_lock(); |
278 | for (addr = 0; addr < 64; addr++) { | 278 | for (addr = cb->args[0]; addr < 64; addr++) { |
279 | struct net_device *dev; | 279 | struct net_device *dev = phonet_route_get_rcu(net, addr << 2); |
280 | 280 | ||
281 | dev = phonet_route_get_rcu(net, addr << 2); | ||
282 | if (!dev) | 281 | if (!dev) |
283 | continue; | 282 | continue; |
284 | 283 | ||
285 | if (addr_idx++ < addr_start_idx) | 284 | if (fill_route(skb, dev, addr << 2, NETLINK_CB(cb->skb).portid, |
286 | continue; | 285 | cb->nlh->nlmsg_seq, RTM_NEWROUTE) < 0) |
287 | fill_route(skb, dev, addr << 2, NETLINK_CB(cb->skb).portid, | 286 | goto out; |
288 | cb->nlh->nlmsg_seq, RTM_NEWROUTE); | ||
289 | /* fill_route() used to return > 0 (or negative errors) but | ||
290 | * never 0 - ignore the return value and just go out to | ||
291 | * call dumpit again from outside to preserve the behavior | ||
292 | */ | ||
293 | goto out; | ||
294 | } | 287 | } |
295 | 288 | ||
296 | out: | 289 | out: |
297 | rcu_read_unlock(); | 290 | rcu_read_unlock(); |
298 | cb->args[0] = addr_idx; | 291 | cb->args[0] = addr; |
299 | cb->args[1] = 0; | ||
300 | 292 | ||
301 | return skb->len; | 293 | return skb->len; |
302 | } | 294 | } |