Import 2.3.41pre2
[davej-history.git] / net / ipv6 / af_inet6.c
bloba8d396ba365324d09a55d7ad2ee0ea07e1a0cd17
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.52 2000/01/18 08:24:21 davem Exp $
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
19 #include <linux/module.h>
20 #include <linux/config.h>
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/socket.h>
24 #include <linux/in.h>
25 #include <linux/kernel.h>
26 #include <linux/major.h>
27 #include <linux/sched.h>
28 #include <linux/timer.h>
29 #include <linux/string.h>
30 #include <linux/sockios.h>
31 #include <linux/net.h>
32 #include <linux/fcntl.h>
33 #include <linux/mm.h>
34 #include <linux/interrupt.h>
35 #include <linux/proc_fs.h>
36 #include <linux/stat.h>
37 #include <linux/init.h>
38 #include <linux/version.h>
40 #include <linux/inet.h>
41 #include <linux/netdevice.h>
42 #include <linux/icmpv6.h>
43 #include <linux/smp_lock.h>
45 #include <net/ip.h>
46 #include <net/ipv6.h>
47 #include <net/udp.h>
48 #include <net/tcp.h>
49 #include <net/ipip.h>
50 #include <net/protocol.h>
51 #include <net/inet_common.h>
52 #include <net/transp_v6.h>
53 #include <net/ip6_route.h>
54 #include <net/addrconf.h>
56 #include <asm/uaccess.h>
57 #include <asm/system.h>
59 #ifdef MODULE
60 static int unloadable = 0; /* XX: Turn to one when all is ok within the
61 module for allowing unload */
62 #endif
64 #if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
65 MODULE_AUTHOR("Cast of dozens");
66 MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
67 MODULE_PARM(unloadable, "i");
68 #endif
70 extern struct proto_ops inet6_stream_ops;
71 extern struct proto_ops inet6_dgram_ops;
73 /* IPv6 procfs goodies... */
75 #ifdef CONFIG_PROC_FS
76 extern int raw6_get_info(char *, char **, off_t, int);
77 extern int tcp6_get_info(char *, char **, off_t, int);
78 extern int udp6_get_info(char *, char **, off_t, int);
79 extern int afinet6_get_info(char *, char **, off_t, int);
80 extern int afinet6_get_snmp(char *, char **, off_t, int);
81 #endif
83 #ifdef CONFIG_SYSCTL
84 extern void ipv6_sysctl_register(void);
85 extern void ipv6_sysctl_unregister(void);
86 #endif
88 #ifdef INET_REFCNT_DEBUG
89 atomic_t inet6_sock_nr;
90 #endif
92 static void inet6_sock_destruct(struct sock *sk)
94 inet_sock_destruct(sk);
96 #ifdef INET_REFCNT_DEBUG
97 atomic_dec(&inet6_sock_nr);
98 #endif
99 MOD_DEC_USE_COUNT;
102 static int inet6_create(struct socket *sock, int protocol)
104 struct sock *sk;
105 struct proto *prot;
107 sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
108 if (sk == NULL)
109 goto do_oom;
111 if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) {
112 if (protocol && protocol != IPPROTO_TCP)
113 goto free_and_noproto;
114 protocol = IPPROTO_TCP;
115 prot = &tcpv6_prot;
116 sock->ops = &inet6_stream_ops;
117 } else if(sock->type == SOCK_DGRAM) {
118 if (protocol && protocol != IPPROTO_UDP)
119 goto free_and_noproto;
120 protocol = IPPROTO_UDP;
121 sk->no_check = UDP_CSUM_DEFAULT;
122 prot=&udpv6_prot;
123 sock->ops = &inet6_dgram_ops;
124 } else if(sock->type == SOCK_RAW) {
125 if (!capable(CAP_NET_RAW))
126 goto free_and_badperm;
127 if (!protocol)
128 goto free_and_noproto;
129 prot = &rawv6_prot;
130 sock->ops = &inet6_dgram_ops;
131 sk->reuse = 1;
132 sk->num = protocol;
133 } else {
134 goto free_and_badtype;
137 sock_init_data(sock, sk);
139 sk->destruct = inet6_sock_destruct;
140 sk->zapped = 0;
141 sk->family = PF_INET6;
142 sk->protocol = protocol;
144 sk->prot = prot;
145 sk->backlog_rcv = prot->backlog_rcv;
147 sk->net_pinfo.af_inet6.hop_limit = -1;
148 sk->net_pinfo.af_inet6.mcast_hops = -1;
149 sk->net_pinfo.af_inet6.mc_loop = 1;
150 sk->net_pinfo.af_inet6.pmtudisc = IPV6_PMTUDISC_WANT;
152 /* Init the ipv4 part of the socket since we can have sockets
153 * using v6 API for ipv4.
155 sk->protinfo.af_inet.ttl = 64;
157 sk->protinfo.af_inet.mc_loop = 1;
158 sk->protinfo.af_inet.mc_ttl = 1;
159 sk->protinfo.af_inet.mc_index = 0;
160 sk->protinfo.af_inet.mc_list = NULL;
162 if (ipv4_config.no_pmtu_disc)
163 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
164 else
165 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
168 #ifdef INET_REFCNT_DEBUG
169 atomic_inc(&inet6_sock_nr);
170 atomic_inc(&inet_sock_nr);
171 #endif
172 MOD_INC_USE_COUNT;
174 if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW)
175 sk->protinfo.af_inet.hdrincl=1;
177 if (sk->num) {
178 /* It assumes that any protocol which allows
179 * the user to assign a number at socket
180 * creation time automatically shares.
182 sk->sport = ntohs(sk->num);
183 sk->prot->hash(sk);
186 if (sk->prot->init) {
187 int err = sk->prot->init(sk);
188 if (err != 0) {
189 sk->dead = 1;
190 inet_sock_release(sk);
191 return(err);
194 return(0);
196 free_and_badtype:
197 sk_free(sk);
198 return -ESOCKTNOSUPPORT;
199 free_and_badperm:
200 sk_free(sk);
201 return -EPERM;
202 free_and_noproto:
203 sk_free(sk);
204 return -EPROTONOSUPPORT;
205 do_oom:
206 return -ENOBUFS;
210 /* bind for INET6 API */
211 static int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
213 struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr;
214 struct sock *sk = sock->sk;
215 __u32 v4addr = 0;
216 unsigned short snum;
217 int addr_type = 0;
219 /* If the socket has its own bind function then use it. */
220 if(sk->prot->bind)
221 return sk->prot->bind(sk, uaddr, addr_len);
223 if (addr_len < sizeof(struct sockaddr_in6))
224 return -EINVAL;
226 addr_type = ipv6_addr_type(&addr->sin6_addr);
227 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
228 return -EINVAL;
230 /* Check if the address belongs to the host. */
231 if (addr_type == IPV6_ADDR_MAPPED) {
232 v4addr = addr->sin6_addr.s6_addr32[3];
233 if (inet_addr_type(v4addr) != RTN_LOCAL)
234 return -EADDRNOTAVAIL;
235 } else {
236 if (addr_type != IPV6_ADDR_ANY) {
237 /* ipv4 addr of the socket is invalid. Only the
238 * unpecified and mapped address have a v4 equivalent.
240 v4addr = LOOPBACK4_IPV6;
241 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
242 if (!ipv6_chk_addr(&addr->sin6_addr, NULL))
243 return -EADDRNOTAVAIL;
248 snum = ntohs(addr->sin6_port);
249 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
250 return -EACCES;
252 lock_sock(sk);
254 /* Check these errors (active socket, double bind). */
255 if ((sk->state != TCP_CLOSE) ||
256 (sk->num != 0)) {
257 release_sock(sk);
258 return -EINVAL;
261 sk->rcv_saddr = v4addr;
262 sk->saddr = v4addr;
264 ipv6_addr_copy(&sk->net_pinfo.af_inet6.rcv_saddr, &addr->sin6_addr);
266 if (!(addr_type & IPV6_ADDR_MULTICAST))
267 ipv6_addr_copy(&sk->net_pinfo.af_inet6.saddr, &addr->sin6_addr);
269 /* Make sure we are allowed to bind here. */
270 if (sk->prot->get_port(sk, snum) != 0) {
271 sk->rcv_saddr = 0;
272 sk->saddr = 0;
273 memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, sizeof(struct in6_addr));
274 memset(&sk->net_pinfo.af_inet6.saddr, 0, sizeof(struct in6_addr));
276 release_sock(sk);
277 return -EADDRINUSE;
280 sk->sport = ntohs(sk->num);
281 sk->dport = 0;
282 sk->daddr = 0;
283 sk->prot->hash(sk);
284 release_sock(sk);
286 return 0;
289 static int inet6_release(struct socket *sock)
291 struct sock *sk = sock->sk;
293 if (sk == NULL)
294 return -EINVAL;
296 /* Free mc lists */
297 ipv6_sock_mc_close(sk);
299 return inet_release(sock);
302 int inet6_destroy_sock(struct sock *sk)
304 struct sk_buff *skb;
305 struct ipv6_txoptions *opt;
308 * Release destination entry
311 sk_dst_reset(sk);
313 /* Release rx options */
315 if ((skb = xchg(&sk->net_pinfo.af_inet6.pktoptions, NULL)) != NULL)
316 kfree_skb(skb);
318 /* Free flowlabels */
319 fl6_free_socklist(sk);
321 /* Free tx options */
323 if ((opt = xchg(&sk->net_pinfo.af_inet6.opt, NULL)) != NULL)
324 sock_kfree_s(sk, opt, opt->tot_len);
326 return 0;
330 * This does both peername and sockname.
333 static int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
334 int *uaddr_len, int peer)
336 struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;
337 struct sock *sk = sock->sk;
339 sin->sin6_family = AF_INET6;
340 sin->sin6_flowinfo = 0;
341 if (peer) {
342 if (!sk->dport)
343 return -ENOTCONN;
344 sin->sin6_port = sk->dport;
345 memcpy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.daddr,
346 sizeof(struct in6_addr));
347 if (sk->net_pinfo.af_inet6.sndflow)
348 sin->sin6_flowinfo = sk->net_pinfo.af_inet6.flow_label;
349 } else {
350 if (ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr) == IPV6_ADDR_ANY)
351 memcpy(&sin->sin6_addr,
352 &sk->net_pinfo.af_inet6.saddr,
353 sizeof(struct in6_addr));
354 else
355 memcpy(&sin->sin6_addr,
356 &sk->net_pinfo.af_inet6.rcv_saddr,
357 sizeof(struct in6_addr));
359 sin->sin6_port = sk->sport;
361 *uaddr_len = sizeof(*sin);
362 return(0);
365 static int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
367 struct sock *sk = sock->sk;
368 int err = -EINVAL;
369 int pid;
371 switch(cmd)
373 case FIOSETOWN:
374 case SIOCSPGRP:
375 err = get_user(pid, (int *) arg);
376 if(err)
377 return err;
379 /* see sock_no_fcntl */
380 if (current->pid != pid && current->pgrp != -pid &&
381 !capable(CAP_NET_ADMIN))
382 return -EPERM;
383 sk->proc = pid;
384 return(0);
385 case FIOGETOWN:
386 case SIOCGPGRP:
387 err = put_user(sk->proc,(int *)arg);
388 if(err)
389 return err;
390 return(0);
391 case SIOCGSTAMP:
392 if(sk->stamp.tv_sec==0)
393 return -ENOENT;
394 err = copy_to_user((void *)arg, &sk->stamp,
395 sizeof(struct timeval));
396 if (err)
397 return -EFAULT;
398 return 0;
400 case SIOCADDRT:
401 case SIOCDELRT:
403 return(ipv6_route_ioctl(cmd,(void *)arg));
405 case SIOCSIFADDR:
406 return addrconf_add_ifaddr((void *) arg);
407 case SIOCDIFADDR:
408 return addrconf_del_ifaddr((void *) arg);
409 case SIOCSIFDSTADDR:
410 return addrconf_set_dstaddr((void *) arg);
411 default:
412 if ((cmd >= SIOCDEVPRIVATE) &&
413 (cmd <= (SIOCDEVPRIVATE + 15)))
414 return(dev_ioctl(cmd,(void *) arg));
416 if(sk->prot->ioctl==0 || (err=sk->prot->ioctl(sk, cmd, arg))==-ENOIOCTLCMD)
417 return(dev_ioctl(cmd,(void *) arg));
418 return err;
420 /*NOTREACHED*/
421 return(0);
424 struct proto_ops inet6_stream_ops = {
425 PF_INET6,
427 inet6_release,
428 inet6_bind,
429 inet_stream_connect, /* ok */
430 sock_no_socketpair, /* a do nothing */
431 inet_accept, /* ok */
432 inet6_getname,
433 tcp_poll, /* ok */
434 inet6_ioctl, /* must change */
435 inet_listen, /* ok */
436 inet_shutdown, /* ok */
437 inet_setsockopt, /* ok */
438 inet_getsockopt, /* ok */
439 sock_no_fcntl, /* ok */
440 inet_sendmsg, /* ok */
441 inet_recvmsg, /* ok */
442 sock_no_mmap
445 struct proto_ops inet6_dgram_ops = {
446 PF_INET6,
448 inet6_release,
449 inet6_bind,
450 inet_dgram_connect, /* ok */
451 sock_no_socketpair, /* a do nothing */
452 inet_accept, /* ok */
453 inet6_getname,
454 datagram_poll, /* ok */
455 inet6_ioctl, /* must change */
456 sock_no_listen, /* ok */
457 inet_shutdown, /* ok */
458 inet_setsockopt, /* ok */
459 inet_getsockopt, /* ok */
460 sock_no_fcntl, /* ok */
461 inet_sendmsg, /* ok */
462 inet_recvmsg, /* ok */
463 sock_no_mmap,
466 struct net_proto_family inet6_family_ops = {
467 PF_INET6,
468 inet6_create
471 #ifdef MODULE
472 int ipv6_unload(void)
474 if (!unloadable) return 1;
475 /* We keep internally 3 raw sockets */
476 return atomic_read(&(__this_module.uc.usecount)) - 3;
478 #endif
480 #if defined(MODULE) && defined(CONFIG_SYSCTL)
481 extern void ipv6_sysctl_register(void);
482 extern void ipv6_sysctl_unregister(void);
483 #endif
485 #ifdef MODULE
486 int init_module(void)
487 #else
488 void __init inet6_proto_init(struct net_proto *pro)
489 #endif
491 struct sk_buff *dummy_skb;
492 int err;
494 #ifdef MODULE
495 if (!mod_member_present(&__this_module, can_unload))
496 return -EINVAL;
498 __this_module.can_unload = &ipv6_unload;
499 #endif
501 printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
503 if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
505 printk(KERN_CRIT "inet6_proto_init: size fault\n");
506 #ifdef MODULE
507 return -EINVAL;
508 #else
509 return;
510 #endif
514 * ipngwg API draft makes clear that the correct semantics
515 * for TCP and UDP is to consider one TCP and UDP instance
516 * in a host availiable by both INET and INET6 APIs and
517 * able to communicate via both network protocols.
520 #if defined(MODULE) && defined(CONFIG_SYSCTL)
521 ipv6_sysctl_register();
522 #endif
523 err = icmpv6_init(&inet6_family_ops);
524 if (err)
525 goto icmp_fail;
526 err = ndisc_init(&inet6_family_ops);
527 if (err)
528 goto ndisc_fail;
529 err = igmp6_init(&inet6_family_ops);
530 if (err)
531 goto igmp_fail;
532 ipv6_netdev_notif_init();
533 ipv6_packet_init();
534 ip6_route_init();
535 ip6_flowlabel_init();
536 addrconf_init();
537 sit_init();
539 /* Init v6 transport protocols. */
540 udpv6_init();
541 tcpv6_init();
543 /* Create /proc/foo6 entries. */
544 #ifdef CONFIG_PROC_FS
545 proc_net_create("raw6", 0, raw6_get_info);
546 proc_net_create("tcp6", 0, tcp6_get_info);
547 proc_net_create("udp6", 0, udp6_get_info);
548 proc_net_create("sockstat6", 0, afinet6_get_info);
549 proc_net_create("snmp6", 0, afinet6_get_snmp);
550 #endif
552 /* Now the userspace is allowed to create INET6 sockets. */
553 (void) sock_register(&inet6_family_ops);
555 #ifdef MODULE
556 return 0;
557 #else
558 return;
559 #endif
561 igmp_fail:
562 ndisc_cleanup();
563 ndisc_fail:
564 icmpv6_cleanup();
565 icmp_fail:
566 #if defined(MODULE) && defined(CONFIG_SYSCTL)
567 ipv6_sysctl_unregister();
568 #endif
569 #ifdef MODULE
570 return err;
571 #else
572 return;
573 #endif
576 #ifdef MODULE
577 void cleanup_module(void)
579 /* First of all disallow new sockets creation. */
580 sock_unregister(PF_INET6);
581 #ifdef CONFIG_PROC_FS
582 proc_net_remove("raw6");
583 proc_net_remove("tcp6");
584 proc_net_remove("udp6");
585 proc_net_remove("sockstat6");
586 proc_net_remove("snmp6");
587 #endif
588 /* Cleanup code parts. */
589 sit_cleanup();
590 ipv6_netdev_notif_cleanup();
591 ip6_flowlabel_cleanup();
592 addrconf_cleanup();
593 ip6_route_cleanup();
594 ipv6_packet_cleanup();
595 igmp6_cleanup();
596 ndisc_cleanup();
597 icmpv6_cleanup();
598 #ifdef CONFIG_SYSCTL
599 ipv6_sysctl_unregister();
600 #endif
602 #endif /* MODULE */