From: David Ahern <dsah...@gmail.com> Date: Thu, 10 Aug 2017 13:49:10 -0700
> Attempts to connect to a local address with a socket bound > to a device with the local address hangs if there is no listener: > > $ ip addr sh dev eth1 > 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group > default qlen 1000 > link/ether 02:e0:f9:1c:00:37 brd ff:ff:ff:ff:ff:ff > inet 10.100.1.4/24 scope global eth1 > valid_lft forever preferred_lft forever > inet6 2001:db8:1::4/120 scope global > valid_lft forever preferred_lft forever > inet6 fe80::e0:f9ff:fe1c:37/64 scope link > valid_lft forever preferred_lft forever > > $ vrf-test -I eth1 -r 10.100.1.4 > <hangs when there is no server> > > (don't let the command name fool you; vrf-test works without vrfs.) > > The problem is that the original intended device, eth1 in this case, is > lost when the tcp reset is sent, so the socket lookup does not find a > match for the reset and the connect attempt hangs. Fix by adjusting > orig_oif for local traffic to the device from the fib lookup result. > > With this patch you get the more user friendly: > $ vrf-test -I eth1 -r 10.100.1.4 > connect failed: 111: Connection refused > > orig_oif is saved to the newly created rtable as rt_iif and when set > it is used as the dif for socket lookups. It is set based on flowi4_oif > passed in to ip_route_output_key_hash_rcu and will be set to either > the loopback device, an l3mdev device, nothing (flowi4_oif = 0 which > is the case in the example above) or a netdev index depending on the > lookup path. In each case, resetting orig_oif to the device in the fib > result for the RTN_LOCAL case allows the actual device to be preserved > as the skb tx and rx is done over the loopback or VRF device. > > Signed-off-by: David Ahern <dsah...@gmail.com> > --- > As far as I can tell the current behavior goes back to the 2.6 days > at least. Not sure it is worth adding to stable branches. Applied, thanks David.