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 hlist_node *node;
64 struct sock *sk;
65
66 sk_for_each_bound(sk, node, &l2tp_ip6_bind_table) {
67 struct in6_addr *addr = inet6_rcv_saddr(sk);
68 struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
69
70 if (l2tp == NULL)
71 continue;
72
73 if ((l2tp->conn_id == tunnel_id) &&
74 net_eq(sock_net(sk), net) &&
75 !(addr && ipv6_addr_equal(addr, laddr)) &&
76 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
77 goto found;
78 }
79
80 sk = NULL;
81found:
82 return sk;
83}
84
85static inline struct sock *l2tp_ip6_bind_lookup(struct net *net,
86 struct in6_addr *laddr,
87 int dif, u32 tunnel_id)
88{
89 struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id);
90 if (sk)
91 sock_hold(sk);
92
93 return sk;
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
128
129static int l2tp_ip6_recv(struct sk_buff *skb)
130{
131 struct sock *sk;
132 u32 session_id;
133 u32 tunnel_id;
134 unsigned char *ptr, *optr;
135 struct l2tp_session *session;
136 struct l2tp_tunnel *tunnel = NULL;
137 int length;
138
139
140 optr = ptr = skb->data;
141
142 if (!pskb_may_pull(skb, 4))
143 goto discard;
144
145 session_id = ntohl(*((__be32 *) ptr));
146 ptr += 4;
147
148
149
150
151
152 if (session_id == 0) {
153 __skb_pull(skb, 4);
154 goto pass_up;
155 }
156
157
158 session = l2tp_session_find(&init_net, NULL, session_id);
159 if (session == NULL)
160 goto discard;
161
162 tunnel = session->tunnel;
163 if (tunnel == NULL)
164 goto discard;
165
166
167 if (tunnel->debug & L2TP_MSG_DATA) {
168 length = min(32u, skb->len);
169 if (!pskb_may_pull(skb, length))
170 goto discard;
171
172 pr_debug("%s: ip recv\n", tunnel->name);
173 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
174 }
175
176 l2tp_recv_common(session, skb, ptr, optr, 0, skb->len,
177 tunnel->recv_payload_hook);
178 return 0;
179
180pass_up:
181
182 if (!pskb_may_pull(skb, 12))
183 goto discard;
184
185 if ((skb->data[0] & 0xc0) != 0xc0)
186 goto discard;
187
188 tunnel_id = ntohl(*(__be32 *) &skb->data[4]);
189 tunnel = l2tp_tunnel_find(&init_net, tunnel_id);
190 if (tunnel != NULL)
191 sk = tunnel->sock;
192 else {
193 struct ipv6hdr *iph = ipv6_hdr(skb);
194
195 read_lock_bh(&l2tp_ip6_lock);
196 sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr,
197 0, tunnel_id);
198 read_unlock_bh(&l2tp_ip6_lock);
199 }
200
201 if (sk == NULL)
202 goto discard;
203
204 sock_hold(sk);
205
206 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
207 goto discard_put;
208
209 nf_reset(skb);
210
211 return sk_receive_skb(sk, skb, 1);
212
213discard_put:
214 sock_put(sk);
215
216discard:
217 kfree_skb(skb);
218 return 0;
219}
220
221static int l2tp_ip6_open(struct sock *sk)
222{
223
224 inet_sk(sk)->inet_num = IPPROTO_L2TP;
225
226 write_lock_bh(&l2tp_ip6_lock);
227 sk_add_node(sk, &l2tp_ip6_table);
228 write_unlock_bh(&l2tp_ip6_lock);
229
230 return 0;
231}
232
233static void l2tp_ip6_close(struct sock *sk, long timeout)
234{
235 write_lock_bh(&l2tp_ip6_lock);
236 hlist_del_init(&sk->sk_bind_node);
237 sk_del_node_init(sk);
238 write_unlock_bh(&l2tp_ip6_lock);
239
240 sk_common_release(sk);
241}
242
243static void l2tp_ip6_destroy_sock(struct sock *sk)
244{
245 lock_sock(sk);
246 ip6_flush_pending_frames(sk);
247 release_sock(sk);
248
249 inet6_destroy_sock(sk);
250}
251
252static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
253{
254 struct inet_sock *inet = inet_sk(sk);
255 struct ipv6_pinfo *np = inet6_sk(sk);
256 struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr;
257 __be32 v4addr = 0;
258 int addr_type;
259 int err;
260
261 if (!sock_flag(sk, SOCK_ZAPPED))
262 return -EINVAL;
263 if (addr->l2tp_family != AF_INET6)
264 return -EINVAL;
265 if (addr_len < sizeof(*addr))
266 return -EINVAL;
267
268 addr_type = ipv6_addr_type(&addr->l2tp_addr);
269
270
271 if (addr_type == IPV6_ADDR_MAPPED)
272 return -EADDRNOTAVAIL;
273
274
275 if (addr_type & IPV6_ADDR_MULTICAST)
276 return -EADDRNOTAVAIL;
277
278 err = -EADDRINUSE;
279 read_lock_bh(&l2tp_ip6_lock);
280 if (__l2tp_ip6_bind_lookup(&init_net, &addr->l2tp_addr,
281 sk->sk_bound_dev_if, addr->l2tp_conn_id))
282 goto out_in_use;
283 read_unlock_bh(&l2tp_ip6_lock);
284
285 lock_sock(sk);
286
287 err = -EINVAL;
288 if (sk->sk_state != TCP_CLOSE)
289 goto out_unlock;
290
291
292 rcu_read_lock();
293 if (addr_type != IPV6_ADDR_ANY) {
294 struct net_device *dev = NULL;
295
296 if (addr_type & IPV6_ADDR_LINKLOCAL) {
297 if (addr_len >= sizeof(struct sockaddr_in6) &&
298 addr->l2tp_scope_id) {
299
300
301
302 sk->sk_bound_dev_if = addr->l2tp_scope_id;
303 }
304
305
306
307 if (!sk->sk_bound_dev_if)
308 goto out_unlock_rcu;
309
310 err = -ENODEV;
311 dev = dev_get_by_index_rcu(sock_net(sk),
312 sk->sk_bound_dev_if);
313 if (!dev)
314 goto out_unlock_rcu;
315 }
316
317
318
319
320 v4addr = LOOPBACK4_IPV6;
321 err = -EADDRNOTAVAIL;
322 if (!ipv6_chk_addr(sock_net(sk), &addr->l2tp_addr, dev, 0))
323 goto out_unlock_rcu;
324 }
325 rcu_read_unlock();
326
327 inet->inet_rcv_saddr = inet->inet_saddr = v4addr;
328 np->rcv_saddr = addr->l2tp_addr;
329 np->saddr = addr->l2tp_addr;
330
331 l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id;
332
333 write_lock_bh(&l2tp_ip6_lock);
334 sk_add_bind_node(sk, &l2tp_ip6_bind_table);
335 sk_del_node_init(sk);
336 write_unlock_bh(&l2tp_ip6_lock);
337
338 sock_reset_flag(sk, SOCK_ZAPPED);
339 release_sock(sk);
340 return 0;
341
342out_unlock_rcu:
343 rcu_read_unlock();
344out_unlock:
345 release_sock(sk);
346 return err;
347
348out_in_use:
349 read_unlock_bh(&l2tp_ip6_lock);
350 return err;
351}
352
353static 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 (sock_flag(sk, SOCK_ZAPPED))
363 return -EINVAL;
364
365 if (addr_len < sizeof(*lsa))
366 return -EINVAL;
367
368 addr_type = ipv6_addr_type(&usin->sin6_addr);
369 if (addr_type & IPV6_ADDR_MULTICAST)
370 return -EINVAL;
371
372 if (addr_type & IPV6_ADDR_MAPPED) {
373 daddr = &usin->sin6_addr;
374 if (ipv4_is_multicast(daddr->s6_addr32[3]))
375 return -EINVAL;
376 }
377
378 rc = ip6_datagram_connect(sk, uaddr, addr_len);
379
380 lock_sock(sk);
381
382 l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
383
384 write_lock_bh(&l2tp_ip6_lock);
385 hlist_del_init(&sk->sk_bind_node);
386 sk_add_bind_node(sk, &l2tp_ip6_bind_table);
387 write_unlock_bh(&l2tp_ip6_lock);
388
389 release_sock(sk);
390
391 return rc;
392}
393
394static int l2tp_ip6_disconnect(struct sock *sk, int flags)
395{
396 if (sock_flag(sk, SOCK_ZAPPED))
397 return 0;
398
399 return udp_disconnect(sk, flags);
400}
401
402static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,
403 int *uaddr_len, int peer)
404{
405 struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)uaddr;
406 struct sock *sk = sock->sk;
407 struct ipv6_pinfo *np = inet6_sk(sk);
408 struct l2tp_ip6_sock *lsk = l2tp_ip6_sk(sk);
409
410 lsa->l2tp_family = AF_INET6;
411 lsa->l2tp_flowinfo = 0;
412 lsa->l2tp_scope_id = 0;
413 lsa->l2tp_unused = 0;
414 if (peer) {
415 if (!lsk->peer_conn_id)
416 return -ENOTCONN;
417 lsa->l2tp_conn_id = lsk->peer_conn_id;
418 lsa->l2tp_addr = np->daddr;
419 if (np->sndflow)
420 lsa->l2tp_flowinfo = np->flow_label;
421 } else {
422 if (ipv6_addr_any(&np->rcv_saddr))
423 lsa->l2tp_addr = np->saddr;
424 else
425 lsa->l2tp_addr = np->rcv_saddr;
426
427 lsa->l2tp_conn_id = lsk->conn_id;
428 }
429 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
430 lsa->l2tp_scope_id = sk->sk_bound_dev_if;
431 *uaddr_len = sizeof(*lsa);
432 return 0;
433}
434
435static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb)
436{
437 int rc;
438
439
440 rc = sock_queue_rcv_skb(sk, skb);
441 if (rc < 0)
442 goto drop;
443
444 return 0;
445
446drop:
447 IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS);
448 kfree_skb(skb);
449 return -1;
450}
451
452static int l2tp_ip6_push_pending_frames(struct sock *sk)
453{
454 struct sk_buff *skb;
455 __be32 *transhdr = NULL;
456 int err = 0;
457
458 skb = skb_peek(&sk->sk_write_queue);
459 if (skb == NULL)
460 goto out;
461
462 transhdr = (__be32 *)skb_transport_header(skb);
463 *transhdr = 0;
464
465 err = ip6_push_pending_frames(sk);
466
467out:
468 return err;
469}
470
471
472
473
474static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
475 struct msghdr *msg, size_t len)
476{
477 struct ipv6_txoptions opt_space;
478 struct sockaddr_l2tpip6 *lsa =
479 (struct sockaddr_l2tpip6 *) msg->msg_name;
480 struct in6_addr *daddr, *final_p, final;
481 struct ipv6_pinfo *np = inet6_sk(sk);
482 struct ipv6_txoptions *opt = NULL;
483 struct ip6_flowlabel *flowlabel = NULL;
484 struct dst_entry *dst = NULL;
485 struct flowi6 fl6;
486 int addr_len = msg->msg_namelen;
487 int hlimit = -1;
488 int tclass = -1;
489 int dontfrag = -1;
490 int transhdrlen = 4;
491 int ulen = len + transhdrlen;
492 int err;
493
494
495
496
497 if (len > INT_MAX)
498 return -EMSGSIZE;
499
500
501 if (msg->msg_flags & MSG_OOB)
502 return -EOPNOTSUPP;
503
504
505
506
507 memset(&fl6, 0, sizeof(fl6));
508
509 fl6.flowi6_mark = sk->sk_mark;
510
511 if (lsa) {
512 if (addr_len < SIN6_LEN_RFC2133)
513 return -EINVAL;
514
515 if (lsa->l2tp_family && lsa->l2tp_family != AF_INET6)
516 return -EAFNOSUPPORT;
517
518 daddr = &lsa->l2tp_addr;
519 if (np->sndflow) {
520 fl6.flowlabel = lsa->l2tp_flowinfo & IPV6_FLOWINFO_MASK;
521 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
522 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
523 if (flowlabel == NULL)
524 return -EINVAL;
525 daddr = &flowlabel->dst;
526 }
527 }
528
529
530
531
532
533 if (sk->sk_state == TCP_ESTABLISHED &&
534 ipv6_addr_equal(daddr, &np->daddr))
535 daddr = &np->daddr;
536
537 if (addr_len >= sizeof(struct sockaddr_in6) &&
538 lsa->l2tp_scope_id &&
539 ipv6_addr_type(daddr) & IPV6_ADDR_LINKLOCAL)
540 fl6.flowi6_oif = lsa->l2tp_scope_id;
541 } else {
542 if (sk->sk_state != TCP_ESTABLISHED)
543 return -EDESTADDRREQ;
544
545 daddr = &np->daddr;
546 fl6.flowlabel = np->flow_label;
547 }
548
549 if (fl6.flowi6_oif == 0)
550 fl6.flowi6_oif = sk->sk_bound_dev_if;
551
552 if (msg->msg_controllen) {
553 opt = &opt_space;
554 memset(opt, 0, sizeof(struct ipv6_txoptions));
555 opt->tot_len = sizeof(struct ipv6_txoptions);
556
557 err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
558 &hlimit, &tclass, &dontfrag);
559 if (err < 0) {
560 fl6_sock_release(flowlabel);
561 return err;
562 }
563 if ((fl6.flowlabel & IPV6_FLOWLABEL_MASK) && !flowlabel) {
564 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
565 if (flowlabel == NULL)
566 return -EINVAL;
567 }
568 if (!(opt->opt_nflen|opt->opt_flen))
569 opt = NULL;
570 }
571
572 if (opt == NULL)
573 opt = np->opt;
574 if (flowlabel)
575 opt = fl6_merge_options(&opt_space, flowlabel, opt);
576 opt = ipv6_fixup_options(&opt_space, opt);
577
578 fl6.flowi6_proto = sk->sk_protocol;
579 if (!ipv6_addr_any(daddr))
580 fl6.daddr = *daddr;
581 else
582 fl6.daddr.s6_addr[15] = 0x1;
583 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
584 fl6.saddr = np->saddr;
585
586 final_p = fl6_update_dst(&fl6, opt, &final);
587
588 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
589 fl6.flowi6_oif = np->mcast_oif;
590 else if (!fl6.flowi6_oif)
591 fl6.flowi6_oif = np->ucast_oif;
592
593 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
594
595 dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
596 if (IS_ERR(dst)) {
597 err = PTR_ERR(dst);
598 goto out;
599 }
600
601 if (hlimit < 0) {
602 if (ipv6_addr_is_multicast(&fl6.daddr))
603 hlimit = np->mcast_hops;
604 else
605 hlimit = np->hop_limit;
606 if (hlimit < 0)
607 hlimit = ip6_dst_hoplimit(dst);
608 }
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->msg_iov,
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 kiocb *iocb, struct sock *sk,
646 struct msghdr *msg, size_t len, int noblock,
647 int flags, int *addr_len)
648{
649 struct inet_sock *inet = inet_sk(sk);
650 struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name;
651 size_t copied = 0;
652 int err = -EOPNOTSUPP;
653 struct sk_buff *skb;
654
655 if (flags & MSG_OOB)
656 goto out;
657
658 if (addr_len)
659 *addr_len = sizeof(*lsa);
660
661 if (flags & MSG_ERRQUEUE)
662 return ipv6_recv_error(sk, msg, len);
663
664 skb = skb_recv_datagram(sk, flags, noblock, &err);
665 if (!skb)
666 goto out;
667
668 copied = skb->len;
669 if (len < copied) {
670 msg->msg_flags |= MSG_TRUNC;
671 copied = len;
672 }
673
674 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
675 if (err)
676 goto done;
677
678 sock_recv_timestamp(msg, sk, skb);
679
680
681 if (lsa) {
682 lsa->l2tp_family = AF_INET6;
683 lsa->l2tp_unused = 0;
684 lsa->l2tp_addr = ipv6_hdr(skb)->saddr;
685 lsa->l2tp_flowinfo = 0;
686 lsa->l2tp_scope_id = 0;
687 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
688 lsa->l2tp_scope_id = IP6CB(skb)->iif;
689 }
690
691 if (inet->cmsg_flags)
692 ip_cmsg_recv(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 .no_check = 0,
757};
758
759static struct inet6_protocol l2tp_ip6_protocol __read_mostly = {
760 .handler = l2tp_ip6_recv,
761};
762
763static int __init l2tp_ip6_init(void)
764{
765 int err;
766
767 pr_info("L2TP IP encapsulation support for IPv6 (L2TPv3)\n");
768
769 err = proto_register(&l2tp_ip6_prot, 1);
770 if (err != 0)
771 goto out;
772
773 err = inet6_add_protocol(&l2tp_ip6_protocol, IPPROTO_L2TP);
774 if (err)
775 goto out1;
776
777 inet6_register_protosw(&l2tp_ip6_protosw);
778 return 0;
779
780out1:
781 proto_unregister(&l2tp_ip6_prot);
782out:
783 return err;
784}
785
786static void __exit l2tp_ip6_exit(void)
787{
788 inet6_unregister_protosw(&l2tp_ip6_protosw);
789 inet6_del_protocol(&l2tp_ip6_protocol, IPPROTO_L2TP);
790 proto_unregister(&l2tp_ip6_prot);
791}
792
793module_init(l2tp_ip6_init);
794module_exit(l2tp_ip6_exit);
795
796MODULE_LICENSE("GPL");
797MODULE_AUTHOR("Chris Elston <celston@katalix.com>");
798MODULE_DESCRIPTION("L2TP IP encapsulation for IPv6");
799MODULE_VERSION("1.0");
800
801
802
803
804MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 2, IPPROTO_L2TP);
805