[IPV4/6]: Check if packet was actually delivered to a raw socket to decide whether...
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / net / ipv6 / af_inet6.c
CommitLineData
1da177e4
LT
1/*
2 * PF_INET6 socket protocol family
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Adapted from linux/net/ipv4/af_inet.c
9 *
10 * $Id: af_inet6.c,v 1.66 2002/02/01 22:01:04 davem Exp $
11 *
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
16 *
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.
21 */
22
23
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>
1da177e4
LT
31#include <linux/sched.h>
32#include <linux/timer.h>
33#include <linux/string.h>
34#include <linux/sockios.h>
35#include <linux/net.h>
36#include <linux/fcntl.h>
37#include <linux/mm.h>
38#include <linux/interrupt.h>
39#include <linux/proc_fs.h>
40#include <linux/stat.h>
41#include <linux/init.h>
42
43#include <linux/inet.h>
44#include <linux/netdevice.h>
45#include <linux/icmpv6.h>
46#include <linux/smp_lock.h>
2cc7d573 47#include <linux/netfilter_ipv6.h>
1da177e4
LT
48
49#include <net/ip.h>
50#include <net/ipv6.h>
51#include <net/udp.h>
52#include <net/tcp.h>
53#include <net/ipip.h>
54#include <net/protocol.h>
55#include <net/inet_common.h>
56#include <net/transp_v6.h>
57#include <net/ip6_route.h>
58#include <net/addrconf.h>
59#ifdef CONFIG_IPV6_TUNNEL
60#include <net/ip6_tunnel.h>
61#endif
62
63#include <asm/uaccess.h>
64#include <asm/system.h>
65
66MODULE_AUTHOR("Cast of dozens");
67MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
68MODULE_LICENSE("GPL");
69
70/* IPv6 procfs goodies... */
71
72#ifdef CONFIG_PROC_FS
73extern int raw6_proc_init(void);
74extern void raw6_proc_exit(void);
75extern int tcp6_proc_init(void);
76extern void tcp6_proc_exit(void);
77extern int udp6_proc_init(void);
78extern void udp6_proc_exit(void);
79extern int ipv6_misc_proc_init(void);
80extern void ipv6_misc_proc_exit(void);
81extern int ac6_proc_init(void);
82extern void ac6_proc_exit(void);
83extern int if6_proc_init(void);
84extern void if6_proc_exit(void);
85#endif
86
87int sysctl_ipv6_bindv6only;
88
89#ifdef INET_REFCNT_DEBUG
90atomic_t inet6_sock_nr;
edec231a 91EXPORT_SYMBOL(inet6_sock_nr);
1da177e4
LT
92#endif
93
94/* The inetsw table contains everything that inet_create needs to
95 * build a new socket.
96 */
97static struct list_head inetsw6[SOCK_MAX];
98static DEFINE_SPINLOCK(inetsw6_lock);
99
100static void inet6_sock_destruct(struct sock *sk)
101{
102 inet_sock_destruct(sk);
103
104#ifdef INET_REFCNT_DEBUG
105 atomic_dec(&inet6_sock_nr);
106#endif
107}
108
109static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
110{
111 const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo);
112
113 return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
114}
115
116static int inet6_create(struct socket *sock, int protocol)
117{
118 struct inet_sock *inet;
119 struct ipv6_pinfo *np;
120 struct sock *sk;
121 struct list_head *p;
122 struct inet_protosw *answer;
123 struct proto *answer_prot;
124 unsigned char answer_flags;
125 char answer_no_check;
126 int rc;
127
128 /* Look for the requested type/protocol pair. */
129 answer = NULL;
130 rcu_read_lock();
131 list_for_each_rcu(p, &inetsw6[sock->type]) {
132 answer = list_entry(p, struct inet_protosw, list);
133
134 /* Check the non-wild match. */
135 if (protocol == answer->protocol) {
136 if (protocol != IPPROTO_IP)
137 break;
138 } else {
139 /* Check for the two wild cases. */
140 if (IPPROTO_IP == protocol) {
141 protocol = answer->protocol;
142 break;
143 }
144 if (IPPROTO_IP == answer->protocol)
145 break;
146 }
147 answer = NULL;
148 }
149
150 rc = -ESOCKTNOSUPPORT;
151 if (!answer)
152 goto out_rcu_unlock;
153 rc = -EPERM;
154 if (answer->capability > 0 && !capable(answer->capability))
155 goto out_rcu_unlock;
156 rc = -EPROTONOSUPPORT;
157 if (!protocol)
158 goto out_rcu_unlock;
159
160 sock->ops = answer->ops;
161
162 answer_prot = answer->prot;
163 answer_no_check = answer->no_check;
164 answer_flags = answer->flags;
165 rcu_read_unlock();
166
167 BUG_TRAP(answer_prot->slab != NULL);
168
169 rc = -ENOBUFS;
170 sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
171 if (sk == NULL)
172 goto out;
173
174 sock_init_data(sock, sk);
175
176 rc = 0;
177 sk->sk_no_check = answer_no_check;
178 if (INET_PROTOSW_REUSE & answer_flags)
179 sk->sk_reuse = 1;
180
181 inet = inet_sk(sk);
182
183 if (SOCK_RAW == sock->type) {
184 inet->num = protocol;
185 if (IPPROTO_RAW == protocol)
186 inet->hdrincl = 1;
187 }
188
189 sk->sk_destruct = inet6_sock_destruct;
190 sk->sk_family = PF_INET6;
191 sk->sk_protocol = protocol;
192
193 sk->sk_backlog_rcv = answer->prot->backlog_rcv;
194
195 inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk);
196 np->hop_limit = -1;
197 np->mcast_hops = -1;
198 np->mc_loop = 1;
199 np->pmtudisc = IPV6_PMTUDISC_WANT;
200 np->ipv6only = sysctl_ipv6_bindv6only;
201
202 /* Init the ipv4 part of the socket since we can have sockets
203 * using v6 API for ipv4.
204 */
205 inet->uc_ttl = -1;
206
207 inet->mc_loop = 1;
208 inet->mc_ttl = 1;
209 inet->mc_index = 0;
210 inet->mc_list = NULL;
211
212 if (ipv4_config.no_pmtu_disc)
213 inet->pmtudisc = IP_PMTUDISC_DONT;
214 else
215 inet->pmtudisc = IP_PMTUDISC_WANT;
216
217
218#ifdef INET_REFCNT_DEBUG
219 atomic_inc(&inet6_sock_nr);
220 atomic_inc(&inet_sock_nr);
221#endif
222 if (inet->num) {
223 /* It assumes that any protocol which allows
224 * the user to assign a number at socket
225 * creation time automatically shares.
226 */
227 inet->sport = ntohs(inet->num);
228 sk->sk_prot->hash(sk);
229 }
230 if (sk->sk_prot->init) {
231 rc = sk->sk_prot->init(sk);
232 if (rc) {
233 sk_common_release(sk);
234 goto out;
235 }
236 }
237out:
238 return rc;
239out_rcu_unlock:
240 rcu_read_unlock();
241 goto out;
242}
243
244
245/* bind for INET6 API */
246int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
247{
248 struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr;
249 struct sock *sk = sock->sk;
250 struct inet_sock *inet = inet_sk(sk);
251 struct ipv6_pinfo *np = inet6_sk(sk);
252 __u32 v4addr = 0;
253 unsigned short snum;
254 int addr_type = 0;
255 int err = 0;
256
257 /* If the socket has its own bind function then use it. */
258 if (sk->sk_prot->bind)
259 return sk->sk_prot->bind(sk, uaddr, addr_len);
260
261 if (addr_len < SIN6_LEN_RFC2133)
262 return -EINVAL;
263 addr_type = ipv6_addr_type(&addr->sin6_addr);
264 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
265 return -EINVAL;
266
267 snum = ntohs(addr->sin6_port);
268 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
269 return -EACCES;
270
271 lock_sock(sk);
272
273 /* Check these errors (active socket, double bind). */
274 if (sk->sk_state != TCP_CLOSE || inet->num) {
275 err = -EINVAL;
276 goto out;
277 }
278
279 /* Check if the address belongs to the host. */
280 if (addr_type == IPV6_ADDR_MAPPED) {
281 v4addr = addr->sin6_addr.s6_addr32[3];
282 if (inet_addr_type(v4addr) != RTN_LOCAL) {
283 err = -EADDRNOTAVAIL;
284 goto out;
285 }
286 } else {
287 if (addr_type != IPV6_ADDR_ANY) {
288 struct net_device *dev = NULL;
289
290 if (addr_type & IPV6_ADDR_LINKLOCAL) {
291 if (addr_len >= sizeof(struct sockaddr_in6) &&
292 addr->sin6_scope_id) {
293 /* Override any existing binding, if another one
294 * is supplied by user.
295 */
296 sk->sk_bound_dev_if = addr->sin6_scope_id;
297 }
298
299 /* Binding to link-local address requires an interface */
300 if (!sk->sk_bound_dev_if) {
301 err = -EINVAL;
302 goto out;
303 }
304 dev = dev_get_by_index(sk->sk_bound_dev_if);
305 if (!dev) {
306 err = -ENODEV;
307 goto out;
308 }
309 }
310
311 /* ipv4 addr of the socket is invalid. Only the
312 * unspecified and mapped address have a v4 equivalent.
313 */
314 v4addr = LOOPBACK4_IPV6;
315 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
316 if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) {
317 if (dev)
318 dev_put(dev);
319 err = -EADDRNOTAVAIL;
320 goto out;
321 }
322 }
323 if (dev)
324 dev_put(dev);
325 }
326 }
327
328 inet->rcv_saddr = v4addr;
329 inet->saddr = v4addr;
330
331 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr);
332
333 if (!(addr_type & IPV6_ADDR_MULTICAST))
334 ipv6_addr_copy(&np->saddr, &addr->sin6_addr);
335
336 /* Make sure we are allowed to bind here. */
337 if (sk->sk_prot->get_port(sk, snum)) {
338 inet_reset_saddr(sk);
339 err = -EADDRINUSE;
340 goto out;
341 }
342
343 if (addr_type != IPV6_ADDR_ANY)
344 sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
345 if (snum)
346 sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
347 inet->sport = ntohs(inet->num);
348 inet->dport = 0;
349 inet->daddr = 0;
350out:
351 release_sock(sk);
352 return err;
353}
354
355int inet6_release(struct socket *sock)
356{
357 struct sock *sk = sock->sk;
358
359 if (sk == NULL)
360 return -EINVAL;
361
362 /* Free mc lists */
363 ipv6_sock_mc_close(sk);
364
365 /* Free ac lists */
366 ipv6_sock_ac_close(sk);
367
368 return inet_release(sock);
369}
370
371int inet6_destroy_sock(struct sock *sk)
372{
373 struct ipv6_pinfo *np = inet6_sk(sk);
374 struct sk_buff *skb;
375 struct ipv6_txoptions *opt;
376
377 /*
378 * Release destination entry
379 */
380
381 sk_dst_reset(sk);
382
383 /* Release rx options */
384
385 if ((skb = xchg(&np->pktoptions, NULL)) != NULL)
386 kfree_skb(skb);
387
388 /* Free flowlabels */
389 fl6_free_socklist(sk);
390
391 /* Free tx options */
392
393 if ((opt = xchg(&np->opt, NULL)) != NULL)
394 sock_kfree_s(sk, opt, opt->tot_len);
395
396 return 0;
397}
398
399/*
400 * This does both peername and sockname.
401 */
402
403int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
404 int *uaddr_len, int peer)
405{
406 struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;
407 struct sock *sk = sock->sk;
408 struct inet_sock *inet = inet_sk(sk);
409 struct ipv6_pinfo *np = inet6_sk(sk);
410
411 sin->sin6_family = AF_INET6;
412 sin->sin6_flowinfo = 0;
413 sin->sin6_scope_id = 0;
414 if (peer) {
415 if (!inet->dport)
416 return -ENOTCONN;
417 if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) &&
418 peer == 1)
419 return -ENOTCONN;
420 sin->sin6_port = inet->dport;
421 ipv6_addr_copy(&sin->sin6_addr, &np->daddr);
422 if (np->sndflow)
423 sin->sin6_flowinfo = np->flow_label;
424 } else {
425 if (ipv6_addr_any(&np->rcv_saddr))
426 ipv6_addr_copy(&sin->sin6_addr, &np->saddr);
427 else
428 ipv6_addr_copy(&sin->sin6_addr, &np->rcv_saddr);
429
430 sin->sin6_port = inet->sport;
431 }
432 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
433 sin->sin6_scope_id = sk->sk_bound_dev_if;
434 *uaddr_len = sizeof(*sin);
435 return(0);
436}
437
438int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
439{
440 struct sock *sk = sock->sk;
441 int err = -EINVAL;
442
443 switch(cmd)
444 {
445 case SIOCGSTAMP:
446 return sock_get_timestamp(sk, (struct timeval __user *)arg);
447
448 case SIOCADDRT:
449 case SIOCDELRT:
450
451 return(ipv6_route_ioctl(cmd,(void __user *)arg));
452
453 case SIOCSIFADDR:
454 return addrconf_add_ifaddr((void __user *) arg);
455 case SIOCDIFADDR:
456 return addrconf_del_ifaddr((void __user *) arg);
457 case SIOCSIFDSTADDR:
458 return addrconf_set_dstaddr((void __user *) arg);
459 default:
460 if (!sk->sk_prot->ioctl ||
461 (err = sk->sk_prot->ioctl(sk, cmd, arg)) == -ENOIOCTLCMD)
462 return(dev_ioctl(cmd,(void __user *) arg));
463 return err;
464 }
465 /*NOTREACHED*/
466 return(0);
467}
468
469struct proto_ops inet6_stream_ops = {
470 .family = PF_INET6,
471 .owner = THIS_MODULE,
472 .release = inet6_release,
473 .bind = inet6_bind,
474 .connect = inet_stream_connect, /* ok */
475 .socketpair = sock_no_socketpair, /* a do nothing */
476 .accept = inet_accept, /* ok */
477 .getname = inet6_getname,
478 .poll = tcp_poll, /* ok */
479 .ioctl = inet6_ioctl, /* must change */
480 .listen = inet_listen, /* ok */
481 .shutdown = inet_shutdown, /* ok */
482 .setsockopt = sock_common_setsockopt, /* ok */
483 .getsockopt = sock_common_getsockopt, /* ok */
484 .sendmsg = inet_sendmsg, /* ok */
485 .recvmsg = sock_common_recvmsg, /* ok */
486 .mmap = sock_no_mmap,
487 .sendpage = tcp_sendpage
488};
489
490struct proto_ops inet6_dgram_ops = {
491 .family = PF_INET6,
492 .owner = THIS_MODULE,
493 .release = inet6_release,
494 .bind = inet6_bind,
495 .connect = inet_dgram_connect, /* ok */
496 .socketpair = sock_no_socketpair, /* a do nothing */
497 .accept = sock_no_accept, /* a do nothing */
498 .getname = inet6_getname,
499 .poll = udp_poll, /* ok */
500 .ioctl = inet6_ioctl, /* must change */
501 .listen = sock_no_listen, /* ok */
502 .shutdown = inet_shutdown, /* ok */
503 .setsockopt = sock_common_setsockopt, /* ok */
504 .getsockopt = sock_common_getsockopt, /* ok */
505 .sendmsg = inet_sendmsg, /* ok */
506 .recvmsg = sock_common_recvmsg, /* ok */
507 .mmap = sock_no_mmap,
508 .sendpage = sock_no_sendpage,
509};
510
511static struct net_proto_family inet6_family_ops = {
512 .family = PF_INET6,
513 .create = inet6_create,
514 .owner = THIS_MODULE,
515};
516
517#ifdef CONFIG_SYSCTL
518extern void ipv6_sysctl_register(void);
519extern void ipv6_sysctl_unregister(void);
520#endif
521
522/* Same as inet6_dgram_ops, sans udp_poll. */
523static struct proto_ops inet6_sockraw_ops = {
524 .family = PF_INET6,
525 .owner = THIS_MODULE,
526 .release = inet6_release,
527 .bind = inet6_bind,
528 .connect = inet_dgram_connect, /* ok */
529 .socketpair = sock_no_socketpair, /* a do nothing */
530 .accept = sock_no_accept, /* a do nothing */
531 .getname = inet6_getname,
532 .poll = datagram_poll, /* ok */
533 .ioctl = inet6_ioctl, /* must change */
534 .listen = sock_no_listen, /* ok */
535 .shutdown = inet_shutdown, /* ok */
536 .setsockopt = sock_common_setsockopt, /* ok */
537 .getsockopt = sock_common_getsockopt, /* ok */
538 .sendmsg = inet_sendmsg, /* ok */
539 .recvmsg = sock_common_recvmsg, /* ok */
540 .mmap = sock_no_mmap,
541 .sendpage = sock_no_sendpage,
542};
543
544static struct inet_protosw rawv6_protosw = {
545 .type = SOCK_RAW,
546 .protocol = IPPROTO_IP, /* wild card */
547 .prot = &rawv6_prot,
548 .ops = &inet6_sockraw_ops,
549 .capability = CAP_NET_RAW,
550 .no_check = UDP_CSUM_DEFAULT,
551 .flags = INET_PROTOSW_REUSE,
552};
553
554void
555inet6_register_protosw(struct inet_protosw *p)
556{
557 struct list_head *lh;
558 struct inet_protosw *answer;
559 int protocol = p->protocol;
560 struct list_head *last_perm;
561
562 spin_lock_bh(&inetsw6_lock);
563
564 if (p->type >= SOCK_MAX)
565 goto out_illegal;
566
567 /* If we are trying to override a permanent protocol, bail. */
568 answer = NULL;
569 last_perm = &inetsw6[p->type];
570 list_for_each(lh, &inetsw6[p->type]) {
571 answer = list_entry(lh, struct inet_protosw, list);
572
573 /* Check only the non-wild match. */
574 if (INET_PROTOSW_PERMANENT & answer->flags) {
575 if (protocol == answer->protocol)
576 break;
577 last_perm = lh;
578 }
579
580 answer = NULL;
581 }
582 if (answer)
583 goto out_permanent;
584
585 /* Add the new entry after the last permanent entry if any, so that
586 * the new entry does not override a permanent entry when matched with
587 * a wild-card protocol. But it is allowed to override any existing
588 * non-permanent entry. This means that when we remove this entry, the
589 * system automatically returns to the old behavior.
590 */
591 list_add_rcu(&p->list, last_perm);
592out:
593 spin_unlock_bh(&inetsw6_lock);
594 return;
595
596out_permanent:
597 printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
598 protocol);
599 goto out;
600
601out_illegal:
602 printk(KERN_ERR
603 "Ignoring attempt to register invalid socket type %d.\n",
604 p->type);
605 goto out;
606}
607
608void
609inet6_unregister_protosw(struct inet_protosw *p)
610{
611 if (INET_PROTOSW_PERMANENT & p->flags) {
612 printk(KERN_ERR
613 "Attempt to unregister permanent protocol %d.\n",
614 p->protocol);
615 } else {
616 spin_lock_bh(&inetsw6_lock);
617 list_del_rcu(&p->list);
618 spin_unlock_bh(&inetsw6_lock);
619
620 synchronize_net();
621 }
622}
623
624int
625snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
626{
627 if (ptr == NULL)
628 return -EINVAL;
629
630 ptr[0] = __alloc_percpu(mibsize, mibalign);
631 if (!ptr[0])
632 goto err0;
633
634 ptr[1] = __alloc_percpu(mibsize, mibalign);
635 if (!ptr[1])
636 goto err1;
637
638 return 0;
639
640err1:
641 free_percpu(ptr[0]);
642 ptr[0] = NULL;
643err0:
644 return -ENOMEM;
645}
646
647void
648snmp6_mib_free(void *ptr[2])
649{
650 if (ptr == NULL)
651 return;
652 if (ptr[0])
653 free_percpu(ptr[0]);
654 if (ptr[1])
655 free_percpu(ptr[1]);
656 ptr[0] = ptr[1] = NULL;
657}
658
659static int __init init_ipv6_mibs(void)
660{
661 if (snmp6_mib_init((void **)ipv6_statistics, sizeof (struct ipstats_mib),
662 __alignof__(struct ipstats_mib)) < 0)
663 goto err_ip_mib;
664 if (snmp6_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),
665 __alignof__(struct icmpv6_mib)) < 0)
666 goto err_icmp_mib;
667 if (snmp6_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),
668 __alignof__(struct udp_mib)) < 0)
669 goto err_udp_mib;
670 return 0;
671
672err_udp_mib:
673 snmp6_mib_free((void **)icmpv6_statistics);
674err_icmp_mib:
675 snmp6_mib_free((void **)ipv6_statistics);
676err_ip_mib:
677 return -ENOMEM;
678
679}
680
681static void cleanup_ipv6_mibs(void)
682{
683 snmp6_mib_free((void **)ipv6_statistics);
684 snmp6_mib_free((void **)icmpv6_statistics);
685 snmp6_mib_free((void **)udp_stats_in6);
686}
687
688extern int ipv6_misc_proc_init(void);
689
690static int __init inet6_init(void)
691{
692 struct sk_buff *dummy_skb;
693 struct list_head *r;
694 int err;
695
696#ifdef MODULE
697#if 0 /* FIXME --RR */
698 if (!mod_member_present(&__this_module, can_unload))
699 return -EINVAL;
700
701 __this_module.can_unload = &ipv6_unload;
702#endif
703#endif
704
705 if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)) {
706 printk(KERN_CRIT "inet6_proto_init: size fault\n");
707 return -EINVAL;
708 }
709
710 err = proto_register(&tcpv6_prot, 1);
711 if (err)
712 goto out;
713
714 err = proto_register(&udpv6_prot, 1);
715 if (err)
716 goto out_unregister_tcp_proto;
717
718 err = proto_register(&rawv6_prot, 1);
719 if (err)
720 goto out_unregister_udp_proto;
721
722
723 /* Register the socket-side information for inet6_create. */
724 for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
725 INIT_LIST_HEAD(r);
726
727 /* We MUST register RAW sockets before we create the ICMP6,
728 * IGMP6, or NDISC control sockets.
729 */
730 inet6_register_protosw(&rawv6_protosw);
731
732 /* Register the family here so that the init calls below will
733 * be able to create sockets. (?? is this dangerous ??)
734 */
735 (void) sock_register(&inet6_family_ops);
736
737 /* Initialise ipv6 mibs */
738 err = init_ipv6_mibs();
739 if (err)
740 goto out_unregister_raw_proto;
741
742 /*
743 * ipngwg API draft makes clear that the correct semantics
744 * for TCP and UDP is to consider one TCP and UDP instance
745 * in a host availiable by both INET and INET6 APIs and
746 * able to communicate via both network protocols.
747 */
748
749#ifdef CONFIG_SYSCTL
750 ipv6_sysctl_register();
751#endif
752 err = icmpv6_init(&inet6_family_ops);
753 if (err)
754 goto icmp_fail;
755 err = ndisc_init(&inet6_family_ops);
756 if (err)
757 goto ndisc_fail;
758 err = igmp6_init(&inet6_family_ops);
759 if (err)
760 goto igmp_fail;
2cc7d573
HW
761 err = ipv6_netfilter_init();
762 if (err)
763 goto netfilter_fail;
1da177e4
LT
764 /* Create /proc/foo6 entries. */
765#ifdef CONFIG_PROC_FS
766 err = -ENOMEM;
767 if (raw6_proc_init())
768 goto proc_raw6_fail;
769 if (tcp6_proc_init())
770 goto proc_tcp6_fail;
771 if (udp6_proc_init())
772 goto proc_udp6_fail;
773 if (ipv6_misc_proc_init())
774 goto proc_misc6_fail;
775
776 if (ac6_proc_init())
777 goto proc_anycast6_fail;
778 if (if6_proc_init())
779 goto proc_if6_fail;
780#endif
1da177e4
LT
781 ip6_route_init();
782 ip6_flowlabel_init();
783 err = addrconf_init();
784 if (err)
785 goto addrconf_fail;
786 sit_init();
787
788 /* Init v6 extension headers. */
789 ipv6_rthdr_init();
790 ipv6_frag_init();
791 ipv6_nodata_init();
792 ipv6_destopt_init();
793
794 /* Init v6 transport protocols. */
795 udpv6_init();
796 tcpv6_init();
e2ed4052
HX
797
798 ipv6_packet_init();
1da177e4
LT
799 err = 0;
800out:
801 return err;
802
803addrconf_fail:
804 ip6_flowlabel_cleanup();
805 ip6_route_cleanup();
1da177e4
LT
806#ifdef CONFIG_PROC_FS
807 if6_proc_exit();
808proc_if6_fail:
809 ac6_proc_exit();
810proc_anycast6_fail:
811 ipv6_misc_proc_exit();
812proc_misc6_fail:
813 udp6_proc_exit();
814proc_udp6_fail:
815 tcp6_proc_exit();
816proc_tcp6_fail:
817 raw6_proc_exit();
818proc_raw6_fail:
819#endif
2cc7d573
HW
820 ipv6_netfilter_fini();
821netfilter_fail:
1da177e4
LT
822 igmp6_cleanup();
823igmp_fail:
824 ndisc_cleanup();
825ndisc_fail:
826 icmpv6_cleanup();
827icmp_fail:
828#ifdef CONFIG_SYSCTL
829 ipv6_sysctl_unregister();
830#endif
831 cleanup_ipv6_mibs();
832out_unregister_raw_proto:
833 proto_unregister(&rawv6_prot);
834out_unregister_udp_proto:
835 proto_unregister(&udpv6_prot);
836out_unregister_tcp_proto:
837 proto_unregister(&tcpv6_prot);
838 goto out;
839}
840module_init(inet6_init);
841
842static void __exit inet6_exit(void)
843{
844 /* First of all disallow new sockets creation. */
845 sock_unregister(PF_INET6);
846#ifdef CONFIG_PROC_FS
847 if6_proc_exit();
848 ac6_proc_exit();
849 ipv6_misc_proc_exit();
850 udp6_proc_exit();
851 tcp6_proc_exit();
852 raw6_proc_exit();
853#endif
854 /* Cleanup code parts. */
855 sit_cleanup();
856 ip6_flowlabel_cleanup();
857 addrconf_cleanup();
858 ip6_route_cleanup();
859 ipv6_packet_cleanup();
860 igmp6_cleanup();
2cc7d573 861 ipv6_netfilter_fini();
1da177e4
LT
862 ndisc_cleanup();
863 icmpv6_cleanup();
864#ifdef CONFIG_SYSCTL
865 ipv6_sysctl_unregister();
866#endif
867 cleanup_ipv6_mibs();
868 proto_unregister(&rawv6_prot);
869 proto_unregister(&udpv6_prot);
870 proto_unregister(&tcpv6_prot);
871}
872module_exit(inet6_exit);
873
874MODULE_ALIAS_NETPROTO(PF_INET6);