On Thu, 2016-10-13 at 13:14 -0700, David Ahern wrote: > Currently, socket lookups for l3mdev (vrf) use cases can match a socket > that is bound to a port but not a device (ie., a global socket). If the > sysctl tcp_l3mdev_accept is not set this leads to ack packets going out > based on the main table even though the packet came in from an L3 domain. > The end result is that the connection does not establish creating > confusion for users since the service is running and a socket shows in > ss output. Fix by requiring an exact dif to sk_bound_dev_if match if the > dif is an l3mdev device and the tcp_l3mdev_accept is not set. > > Fixes: 193125dbd8eb ("net: Introduce VRF device driver") > Signed-off-by: David Ahern <d...@cumulusnetworks.com> > --- > include/net/inet_sock.h | 10 ++++++++++ > net/ipv4/inet_hashtables.c | 7 ++++--- > net/ipv6/inet6_hashtables.c | 7 ++++--- > 3 files changed, 18 insertions(+), 6 deletions(-) > > diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h > index 236a81034fef..abb4e720a769 100644 > --- a/include/net/inet_sock.h > +++ b/include/net/inet_sock.h > @@ -132,6 +132,16 @@ static inline int inet_request_bound_dev_if(const struct > sock *sk, > return sk->sk_bound_dev_if; > } > > +static inline bool inet_exact_dif_match(struct net *net, int dif) > +{ > +#ifdef CONFIG_NET_L3_MASTER_DEV > + if (netif_index_is_l3_master(net, dif) && > + !net->ipv4.sysctl_tcp_l3mdev_accept) > + return true;
Since netif_index_is_l3_master() is not cheap, can you reorder the test ? if (!net->ipv4.sysctl_tcp_l3mdev_accept) return netif_index_is_l3_master(net, dif);