diff options
author | Shmulik Ladkani <shmulik.ladkani@gmail.com> | 2016-05-26 13:16:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-30 03:03:53 -0400 |
commit | 0e6b5259824e97a0f7e7b450421ff12865d3b0e2 (patch) | |
tree | 58e073d906dd71972348cdcbc80c5a3037eb886b | |
parent | 176b346b37f0b9c03e91eb6f1460e00f3c0c3edf (diff) |
net: l2tp: Make l2tp_ip6 namespace aware
l2tp_ip6 tunnel and session lookups were still using init_net, although
the l2tp core infrastructure already supports lookups keyed by 'net'.
As a result, l2tp_ip6_recv discarded packets for tunnels/sessions
created in namespaces other than the init_net.
Fix, by using dev_net(skb->dev) or sock_net(sk) where appropriate.
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index c6f5df1bed12..6c54e03fe9c1 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -128,6 +128,7 @@ static inline struct sock *l2tp_ip6_bind_lookup(struct net *net, | |||
128 | */ | 128 | */ |
129 | static int l2tp_ip6_recv(struct sk_buff *skb) | 129 | static int l2tp_ip6_recv(struct sk_buff *skb) |
130 | { | 130 | { |
131 | struct net *net = dev_net(skb->dev); | ||
131 | struct sock *sk; | 132 | struct sock *sk; |
132 | u32 session_id; | 133 | u32 session_id; |
133 | u32 tunnel_id; | 134 | u32 tunnel_id; |
@@ -154,7 +155,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb) | |||
154 | } | 155 | } |
155 | 156 | ||
156 | /* Ok, this is a data packet. Lookup the session. */ | 157 | /* Ok, this is a data packet. Lookup the session. */ |
157 | session = l2tp_session_find(&init_net, NULL, session_id); | 158 | session = l2tp_session_find(net, NULL, session_id); |
158 | if (session == NULL) | 159 | if (session == NULL) |
159 | goto discard; | 160 | goto discard; |
160 | 161 | ||
@@ -188,14 +189,14 @@ pass_up: | |||
188 | goto discard; | 189 | goto discard; |
189 | 190 | ||
190 | tunnel_id = ntohl(*(__be32 *) &skb->data[4]); | 191 | tunnel_id = ntohl(*(__be32 *) &skb->data[4]); |
191 | tunnel = l2tp_tunnel_find(&init_net, tunnel_id); | 192 | tunnel = l2tp_tunnel_find(net, tunnel_id); |
192 | if (tunnel != NULL) | 193 | if (tunnel != NULL) |
193 | sk = tunnel->sock; | 194 | sk = tunnel->sock; |
194 | else { | 195 | else { |
195 | struct ipv6hdr *iph = ipv6_hdr(skb); | 196 | struct ipv6hdr *iph = ipv6_hdr(skb); |
196 | 197 | ||
197 | read_lock_bh(&l2tp_ip6_lock); | 198 | read_lock_bh(&l2tp_ip6_lock); |
198 | sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr, | 199 | sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, |
199 | 0, tunnel_id); | 200 | 0, tunnel_id); |
200 | read_unlock_bh(&l2tp_ip6_lock); | 201 | read_unlock_bh(&l2tp_ip6_lock); |
201 | } | 202 | } |
@@ -263,6 +264,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
263 | struct inet_sock *inet = inet_sk(sk); | 264 | struct inet_sock *inet = inet_sk(sk); |
264 | struct ipv6_pinfo *np = inet6_sk(sk); | 265 | struct ipv6_pinfo *np = inet6_sk(sk); |
265 | struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; | 266 | struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; |
267 | struct net *net = sock_net(sk); | ||
266 | __be32 v4addr = 0; | 268 | __be32 v4addr = 0; |
267 | int addr_type; | 269 | int addr_type; |
268 | int err; | 270 | int err; |
@@ -286,7 +288,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
286 | 288 | ||
287 | err = -EADDRINUSE; | 289 | err = -EADDRINUSE; |
288 | read_lock_bh(&l2tp_ip6_lock); | 290 | read_lock_bh(&l2tp_ip6_lock); |
289 | if (__l2tp_ip6_bind_lookup(&init_net, &addr->l2tp_addr, | 291 | if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, |
290 | sk->sk_bound_dev_if, addr->l2tp_conn_id)) | 292 | sk->sk_bound_dev_if, addr->l2tp_conn_id)) |
291 | goto out_in_use; | 293 | goto out_in_use; |
292 | read_unlock_bh(&l2tp_ip6_lock); | 294 | read_unlock_bh(&l2tp_ip6_lock); |
@@ -456,7 +458,7 @@ static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb) | |||
456 | return 0; | 458 | return 0; |
457 | 459 | ||
458 | drop: | 460 | drop: |
459 | IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS); | 461 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); |
460 | kfree_skb(skb); | 462 | kfree_skb(skb); |
461 | return -1; | 463 | return -1; |
462 | } | 464 | } |