diff options
author | David S. Miller <davem@davemloft.net> | 2013-02-05 14:36:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-05 14:37:01 -0500 |
commit | 9d6ddb19905223828485d8c40deaec76e4dea3a5 (patch) | |
tree | bc9293105e2410ed78fff72416d4ba36f60a4c79 /net/l2tp/l2tp_ip.c | |
parent | 167eb17e0b178549f5e19036b16b6d6e35856b67 (diff) |
l2tp: Make ipv4 protocol handler namespace aware.
The infrastructure is already pretty much entirely there
to allow this conversion.
The tunnel and session lookups have per-namespace tables,
and the ipv4 bind lookup includes the namespace in the
lookup key.
Set netns_ok in l2tp_ip_protocol.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_ip.c')
-rw-r--r-- | net/l2tp/l2tp_ip.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 61d8b75d2686..f7ac8f42fee2 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -115,6 +115,7 @@ static inline struct sock *l2tp_ip_bind_lookup(struct net *net, __be32 laddr, in | |||
115 | */ | 115 | */ |
116 | static int l2tp_ip_recv(struct sk_buff *skb) | 116 | static int l2tp_ip_recv(struct sk_buff *skb) |
117 | { | 117 | { |
118 | struct net *net = dev_net(skb->dev); | ||
118 | struct sock *sk; | 119 | struct sock *sk; |
119 | u32 session_id; | 120 | u32 session_id; |
120 | u32 tunnel_id; | 121 | u32 tunnel_id; |
@@ -142,7 +143,7 @@ static int l2tp_ip_recv(struct sk_buff *skb) | |||
142 | } | 143 | } |
143 | 144 | ||
144 | /* Ok, this is a data packet. Lookup the session. */ | 145 | /* Ok, this is a data packet. Lookup the session. */ |
145 | session = l2tp_session_find(&init_net, NULL, session_id); | 146 | session = l2tp_session_find(net, NULL, session_id); |
146 | if (session == NULL) | 147 | if (session == NULL) |
147 | goto discard; | 148 | goto discard; |
148 | 149 | ||
@@ -173,14 +174,14 @@ pass_up: | |||
173 | goto discard; | 174 | goto discard; |
174 | 175 | ||
175 | tunnel_id = ntohl(*(__be32 *) &skb->data[4]); | 176 | tunnel_id = ntohl(*(__be32 *) &skb->data[4]); |
176 | tunnel = l2tp_tunnel_find(&init_net, tunnel_id); | 177 | tunnel = l2tp_tunnel_find(net, tunnel_id); |
177 | if (tunnel != NULL) | 178 | if (tunnel != NULL) |
178 | sk = tunnel->sock; | 179 | sk = tunnel->sock; |
179 | else { | 180 | else { |
180 | struct iphdr *iph = (struct iphdr *) skb_network_header(skb); | 181 | struct iphdr *iph = (struct iphdr *) skb_network_header(skb); |
181 | 182 | ||
182 | read_lock_bh(&l2tp_ip_lock); | 183 | read_lock_bh(&l2tp_ip_lock); |
183 | sk = __l2tp_ip_bind_lookup(&init_net, iph->daddr, 0, tunnel_id); | 184 | sk = __l2tp_ip_bind_lookup(net, iph->daddr, 0, tunnel_id); |
184 | read_unlock_bh(&l2tp_ip_lock); | 185 | read_unlock_bh(&l2tp_ip_lock); |
185 | } | 186 | } |
186 | 187 | ||
@@ -239,6 +240,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
239 | { | 240 | { |
240 | struct inet_sock *inet = inet_sk(sk); | 241 | struct inet_sock *inet = inet_sk(sk); |
241 | struct sockaddr_l2tpip *addr = (struct sockaddr_l2tpip *) uaddr; | 242 | struct sockaddr_l2tpip *addr = (struct sockaddr_l2tpip *) uaddr; |
243 | struct net *net = sock_net(sk); | ||
242 | int ret; | 244 | int ret; |
243 | int chk_addr_ret; | 245 | int chk_addr_ret; |
244 | 246 | ||
@@ -251,7 +253,8 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
251 | 253 | ||
252 | ret = -EADDRINUSE; | 254 | ret = -EADDRINUSE; |
253 | read_lock_bh(&l2tp_ip_lock); | 255 | read_lock_bh(&l2tp_ip_lock); |
254 | if (__l2tp_ip_bind_lookup(&init_net, addr->l2tp_addr.s_addr, sk->sk_bound_dev_if, addr->l2tp_conn_id)) | 256 | if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr, |
257 | sk->sk_bound_dev_if, addr->l2tp_conn_id)) | ||
255 | goto out_in_use; | 258 | goto out_in_use; |
256 | 259 | ||
257 | read_unlock_bh(&l2tp_ip_lock); | 260 | read_unlock_bh(&l2tp_ip_lock); |
@@ -260,7 +263,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
260 | if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip)) | 263 | if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip)) |
261 | goto out; | 264 | goto out; |
262 | 265 | ||
263 | chk_addr_ret = inet_addr_type(&init_net, addr->l2tp_addr.s_addr); | 266 | chk_addr_ret = inet_addr_type(net, addr->l2tp_addr.s_addr); |
264 | ret = -EADDRNOTAVAIL; | 267 | ret = -EADDRNOTAVAIL; |
265 | if (addr->l2tp_addr.s_addr && chk_addr_ret != RTN_LOCAL && | 268 | if (addr->l2tp_addr.s_addr && chk_addr_ret != RTN_LOCAL && |
266 | chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) | 269 | chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) |
@@ -369,7 +372,7 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) | |||
369 | return 0; | 372 | return 0; |
370 | 373 | ||
371 | drop: | 374 | drop: |
372 | IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS); | 375 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); |
373 | kfree_skb(skb); | 376 | kfree_skb(skb); |
374 | return -1; | 377 | return -1; |
375 | } | 378 | } |
@@ -605,6 +608,7 @@ static struct inet_protosw l2tp_ip_protosw = { | |||
605 | 608 | ||
606 | static struct net_protocol l2tp_ip_protocol __read_mostly = { | 609 | static struct net_protocol l2tp_ip_protocol __read_mostly = { |
607 | .handler = l2tp_ip_recv, | 610 | .handler = l2tp_ip_recv, |
611 | .netns_ok = 1, | ||
608 | }; | 612 | }; |
609 | 613 | ||
610 | static int __init l2tp_ip_init(void) | 614 | static int __init l2tp_ip_init(void) |