summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-11-02 12:56:52 +0000
committerDavid S. Miller <davem@davemloft.net>2012-11-02 21:53:35 -0400
commit25b1e67921f448cdddf70042ba233ffe43d33a9c (patch)
tree80049b1fc9689f357c9fdaaa22c35fab8d3159c2
parent1a72418bd7f0edcb85c817964efd370254fe749d (diff)
net: Fix continued iteration in rtnl_bridge_getlink()
Commit e5a55a898720096f43bc24938f8875c0a1b34cd7 ('net: create generic bridge ops') broke the handling of a non-zero starting index in rtnl_bridge_getlink() (based on the old br_dump_ifinfo()). When the starting index is non-zero, we need to increment the current index for each entry that we are skipping. Also, we need to check the index before both cases, since we may previously have stopped iteration between getting information about a device from its master and from itself. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Tested-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/rtnetlink.c23
1 files changed, 7 insertions, 16 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 51dc58ff009..a0e350763fb 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2315,28 +2315,19 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
const struct net_device_ops *ops = dev->netdev_ops;
struct net_device *master = dev->master;
- if (idx < cb->args[0])
- continue;
-
if (master && master->netdev_ops->ndo_bridge_getlink) {
- const struct net_device_ops *bops = master->netdev_ops;
- int err = bops->ndo_bridge_getlink(skb, portid,
- seq, dev);
-
- if (err < 0)
+ if (idx >= cb->args[0] &&
+ master->netdev_ops->ndo_bridge_getlink(
+ skb, portid, seq, dev) < 0)
break;
- else
- idx++;
+ idx++;
}
if (ops->ndo_bridge_getlink) {
- int err = ops->ndo_bridge_getlink(skb, portid,
- seq, dev);
-
- if (err < 0)
+ if (idx >= cb->args[0] &&
+ ops->ndo_bridge_getlink(skb, portid, seq, dev) < 0)
break;
- else
- idx++;
+ idx++;
}
}
rcu_read_unlock();