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>
This commit is contained in:
Родитель
986f7cbc51
Коммит
c5fdae0440
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче