net: make for_each_netdev_dump() a little more bug-proof
commit f22b4b55edb507a2b30981e133b66b642be4d13f upstream. I find the behavior of xa_for_each_start() slightly counter-intuitive. It doesn't end the iteration by making the index point after the last element. IOW calling xa_for_each_start() again after it "finished" will run the body of the loop for the last valid element, instead of doing nothing. This works fine for netlink dumps if they terminate correctly (i.e. coalesce or carefully handle NLM_DONE), but as we keep getting reminded legacy dumps are unlikely to go away. Fixing this generically at the xa_for_each_start() level seems hard - there is no index reserved for "end of iteration". ifindexes are 31b wide, tho, and iterator is ulong so for for_each_netdev_dump() it's safe to go to the next element. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net> [ The mctp RTM_GETADDR rework backport ofacab78ae12
("net: mctp: Don't access ifa_index when missing") pulled2d45eeb7d5
("mctp: no longer rely on net->dev_index_head[]") as a dependency. However, that change relies on this backport for correct behaviour of for_each_netdev_dump(). Jakub mentions[1] that nothing should be relying on the old behaviour of for_each_netdev_dump(), hence the backport. [1]: https://lore.kernel.org/netdev/20250609083749.741c27f5@kernel.org/ ] Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b8ced2b9a2
commit
cfa7fa0207
@@ -3036,7 +3036,8 @@ extern rwlock_t dev_base_lock; /* Device list lock */
|
|||||||
#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
|
#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
|
||||||
|
|
||||||
#define for_each_netdev_dump(net, d, ifindex) \
|
#define for_each_netdev_dump(net, d, ifindex) \
|
||||||
xa_for_each_start(&(net)->dev_by_index, (ifindex), (d), (ifindex))
|
for (; (d = xa_find(&(net)->dev_by_index, &ifindex, \
|
||||||
|
ULONG_MAX, XA_PRESENT)); ifindex++)
|
||||||
|
|
||||||
static inline struct net_device *next_net_device(struct net_device *dev)
|
static inline struct net_device *next_net_device(struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user