aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-11-02 08:56:52 -0400
committerDavid S. Miller <davem@davemloft.net>2012-11-02 21:53:35 -0400
commit25b1e67921f448cdddf70042ba233ffe43d33a9c (patch)
tree80049b1fc9689f357c9fdaaa22c35fab8d3159c2 /net/core/rtnetlink.c
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>
Diffstat (limited to 'net/core/rtnetlink.c')
-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 51dc58ff0091..a0e350763fbe 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)
2315 const struct net_device_ops *ops = dev->netdev_ops; 2315 const struct net_device_ops *ops = dev->netdev_ops;
2316 struct net_device *master = dev->master; 2316 struct net_device *master = dev->master;
2317 2317
2318 if (idx < cb->args[0])
2319 continue;
2320
2321 if (master && master->netdev_ops->ndo_bridge_getlink) { 2318 if (master && master->netdev_ops->ndo_bridge_getlink) {
2322 const struct net_device_ops *bops = master->netdev_ops; 2319 if (idx >= cb->args[0] &&
2323 int err = bops->ndo_bridge_getlink(skb, portid, 2320 master->netdev_ops->ndo_bridge_getlink(
2324 seq, dev); 2321 skb, portid, seq, dev) < 0)
2325
2326 if (err < 0)
2327 break; 2322 break;
2328 else 2323 idx++;
2329 idx++;
2330 } 2324 }
2331 2325
2332 if (ops->ndo_bridge_getlink) { 2326 if (ops->ndo_bridge_getlink) {
2333 int err = ops->ndo_bridge_getlink(skb, portid, 2327 if (idx >= cb->args[0] &&
2334 seq, dev); 2328 ops->ndo_bridge_getlink(skb, portid, seq, dev) < 0)
2335
2336 if (err < 0)
2337 break; 2329 break;
2338 else 2330 idx++;
2339 idx++;
2340 } 2331 }
2341 } 2332 }
2342 rcu_read_unlock(); 2333 rcu_read_unlock();