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 <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
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;