diff options
-rw-r--r-- | net/ipv6/addrconf.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 024bba30de21..f9f7fd6ee1f3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3823,28 +3823,39 @@ nla_put_failure: | |||
3823 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 3823 | static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
3824 | { | 3824 | { |
3825 | struct net *net = sock_net(skb->sk); | 3825 | struct net *net = sock_net(skb->sk); |
3826 | int idx, err; | 3826 | int h, s_h; |
3827 | int s_idx = cb->args[0]; | 3827 | int idx = 0, err, s_idx; |
3828 | struct net_device *dev; | 3828 | struct net_device *dev; |
3829 | struct inet6_dev *idev; | 3829 | struct inet6_dev *idev; |
3830 | struct hlist_head *head; | ||
3831 | struct hlist_node *node; | ||
3830 | 3832 | ||
3831 | read_lock(&dev_base_lock); | 3833 | s_h = cb->args[0]; |
3832 | idx = 0; | 3834 | s_idx = cb->args[1]; |
3833 | for_each_netdev(net, dev) { | 3835 | |
3834 | if (idx < s_idx) | 3836 | rcu_read_lock(); |
3835 | goto cont; | 3837 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { |
3836 | if ((idev = in6_dev_get(dev)) == NULL) | 3838 | idx = 0; |
3837 | goto cont; | 3839 | head = &net->dev_index_head[h]; |
3838 | err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, | 3840 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
3839 | cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); | 3841 | if (idx < s_idx) |
3840 | in6_dev_put(idev); | 3842 | goto cont; |
3841 | if (err <= 0) | 3843 | idev = __in6_dev_get(dev); |
3842 | break; | 3844 | if (!idev) |
3845 | goto cont; | ||
3846 | if (inet6_fill_ifinfo(skb, idev, | ||
3847 | NETLINK_CB(cb->skb).pid, | ||
3848 | cb->nlh->nlmsg_seq, | ||
3849 | RTM_NEWLINK, NLM_F_MULTI) <= 0) | ||
3850 | goto out; | ||
3843 | cont: | 3851 | cont: |
3844 | idx++; | 3852 | idx++; |
3853 | } | ||
3845 | } | 3854 | } |
3846 | read_unlock(&dev_base_lock); | 3855 | out: |
3847 | cb->args[0] = idx; | 3856 | rcu_read_unlock(); |
3857 | cb->args[1] = idx; | ||
3858 | cb->args[0] = h; | ||
3848 | 3859 | ||
3849 | return skb->len; | 3860 | return skb->len; |
3850 | } | 3861 | } |