From: Guillaume Nault Date: Fri, 6 Jan 2017 19:03:57 +0000 (+0100) Subject: l2tp: rework socket comparison in __l2tp_ip*_bind_lookup() X-Git-Tag: v4.11-rc1~94^2~75^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c5fdae044030f753c9e6a3efa8db28fe00f8fdad;p=platform%2Fkernel%2Flinux-exynos.git l2tp: rework socket comparison in __l2tp_ip*_bind_lookup() Split conditions, so that each test becomes clearer. Also, for l2tp_ip, check if "laddr" is 0. This prevents a socket from binding to the unspecified address when other sockets are already bound using the same device (if any), connection ID and namespace. Same thing for l2tp_ip6: add ipv6_addr_any(laddr) and ipv6_addr_any(raddr) tests to ensure that an IPv6 unspecified address passed as parameter is properly treated a wildcard. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller --- diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 499d3cd..b07a859 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -56,13 +56,23 @@ static struct sock *__l2tp_ip_bind_lookup(const struct net *net, __be32 laddr, const struct l2tp_ip_sock *l2tp = l2tp_ip_sk(sk); const struct inet_sock *inet = inet_sk(sk); - if ((l2tp->conn_id == tunnel_id) && - net_eq(sock_net(sk), net) && - !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && - (!inet->inet_daddr || !raddr || inet->inet_daddr == raddr) && - (!sk->sk_bound_dev_if || !dif || - sk->sk_bound_dev_if == dif)) - goto found; + if (!net_eq(sock_net(sk), net)) + continue; + + if (sk->sk_bound_dev_if && dif && sk->sk_bound_dev_if != dif) + continue; + + if (inet->inet_rcv_saddr && laddr && + inet->inet_rcv_saddr != laddr) + continue; + + if (inet->inet_daddr && raddr && inet->inet_daddr != raddr) + continue; + + if (l2tp->conn_id != tunnel_id) + continue; + + goto found; } sk = NULL; diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 7165b06..4b06eb4 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -69,13 +69,24 @@ static struct sock *__l2tp_ip6_bind_lookup(const struct net *net, const struct in6_addr *sk_raddr = &sk->sk_v6_daddr; const struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk); - if ((l2tp->conn_id == tunnel_id) && - net_eq(sock_net(sk), net) && - (!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) && - (!raddr || ipv6_addr_any(sk_raddr) || ipv6_addr_equal(sk_raddr, raddr)) && - (!sk->sk_bound_dev_if || !dif || - sk->sk_bound_dev_if == dif)) - goto found; + if (!net_eq(sock_net(sk), net)) + continue; + + if (sk->sk_bound_dev_if && dif && sk->sk_bound_dev_if != dif) + continue; + + if (sk_laddr && !ipv6_addr_any(sk_laddr) && + !ipv6_addr_any(laddr) && !ipv6_addr_equal(sk_laddr, laddr)) + continue; + + if (!ipv6_addr_any(sk_raddr) && raddr && + !ipv6_addr_any(raddr) && !ipv6_addr_equal(sk_raddr, raddr)) + continue; + + if (l2tp->conn_id != tunnel_id) + continue; + + goto found; } sk = NULL;