* [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6
@ 2016-12-30 18:48 Guillaume Nault
2016-12-30 18:48 ` [PATCH net 1/2] l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup Guillaume Nault
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Guillaume Nault @ 2016-12-30 18:48 UTC (permalink / raw)
To: netdev; +Cc: James Chapman, Chris Elston
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.
Guillaume Nault (2):
l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup
l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket
lookups
net/l2tp/l2tp_ip.c | 19 ++++++-------------
net/l2tp/l2tp_ip6.c | 24 ++++++++----------------
2 files changed, 14 insertions(+), 29 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net 1/2] l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup
2016-12-30 18:48 [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 Guillaume Nault
@ 2016-12-30 18:48 ` Guillaume Nault
2016-12-30 18:48 ` [PATCH net 2/2] l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups Guillaume Nault
2017-01-02 3:07 ` [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Guillaume Nault @ 2016-12-30 18:48 UTC (permalink / raw)
To: netdev; +Cc: James Chapman, Chris Elston
An L2TP socket bound to the unspecified address should match with any
address. If not, it can't receive any packet and __l2tp_ip6_bind_lookup()
can't prevent another socket from binding on the same device/tunnel ID.
While there, rename the 'addr' variable to 'sk_laddr' (local addr), to
make following patch clearer.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
---
net/l2tp/l2tp_ip6.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index f092ac441fdd..3135b9d55df5 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -64,7 +64,7 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
struct sock *sk;
sk_for_each_bound(sk, &l2tp_ip6_bind_table) {
- const struct in6_addr *addr = inet6_rcv_saddr(sk);
+ const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk);
struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
if (l2tp == NULL)
@@ -72,7 +72,7 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
if ((l2tp->conn_id == tunnel_id) &&
net_eq(sock_net(sk), net) &&
- (!addr || ipv6_addr_equal(addr, laddr)) &&
+ (!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) &&
(!sk->sk_bound_dev_if || !dif ||
sk->sk_bound_dev_if == dif))
goto found;
--
2.11.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH net 2/2] l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups
2016-12-30 18:48 [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 Guillaume Nault
2016-12-30 18:48 ` [PATCH net 1/2] l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup Guillaume Nault
@ 2016-12-30 18:48 ` Guillaume Nault
2017-01-02 3:07 ` [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Guillaume Nault @ 2016-12-30 18:48 UTC (permalink / raw)
To: netdev; +Cc: James Chapman, Chris Elston
For connected sockets, __l2tp_ip{,6}_bind_lookup() needs to check the
remote IP when looking for a matching socket. Otherwise a connected
socket can receive traffic not originating from its peer.
Drop l2tp_ip_bind_lookup() and l2tp_ip6_bind_lookup() instead of
updating their prototype, as these functions aren't used.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
---
net/l2tp/l2tp_ip.c | 19 ++++++-------------
net/l2tp/l2tp_ip6.c | 20 ++++++--------------
2 files changed, 12 insertions(+), 27 deletions(-)
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 8938b6ba57a0..3d73278b86ca 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -47,7 +47,8 @@ static inline struct l2tp_ip_sock *l2tp_ip_sk(const struct sock *sk)
return (struct l2tp_ip_sock *)sk;
}
-static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id)
+static struct sock *__l2tp_ip_bind_lookup(const struct net *net, __be32 laddr,
+ __be32 raddr, int dif, u32 tunnel_id)
{
struct sock *sk;
@@ -61,6 +62,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
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;
@@ -71,15 +73,6 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
return sk;
}
-static inline struct sock *l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id)
-{
- struct sock *sk = __l2tp_ip_bind_lookup(net, laddr, dif, tunnel_id);
- if (sk)
- sock_hold(sk);
-
- return sk;
-}
-
/* When processing receive frames, there are two cases to
* consider. Data frames consist of a non-zero session-id and an
* optional cookie. Control frames consist of a regular L2TP header
@@ -183,8 +176,8 @@ static int l2tp_ip_recv(struct sk_buff *skb)
struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
read_lock_bh(&l2tp_ip_lock);
- sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb),
- tunnel_id);
+ sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr,
+ inet_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip_lock);
goto discard;
@@ -280,7 +273,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
inet->inet_saddr = 0; /* Use device */
write_lock_bh(&l2tp_ip_lock);
- if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
+ if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr, 0,
sk->sk_bound_dev_if, addr->l2tp_conn_id)) {
write_unlock_bh(&l2tp_ip_lock);
ret = -EADDRINUSE;
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 3135b9d55df5..331ccf5a7bad 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -59,12 +59,14 @@ static inline struct l2tp_ip6_sock *l2tp_ip6_sk(const struct sock *sk)
static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
struct in6_addr *laddr,
+ const struct in6_addr *raddr,
int dif, u32 tunnel_id)
{
struct sock *sk;
sk_for_each_bound(sk, &l2tp_ip6_bind_table) {
const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk);
+ const struct in6_addr *sk_raddr = &sk->sk_v6_daddr;
struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
if (l2tp == NULL)
@@ -73,6 +75,7 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
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;
@@ -83,17 +86,6 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
return sk;
}
-static inline struct sock *l2tp_ip6_bind_lookup(struct net *net,
- struct in6_addr *laddr,
- int dif, u32 tunnel_id)
-{
- struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id);
- if (sk)
- sock_hold(sk);
-
- return sk;
-}
-
/* When processing receive frames, there are two cases to
* consider. Data frames consist of a non-zero session-id and an
* optional cookie. Control frames consist of a regular L2TP header
@@ -197,8 +189,8 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
struct ipv6hdr *iph = ipv6_hdr(skb);
read_lock_bh(&l2tp_ip6_lock);
- sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb),
- tunnel_id);
+ sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr,
+ inet6_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip6_lock);
goto discard;
@@ -330,7 +322,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
rcu_read_unlock();
write_lock_bh(&l2tp_ip6_lock);
- if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if,
+ if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, NULL, bound_dev_if,
addr->l2tp_conn_id)) {
write_unlock_bh(&l2tp_ip6_lock);
err = -EADDRINUSE;
--
2.11.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6
2016-12-30 18:48 [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 Guillaume Nault
2016-12-30 18:48 ` [PATCH net 1/2] l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup Guillaume Nault
2016-12-30 18:48 ` [PATCH net 2/2] l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups Guillaume Nault
@ 2017-01-02 3:07 ` David Miller
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2017-01-02 3:07 UTC (permalink / raw)
To: g.nault; +Cc: netdev, jchapman, celston
From: Guillaume Nault <g.nault@alphalink.fr>
Date: Fri, 30 Dec 2016 19:48:17 +0100
> 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.
Series applied, thank you.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-01-02 3:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-30 18:48 [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 Guillaume Nault
2016-12-30 18:48 ` [PATCH net 1/2] l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup Guillaume Nault
2016-12-30 18:48 ` [PATCH net 2/2] l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups Guillaume Nault
2017-01-02 3:07 ` [PATCH net 0/2] l2tp: socket lookup fixes for l2tp_ip and l2tp_ip6 David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).