2 * PF_INET6 socket protocol family
3 * Linux INET6 implementation
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>
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>
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>
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>
60 static int unloadable
= 0; /* XX: Turn to one when all is ok within the
61 module for allowing unload */
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");
70 extern struct proto_ops inet6_stream_ops
;
71 extern struct proto_ops inet6_dgram_ops
;
73 /* IPv6 procfs goodies... */
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);
84 extern void ipv6_sysctl_register(void);
85 extern void ipv6_sysctl_unregister(void);
88 #ifdef INET_REFCNT_DEBUG
89 atomic_t inet6_sock_nr
;
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
);
102 static int inet6_create(struct socket
*sock
, int protocol
)
107 sk
= sk_alloc(PF_INET6
, GFP_KERNEL
, 1);
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
;
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
;
123 sock
->ops
= &inet6_dgram_ops
;
124 } else if(sock
->type
== SOCK_RAW
) {
125 if (!capable(CAP_NET_RAW
))
126 goto free_and_badperm
;
128 goto free_and_noproto
;
130 sock
->ops
= &inet6_dgram_ops
;
134 goto free_and_badtype
;
137 sock_init_data(sock
, sk
);
139 sk
->destruct
= inet6_sock_destruct
;
141 sk
->family
= PF_INET6
;
142 sk
->protocol
= protocol
;
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
;
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
);
174 if (sk
->type
==SOCK_RAW
&& protocol
==IPPROTO_RAW
)
175 sk
->protinfo
.af_inet
.hdrincl
=1;
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
);
186 if (sk
->prot
->init
) {
187 int err
= sk
->prot
->init(sk
);
190 inet_sock_release(sk
);
198 return -ESOCKTNOSUPPORT
;
204 return -EPROTONOSUPPORT
;
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
;
219 /* If the socket has its own bind function then use it. */
221 return sk
->prot
->bind(sk
, uaddr
, addr_len
);
223 if (addr_len
< sizeof(struct sockaddr_in6
))
226 addr_type
= ipv6_addr_type(&addr
->sin6_addr
);
227 if ((addr_type
& IPV6_ADDR_MULTICAST
) && sock
->type
== SOCK_STREAM
)
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
;
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
))
254 /* Check these errors (active socket, double bind). */
255 if ((sk
->state
!= TCP_CLOSE
) ||
261 sk
->rcv_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) {
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
));
280 sk
->sport
= ntohs(sk
->num
);
289 static int inet6_release(struct socket
*sock
)
291 struct sock
*sk
= sock
->sk
;
297 ipv6_sock_mc_close(sk
);
299 return inet_release(sock
);
302 int inet6_destroy_sock(struct sock
*sk
)
305 struct ipv6_txoptions
*opt
;
308 * Release destination entry
313 /* Release rx options */
315 if ((skb
= xchg(&sk
->net_pinfo
.af_inet6
.pktoptions
, NULL
)) != NULL
)
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
);
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;
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
;
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
));
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
);
365 static int inet6_ioctl(struct socket
*sock
, unsigned int cmd
, unsigned long arg
)
367 struct sock
*sk
= sock
->sk
;
375 err
= get_user(pid
, (int *) arg
);
379 /* see sock_no_fcntl */
380 if (current
->pid
!= pid
&& current
->pgrp
!= -pid
&&
381 !capable(CAP_NET_ADMIN
))
387 err
= put_user(sk
->proc
,(int *)arg
);
392 if(sk
->stamp
.tv_sec
==0)
394 err
= copy_to_user((void *)arg
, &sk
->stamp
,
395 sizeof(struct timeval
));
403 return(ipv6_route_ioctl(cmd
,(void *)arg
));
406 return addrconf_add_ifaddr((void *) arg
);
408 return addrconf_del_ifaddr((void *) arg
);
410 return addrconf_set_dstaddr((void *) arg
);
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
));
424 struct proto_ops inet6_stream_ops
= {
429 inet_stream_connect
, /* ok */
430 sock_no_socketpair
, /* a do nothing */
431 inet_accept
, /* 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 */
445 struct proto_ops inet6_dgram_ops
= {
450 inet_dgram_connect
, /* ok */
451 sock_no_socketpair
, /* a do nothing */
452 inet_accept
, /* ok */
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 */
466 struct net_proto_family inet6_family_ops
= {
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;
480 #if defined(MODULE) && defined(CONFIG_SYSCTL)
481 extern void ipv6_sysctl_register(void);
482 extern void ipv6_sysctl_unregister(void);
486 int init_module(void)
488 void __init
inet6_proto_init(struct net_proto
*pro
)
491 struct sk_buff
*dummy_skb
;
495 if (!mod_member_present(&__this_module
, can_unload
))
498 __this_module
.can_unload
= &ipv6_unload
;
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");
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();
523 err
= icmpv6_init(&inet6_family_ops
);
526 err
= ndisc_init(&inet6_family_ops
);
529 err
= igmp6_init(&inet6_family_ops
);
532 ipv6_netdev_notif_init();
535 ip6_flowlabel_init();
539 /* Init v6 transport protocols. */
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
);
552 /* Now the userspace is allowed to create INET6 sockets. */
553 (void) sock_register(&inet6_family_ops
);
566 #if defined(MODULE) && defined(CONFIG_SYSCTL)
567 ipv6_sysctl_unregister();
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");
588 /* Cleanup code parts. */
590 ipv6_netdev_notif_cleanup();
591 ip6_flowlabel_cleanup();
594 ipv6_packet_cleanup();
599 ipv6_sysctl_unregister();