Merge with Linux 2.5.48.
[linux-2.6/linux-mips.git] / net / ipv6 / af_inet6.c
blob86cbad545ca8746c916a37e1159da03fa0f220fd
1 /*
2 * PF_INET6 socket protocol family
3 * Linux INET6 implementation
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
8 * Adapted from linux/net/ipv4/af_inet.c
10 * $Id: af_inet6.c,v 1.66 2002/02/01 22:01:04 davem Exp $
12 * Fixes:
13 * piggy, Karl Knutson : Socket protocol table
14 * Hideaki YOSHIFUJI : sin6_scope_id support
15 * Arnaldo Melo : check proc_net_create return, cleanups
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version
20 * 2 of the License, or (at your option) any later version.
24 #include <linux/module.h>
25 #include <linux/config.h>
26 #include <linux/errno.h>
27 #include <linux/types.h>
28 #include <linux/socket.h>
29 #include <linux/in.h>
30 #include <linux/kernel.h>
31 #include <linux/major.h>
32 #include <linux/sched.h>
33 #include <linux/timer.h>
34 #include <linux/string.h>
35 #include <linux/sockios.h>
36 #include <linux/net.h>
37 #include <linux/fcntl.h>
38 #include <linux/mm.h>
39 #include <linux/interrupt.h>
40 #include <linux/proc_fs.h>
41 #include <linux/stat.h>
42 #include <linux/init.h>
43 #include <linux/version.h>
45 #include <linux/inet.h>
46 #include <linux/netdevice.h>
47 #include <linux/icmpv6.h>
48 #include <linux/brlock.h>
49 #include <linux/smp_lock.h>
51 #include <net/ip.h>
52 #include <net/ipv6.h>
53 #include <net/udp.h>
54 #include <net/tcp.h>
55 #include <net/ipip.h>
56 #include <net/protocol.h>
57 #include <net/inet_common.h>
58 #include <net/transp_v6.h>
59 #include <net/ip6_route.h>
60 #include <net/addrconf.h>
62 #include <asm/uaccess.h>
63 #include <asm/system.h>
65 #ifdef MODULE
66 static int unloadable = 0; /* XX: Turn to one when all is ok within the
67 module for allowing unload */
68 #endif
70 #if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
71 MODULE_AUTHOR("Cast of dozens");
72 MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
73 MODULE_PARM(unloadable, "i");
74 #endif
76 /* IPv6 procfs goodies... */
78 #ifdef CONFIG_PROC_FS
79 extern int raw6_get_info(char *, char **, off_t, int);
80 extern int tcp6_get_info(char *, char **, off_t, int);
81 extern int udp6_get_info(char *, char **, off_t, int);
82 extern int afinet6_get_info(char *, char **, off_t, int);
83 extern int afinet6_get_snmp(char *, char **, off_t, int);
84 #endif
86 #ifdef CONFIG_SYSCTL
87 extern void ipv6_sysctl_register(void);
88 extern void ipv6_sysctl_unregister(void);
89 #endif
91 int sysctl_ipv6_bindv6only;
93 #ifdef INET_REFCNT_DEBUG
94 atomic_t inet6_sock_nr;
95 #endif
97 /* Per protocol sock slabcache */
98 kmem_cache_t *tcp6_sk_cachep;
99 kmem_cache_t *udp6_sk_cachep;
100 kmem_cache_t *raw6_sk_cachep;
102 /* The inetsw table contains everything that inet_create needs to
103 * build a new socket.
105 struct list_head inetsw6[SOCK_MAX];
107 static void inet6_sock_destruct(struct sock *sk)
109 inet_sock_destruct(sk);
111 #ifdef INET_REFCNT_DEBUG
112 atomic_dec(&inet6_sock_nr);
113 #endif
114 MOD_DEC_USE_COUNT;
117 static __inline__ kmem_cache_t *inet6_sk_slab(int protocol)
119 kmem_cache_t* rc = tcp6_sk_cachep;
121 if (protocol == IPPROTO_UDP)
122 rc = udp6_sk_cachep;
123 else if (protocol == IPPROTO_RAW)
124 rc = raw6_sk_cachep;
125 return rc;
128 static __inline__ int inet6_sk_size(int protocol)
130 int rc = sizeof(struct tcp6_sock);
132 if (protocol == IPPROTO_UDP)
133 rc = sizeof(struct udp6_sock);
134 else if (protocol == IPPROTO_RAW)
135 rc = sizeof(struct raw6_sock);
136 return rc;
139 static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
141 struct ipv6_pinfo *rc = (&((struct tcp6_sock *)sk)->inet6);
143 if (sk->protocol == IPPROTO_UDP)
144 rc = (&((struct udp6_sock *)sk)->inet6);
145 else if (sk->protocol == IPPROTO_RAW)
146 rc = (&((struct raw6_sock *)sk)->inet6);
147 return rc;
150 static int inet6_create(struct socket *sock, int protocol)
152 struct inet_opt *inet;
153 struct ipv6_pinfo *np;
154 struct sock *sk;
155 struct tcp6_sock* tcp6sk;
156 struct list_head *p;
157 struct inet_protosw *answer;
159 sk = sk_alloc(PF_INET6, GFP_KERNEL, inet6_sk_size(protocol),
160 inet6_sk_slab(protocol));
161 if (sk == NULL)
162 goto do_oom;
164 /* Look for the requested type/protocol pair. */
165 answer = NULL;
166 br_read_lock_bh(BR_NETPROTO_LOCK);
167 list_for_each(p, &inetsw6[sock->type]) {
168 answer = list_entry(p, struct inet_protosw, list);
170 /* Check the non-wild match. */
171 if (protocol == answer->protocol) {
172 if (protocol != IPPROTO_IP)
173 break;
174 } else {
175 /* Check for the two wild cases. */
176 if (IPPROTO_IP == protocol) {
177 protocol = answer->protocol;
178 break;
180 if (IPPROTO_IP == answer->protocol)
181 break;
183 answer = NULL;
185 br_read_unlock_bh(BR_NETPROTO_LOCK);
187 if (!answer)
188 goto free_and_badtype;
189 if (answer->capability > 0 && !capable(answer->capability))
190 goto free_and_badperm;
191 if (!protocol)
192 goto free_and_noproto;
194 sock->ops = answer->ops;
195 sock_init_data(sock, sk);
197 sk->prot = answer->prot;
198 sk->no_check = answer->no_check;
199 if (INET_PROTOSW_REUSE & answer->flags)
200 sk->reuse = 1;
202 inet = inet_sk(sk);
204 if (SOCK_RAW == sock->type) {
205 inet->num = protocol;
206 if (IPPROTO_RAW == protocol)
207 inet->hdrincl = 1;
210 sk->destruct = inet6_sock_destruct;
211 sk->zapped = 0;
212 sk->family = PF_INET6;
213 sk->protocol = protocol;
215 sk->backlog_rcv = answer->prot->backlog_rcv;
217 tcp6sk = (struct tcp6_sock *)sk;
218 tcp6sk->pinet6 = np = inet6_sk_generic(sk);
219 np->hop_limit = -1;
220 np->mcast_hops = -1;
221 np->mc_loop = 1;
222 np->pmtudisc = IPV6_PMTUDISC_WANT;
223 np->ipv6only = sysctl_ipv6_bindv6only;
225 /* Init the ipv4 part of the socket since we can have sockets
226 * using v6 API for ipv4.
228 inet->ttl = 64;
230 inet->mc_loop = 1;
231 inet->mc_ttl = 1;
232 inet->mc_index = 0;
233 inet->mc_list = NULL;
235 if (ipv4_config.no_pmtu_disc)
236 inet->pmtudisc = IP_PMTUDISC_DONT;
237 else
238 inet->pmtudisc = IP_PMTUDISC_WANT;
241 #ifdef INET_REFCNT_DEBUG
242 atomic_inc(&inet6_sock_nr);
243 atomic_inc(&inet_sock_nr);
244 #endif
245 MOD_INC_USE_COUNT;
247 if (inet->num) {
248 /* It assumes that any protocol which allows
249 * the user to assign a number at socket
250 * creation time automatically shares.
252 inet->sport = ntohs(inet->num);
253 sk->prot->hash(sk);
255 if (sk->prot->init) {
256 int err = sk->prot->init(sk);
257 if (err != 0) {
258 MOD_DEC_USE_COUNT;
259 inet_sock_release(sk);
260 return err;
263 return 0;
265 free_and_badtype:
266 sk_free(sk);
267 return -ESOCKTNOSUPPORT;
268 free_and_badperm:
269 sk_free(sk);
270 return -EPERM;
271 free_and_noproto:
272 sk_free(sk);
273 return -EPROTONOSUPPORT;
274 do_oom:
275 return -ENOBUFS;
279 /* bind for INET6 API */
280 int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
282 struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr;
283 struct sock *sk = sock->sk;
284 struct inet_opt *inet = inet_sk(sk);
285 struct ipv6_pinfo *np = inet6_sk(sk);
286 __u32 v4addr = 0;
287 unsigned short snum;
288 int addr_type = 0;
290 /* If the socket has its own bind function then use it. */
291 if(sk->prot->bind)
292 return sk->prot->bind(sk, uaddr, addr_len);
294 if (addr_len < SIN6_LEN_RFC2133)
295 return -EINVAL;
296 addr_type = ipv6_addr_type(&addr->sin6_addr);
297 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
298 return -EINVAL;
300 /* Check if the address belongs to the host. */
301 if (addr_type == IPV6_ADDR_MAPPED) {
302 v4addr = addr->sin6_addr.s6_addr32[3];
303 if (inet_addr_type(v4addr) != RTN_LOCAL)
304 return -EADDRNOTAVAIL;
305 } else {
306 if (addr_type != IPV6_ADDR_ANY) {
307 /* ipv4 addr of the socket is invalid. Only the
308 * unpecified and mapped address have a v4 equivalent.
310 v4addr = LOOPBACK4_IPV6;
311 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
312 if (!ipv6_chk_addr(&addr->sin6_addr, NULL))
313 return -EADDRNOTAVAIL;
318 snum = ntohs(addr->sin6_port);
319 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
320 return -EACCES;
322 lock_sock(sk);
324 /* Check these errors (active socket, double bind). */
325 if (sk->state != TCP_CLOSE || inet->num) {
326 release_sock(sk);
327 return -EINVAL;
330 if (addr_type & IPV6_ADDR_LINKLOCAL) {
331 if (addr_len >= sizeof(struct sockaddr_in6) &&
332 addr->sin6_scope_id) {
333 /* Override any existing binding, if another one
334 * is supplied by user.
336 sk->bound_dev_if = addr->sin6_scope_id;
339 /* Binding to link-local address requires an interface */
340 if (sk->bound_dev_if == 0) {
341 release_sock(sk);
342 return -EINVAL;
346 inet->rcv_saddr = v4addr;
347 inet->saddr = v4addr;
349 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr);
351 if (!(addr_type & IPV6_ADDR_MULTICAST))
352 ipv6_addr_copy(&np->saddr, &addr->sin6_addr);
354 /* Make sure we are allowed to bind here. */
355 if (sk->prot->get_port(sk, snum) != 0) {
356 inet->rcv_saddr = inet->saddr = 0;
357 memset(&np->rcv_saddr, 0, sizeof(struct in6_addr));
358 memset(&np->saddr, 0, sizeof(struct in6_addr));
360 release_sock(sk);
361 return -EADDRINUSE;
364 if (addr_type != IPV6_ADDR_ANY)
365 sk->userlocks |= SOCK_BINDADDR_LOCK;
366 if (snum)
367 sk->userlocks |= SOCK_BINDPORT_LOCK;
368 inet->sport = ntohs(inet->num);
369 inet->dport = 0;
370 inet->daddr = 0;
371 release_sock(sk);
373 return 0;
376 int inet6_release(struct socket *sock)
378 struct sock *sk = sock->sk;
380 if (sk == NULL)
381 return -EINVAL;
383 /* Free mc lists */
384 ipv6_sock_mc_close(sk);
386 return inet_release(sock);
389 int inet6_destroy_sock(struct sock *sk)
391 struct ipv6_pinfo *np = inet6_sk(sk);
392 struct sk_buff *skb;
393 struct ipv6_txoptions *opt;
396 * Release destination entry
399 sk_dst_reset(sk);
401 /* Release rx options */
403 if ((skb = xchg(&np->pktoptions, NULL)) != NULL)
404 kfree_skb(skb);
406 /* Free flowlabels */
407 fl6_free_socklist(sk);
409 /* Free tx options */
411 if ((opt = xchg(&np->opt, NULL)) != NULL)
412 sock_kfree_s(sk, opt, opt->tot_len);
414 return 0;
418 * This does both peername and sockname.
421 int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
422 int *uaddr_len, int peer)
424 struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;
425 struct sock *sk = sock->sk;
426 struct inet_opt *inet = inet_sk(sk);
427 struct ipv6_pinfo *np = inet6_sk(sk);
429 sin->sin6_family = AF_INET6;
430 sin->sin6_flowinfo = 0;
431 sin->sin6_scope_id = 0;
432 if (peer) {
433 if (!inet->dport)
434 return -ENOTCONN;
435 if (((1<<sk->state)&(TCPF_CLOSE|TCPF_SYN_SENT)) && peer == 1)
436 return -ENOTCONN;
437 sin->sin6_port = inet->dport;
438 memcpy(&sin->sin6_addr, &np->daddr, sizeof(struct in6_addr));
439 if (np->sndflow)
440 sin->sin6_flowinfo = np->flow_label;
441 } else {
442 if (ipv6_addr_type(&np->rcv_saddr) == IPV6_ADDR_ANY)
443 memcpy(&sin->sin6_addr, &np->saddr,
444 sizeof(struct in6_addr));
445 else
446 memcpy(&sin->sin6_addr, &np->rcv_saddr,
447 sizeof(struct in6_addr));
449 sin->sin6_port = inet->sport;
451 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
452 sin->sin6_scope_id = sk->bound_dev_if;
453 *uaddr_len = sizeof(*sin);
454 return(0);
457 int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
459 struct sock *sk = sock->sk;
460 int err = -EINVAL;
462 switch(cmd)
464 case SIOCGSTAMP:
465 if(sk->stamp.tv_sec==0)
466 return -ENOENT;
467 err = copy_to_user((void *)arg, &sk->stamp,
468 sizeof(struct timeval));
469 if (err)
470 return -EFAULT;
471 return 0;
473 case SIOCADDRT:
474 case SIOCDELRT:
476 return(ipv6_route_ioctl(cmd,(void *)arg));
478 case SIOCSIFADDR:
479 return addrconf_add_ifaddr((void *) arg);
480 case SIOCDIFADDR:
481 return addrconf_del_ifaddr((void *) arg);
482 case SIOCSIFDSTADDR:
483 return addrconf_set_dstaddr((void *) arg);
484 default:
485 if(sk->prot->ioctl==0 || (err=sk->prot->ioctl(sk, cmd, arg))==-ENOIOCTLCMD)
486 return(dev_ioctl(cmd,(void *) arg));
487 return err;
489 /*NOTREACHED*/
490 return(0);
493 struct proto_ops inet6_stream_ops = {
494 .family = PF_INET6,
496 .release = inet6_release,
497 .bind = inet6_bind,
498 .connect = inet_stream_connect, /* ok */
499 .socketpair = sock_no_socketpair, /* a do nothing */
500 .accept = inet_accept, /* ok */
501 .getname = inet6_getname,
502 .poll = tcp_poll, /* ok */
503 .ioctl = inet6_ioctl, /* must change */
504 .listen = inet_listen, /* ok */
505 .shutdown = inet_shutdown, /* ok */
506 .setsockopt = inet_setsockopt, /* ok */
507 .getsockopt = inet_getsockopt, /* ok */
508 .sendmsg = inet_sendmsg, /* ok */
509 .recvmsg = inet_recvmsg, /* ok */
510 .mmap = sock_no_mmap,
511 .sendpage = tcp_sendpage
514 struct proto_ops inet6_dgram_ops = {
515 .family = PF_INET6,
517 .release = inet6_release,
518 .bind = inet6_bind,
519 .connect = inet_dgram_connect, /* ok */
520 .socketpair = sock_no_socketpair, /* a do nothing */
521 .accept = sock_no_accept, /* a do nothing */
522 .getname = inet6_getname,
523 .poll = datagram_poll, /* ok */
524 .ioctl = inet6_ioctl, /* must change */
525 .listen = sock_no_listen, /* ok */
526 .shutdown = inet_shutdown, /* ok */
527 .setsockopt = inet_setsockopt, /* ok */
528 .getsockopt = inet_getsockopt, /* ok */
529 .sendmsg = inet_sendmsg, /* ok */
530 .recvmsg = inet_recvmsg, /* ok */
531 .mmap = sock_no_mmap,
532 .sendpage = sock_no_sendpage,
535 struct net_proto_family inet6_family_ops = {
536 .family =PF_INET6,
537 .create =inet6_create,
540 #ifdef MODULE
541 #if 0 /* FIXME --RR */
542 int ipv6_unload(void)
544 if (!unloadable) return 1;
545 /* We keep internally 3 raw sockets */
546 return atomic_read(&(__this_module.uc.usecount)) - 3;
548 #endif
549 #endif
551 #if defined(MODULE) && defined(CONFIG_SYSCTL)
552 extern void ipv6_sysctl_register(void);
553 extern void ipv6_sysctl_unregister(void);
554 #endif
556 static struct inet_protosw rawv6_protosw = {
557 .type = SOCK_RAW,
558 .protocol = IPPROTO_IP, /* wild card */
559 .prot = &rawv6_prot,
560 .ops = &inet6_dgram_ops,
561 .capability =CAP_NET_RAW,
562 .no_check = UDP_CSUM_DEFAULT,
563 .flags = INET_PROTOSW_REUSE,
566 #define INETSW6_ARRAY_LEN (sizeof(inetsw6_array) / sizeof(struct inet_protosw))
568 void
569 inet6_register_protosw(struct inet_protosw *p)
571 struct list_head *lh;
572 struct inet_protosw *answer;
573 int protocol = p->protocol;
575 br_write_lock_bh(BR_NETPROTO_LOCK);
577 if (p->type > SOCK_MAX)
578 goto out_illegal;
580 /* If we are trying to override a permanent protocol, bail. */
581 answer = NULL;
582 list_for_each(lh, &inetsw6[p->type]) {
583 answer = list_entry(lh, struct inet_protosw, list);
585 /* Check only the non-wild match. */
586 if (protocol == answer->protocol &&
587 (INET_PROTOSW_PERMANENT & answer->flags))
588 break;
590 answer = NULL;
592 if (answer)
593 goto out_permanent;
595 /* Add to the BEGINNING so that we override any existing
596 * entry. This means that when we remove this entry, the
597 * system automatically returns to the old behavior.
599 list_add(&p->list, &inetsw6[p->type]);
600 out:
601 br_write_unlock_bh(BR_NETPROTO_LOCK);
602 return;
604 out_permanent:
605 printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
606 protocol);
607 goto out;
609 out_illegal:
610 printk(KERN_ERR
611 "Ignoring attempt to register illegal socket type %d.\n",
612 p->type);
613 goto out;
616 void
617 inet6_unregister_protosw(struct inet_protosw *p)
619 inet_unregister_protosw(p);
622 static int __init inet6_init(void)
624 struct sk_buff *dummy_skb;
625 struct list_head *r;
626 int err;
628 #ifdef MODULE
629 #if 0 /* FIXME --RR */
630 if (!mod_member_present(&__this_module, can_unload))
631 return -EINVAL;
633 __this_module.can_unload = &ipv6_unload;
634 #endif
635 #endif
637 printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
639 if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
641 printk(KERN_CRIT "inet6_proto_init: size fault\n");
642 return -EINVAL;
644 /* allocate our sock slab caches */
645 tcp6_sk_cachep = kmem_cache_create("tcp6_sock",
646 sizeof(struct tcp6_sock), 0,
647 SLAB_HWCACHE_ALIGN, 0, 0);
648 udp6_sk_cachep = kmem_cache_create("udp6_sock",
649 sizeof(struct udp6_sock), 0,
650 SLAB_HWCACHE_ALIGN, 0, 0);
651 raw6_sk_cachep = kmem_cache_create("raw6_sock",
652 sizeof(struct raw6_sock), 0,
653 SLAB_HWCACHE_ALIGN, 0, 0);
654 if (!tcp6_sk_cachep || !udp6_sk_cachep || !raw6_sk_cachep)
655 printk(KERN_CRIT "%s: Can't create protocol sock SLAB "
656 "caches!\n", __FUNCTION__);
658 /* Register the socket-side information for inet6_create. */
659 for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
660 INIT_LIST_HEAD(r);
662 /* We MUST register RAW sockets before we create the ICMP6,
663 * IGMP6, or NDISC control sockets.
665 inet6_register_protosw(&rawv6_protosw);
667 /* Register the family here so that the init calls below will
668 * be able to create sockets. (?? is this dangerous ??)
670 (void) sock_register(&inet6_family_ops);
673 * ipngwg API draft makes clear that the correct semantics
674 * for TCP and UDP is to consider one TCP and UDP instance
675 * in a host availiable by both INET and INET6 APIs and
676 * able to communicate via both network protocols.
679 #if defined(MODULE) && defined(CONFIG_SYSCTL)
680 ipv6_sysctl_register();
681 #endif
682 err = icmpv6_init(&inet6_family_ops);
683 if (err)
684 goto icmp_fail;
685 err = ndisc_init(&inet6_family_ops);
686 if (err)
687 goto ndisc_fail;
688 err = igmp6_init(&inet6_family_ops);
689 if (err)
690 goto igmp_fail;
691 /* Create /proc/foo6 entries. */
692 #ifdef CONFIG_PROC_FS
693 err = -ENOMEM;
694 if (!proc_net_create("raw6", 0, raw6_get_info))
695 goto proc_raw6_fail;
696 if (!proc_net_create("tcp6", 0, tcp6_get_info))
697 goto proc_tcp6_fail;
698 if (!proc_net_create("udp6", 0, udp6_get_info))
699 goto proc_udp6_fail;
700 if (!proc_net_create("sockstat6", 0, afinet6_get_info))
701 goto proc_sockstat6_fail;
702 if (!proc_net_create("snmp6", 0, afinet6_get_snmp))
703 goto proc_snmp6_fail;
704 #endif
705 ipv6_netdev_notif_init();
706 ipv6_packet_init();
707 ip6_route_init();
708 ip6_flowlabel_init();
709 addrconf_init();
710 sit_init();
712 /* Init v6 transport protocols. */
713 udpv6_init();
714 tcpv6_init();
716 return 0;
718 #ifdef CONFIG_PROC_FS
719 proc_snmp6_fail:
720 proc_net_remove("sockstat6");
721 proc_sockstat6_fail:
722 proc_net_remove("udp6");
723 proc_udp6_fail:
724 proc_net_remove("tcp6");
725 proc_tcp6_fail:
726 proc_net_remove("raw6");
727 proc_raw6_fail:
728 igmp6_cleanup();
729 #endif
730 igmp_fail:
731 ndisc_cleanup();
732 ndisc_fail:
733 icmpv6_cleanup();
734 icmp_fail:
735 #if defined(MODULE) && defined(CONFIG_SYSCTL)
736 ipv6_sysctl_unregister();
737 #endif
738 return err;
740 module_init(inet6_init);
743 #ifdef MODULE
744 static void inet6_exit(void)
746 /* First of all disallow new sockets creation. */
747 sock_unregister(PF_INET6);
748 #ifdef CONFIG_PROC_FS
749 proc_net_remove("raw6");
750 proc_net_remove("tcp6");
751 proc_net_remove("udp6");
752 proc_net_remove("sockstat6");
753 proc_net_remove("snmp6");
754 #endif
755 /* Cleanup code parts. */
756 sit_cleanup();
757 ipv6_netdev_notif_cleanup();
758 ip6_flowlabel_cleanup();
759 addrconf_cleanup();
760 ip6_route_cleanup();
761 ipv6_packet_cleanup();
762 igmp6_cleanup();
763 ndisc_cleanup();
764 icmpv6_cleanup();
765 #ifdef CONFIG_SYSCTL
766 ipv6_sysctl_unregister();
767 #endif
769 module_exit(inet6_exit);
770 #endif /* MODULE */
771 MODULE_LICENSE("GPL");