From e78190581aff7c96fbd6324aa633170934650b65 Mon Sep 17 00:00:00 2001 From: Mike Manning Date: Wed, 7 Nov 2018 15:36:03 +0000 Subject: net: ensure unbound stream socket to be chosen when not in a VRF The commit a04a480d4392 ("net: Require exact match for TCP socket lookups if dif is l3mdev") only ensures that the correct socket is selected for packets in a VRF. However, there is no guarantee that the unbound socket will be selected for packets when not in a VRF. By checking for a device match in compute_score() also for the case when there is no bound device and attaching a score to this, the unbound socket is selected. And if a failure is returned when there is no device match, this ensures that bound sockets are never selected, even if there is no unbound socket. Signed-off-by: Mike Manning Reviewed-by: David Ahern Tested-by: David Ahern Signed-off-by: David S. Miller --- include/net/inet_hashtables.h | 11 +++++++++++ include/net/inet_sock.h | 8 ++++++++ 2 files changed, 19 insertions(+) (limited to 'include') diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 4ae060b4bac2..0ce460e93dc4 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -189,6 +189,17 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo) hashinfo->ehash_locks = NULL; } +static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if, + int dif, int sdif) +{ +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) + return inet_bound_dev_eq(!!net->ipv4.sysctl_tcp_l3mdev_accept, + bound_dev_if, dif, sdif); +#else + return inet_bound_dev_eq(true, bound_dev_if, dif, sdif); +#endif +} + struct inet_bind_bucket * inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net, struct inet_bind_hashbucket *head, diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index ed3f723af00b..e8eef85006aa 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -143,6 +143,14 @@ static inline int inet_sk_bound_l3mdev(const struct sock *sk) return 0; } +static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if, + int dif, int sdif) +{ + if (!bound_dev_if) + return !sdif || l3mdev_accept; + return bound_dev_if == dif || bound_dev_if == sdif; +} + struct inet_cork { unsigned int flags; __be32 addr; -- cgit v1.2.3-59-g8ed1b