Skip to content

Commit eb7903b

Browse files
committed
Merge branch 'l2tp-socket-lookup-fixes'
Guillaume Nault says: ==================== l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 There are still some cases that aren't correctly handled in the socket lookup functions of l2tp_ip and l2tp_ip6. This series fixes lookups for connected sockets and for sockets bound to the IPv6 unspecified address. bind() and connect() should now work as expected on IPPROTO_L2TP sockets. Extra features, like SO_REUSEADDR, remain unsupported. The matching conditions in __l2tp_ip6_bind_lookup() and __l2tp_ip_bind_lookup() are getting hard to read. I've kept the single test approach to make the intend of the patches clear. I'll split the conditionals once these fixes reach net-next. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 4200462 + a9b2dff commit eb7903b

File tree

2 files changed

+14
-29
lines changed

2 files changed

+14
-29
lines changed

net/l2tp/l2tp_ip.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ static inline struct l2tp_ip_sock *l2tp_ip_sk(const struct sock *sk)
4747
return (struct l2tp_ip_sock *)sk;
4848
}
4949

50-
static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id)
50+
static struct sock *__l2tp_ip_bind_lookup(const struct net *net, __be32 laddr,
51+
__be32 raddr, int dif, u32 tunnel_id)
5152
{
5253
struct sock *sk;
5354

@@ -61,6 +62,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
6162
if ((l2tp->conn_id == tunnel_id) &&
6263
net_eq(sock_net(sk), net) &&
6364
!(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
65+
(!inet->inet_daddr || !raddr || inet->inet_daddr == raddr) &&
6466
(!sk->sk_bound_dev_if || !dif ||
6567
sk->sk_bound_dev_if == dif))
6668
goto found;
@@ -71,15 +73,6 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
7173
return sk;
7274
}
7375

74-
static inline struct sock *l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id)
75-
{
76-
struct sock *sk = __l2tp_ip_bind_lookup(net, laddr, dif, tunnel_id);
77-
if (sk)
78-
sock_hold(sk);
79-
80-
return sk;
81-
}
82-
8376
/* When processing receive frames, there are two cases to
8477
* consider. Data frames consist of a non-zero session-id and an
8578
* optional cookie. Control frames consist of a regular L2TP header
@@ -183,8 +176,8 @@ static int l2tp_ip_recv(struct sk_buff *skb)
183176
struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
184177

185178
read_lock_bh(&l2tp_ip_lock);
186-
sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb),
187-
tunnel_id);
179+
sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr,
180+
inet_iif(skb), tunnel_id);
188181
if (!sk) {
189182
read_unlock_bh(&l2tp_ip_lock);
190183
goto discard;
@@ -280,7 +273,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
280273
inet->inet_saddr = 0; /* Use device */
281274

282275
write_lock_bh(&l2tp_ip_lock);
283-
if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
276+
if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr, 0,
284277
sk->sk_bound_dev_if, addr->l2tp_conn_id)) {
285278
write_unlock_bh(&l2tp_ip_lock);
286279
ret = -EADDRINUSE;

net/l2tp/l2tp_ip6.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,23 @@ static inline struct l2tp_ip6_sock *l2tp_ip6_sk(const struct sock *sk)
5959

6060
static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
6161
struct in6_addr *laddr,
62+
const struct in6_addr *raddr,
6263
int dif, u32 tunnel_id)
6364
{
6465
struct sock *sk;
6566

6667
sk_for_each_bound(sk, &l2tp_ip6_bind_table) {
67-
const struct in6_addr *addr = inet6_rcv_saddr(sk);
68+
const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk);
69+
const struct in6_addr *sk_raddr = &sk->sk_v6_daddr;
6870
struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
6971

7072
if (l2tp == NULL)
7173
continue;
7274

7375
if ((l2tp->conn_id == tunnel_id) &&
7476
net_eq(sock_net(sk), net) &&
75-
(!addr || ipv6_addr_equal(addr, laddr)) &&
77+
(!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) &&
78+
(!raddr || ipv6_addr_any(sk_raddr) || ipv6_addr_equal(sk_raddr, raddr)) &&
7679
(!sk->sk_bound_dev_if || !dif ||
7780
sk->sk_bound_dev_if == dif))
7881
goto found;
@@ -83,17 +86,6 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
8386
return sk;
8487
}
8588

86-
static inline struct sock *l2tp_ip6_bind_lookup(struct net *net,
87-
struct in6_addr *laddr,
88-
int dif, u32 tunnel_id)
89-
{
90-
struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id);
91-
if (sk)
92-
sock_hold(sk);
93-
94-
return sk;
95-
}
96-
9789
/* When processing receive frames, there are two cases to
9890
* consider. Data frames consist of a non-zero session-id and an
9991
* optional cookie. Control frames consist of a regular L2TP header
@@ -197,8 +189,8 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
197189
struct ipv6hdr *iph = ipv6_hdr(skb);
198190

199191
read_lock_bh(&l2tp_ip6_lock);
200-
sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb),
201-
tunnel_id);
192+
sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr,
193+
inet6_iif(skb), tunnel_id);
202194
if (!sk) {
203195
read_unlock_bh(&l2tp_ip6_lock);
204196
goto discard;
@@ -330,7 +322,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
330322
rcu_read_unlock();
331323

332324
write_lock_bh(&l2tp_ip6_lock);
333-
if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if,
325+
if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, NULL, bound_dev_if,
334326
addr->l2tp_conn_id)) {
335327
write_unlock_bh(&l2tp_ip6_lock);
336328
err = -EADDRINUSE;

0 commit comments

Comments
 (0)