1
2
3
4
5
6
7
8
9
10
11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#include <linux/icmp.h>
15#include <linux/module.h>
16#include <linux/skbuff.h>
17#include <linux/random.h>
18#include <linux/socket.h>
19#include <linux/l2tp.h>
20#include <linux/in.h>
21#include <linux/in6.h>
22#include <net/sock.h>
23#include <net/ip.h>
24#include <net/icmp.h>
25#include <net/udp.h>
26#include <net/inet_common.h>
27#include <net/inet_hashtables.h>
28#include <net/tcp_states.h>
29#include <net/protocol.h>
30#include <net/xfrm.h>
31
32#include <net/transp_v6.h>
33#include <net/addrconf.h>
34#include <net/ip6_route.h>
35
36#include "l2tp_core.h"
37
38struct l2tp_ip6_sock {
39
40 struct inet_sock inet;
41
42 u32 conn_id;
43 u32 peer_conn_id;
44
45
46
47 struct ipv6_pinfo inet6;
48};
49
50static DEFINE_RWLOCK(l2tp_ip6_lock);
51static struct hlist_head l2tp_ip6_table;
52static struct hlist_head l2tp_ip6_bind_table;
53
54static inline struct l2tp_ip6_sock *l2tp_ip6_sk(const struct sock *sk)
55{
56 return (struct l2tp_ip6_sock *)sk;
57}
58
59static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
60 struct in6_addr *laddr,
61 int dif, u32 tunnel_id)
62{
63 struct sock *sk;
64
65 sk_for_each_bound(sk, &l2tp_ip6_bind_table) {
66 const struct in6_addr *addr = inet6_rcv_saddr(sk);
67 struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
68
69 if (l2tp == NULL)
70 continue;
71
72 if ((l2tp->conn_id == tunnel_id) &&
73 net_eq(sock_net(sk), net) &&
74 !(addr && ipv6_addr_equal(addr, laddr)) &&
75 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
76 goto found;
77 }
78
79 sk = NULL;
80found:
81 return sk;
82}
83
84static inline struct sock *l2tp_ip6_bind_lookup(struct net *net,
85 struct in6_addr *laddr,
86 int dif, u32 tunnel_id)
87{
88 struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id);
89 if (sk)
90 sock_hold(sk);
91
92 return sk;
93}
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128static int l2tp_ip6_recv(struct sk_buff *skb)
129{
130 struct sock *sk;
131 u32 session_id;
132 u32 tunnel_id;
133 unsigned char *ptr, *optr;
134 struct l2tp_session *session;
135 struct l2tp_tunnel *tunnel = NULL;
136 int length;
137
138
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
148
149
150
151 if (session_id == 0) {
152 __skb_pull(skb, 4);
153 goto pass_up;
154 }
155
156
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
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 pr_debug("%s: ip recv\n", tunnel->name);
172 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
173 }
174
175 l2tp_recv_common(session, skb, ptr, optr, 0, skb->len,
176 tunnel->recv_payload_hook);
177 return 0;
178
179pass_up:
180
181 if (!pskb_may_pull(skb, 12))
182 goto discard;
183
184 if ((skb->data[0] & 0xc0) != 0xc0)
185 goto discard;
186
187 tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
188 tunnel = l2tp_tunnel_find(&init_net, tunnel_id);
189 if (tunnel != NULL)
190 sk = tunnel->sock;
191 else {
192 struct ipv6hdr *iph = ipv6_hdr(skb);
193
194 read_lock_bh(&l2tp_ip6_lock);
195 sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr,
196 0, tunnel_id);
197 read_unlock_bh(&l2tp_ip6_lock);
198 }
199
200 if (sk == NULL)
201 goto discard;
202
203 sock_hold(sk);
204
205 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
206 goto discard_put;
207
208 nf_reset(skb);
209
210 return sk_receive_skb(sk, skb, 1);
211
212discard_put:
213 sock_put(sk);
214
215discard:
216 kfree_skb(skb);
217 return 0;
218}
219
220static int l2tp_ip6_open(struct sock *sk)
221{
222
223 inet_sk(sk)->inet_num = IPPROTO_L2TP;
224
225 write_lock_bh(&l2tp_ip6_lock);
226 sk_add_node(sk, &l2tp_ip6_table);
227 write_unlock_bh(&l2tp_ip6_lock);
228
229 return 0;
230}
231
232static void l2tp_ip6_close(struct sock *sk, long timeout)
233{
234 write_lock_bh(&l2tp_ip6_lock);
235 hlist_del_init(&sk->sk_bind_node);
236 sk_del_node_init(sk);
237 write_unlock_bh(&l2tp_ip6_lock);
238
239 sk_common_release(sk);
240}
241
242static void l2tp_ip6_destroy_sock(struct sock *sk)
243{
244 struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
245
246 lock_sock(sk);
247 ip6_flush_pending_frames(sk);
248 release_sock(sk);
249
250 if (tunnel) {
251 l2tp_tunnel_closeall(tunnel);
252 sock_put(sk);
253 }
254
255 inet6_destroy_sock(sk);
256}
257
258static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
259{
260 struct inet_sock *inet = inet_sk(sk);
261 struct ipv6_pinfo *np = inet6_sk(sk);
262 struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr;
263 __be32 v4addr = 0;
264 int addr_type;
265 int err;
266
267 if (!sock_flag(sk, SOCK_ZAPPED))
268 return -EINVAL;
269 if (addr->l2tp_family != AF_INET6)
270 return -EINVAL;
271 if (addr_len < sizeof(*addr))
272 return -EINVAL;
273
274 addr_type = ipv6_addr_type(&addr->l2tp_addr);
275
276
277 if (addr_type == IPV6_ADDR_MAPPED)
278 return -EADDRNOTAVAIL;
279
280
281 if (addr_type & IPV6_ADDR_MULTICAST)
282 return -EADDRNOTAVAIL;
283
284 err = -EADDRINUSE;
285 read_lock_bh(&l2tp_ip6_lock);
286 if (__l2tp_ip6_bind_lookup(&init_net, &addr->l2tp_addr,
287 sk->sk_bound_dev_if, addr->l2tp_conn_id))
288 goto out_in_use;
289 read_unlock_bh(&l2tp_ip6_lock);
290
291 lock_sock(sk);
292
293 err = -EINVAL;
294 if (sk->sk_state != TCP_CLOSE)
295 goto out_unlock;
296
297
298 rcu_read_lock();
299 if (addr_type != IPV6_ADDR_ANY) {
300 struct net_device *dev = NULL;
301
302 if (addr_type & IPV6_ADDR_LINKLOCAL) {
303 if (addr_len >= sizeof(struct sockaddr_in6) &&
304 addr->l2tp_scope_id) {
305
306
307
308 sk->sk_bound_dev_if = addr->l2tp_scope_id;
309 }
310
311
312
313 if (!sk->sk_bound_dev_if)
314 goto out_unlock_rcu;
315
316 err = -ENODEV;
317 dev = dev_get_by_index_rcu(sock_net(sk),
318 sk->sk_bound_dev_if);
319 if (!dev)
320 goto out_unlock_rcu;
321 }
322
323
324
325
326 v4addr = LOOPBACK4_IPV6;
327 err = -EADDRNOTAVAIL;
328 if (!ipv6_chk_addr(sock_net(sk), &addr->l2tp_addr, dev, 0))
329 goto out_unlock_rcu;
330 }
331 rcu_read_unlock();
332
333 inet->inet_rcv_saddr = inet->inet_saddr = v4addr;
334 sk->sk_v6_rcv_saddr = addr->l2tp_addr;
335 np->saddr = addr->l2tp_addr;
336
337 l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id;
338
339 write_lock_bh(&l2tp_ip6_lock);
340 sk_add_bind_node(sk, &l2tp_ip6_bind_table);
341 sk_del_node_init(sk);
342 write_unlock_bh(&l2tp_ip6_lock);
343
344 sock_reset_flag(sk, SOCK_ZAPPED);
345 release_sock(sk);
346 return 0;
347
348out_unlock_rcu:
349 rcu_read_unlock();
350out_unlock:
351 release_sock(sk);
352 return err;
353
354out_in_use:
355 read_unlock_bh(&l2tp_ip6_lock);
356 return err;
357}
358
359static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
360 int addr_len)
361{
362 struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *) uaddr;
363 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
364 struct in6_addr *daddr;
365 int addr_type;
366 int rc;
367
368 if (sock_flag(sk, SOCK_ZAPPED))
369 return -EINVAL;
370
371 if (addr_len < sizeof(*lsa))
372 return -EINVAL;
373
374 if (usin->sin6_family != AF_INET6)
375 return -EINVAL;
376
377 addr_type = ipv6_addr_type(&usin->sin6_addr);
378 if (addr_type & IPV6_ADDR_MULTICAST)
379 return -EINVAL;
380
381 if (addr_type & IPV6_ADDR_MAPPED) {
382 daddr = &usin->sin6_addr;
383 if (ipv4_is_multicast(daddr->s6_addr32[3]))
384 return -EINVAL;
385 }
386
387 rc = ip6_datagram_connect(sk, uaddr, addr_len);
388
389 lock_sock(sk);
390
391 l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
392
393 write_lock_bh(&l2tp_ip6_lock);
394 hlist_del_init(&sk->sk_bind_node);
395 sk_add_bind_node(sk, &l2tp_ip6_bind_table);
396 write_unlock_bh(&l2tp_ip6_lock);
397
398 release_sock(sk);
399
400 return rc;
401}
402
403static int l2tp_ip6_disconnect(struct sock *sk, int flags)
404{
405 if (sock_flag(sk, SOCK_ZAPPED))
406 return 0;
407
408 return udp_disconnect(sk, flags);
409}
410
411static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,
412 int *uaddr_len, int peer)
413{
414 struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)uaddr;
415 struct sock *sk = sock->sk;
416 struct ipv6_pinfo *np = inet6_sk(sk);
417 struct l2tp_ip6_sock *lsk = l2tp_ip6_sk(sk);
418
419 lsa->l2tp_family = AF_INET6;
420 lsa->l2tp_flowinfo = 0;
421 lsa->l2tp_scope_id = 0;
422 lsa->l2tp_unused = 0;
423 if (peer) {
424 if (!lsk->peer_conn_id)
425 return -ENOTCONN;
426 lsa->l2tp_conn_id = lsk->peer_conn_id;
427 lsa->l2tp_addr = sk->sk_v6_daddr;
428 if (np->sndflow)
429 lsa->l2tp_flowinfo = np->flow_label;
430 } else {
431 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
432 lsa->l2tp_addr = np->saddr;
433 else
434 lsa->l2tp_addr = sk->sk_v6_rcv_saddr;
435
436 lsa->l2tp_conn_id = lsk->conn_id;
437 }
438 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
439 lsa->l2tp_scope_id = sk->sk_bound_dev_if;
440 *uaddr_len = sizeof(*lsa);
441 return 0;
442}
443
444static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb)
445{
446 int rc;
447
448
449 rc = sock_queue_rcv_skb(sk, skb);
450 if (rc < 0)
451 goto drop;
452
453 return 0;
454
455drop:
456 IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS);
457 kfree_skb(skb);
458 return -1;
459}
460
461static int l2tp_ip6_push_pending_frames(struct sock *sk)
462{
463 struct sk_buff *skb;
464 __be32 *transhdr = NULL;
465 int err = 0;
466
467 skb = skb_peek(&sk->sk_write_queue);
468 if (skb == NULL)
469 goto out;
470
471 transhdr = (__be32 *)skb_transport_header(skb);
472 *transhdr = 0;
473
474 err = ip6_push_pending_frames(sk);
475
476out:
477 return err;
478}
479
480
481
482
483static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
484{
485 struct ipv6_txoptions opt_space;
486 DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
487 struct in6_addr *daddr, *final_p, final;
488 struct ipv6_pinfo *np = inet6_sk(sk);
489 struct ipv6_txoptions *opt = NULL;
490 struct ip6_flowlabel *flowlabel = NULL;
491 struct dst_entry *dst = NULL;
492 struct flowi6 fl6;
493 int addr_len = msg->msg_namelen;
494 int hlimit = -1;
495 int tclass = -1;
496 int dontfrag = -1;
497 int transhdrlen = 4;
498 int ulen = len + transhdrlen;
499 int err;
500
501
502
503
504 if (len > INT_MAX)
505 return -EMSGSIZE;
506
507
508 if (msg->msg_flags & MSG_OOB)
509 return -EOPNOTSUPP;
510
511
512
513
514 memset(&fl6, 0, sizeof(fl6));
515
516 fl6.flowi6_mark = sk->sk_mark;
517
518 if (lsa) {
519 if (addr_len < SIN6_LEN_RFC2133)
520 return -EINVAL;
521
522 if (lsa->l2tp_family && lsa->l2tp_family != AF_INET6)
523 return -EAFNOSUPPORT;
524
525 daddr = &lsa->l2tp_addr;
526 if (np->sndflow) {
527 fl6.flowlabel = lsa->l2tp_flowinfo & IPV6_FLOWINFO_MASK;
528 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
529 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
530 if (flowlabel == NULL)
531 return -EINVAL;
532 }
533 }
534
535
536
537
538
539 if (sk->sk_state == TCP_ESTABLISHED &&
540 ipv6_addr_equal(daddr, &sk->sk_v6_daddr))
541 daddr = &sk->sk_v6_daddr;
542
543 if (addr_len >= sizeof(struct sockaddr_in6) &&
544 lsa->l2tp_scope_id &&
545 ipv6_addr_type(daddr) & IPV6_ADDR_LINKLOCAL)
546 fl6.flowi6_oif = lsa->l2tp_scope_id;
547 } else {
548 if (sk->sk_state != TCP_ESTABLISHED)
549 return -EDESTADDRREQ;
550
551 daddr = &sk->sk_v6_daddr;
552 fl6.flowlabel = np->flow_label;
553 }
554
555 if (fl6.flowi6_oif == 0)
556 fl6.flowi6_oif = sk->sk_bound_dev_if;
557
558 if (msg->msg_controllen) {
559 opt = &opt_space;
560 memset(opt, 0, sizeof(struct ipv6_txoptions));
561 opt->tot_len = sizeof(struct ipv6_txoptions);
562
563 err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
564 &hlimit, &tclass, &dontfrag);
565 if (err < 0) {
566 fl6_sock_release(flowlabel);
567 return err;
568 }
569 if ((fl6.flowlabel & IPV6_FLOWLABEL_MASK) && !flowlabel) {
570 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
571 if (flowlabel == NULL)
572 return -EINVAL;
573 }
574 if (!(opt->opt_nflen|opt->opt_flen))
575 opt = NULL;
576 }
577
578 if (opt == NULL)
579 opt = np->opt;
580 if (flowlabel)
581 opt = fl6_merge_options(&opt_space, flowlabel, opt);
582 opt = ipv6_fixup_options(&opt_space, opt);
583
584 fl6.flowi6_proto = sk->sk_protocol;
585 if (!ipv6_addr_any(daddr))
586 fl6.daddr = *daddr;
587 else
588 fl6.daddr.s6_addr[15] = 0x1;
589 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
590 fl6.saddr = np->saddr;
591
592 final_p = fl6_update_dst(&fl6, opt, &final);
593
594 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
595 fl6.flowi6_oif = np->mcast_oif;
596 else if (!fl6.flowi6_oif)
597 fl6.flowi6_oif = np->ucast_oif;
598
599 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
600
601 dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
602 if (IS_ERR(dst)) {
603 err = PTR_ERR(dst);
604 goto out;
605 }
606
607 if (hlimit < 0)
608 hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
609
610 if (tclass < 0)
611 tclass = np->tclass;
612
613 if (dontfrag < 0)
614 dontfrag = np->dontfrag;
615
616 if (msg->msg_flags & MSG_CONFIRM)
617 goto do_confirm;
618
619back_from_confirm:
620 lock_sock(sk);
621 err = ip6_append_data(sk, ip_generic_getfrag, msg,
622 ulen, transhdrlen, hlimit, tclass, opt,
623 &fl6, (struct rt6_info *)dst,
624 msg->msg_flags, dontfrag);
625 if (err)
626 ip6_flush_pending_frames(sk);
627 else if (!(msg->msg_flags & MSG_MORE))
628 err = l2tp_ip6_push_pending_frames(sk);
629 release_sock(sk);
630done:
631 dst_release(dst);
632out:
633 fl6_sock_release(flowlabel);
634
635 return err < 0 ? err : len;
636
637do_confirm:
638 dst_confirm(dst);
639 if (!(msg->msg_flags & MSG_PROBE) || len)
640 goto back_from_confirm;
641 err = 0;
642 goto done;
643}
644
645static int l2tp_ip6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
646 int noblock, int flags, int *addr_len)
647{
648 struct ipv6_pinfo *np = inet6_sk(sk);
649 DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
650 size_t copied = 0;
651 int err = -EOPNOTSUPP;
652 struct sk_buff *skb;
653
654 if (flags & MSG_OOB)
655 goto out;
656
657 if (addr_len)
658 *addr_len = sizeof(*lsa);
659
660 if (flags & MSG_ERRQUEUE)
661 return ipv6_recv_error(sk, msg, len, addr_len);
662
663 skb = skb_recv_datagram(sk, flags, noblock, &err);
664 if (!skb)
665 goto out;
666
667 copied = skb->len;
668 if (len < copied) {
669 msg->msg_flags |= MSG_TRUNC;
670 copied = len;
671 }
672
673 err = skb_copy_datagram_msg(skb, 0, msg, copied);
674 if (err)
675 goto done;
676
677 sock_recv_timestamp(msg, sk, skb);
678
679
680 if (lsa) {
681 lsa->l2tp_family = AF_INET6;
682 lsa->l2tp_unused = 0;
683 lsa->l2tp_addr = ipv6_hdr(skb)->saddr;
684 lsa->l2tp_flowinfo = 0;
685 lsa->l2tp_scope_id = 0;
686 lsa->l2tp_conn_id = 0;
687 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
688 lsa->l2tp_scope_id = inet6_iif(skb);
689 }
690
691 if (np->rxopt.all)
692 ip6_datagram_recv_ctl(sk, msg, skb);
693
694 if (flags & MSG_TRUNC)
695 copied = skb->len;
696done:
697 skb_free_datagram(sk, skb);
698out:
699 return err ? err : copied;
700}
701
702static struct proto l2tp_ip6_prot = {
703 .name = "L2TP/IPv6",
704 .owner = THIS_MODULE,
705 .init = l2tp_ip6_open,
706 .close = l2tp_ip6_close,
707 .bind = l2tp_ip6_bind,
708 .connect = l2tp_ip6_connect,
709 .disconnect = l2tp_ip6_disconnect,
710 .ioctl = udp_ioctl,
711 .destroy = l2tp_ip6_destroy_sock,
712 .setsockopt = ipv6_setsockopt,
713 .getsockopt = ipv6_getsockopt,
714 .sendmsg = l2tp_ip6_sendmsg,
715 .recvmsg = l2tp_ip6_recvmsg,
716 .backlog_rcv = l2tp_ip6_backlog_recv,
717 .hash = inet_hash,
718 .unhash = inet_unhash,
719 .obj_size = sizeof(struct l2tp_ip6_sock),
720#ifdef CONFIG_COMPAT
721 .compat_setsockopt = compat_ipv6_setsockopt,
722 .compat_getsockopt = compat_ipv6_getsockopt,
723#endif
724};
725
726static const struct proto_ops l2tp_ip6_ops = {
727 .family = PF_INET6,
728 .owner = THIS_MODULE,
729 .release = inet6_release,
730 .bind = inet6_bind,
731 .connect = inet_dgram_connect,
732 .socketpair = sock_no_socketpair,
733 .accept = sock_no_accept,
734 .getname = l2tp_ip6_getname,
735 .poll = datagram_poll,
736 .ioctl = inet6_ioctl,
737 .listen = sock_no_listen,
738 .shutdown = inet_shutdown,
739 .setsockopt = sock_common_setsockopt,
740 .getsockopt = sock_common_getsockopt,
741 .sendmsg = inet_sendmsg,
742 .recvmsg = sock_common_recvmsg,
743 .mmap = sock_no_mmap,
744 .sendpage = sock_no_sendpage,
745#ifdef CONFIG_COMPAT
746 .compat_setsockopt = compat_sock_common_setsockopt,
747 .compat_getsockopt = compat_sock_common_getsockopt,
748#endif
749};
750
751static struct inet_protosw l2tp_ip6_protosw = {
752 .type = SOCK_DGRAM,
753 .protocol = IPPROTO_L2TP,
754 .prot = &l2tp_ip6_prot,
755 .ops = &l2tp_ip6_ops,
756};
757
758static struct inet6_protocol l2tp_ip6_protocol __read_mostly = {
759 .handler = l2tp_ip6_recv,
760};
761
762static int __init l2tp_ip6_init(void)
763{
764 int err;
765
766 pr_info("L2TP IP encapsulation support for IPv6 (L2TPv3)\n");
767
768 err = proto_register(&l2tp_ip6_prot, 1);
769 if (err != 0)
770 goto out;
771
772 err = inet6_add_protocol(&l2tp_ip6_protocol, IPPROTO_L2TP);
773 if (err)
774 goto out1;
775
776 inet6_register_protosw(&l2tp_ip6_protosw);
777 return 0;
778
779out1:
780 proto_unregister(&l2tp_ip6_prot);
781out:
782 return err;
783}
784
785static void __exit l2tp_ip6_exit(void)
786{
787 inet6_unregister_protosw(&l2tp_ip6_protosw);
788 inet6_del_protocol(&l2tp_ip6_protocol, IPPROTO_L2TP);
789 proto_unregister(&l2tp_ip6_prot);
790}
791
792module_init(l2tp_ip6_init);
793module_exit(l2tp_ip6_exit);
794
795MODULE_LICENSE("GPL");
796MODULE_AUTHOR("Chris Elston <celston@katalix.com>");
797MODULE_DESCRIPTION("L2TP IP encapsulation for IPv6");
798MODULE_VERSION("1.0");
799
800
801
802
803MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 2, IPPROTO_L2TP);
804