After v3.6, output routes are cached, however, the 'rt_iif' field of struct rtable can not be shared by various traffics using SO_BINDTODEVICE. It causes that traffic can not reach the local receiver which also uses SO_BINDTODEVICE after another traffic creates a local route cache.
/* sender and receiver are running on same host. */ sender: - socket(SOCK_DGRAM) - setsockopt(SO_BINDTODEVICE, "eth0") - connect(INADDR_ANY) - send("message") ------>[loopback]------+ | receiver: | - socket(SOCK_DGRAM) | - setsockopt(SO_BINDTODEVICE, "eth0") | - bind(INADDR_ANY) | - recv() <------------------------------+ /* sometimes reach, sometimes not reach!!! */ Before v3.6, above traffics always reached. It seems to be a regression. Actually the 'dhcp_release' command relies on it. Commit 7bd86cc282a458b66c41e3f6 ("ipv4: Cache local output routes") originated this issue. Revert it conditionally. Signed-off-by: Kouya Shimura <ko...@jp.fujitsu.com> --- net/ipv4/route.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 02c6229..4b5e024 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2285,6 +2285,8 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4, } dev_out = net->loopback_dev; fl4->flowi4_oif = dev_out->ifindex; + if (orig_oif) + res.fi = NULL; flags |= RTCF_LOCAL; goto make_route; } -- 1.9.1