Import 2.3.49pre1
[davej-history.git] / net / ipv6 / af_inet6.c
blob919abf4f9198cc9825e40f06c633c56bec9ff73f
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.55 2000/02/27 19:51:47 davem Exp $
12 * Fixes:
13 * Hideaki YOSHIFUJI : sin6_scope_id support
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
22 #include <linux/module.h>
23 #include <linux/config.h>
24 #include <linux/errno.h>
25 #include <linux/types.h>
26 #include <linux/socket.h>
27 #include <linux/in.h>
28 #include <linux/kernel.h>
29 #include <linux/major.h>
30 #include <linux/sched.h>
31 #include <linux/timer.h>
32 #include <linux/string.h>
33 #include <linux/sockios.h>
34 #include <linux/net.h>
35 #include <linux/fcntl.h>
36 #include <linux/mm.h>
37 #include <linux/interrupt.h>
38 #include <linux/proc_fs.h>
39 #include <linux/stat.h>
40 #include <linux/init.h>
41 #include <linux/version.h>
43 #include <linux/inet.h>
44 #include <linux/netdevice.h>
45 #include <linux/icmpv6.h>
46 #include <linux/smp_lock.h>
48 #include <net/ip.h>
49 #include <net/ipv6.h>
50 #include <net/udp.h>
51 #include <net/tcp.h>
52 #include <net/ipip.h>
53 #include <net/protocol.h>
54 #include <net/inet_common.h>
55 #include <net/transp_v6.h>
56 #include <net/ip6_route.h>
57 #include <net/addrconf.h>
59 #include <asm/uaccess.h>
60 #include <asm/system.h>
62 #ifdef MODULE
63 static int unloadable = 0; /* XX: Turn to one when all is ok within the
64 module for allowing unload */
65 #endif
67 #if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
68 MODULE_AUTHOR("Cast of dozens");
69 MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
70 MODULE_PARM(unloadable, "i");
71 #endif
73 extern struct proto_ops inet6_stream_ops;
74 extern struct proto_ops inet6_dgram_ops;
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 #ifdef INET_REFCNT_DEBUG
92 atomic_t inet6_sock_nr;
93 #endif
95 static void inet6_sock_destruct(struct sock *sk)
97 inet_sock_destruct(sk);
99 #ifdef INET_REFCNT_DEBUG
100 atomic_dec(&inet6_sock_nr);
101 #endif
102 MOD_DEC_USE_COUNT;
105 static int inet6_create(struct socket *sock, int protocol)
107 struct sock *sk;
108 struct proto *prot;
110 sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
111 if (sk == NULL)
112 goto do_oom;
114 if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) {
115 if (protocol && protocol != IPPROTO_TCP)
116 goto free_and_noproto;
117 protocol = IPPROTO_TCP;
118 prot = &tcpv6_prot;
119 sock->ops = &inet6_stream_ops;
120 } else if(sock->type == SOCK_DGRAM) {
121 if (protocol && protocol != IPPROTO_UDP)
122 goto free_and_noproto;
123 protocol = IPPROTO_UDP;
124 sk->no_check = UDP_CSUM_DEFAULT;
125 prot=&udpv6_prot;
126 sock->ops = &inet6_dgram_ops;
127 } else if(sock->type == SOCK_RAW) {
128 if (!capable(CAP_NET_RAW))
129 goto free_and_badperm;
130 if (!protocol)
131 goto free_and_noproto;
132 prot = &rawv6_prot;
133 sock->ops = &inet6_dgram_ops;
134 sk->reuse = 1;
135 sk->num = protocol;
136 } else {
137 goto free_and_badtype;
140 sock_init_data(sock, sk);
142 sk->destruct = inet6_sock_destruct;
143 sk->zapped = 0;
144 sk->family = PF_INET6;
145 sk->protocol = protocol;
147 sk->prot = prot;
148 sk->backlog_rcv = prot->backlog_rcv;
150 sk->net_pinfo.af_inet6.hop_limit = -1;
151 sk->net_pinfo.af_inet6.mcast_hops = -1;
152 sk->net_pinfo.af_inet6.mc_loop = 1;
153 sk->net_pinfo.af_inet6.pmtudisc = IPV6_PMTUDISC_WANT;
155 /* Init the ipv4 part of the socket since we can have sockets
156 * using v6 API for ipv4.
158 sk->protinfo.af_inet.ttl = 64;
160 sk->protinfo.af_inet.mc_loop = 1;
161 sk->protinfo.af_inet.mc_ttl = 1;
162 sk->protinfo.af_inet.mc_index = 0;
163 sk->protinfo.af_inet.mc_list = NULL;
165 if (ipv4_config.no_pmtu_disc)
166 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
167 else
168 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
171 #ifdef INET_REFCNT_DEBUG
172 atomic_inc(&inet6_sock_nr);
173 atomic_inc(&inet_sock_nr);
174 #endif
175 MOD_INC_USE_COUNT;
177 if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW)
178 sk->protinfo.af_inet.hdrincl=1;
180 if (sk->num) {
181 /* It assumes that any protocol which allows
182 * the user to assign a number at socket
183 * creation time automatically shares.
185 sk->sport = ntohs(sk->num);
186 sk->prot->hash(sk);
189 if (sk->prot->init) {
190 int err = sk->prot->init(sk);
191 if (err != 0) {
192 sk->dead = 1;
193 inet_sock_release(sk);
194 return(err);
197 return(0);
199 free_and_badtype:
200 sk_free(sk);
201 return -ESOCKTNOSUPPORT;
202 free_and_badperm:
203 sk_free(sk);
204 return -EPERM;
205 free_and_noproto:
206 sk_free(sk);
207 return -EPROTONOSUPPORT;
208 do_oom:
209 return -ENOBUFS;
213 /* bind for INET6 API */
214 static int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
216 struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr;
217 struct sock *sk = sock->sk;
218 __u32 v4addr = 0;
219 unsigned short snum;
220 int addr_type = 0;
222 /* If the socket has its own bind function then use it. */
223 if(sk->prot->bind)
224 return sk->prot->bind(sk, uaddr, addr_len);
226 if (addr_len < SIN6_LEN_RFC2133)
227 return -EINVAL;
228 addr_type = ipv6_addr_type(&addr->sin6_addr);
229 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
230 return -EINVAL;
232 /* Check if the address belongs to the host. */
233 if (addr_type == IPV6_ADDR_MAPPED) {
234 v4addr = addr->sin6_addr.s6_addr32[3];
235 if (inet_addr_type(v4addr) != RTN_LOCAL)
236 return -EADDRNOTAVAIL;
237 } else {
238 if (addr_type != IPV6_ADDR_ANY) {
239 /* ipv4 addr of the socket is invalid. Only the
240 * unpecified and mapped address have a v4 equivalent.
242 v4addr = LOOPBACK4_IPV6;
243 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
244 if (!ipv6_chk_addr(&addr->sin6_addr, NULL))
245 return -EADDRNOTAVAIL;
250 snum = ntohs(addr->sin6_port);
251 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
252 return -EACCES;
254 lock_sock(sk);
256 /* Check these errors (active socket, double bind). */
257 if ((sk->state != TCP_CLOSE) ||
258 (sk->num != 0)) {
259 release_sock(sk);
260 return -EINVAL;
263 if (addr_type & IPV6_ADDR_LINKLOCAL) {
264 if (addr_len >= sizeof(struct sockaddr_in6) &&
265 addr->sin6_scope_id) {
266 /* Override any existing binding, if another one
267 * is supplied by user.
269 sk->bound_dev_if = addr->sin6_scope_id;
272 /* Binding to link-local address requires an interface */
273 if (sk->bound_dev_if == 0) {
274 release_sock(sk);
275 return -EINVAL;
279 sk->rcv_saddr = v4addr;
280 sk->saddr = v4addr;
282 ipv6_addr_copy(&sk->net_pinfo.af_inet6.rcv_saddr, &addr->sin6_addr);
284 if (!(addr_type & IPV6_ADDR_MULTICAST))
285 ipv6_addr_copy(&sk->net_pinfo.af_inet6.saddr, &addr->sin6_addr);
287 /* Make sure we are allowed to bind here. */
288 if (sk->prot->get_port(sk, snum) != 0) {
289 sk->rcv_saddr = 0;
290 sk->saddr = 0;
291 memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, sizeof(struct in6_addr));
292 memset(&sk->net_pinfo.af_inet6.saddr, 0, sizeof(struct in6_addr));
294 release_sock(sk);
295 return -EADDRINUSE;
298 sk->sport = ntohs(sk->num);
299 sk->dport = 0;
300 sk->daddr = 0;
301 sk->prot->hash(sk);
302 release_sock(sk);
304 return 0;
307 static int inet6_release(struct socket *sock)
309 struct sock *sk = sock->sk;
311 if (sk == NULL)
312 return -EINVAL;
314 /* Free mc lists */
315 ipv6_sock_mc_close(sk);
317 return inet_release(sock);
320 int inet6_destroy_sock(struct sock *sk)
322 struct sk_buff *skb;
323 struct ipv6_txoptions *opt;
326 * Release destination entry
329 sk_dst_reset(sk);
331 /* Release rx options */
333 if ((skb = xchg(&sk->net_pinfo.af_inet6.pktoptions, NULL)) != NULL)
334 kfree_skb(skb);
336 /* Free flowlabels */
337 fl6_free_socklist(sk);
339 /* Free tx options */
341 if ((opt = xchg(&sk->net_pinfo.af_inet6.opt, NULL)) != NULL)
342 sock_kfree_s(sk, opt, opt->tot_len);
344 return 0;
348 * This does both peername and sockname.
351 static int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
352 int *uaddr_len, int peer)
354 struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;
355 struct sock *sk = sock->sk;
357 sin->sin6_family = AF_INET6;
358 sin->sin6_flowinfo = 0;
359 sin->sin6_scope_id = 0;
360 if (peer) {
361 if (!sk->dport)
362 return -ENOTCONN;
363 if (((1<<sk->state)&(TCPF_CLOSE|TCPF_SYN_SENT)) && peer == 1)
364 return -ENOTCONN;
365 sin->sin6_port = sk->dport;
366 memcpy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.daddr,
367 sizeof(struct in6_addr));
368 if (sk->net_pinfo.af_inet6.sndflow)
369 sin->sin6_flowinfo = sk->net_pinfo.af_inet6.flow_label;
370 } else {
371 if (ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr) == IPV6_ADDR_ANY)
372 memcpy(&sin->sin6_addr,
373 &sk->net_pinfo.af_inet6.saddr,
374 sizeof(struct in6_addr));
375 else
376 memcpy(&sin->sin6_addr,
377 &sk->net_pinfo.af_inet6.rcv_saddr,
378 sizeof(struct in6_addr));
380 sin->sin6_port = sk->sport;
382 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
383 sin->sin6_scope_id = sk->bound_dev_if;
384 *uaddr_len = sizeof(*sin);
385 return(0);
388 static int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
390 struct sock *sk = sock->sk;
391 int err = -EINVAL;
392 int pid;
394 switch(cmd)
396 case FIOSETOWN:
397 case SIOCSPGRP:
398 err = get_user(pid, (int *) arg);
399 if(err)
400 return err;
402 /* see sock_no_fcntl */
403 if (current->pid != pid && current->pgrp != -pid &&
404 !capable(CAP_NET_ADMIN))
405 return -EPERM;
406 sk->proc = pid;
407 return(0);
408 case FIOGETOWN:
409 case SIOCGPGRP:
410 err = put_user(sk->proc,(int *)arg);
411 if(err)
412 return err;
413 return(0);
414 case SIOCGSTAMP:
415 if(sk->stamp.tv_sec==0)
416 return -ENOENT;
417 err = copy_to_user((void *)arg, &sk->stamp,
418 sizeof(struct timeval));
419 if (err)
420 return -EFAULT;
421 return 0;
423 case SIOCADDRT:
424 case SIOCDELRT:
426 return(ipv6_route_ioctl(cmd,(void *)arg));
428 case SIOCSIFADDR:
429 return addrconf_add_ifaddr((void *) arg);
430 case SIOCDIFADDR:
431 return addrconf_del_ifaddr((void *) arg);
432 case SIOCSIFDSTADDR:
433 return addrconf_set_dstaddr((void *) arg);
434 default:
435 if ((cmd >= SIOCDEVPRIVATE) &&
436 (cmd <= (SIOCDEVPRIVATE + 15)))
437 return(dev_ioctl(cmd,(void *) arg));
439 if(sk->prot->ioctl==0 || (err=sk->prot->ioctl(sk, cmd, arg))==-ENOIOCTLCMD)
440 return(dev_ioctl(cmd,(void *) arg));
441 return err;
443 /*NOTREACHED*/
444 return(0);
447 struct proto_ops inet6_stream_ops = {
448 PF_INET6,
450 inet6_release,
451 inet6_bind,
452 inet_stream_connect, /* ok */
453 sock_no_socketpair, /* a do nothing */
454 inet_accept, /* ok */
455 inet6_getname,
456 tcp_poll, /* ok */
457 inet6_ioctl, /* must change */
458 inet_listen, /* ok */
459 inet_shutdown, /* ok */
460 inet_setsockopt, /* ok */
461 inet_getsockopt, /* ok */
462 sock_no_fcntl, /* ok */
463 inet_sendmsg, /* ok */
464 inet_recvmsg, /* ok */
465 sock_no_mmap
468 struct proto_ops inet6_dgram_ops = {
469 PF_INET6,
471 inet6_release,
472 inet6_bind,
473 inet_dgram_connect, /* ok */
474 sock_no_socketpair, /* a do nothing */
475 sock_no_accept, /* a do nothing */
476 inet6_getname,
477 datagram_poll, /* ok */
478 inet6_ioctl, /* must change */
479 sock_no_listen, /* ok */
480 inet_shutdown, /* ok */
481 inet_setsockopt, /* ok */
482 inet_getsockopt, /* ok */
483 sock_no_fcntl, /* ok */
484 inet_sendmsg, /* ok */
485 inet_recvmsg, /* ok */
486 sock_no_mmap,
489 struct net_proto_family inet6_family_ops = {
490 PF_INET6,
491 inet6_create
494 #ifdef MODULE
495 int ipv6_unload(void)
497 if (!unloadable) return 1;
498 /* We keep internally 3 raw sockets */
499 return atomic_read(&(__this_module.uc.usecount)) - 3;
501 #endif
503 #if defined(MODULE) && defined(CONFIG_SYSCTL)
504 extern void ipv6_sysctl_register(void);
505 extern void ipv6_sysctl_unregister(void);
506 #endif
508 #ifdef MODULE
509 int init_module(void)
510 #else
511 void __init inet6_proto_init(struct net_proto *pro)
512 #endif
514 struct sk_buff *dummy_skb;
515 int err;
517 #ifdef MODULE
518 if (!mod_member_present(&__this_module, can_unload))
519 return -EINVAL;
521 __this_module.can_unload = &ipv6_unload;
522 #endif
524 printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
526 if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
528 printk(KERN_CRIT "inet6_proto_init: size fault\n");
529 #ifdef MODULE
530 return -EINVAL;
531 #else
532 return;
533 #endif
537 * ipngwg API draft makes clear that the correct semantics
538 * for TCP and UDP is to consider one TCP and UDP instance
539 * in a host availiable by both INET and INET6 APIs and
540 * able to communicate via both network protocols.
543 #if defined(MODULE) && defined(CONFIG_SYSCTL)
544 ipv6_sysctl_register();
545 #endif
546 err = icmpv6_init(&inet6_family_ops);
547 if (err)
548 goto icmp_fail;
549 err = ndisc_init(&inet6_family_ops);
550 if (err)
551 goto ndisc_fail;
552 err = igmp6_init(&inet6_family_ops);
553 if (err)
554 goto igmp_fail;
555 ipv6_netdev_notif_init();
556 ipv6_packet_init();
557 ip6_route_init();
558 ip6_flowlabel_init();
559 addrconf_init();
560 sit_init();
562 /* Init v6 transport protocols. */
563 udpv6_init();
564 tcpv6_init();
566 /* Create /proc/foo6 entries. */
567 #ifdef CONFIG_PROC_FS
568 proc_net_create("raw6", 0, raw6_get_info);
569 proc_net_create("tcp6", 0, tcp6_get_info);
570 proc_net_create("udp6", 0, udp6_get_info);
571 proc_net_create("sockstat6", 0, afinet6_get_info);
572 proc_net_create("snmp6", 0, afinet6_get_snmp);
573 #endif
575 /* Now the userspace is allowed to create INET6 sockets. */
576 (void) sock_register(&inet6_family_ops);
578 #ifdef MODULE
579 return 0;
580 #else
581 return;
582 #endif
584 igmp_fail:
585 ndisc_cleanup();
586 ndisc_fail:
587 icmpv6_cleanup();
588 icmp_fail:
589 #if defined(MODULE) && defined(CONFIG_SYSCTL)
590 ipv6_sysctl_unregister();
591 #endif
592 #ifdef MODULE
593 return err;
594 #else
595 return;
596 #endif
599 #ifdef MODULE
600 void cleanup_module(void)
602 /* First of all disallow new sockets creation. */
603 sock_unregister(PF_INET6);
604 #ifdef CONFIG_PROC_FS
605 proc_net_remove("raw6");
606 proc_net_remove("tcp6");
607 proc_net_remove("udp6");
608 proc_net_remove("sockstat6");
609 proc_net_remove("snmp6");
610 #endif
611 /* Cleanup code parts. */
612 sit_cleanup();
613 ipv6_netdev_notif_cleanup();
614 ip6_flowlabel_cleanup();
615 addrconf_cleanup();
616 ip6_route_cleanup();
617 ipv6_packet_cleanup();
618 igmp6_cleanup();
619 ndisc_cleanup();
620 icmpv6_cleanup();
621 #ifdef CONFIG_SYSCTL
622 ipv6_sysctl_unregister();
623 #endif
625 #endif /* MODULE */