Skip to content

Commit b7c8487

Browse files
rshearmandavem330
authored andcommitted
ipv4: Avoid caching l3mdev dst on mismatched local route
David reported that doing the following: ip li add red type vrf table 10 ip link set dev eth1 vrf red ip addr add 127.0.0.1/8 dev red ip link set dev eth1 up ip li set red up ping -c1 -w1 -I red 127.0.0.1 ip li del red when either policy routing IP rules are present or the local table lookup ip rule is before the l3mdev lookup results in a hang with these messages: unregister_netdevice: waiting for red to become free. Usage count = 1 The problem is caused by caching the dst used for sending the packet out of the specified interface on a local route with a different nexthop interface. Thus the dst could stay around until the route in the table the lookup was done is deleted which may be never. Address the problem by not forcing output device to be the l3mdev in the flow's output interface if the lookup didn't use the l3mdev. This then results in the dst using the right device according to the route. Changes in v2: - make the dev_out passed in by __ip_route_output_key_hash correct instead of checking the nh dev if FLOWI_FLAG_SKIP_NH_OIF is set as suggested by David. Fixes: 5f02ce2 ("net: l3mdev: Allow the l3mdev to be a loopback") Reported-by: David Ahern <[email protected]> Suggested-by: David Ahern <[email protected]> Signed-off-by: Robert Shearman <[email protected]> Acked-by: David Ahern <[email protected]> Tested-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 11faa7b commit b7c8487

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

net/ipv4/route.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2359,7 +2359,8 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
23592359
}
23602360

23612361
/* L3 master device is the loopback for that domain */
2362-
dev_out = l3mdev_master_dev_rcu(dev_out) ? : net->loopback_dev;
2362+
dev_out = l3mdev_master_dev_rcu(FIB_RES_DEV(res)) ? :
2363+
net->loopback_dev;
23632364
fl4->flowi4_oif = dev_out->ifindex;
23642365
flags |= RTCF_LOCAL;
23652366
goto make_route;

0 commit comments

Comments
 (0)