Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ben Hutchings and committed by
David S. Miller
25b1e679 1a72418b

+7 -16
+7 -16
net/core/rtnetlink.c
··· 2315 2315 const struct net_device_ops *ops = dev->netdev_ops; 2316 2316 struct net_device *master = dev->master; 2317 2317 2318 - if (idx < cb->args[0]) 2319 - continue; 2320 - 2321 2318 if (master && master->netdev_ops->ndo_bridge_getlink) { 2322 - const struct net_device_ops *bops = master->netdev_ops; 2323 - int err = bops->ndo_bridge_getlink(skb, portid, 2324 - seq, dev); 2325 - 2326 - if (err < 0) 2319 + if (idx >= cb->args[0] && 2320 + master->netdev_ops->ndo_bridge_getlink( 2321 + skb, portid, seq, dev) < 0) 2327 2322 break; 2328 - else 2329 - idx++; 2323 + idx++; 2330 2324 } 2331 2325 2332 2326 if (ops->ndo_bridge_getlink) { 2333 - int err = ops->ndo_bridge_getlink(skb, portid, 2334 - seq, dev); 2335 - 2336 - if (err < 0) 2327 + if (idx >= cb->args[0] && 2328 + ops->ndo_bridge_getlink(skb, portid, seq, dev) < 0) 2337 2329 break; 2338 - else 2339 - idx++; 2330 + idx++; 2340 2331 } 2341 2332 } 2342 2333 rcu_read_unlock();