Commit 89246ef8 authored by Petr Machata's avatar Petr Machata Committed by Jakub Kicinski
Browse files

net: core: neighbour: Process ARP queue later



ARP queue processing unlocks the neighbor lock, which can allow another
thread to asynchronously perform a neighbor update and send an out of order
notification. Therefore this needs to be done after the notification is
sent.

Move it just before the end of the critical section. Since
neigh_update_process_arp_queue() unlocks, it does not form a part of the
critical section anymore but it can benefit from the lock being taken. The
intention is to eventually do the RTNL notification before this call.

This motion crosses a call to neigh_update_is_router(), which should not
influence processing of the ARP queue.

Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/9ea7159e71430ebdc837ebcc880a76b7e82e52a4.1769012464.git.petrm@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 705ef89a
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1369,6 +1369,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
			  struct netlink_ext_ack *extack)
{
	bool gc_update = false, managed_update = false;
	bool process_arp_queue = false;
	int update_isrouter = 0;
	struct net_device *dev;
	int err, notify = 0;
@@ -1504,12 +1505,17 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
		neigh_suspect(neigh);

	if (!(old & NUD_VALID))
		neigh_update_process_arp_queue(neigh);
		process_arp_queue = true;

out:
	if (update_isrouter)
		neigh_update_is_router(neigh, flags, &notify);

	if (process_arp_queue)
		neigh_update_process_arp_queue(neigh);

	write_unlock_bh(&neigh->lock);

	if (((new ^ old) & NUD_PERMANENT) || gc_update)
		neigh_update_gc_list(neigh);
	if (managed_update)