diff options
-rw-r--r-- | include/linux/l2tp.h | 17 | ||||
-rw-r--r-- | net/l2tp/Makefile | 3 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 792 |
3 files changed, 812 insertions, 0 deletions
diff --git a/include/linux/l2tp.h b/include/linux/l2tp.h index 16b834741d16..7eab668f60f3 100644 --- a/include/linux/l2tp.h +++ b/include/linux/l2tp.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/socket.h> | 11 | #include <linux/socket.h> |
12 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
13 | #include <linux/in.h> | 13 | #include <linux/in.h> |
14 | #include <linux/in6.h> | ||
14 | #else | 15 | #else |
15 | #include <netinet/in.h> | 16 | #include <netinet/in.h> |
16 | #endif | 17 | #endif |
@@ -39,6 +40,22 @@ struct sockaddr_l2tpip { | |||
39 | sizeof(__u32)]; | 40 | sizeof(__u32)]; |
40 | }; | 41 | }; |
41 | 42 | ||
43 | /** | ||
44 | * struct sockaddr_l2tpip6 - the sockaddr structure for L2TP-over-IPv6 sockets | ||
45 | * @l2tp_family: address family number AF_L2TPIP. | ||
46 | * @l2tp_addr: protocol specific address information | ||
47 | * @l2tp_conn_id: connection id of tunnel | ||
48 | */ | ||
49 | struct sockaddr_l2tpip6 { | ||
50 | /* The first fields must match struct sockaddr_in6 */ | ||
51 | __kernel_sa_family_t l2tp_family; /* AF_INET6 */ | ||
52 | __be16 l2tp_unused; /* INET port number (unused) */ | ||
53 | __be32 l2tp_flowinfo; /* IPv6 flow information */ | ||
54 | struct in6_addr l2tp_addr; /* IPv6 address */ | ||
55 | __u32 l2tp_scope_id; /* scope id (new in RFC2553) */ | ||
56 | __u32 l2tp_conn_id; /* Connection ID of tunnel */ | ||
57 | }; | ||
58 | |||
42 | /***************************************************************************** | 59 | /***************************************************************************** |
43 | * NETLINK_GENERIC netlink family. | 60 | * NETLINK_GENERIC netlink family. |
44 | *****************************************************************************/ | 61 | *****************************************************************************/ |
diff --git a/net/l2tp/Makefile b/net/l2tp/Makefile index 110e7bc2de5e..2870f41ea44d 100644 --- a/net/l2tp/Makefile +++ b/net/l2tp/Makefile | |||
@@ -10,3 +10,6 @@ obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o | |||
10 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o | 10 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o |
11 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH)) += l2tp_eth.o | 11 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH)) += l2tp_eth.o |
12 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_DEBUGFS)) += l2tp_debugfs.o | 12 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_DEBUGFS)) += l2tp_debugfs.o |
13 | ifneq ($(CONFIG_IPV6),) | ||
14 | obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip6.o | ||
15 | endif | ||
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c new file mode 100644 index 000000000000..88f0abe35443 --- /dev/null +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -0,0 +1,792 @@ | |||
1 | /* | ||
2 | * L2TPv3 IP encapsulation support for IPv6 | ||
3 | * | ||
4 | * Copyright (c) 2012 Katalix Systems Ltd | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/icmp.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | #include <linux/random.h> | ||
16 | #include <linux/socket.h> | ||
17 | #include <linux/l2tp.h> | ||
18 | #include <linux/in.h> | ||
19 | #include <linux/in6.h> | ||
20 | #include <net/sock.h> | ||
21 | #include <net/ip.h> | ||
22 | #include <net/icmp.h> | ||
23 | #include <net/udp.h> | ||
24 | #include <net/inet_common.h> | ||
25 | #include <net/inet_hashtables.h> | ||
26 | #include <net/tcp_states.h> | ||
27 | #include <net/protocol.h> | ||
28 | #include <net/xfrm.h> | ||
29 | |||
30 | #include <net/transp_v6.h> | ||
31 | #include <net/addrconf.h> | ||
32 | #include <net/ip6_route.h> | ||
33 | |||
34 | #include "l2tp_core.h" | ||
35 | |||
36 | struct l2tp_ip6_sock { | ||
37 | /* inet_sock has to be the first member of l2tp_ip6_sock */ | ||
38 | struct inet_sock inet; | ||
39 | |||
40 | u32 conn_id; | ||
41 | u32 peer_conn_id; | ||
42 | |||
43 | /* ipv6_pinfo has to be the last member of l2tp_ip6_sock, see | ||
44 | inet6_sk_generic */ | ||
45 | struct ipv6_pinfo inet6; | ||
46 | }; | ||
47 | |||
48 | static DEFINE_RWLOCK(l2tp_ip6_lock); | ||
49 | static struct hlist_head l2tp_ip6_table; | ||
50 | static struct hlist_head l2tp_ip6_bind_table; | ||
51 | |||
52 | static inline struct l2tp_ip6_sock *l2tp_ip6_sk(const struct sock *sk) | ||
53 | { | ||
54 | return (struct l2tp_ip6_sock *)sk; | ||
55 | } | ||
56 | |||
57 | static struct sock *__l2tp_ip6_bind_lookup(struct net *net, | ||
58 | struct in6_addr *laddr, | ||
59 | int dif, u32 tunnel_id) | ||
60 | { | ||
61 | struct hlist_node *node; | ||
62 | struct sock *sk; | ||
63 | |||
64 | sk_for_each_bound(sk, node, &l2tp_ip6_bind_table) { | ||
65 | struct in6_addr *addr = inet6_rcv_saddr(sk); | ||
66 | struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk); | ||
67 | |||
68 | if (l2tp == NULL) | ||
69 | continue; | ||
70 | |||
71 | if ((l2tp->conn_id == tunnel_id) && | ||
72 | net_eq(sock_net(sk), net) && | ||
73 | !(addr && ipv6_addr_equal(addr, laddr)) && | ||
74 | !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) | ||
75 | goto found; | ||
76 | } | ||
77 | |||
78 | sk = NULL; | ||
79 | found: | ||
80 | return sk; | ||
81 | } | ||
82 | |||
83 | static inline struct sock *l2tp_ip6_bind_lookup(struct net *net, | ||
84 | struct in6_addr *laddr, | ||
85 | int dif, u32 tunnel_id) | ||
86 | { | ||
87 | struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id); | ||
88 | if (sk) | ||
89 | sock_hold(sk); | ||
90 | |||
91 | return sk; | ||
92 | } | ||
93 | |||
94 | /* When processing receive frames, there are two cases to | ||
95 | * consider. Data frames consist of a non-zero session-id and an | ||
96 | * optional cookie. Control frames consist of a regular L2TP header | ||
97 | * preceded by 32-bits of zeros. | ||
98 | * | ||
99 | * L2TPv3 Session Header Over IP | ||
100 | * | ||
101 | * 0 1 2 3 | ||
102 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
103 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
104 | * | Session ID | | ||
105 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
106 | * | Cookie (optional, maximum 64 bits)... | ||
107 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
108 | * | | ||
109 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
110 | * | ||
111 | * L2TPv3 Control Message Header Over IP | ||
112 | * | ||
113 | * 0 1 2 3 | ||
114 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
115 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
116 | * | (32 bits of zeros) | | ||
117 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
118 | * |T|L|x|x|S|x|x|x|x|x|x|x| Ver | Length | | ||
119 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
120 | * | Control Connection ID | | ||
121 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
122 | * | Ns | Nr | | ||
123 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
124 | * | ||
125 | * All control frames are passed to userspace. | ||
126 | */ | ||
127 | static int l2tp_ip6_recv(struct sk_buff *skb) | ||
128 | { | ||
129 | struct sock *sk; | ||
130 | u32 session_id; | ||
131 | u32 tunnel_id; | ||
132 | unsigned char *ptr, *optr; | ||
133 | struct l2tp_session *session; | ||
134 | struct l2tp_tunnel *tunnel = NULL; | ||
135 | int length; | ||
136 | int offset; | ||
137 | |||
138 | /* Point to L2TP header */ | ||
139 | optr = ptr = skb->data; | ||
140 | |||
141 | if (!pskb_may_pull(skb, 4)) | ||
142 | goto discard; | ||
143 | |||
144 | session_id = ntohl(*((__be32 *) ptr)); | ||
145 | ptr += 4; | ||
146 | |||
147 | /* RFC3931: L2TP/IP packets have the first 4 bytes containing | ||
148 | * the session_id. If it is 0, the packet is a L2TP control | ||
149 | * frame and the session_id value can be discarded. | ||
150 | */ | ||
151 | if (session_id == 0) { | ||
152 | __skb_pull(skb, 4); | ||
153 | goto pass_up; | ||
154 | } | ||
155 | |||
156 | /* Ok, this is a data packet. Lookup the session. */ | ||
157 | session = l2tp_session_find(&init_net, NULL, session_id); | ||
158 | if (session == NULL) | ||
159 | goto discard; | ||
160 | |||
161 | tunnel = session->tunnel; | ||
162 | if (tunnel == NULL) | ||
163 | goto discard; | ||
164 | |||
165 | /* Trace packet contents, if enabled */ | ||
166 | if (tunnel->debug & L2TP_MSG_DATA) { | ||
167 | length = min(32u, skb->len); | ||
168 | if (!pskb_may_pull(skb, length)) | ||
169 | goto discard; | ||
170 | |||
171 | printk(KERN_DEBUG "%s: ip recv: ", tunnel->name); | ||
172 | |||
173 | offset = 0; | ||
174 | do { | ||
175 | printk(" %02X", ptr[offset]); | ||
176 | } while (++offset < length); | ||
177 | |||
178 | printk("\n"); | ||
179 | } | ||
180 | |||
181 | l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, | ||
182 | tunnel->recv_payload_hook); | ||
183 | return 0; | ||
184 | |||
185 | pass_up: | ||
186 | /* Get the tunnel_id from the L2TP header */ | ||
187 | if (!pskb_may_pull(skb, 12)) | ||
188 | goto discard; | ||
189 | |||
190 | if ((skb->data[0] & 0xc0) != 0xc0) | ||
191 | goto discard; | ||
192 | |||
193 | tunnel_id = ntohl(*(__be32 *) &skb->data[4]); | ||
194 | tunnel = l2tp_tunnel_find(&init_net, tunnel_id); | ||
195 | if (tunnel != NULL) | ||
196 | sk = tunnel->sock; | ||
197 | else { | ||
198 | struct ipv6hdr *iph = ipv6_hdr(skb); | ||
199 | |||
200 | read_lock_bh(&l2tp_ip6_lock); | ||
201 | sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr, | ||
202 | 0, tunnel_id); | ||
203 | read_unlock_bh(&l2tp_ip6_lock); | ||
204 | } | ||
205 | |||
206 | if (sk == NULL) | ||
207 | goto discard; | ||
208 | |||
209 | sock_hold(sk); | ||
210 | |||
211 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | ||
212 | goto discard_put; | ||
213 | |||
214 | nf_reset(skb); | ||
215 | |||
216 | return sk_receive_skb(sk, skb, 1); | ||
217 | |||
218 | discard_put: | ||
219 | sock_put(sk); | ||
220 | |||
221 | discard: | ||
222 | kfree_skb(skb); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int l2tp_ip6_open(struct sock *sk) | ||
227 | { | ||
228 | /* Prevent autobind. We don't have ports. */ | ||
229 | inet_sk(sk)->inet_num = IPPROTO_L2TP; | ||
230 | |||
231 | write_lock_bh(&l2tp_ip6_lock); | ||
232 | sk_add_node(sk, &l2tp_ip6_table); | ||
233 | write_unlock_bh(&l2tp_ip6_lock); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static void l2tp_ip6_close(struct sock *sk, long timeout) | ||
239 | { | ||
240 | write_lock_bh(&l2tp_ip6_lock); | ||
241 | hlist_del_init(&sk->sk_bind_node); | ||
242 | sk_del_node_init(sk); | ||
243 | write_unlock_bh(&l2tp_ip6_lock); | ||
244 | |||
245 | sk_common_release(sk); | ||
246 | } | ||
247 | |||
248 | static void l2tp_ip6_destroy_sock(struct sock *sk) | ||
249 | { | ||
250 | lock_sock(sk); | ||
251 | ip6_flush_pending_frames(sk); | ||
252 | release_sock(sk); | ||
253 | |||
254 | inet6_destroy_sock(sk); | ||
255 | } | ||
256 | |||
257 | static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | ||
258 | { | ||
259 | struct inet_sock *inet = inet_sk(sk); | ||
260 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
261 | struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; | ||
262 | __be32 v4addr = 0; | ||
263 | int addr_type; | ||
264 | int err; | ||
265 | |||
266 | if (addr_len < sizeof(*addr)) | ||
267 | return -EINVAL; | ||
268 | |||
269 | addr_type = ipv6_addr_type(&addr->l2tp_addr); | ||
270 | |||
271 | /* l2tp_ip6 sockets are IPv6 only */ | ||
272 | if (addr_type == IPV6_ADDR_MAPPED) | ||
273 | return -EADDRNOTAVAIL; | ||
274 | |||
275 | /* L2TP is point-point, not multicast */ | ||
276 | if (addr_type & IPV6_ADDR_MULTICAST) | ||
277 | return -EADDRNOTAVAIL; | ||
278 | |||
279 | err = -EADDRINUSE; | ||
280 | read_lock_bh(&l2tp_ip6_lock); | ||
281 | if (__l2tp_ip6_bind_lookup(&init_net, &addr->l2tp_addr, | ||
282 | sk->sk_bound_dev_if, addr->l2tp_conn_id)) | ||
283 | goto out_in_use; | ||
284 | read_unlock_bh(&l2tp_ip6_lock); | ||
285 | |||
286 | lock_sock(sk); | ||
287 | |||
288 | err = -EINVAL; | ||
289 | if (sk->sk_state != TCP_CLOSE) | ||
290 | goto out_unlock; | ||
291 | |||
292 | /* Check if the address belongs to the host. */ | ||
293 | rcu_read_lock(); | ||
294 | if (addr_type != IPV6_ADDR_ANY) { | ||
295 | struct net_device *dev = NULL; | ||
296 | |||
297 | if (addr_type & IPV6_ADDR_LINKLOCAL) { | ||
298 | if (addr_len >= sizeof(struct sockaddr_in6) && | ||
299 | addr->l2tp_scope_id) { | ||
300 | /* Override any existing binding, if another | ||
301 | * one is supplied by user. | ||
302 | */ | ||
303 | sk->sk_bound_dev_if = addr->l2tp_scope_id; | ||
304 | } | ||
305 | |||
306 | /* Binding to link-local address requires an | ||
307 | interface */ | ||
308 | if (!sk->sk_bound_dev_if) | ||
309 | goto out_unlock_rcu; | ||
310 | |||
311 | err = -ENODEV; | ||
312 | dev = dev_get_by_index_rcu(sock_net(sk), | ||
313 | sk->sk_bound_dev_if); | ||
314 | if (!dev) | ||
315 | goto out_unlock_rcu; | ||
316 | } | ||
317 | |||
318 | /* ipv4 addr of the socket is invalid. Only the | ||
319 | * unspecified and mapped address have a v4 equivalent. | ||
320 | */ | ||
321 | v4addr = LOOPBACK4_IPV6; | ||
322 | err = -EADDRNOTAVAIL; | ||
323 | if (!ipv6_chk_addr(sock_net(sk), &addr->l2tp_addr, dev, 0)) | ||
324 | goto out_unlock_rcu; | ||
325 | } | ||
326 | rcu_read_unlock(); | ||
327 | |||
328 | inet->inet_rcv_saddr = inet->inet_saddr = v4addr; | ||
329 | np->rcv_saddr = addr->l2tp_addr; | ||
330 | np->saddr = addr->l2tp_addr; | ||
331 | |||
332 | l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id; | ||
333 | |||
334 | write_lock_bh(&l2tp_ip6_lock); | ||
335 | sk_add_bind_node(sk, &l2tp_ip6_bind_table); | ||
336 | sk_del_node_init(sk); | ||
337 | write_unlock_bh(&l2tp_ip6_lock); | ||
338 | |||
339 | release_sock(sk); | ||
340 | return 0; | ||
341 | |||
342 | out_unlock_rcu: | ||
343 | rcu_read_unlock(); | ||
344 | out_unlock: | ||
345 | release_sock(sk); | ||
346 | return err; | ||
347 | |||
348 | out_in_use: | ||
349 | read_unlock_bh(&l2tp_ip6_lock); | ||
350 | return err; | ||
351 | } | ||
352 | |||
353 | static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr, | ||
354 | int addr_len) | ||
355 | { | ||
356 | struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *) uaddr; | ||
357 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | ||
358 | struct in6_addr *daddr; | ||
359 | int addr_type; | ||
360 | int rc; | ||
361 | |||
362 | if (addr_len < sizeof(*lsa)) | ||
363 | return -EINVAL; | ||
364 | |||
365 | addr_type = ipv6_addr_type(&usin->sin6_addr); | ||
366 | if (addr_type & IPV6_ADDR_MULTICAST) | ||
367 | return -EINVAL; | ||
368 | |||
369 | if (addr_type & IPV6_ADDR_MAPPED) { | ||
370 | daddr = &usin->sin6_addr; | ||
371 | if (ipv4_is_multicast(daddr->s6_addr32[3])) | ||
372 | return -EINVAL; | ||
373 | } | ||
374 | |||
375 | rc = ip6_datagram_connect(sk, uaddr, addr_len); | ||
376 | |||
377 | lock_sock(sk); | ||
378 | |||
379 | l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id; | ||
380 | |||
381 | write_lock_bh(&l2tp_ip6_lock); | ||
382 | hlist_del_init(&sk->sk_bind_node); | ||
383 | sk_add_bind_node(sk, &l2tp_ip6_bind_table); | ||
384 | write_unlock_bh(&l2tp_ip6_lock); | ||
385 | |||
386 | release_sock(sk); | ||
387 | |||
388 | return rc; | ||
389 | } | ||
390 | |||
391 | static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr, | ||
392 | int *uaddr_len, int peer) | ||
393 | { | ||
394 | struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)uaddr; | ||
395 | struct sock *sk = sock->sk; | ||
396 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
397 | struct l2tp_ip6_sock *lsk = l2tp_ip6_sk(sk); | ||
398 | |||
399 | lsa->l2tp_family = AF_INET6; | ||
400 | lsa->l2tp_flowinfo = 0; | ||
401 | lsa->l2tp_scope_id = 0; | ||
402 | if (peer) { | ||
403 | if (!lsk->peer_conn_id) | ||
404 | return -ENOTCONN; | ||
405 | lsa->l2tp_conn_id = lsk->peer_conn_id; | ||
406 | lsa->l2tp_addr = np->daddr; | ||
407 | if (np->sndflow) | ||
408 | lsa->l2tp_flowinfo = np->flow_label; | ||
409 | } else { | ||
410 | if (ipv6_addr_any(&np->rcv_saddr)) | ||
411 | lsa->l2tp_addr = np->saddr; | ||
412 | else | ||
413 | lsa->l2tp_addr = np->rcv_saddr; | ||
414 | |||
415 | lsa->l2tp_conn_id = lsk->conn_id; | ||
416 | } | ||
417 | if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) | ||
418 | lsa->l2tp_scope_id = sk->sk_bound_dev_if; | ||
419 | *uaddr_len = sizeof(*lsa); | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb) | ||
424 | { | ||
425 | int rc; | ||
426 | |||
427 | /* Charge it to the socket, dropping if the queue is full. */ | ||
428 | rc = sock_queue_rcv_skb(sk, skb); | ||
429 | if (rc < 0) | ||
430 | goto drop; | ||
431 | |||
432 | return 0; | ||
433 | |||
434 | drop: | ||
435 | IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS); | ||
436 | kfree_skb(skb); | ||
437 | return -1; | ||
438 | } | ||
439 | |||
440 | static int l2tp_ip6_push_pending_frames(struct sock *sk) | ||
441 | { | ||
442 | struct sk_buff *skb; | ||
443 | __be32 *transhdr = NULL; | ||
444 | int err = 0; | ||
445 | |||
446 | skb = skb_peek(&sk->sk_write_queue); | ||
447 | if (skb == NULL) | ||
448 | goto out; | ||
449 | |||
450 | transhdr = (__be32 *)skb_transport_header(skb); | ||
451 | *transhdr = 0; | ||
452 | |||
453 | err = ip6_push_pending_frames(sk); | ||
454 | |||
455 | out: | ||
456 | return err; | ||
457 | } | ||
458 | |||
459 | /* Userspace will call sendmsg() on the tunnel socket to send L2TP | ||
460 | * control frames. | ||
461 | */ | ||
462 | static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, | ||
463 | struct msghdr *msg, size_t len) | ||
464 | { | ||
465 | struct ipv6_txoptions opt_space; | ||
466 | struct sockaddr_l2tpip6 *lsa = | ||
467 | (struct sockaddr_l2tpip6 *) msg->msg_name; | ||
468 | struct in6_addr *daddr, *final_p, final; | ||
469 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
470 | struct ipv6_txoptions *opt = NULL; | ||
471 | struct ip6_flowlabel *flowlabel = NULL; | ||
472 | struct dst_entry *dst = NULL; | ||
473 | struct flowi6 fl6; | ||
474 | int addr_len = msg->msg_namelen; | ||
475 | int hlimit = -1; | ||
476 | int tclass = -1; | ||
477 | int dontfrag = -1; | ||
478 | int transhdrlen = 4; /* zero session-id */ | ||
479 | int ulen = len + transhdrlen; | ||
480 | int err; | ||
481 | |||
482 | /* Rough check on arithmetic overflow, | ||
483 | better check is made in ip6_append_data(). | ||
484 | */ | ||
485 | if (len > INT_MAX) | ||
486 | return -EMSGSIZE; | ||
487 | |||
488 | /* Mirror BSD error message compatibility */ | ||
489 | if (msg->msg_flags & MSG_OOB) | ||
490 | return -EOPNOTSUPP; | ||
491 | |||
492 | /* | ||
493 | * Get and verify the address. | ||
494 | */ | ||
495 | memset(&fl6, 0, sizeof(fl6)); | ||
496 | |||
497 | fl6.flowi6_mark = sk->sk_mark; | ||
498 | |||
499 | if (lsa) { | ||
500 | if (addr_len < SIN6_LEN_RFC2133) | ||
501 | return -EINVAL; | ||
502 | |||
503 | if (lsa->l2tp_family && lsa->l2tp_family != AF_INET6) | ||
504 | return -EAFNOSUPPORT; | ||
505 | |||
506 | daddr = &lsa->l2tp_addr; | ||
507 | if (np->sndflow) { | ||
508 | fl6.flowlabel = lsa->l2tp_flowinfo & IPV6_FLOWINFO_MASK; | ||
509 | if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { | ||
510 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | ||
511 | if (flowlabel == NULL) | ||
512 | return -EINVAL; | ||
513 | daddr = &flowlabel->dst; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * Otherwise it will be difficult to maintain | ||
519 | * sk->sk_dst_cache. | ||
520 | */ | ||
521 | if (sk->sk_state == TCP_ESTABLISHED && | ||
522 | ipv6_addr_equal(daddr, &np->daddr)) | ||
523 | daddr = &np->daddr; | ||
524 | |||
525 | if (addr_len >= sizeof(struct sockaddr_in6) && | ||
526 | lsa->l2tp_scope_id && | ||
527 | ipv6_addr_type(daddr) & IPV6_ADDR_LINKLOCAL) | ||
528 | fl6.flowi6_oif = lsa->l2tp_scope_id; | ||
529 | } else { | ||
530 | if (sk->sk_state != TCP_ESTABLISHED) | ||
531 | return -EDESTADDRREQ; | ||
532 | |||
533 | daddr = &np->daddr; | ||
534 | fl6.flowlabel = np->flow_label; | ||
535 | } | ||
536 | |||
537 | if (fl6.flowi6_oif == 0) | ||
538 | fl6.flowi6_oif = sk->sk_bound_dev_if; | ||
539 | |||
540 | if (msg->msg_controllen) { | ||
541 | opt = &opt_space; | ||
542 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | ||
543 | opt->tot_len = sizeof(struct ipv6_txoptions); | ||
544 | |||
545 | err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, | ||
546 | &hlimit, &tclass, &dontfrag); | ||
547 | if (err < 0) { | ||
548 | fl6_sock_release(flowlabel); | ||
549 | return err; | ||
550 | } | ||
551 | if ((fl6.flowlabel & IPV6_FLOWLABEL_MASK) && !flowlabel) { | ||
552 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | ||
553 | if (flowlabel == NULL) | ||
554 | return -EINVAL; | ||
555 | } | ||
556 | if (!(opt->opt_nflen|opt->opt_flen)) | ||
557 | opt = NULL; | ||
558 | } | ||
559 | |||
560 | if (opt == NULL) | ||
561 | opt = np->opt; | ||
562 | if (flowlabel) | ||
563 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | ||
564 | opt = ipv6_fixup_options(&opt_space, opt); | ||
565 | |||
566 | fl6.flowi6_proto = sk->sk_protocol; | ||
567 | if (!ipv6_addr_any(daddr)) | ||
568 | fl6.daddr = *daddr; | ||
569 | else | ||
570 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ | ||
571 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) | ||
572 | fl6.saddr = np->saddr; | ||
573 | |||
574 | final_p = fl6_update_dst(&fl6, opt, &final); | ||
575 | |||
576 | if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) | ||
577 | fl6.flowi6_oif = np->mcast_oif; | ||
578 | else if (!fl6.flowi6_oif) | ||
579 | fl6.flowi6_oif = np->ucast_oif; | ||
580 | |||
581 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | ||
582 | |||
583 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); | ||
584 | if (IS_ERR(dst)) { | ||
585 | err = PTR_ERR(dst); | ||
586 | goto out; | ||
587 | } | ||
588 | |||
589 | if (hlimit < 0) { | ||
590 | if (ipv6_addr_is_multicast(&fl6.daddr)) | ||
591 | hlimit = np->mcast_hops; | ||
592 | else | ||
593 | hlimit = np->hop_limit; | ||
594 | if (hlimit < 0) | ||
595 | hlimit = ip6_dst_hoplimit(dst); | ||
596 | } | ||
597 | |||
598 | if (tclass < 0) | ||
599 | tclass = np->tclass; | ||
600 | |||
601 | if (dontfrag < 0) | ||
602 | dontfrag = np->dontfrag; | ||
603 | |||
604 | if (msg->msg_flags & MSG_CONFIRM) | ||
605 | goto do_confirm; | ||
606 | |||
607 | back_from_confirm: | ||
608 | lock_sock(sk); | ||
609 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, | ||
610 | ulen, transhdrlen, hlimit, tclass, opt, | ||
611 | &fl6, (struct rt6_info *)dst, | ||
612 | msg->msg_flags, dontfrag); | ||
613 | if (err) | ||
614 | ip6_flush_pending_frames(sk); | ||
615 | else if (!(msg->msg_flags & MSG_MORE)) | ||
616 | err = l2tp_ip6_push_pending_frames(sk); | ||
617 | release_sock(sk); | ||
618 | done: | ||
619 | dst_release(dst); | ||
620 | out: | ||
621 | fl6_sock_release(flowlabel); | ||
622 | |||
623 | return err < 0 ? err : len; | ||
624 | |||
625 | do_confirm: | ||
626 | dst_confirm(dst); | ||
627 | if (!(msg->msg_flags & MSG_PROBE) || len) | ||
628 | goto back_from_confirm; | ||
629 | err = 0; | ||
630 | goto done; | ||
631 | } | ||
632 | |||
633 | static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk, | ||
634 | struct msghdr *msg, size_t len, int noblock, | ||
635 | int flags, int *addr_len) | ||
636 | { | ||
637 | struct inet_sock *inet = inet_sk(sk); | ||
638 | struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name; | ||
639 | size_t copied = 0; | ||
640 | int err = -EOPNOTSUPP; | ||
641 | struct sk_buff *skb; | ||
642 | |||
643 | if (flags & MSG_OOB) | ||
644 | goto out; | ||
645 | |||
646 | if (addr_len) | ||
647 | *addr_len = sizeof(*lsa); | ||
648 | |||
649 | if (flags & MSG_ERRQUEUE) | ||
650 | return ipv6_recv_error(sk, msg, len); | ||
651 | |||
652 | skb = skb_recv_datagram(sk, flags, noblock, &err); | ||
653 | if (!skb) | ||
654 | goto out; | ||
655 | |||
656 | copied = skb->len; | ||
657 | if (len < copied) { | ||
658 | msg->msg_flags |= MSG_TRUNC; | ||
659 | copied = len; | ||
660 | } | ||
661 | |||
662 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | ||
663 | if (err) | ||
664 | goto done; | ||
665 | |||
666 | sock_recv_timestamp(msg, sk, skb); | ||
667 | |||
668 | /* Copy the address. */ | ||
669 | if (lsa) { | ||
670 | lsa->l2tp_family = AF_INET6; | ||
671 | lsa->l2tp_unused = 0; | ||
672 | lsa->l2tp_addr = ipv6_hdr(skb)->saddr; | ||
673 | lsa->l2tp_flowinfo = 0; | ||
674 | lsa->l2tp_scope_id = 0; | ||
675 | if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) | ||
676 | lsa->l2tp_scope_id = IP6CB(skb)->iif; | ||
677 | } | ||
678 | |||
679 | if (inet->cmsg_flags) | ||
680 | ip_cmsg_recv(msg, skb); | ||
681 | |||
682 | if (flags & MSG_TRUNC) | ||
683 | copied = skb->len; | ||
684 | done: | ||
685 | skb_free_datagram(sk, skb); | ||
686 | out: | ||
687 | return err ? err : copied; | ||
688 | } | ||
689 | |||
690 | static struct proto l2tp_ip6_prot = { | ||
691 | .name = "L2TP/IPv6", | ||
692 | .owner = THIS_MODULE, | ||
693 | .init = l2tp_ip6_open, | ||
694 | .close = l2tp_ip6_close, | ||
695 | .bind = l2tp_ip6_bind, | ||
696 | .connect = l2tp_ip6_connect, | ||
697 | .disconnect = udp_disconnect, | ||
698 | .ioctl = udp_ioctl, | ||
699 | .destroy = l2tp_ip6_destroy_sock, | ||
700 | .setsockopt = ipv6_setsockopt, | ||
701 | .getsockopt = ipv6_getsockopt, | ||
702 | .sendmsg = l2tp_ip6_sendmsg, | ||
703 | .recvmsg = l2tp_ip6_recvmsg, | ||
704 | .backlog_rcv = l2tp_ip6_backlog_recv, | ||
705 | .hash = inet_hash, | ||
706 | .unhash = inet_unhash, | ||
707 | .obj_size = sizeof(struct l2tp_ip6_sock), | ||
708 | #ifdef CONFIG_COMPAT | ||
709 | .compat_setsockopt = compat_ipv6_setsockopt, | ||
710 | .compat_getsockopt = compat_ipv6_getsockopt, | ||
711 | #endif | ||
712 | }; | ||
713 | |||
714 | static const struct proto_ops l2tp_ip6_ops = { | ||
715 | .family = PF_INET6, | ||
716 | .owner = THIS_MODULE, | ||
717 | .release = inet6_release, | ||
718 | .bind = inet6_bind, | ||
719 | .connect = inet_dgram_connect, | ||
720 | .socketpair = sock_no_socketpair, | ||
721 | .accept = sock_no_accept, | ||
722 | .getname = l2tp_ip6_getname, | ||
723 | .poll = datagram_poll, | ||
724 | .ioctl = inet6_ioctl, | ||
725 | .listen = sock_no_listen, | ||
726 | .shutdown = inet_shutdown, | ||
727 | .setsockopt = sock_common_setsockopt, | ||
728 | .getsockopt = sock_common_getsockopt, | ||
729 | .sendmsg = inet_sendmsg, | ||
730 | .recvmsg = sock_common_recvmsg, | ||
731 | .mmap = sock_no_mmap, | ||
732 | .sendpage = sock_no_sendpage, | ||
733 | #ifdef CONFIG_COMPAT | ||
734 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
735 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
736 | #endif | ||
737 | }; | ||
738 | |||
739 | static struct inet_protosw l2tp_ip6_protosw = { | ||
740 | .type = SOCK_DGRAM, | ||
741 | .protocol = IPPROTO_L2TP, | ||
742 | .prot = &l2tp_ip6_prot, | ||
743 | .ops = &l2tp_ip6_ops, | ||
744 | .no_check = 0, | ||
745 | }; | ||
746 | |||
747 | static struct inet6_protocol l2tp_ip6_protocol __read_mostly = { | ||
748 | .handler = l2tp_ip6_recv, | ||
749 | }; | ||
750 | |||
751 | static int __init l2tp_ip6_init(void) | ||
752 | { | ||
753 | int err; | ||
754 | |||
755 | printk(KERN_INFO "L2TP IP encapsulation support for IPv6 (L2TPv3)\n"); | ||
756 | |||
757 | err = proto_register(&l2tp_ip6_prot, 1); | ||
758 | if (err != 0) | ||
759 | goto out; | ||
760 | |||
761 | err = inet6_add_protocol(&l2tp_ip6_protocol, IPPROTO_L2TP); | ||
762 | if (err) | ||
763 | goto out1; | ||
764 | |||
765 | inet6_register_protosw(&l2tp_ip6_protosw); | ||
766 | return 0; | ||
767 | |||
768 | out1: | ||
769 | proto_unregister(&l2tp_ip6_prot); | ||
770 | out: | ||
771 | return err; | ||
772 | } | ||
773 | |||
774 | static void __exit l2tp_ip6_exit(void) | ||
775 | { | ||
776 | inet6_unregister_protosw(&l2tp_ip6_protosw); | ||
777 | inet6_del_protocol(&l2tp_ip6_protocol, IPPROTO_L2TP); | ||
778 | proto_unregister(&l2tp_ip6_prot); | ||
779 | } | ||
780 | |||
781 | module_init(l2tp_ip6_init); | ||
782 | module_exit(l2tp_ip6_exit); | ||
783 | |||
784 | MODULE_LICENSE("GPL"); | ||
785 | MODULE_AUTHOR("Chris Elston <celston@katalix.com>"); | ||
786 | MODULE_DESCRIPTION("L2TP IP encapsulation for IPv6"); | ||
787 | MODULE_VERSION("1.0"); | ||
788 | |||
789 | /* Use the value of SOCK_DGRAM (2) directory, because __stringify doesn't like | ||
790 | * enums | ||
791 | */ | ||
792 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 2, IPPROTO_L2TP); | ||