aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/af_inet6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/af_inet6.c')
-rw-r--r--net/ipv6/af_inet6.c227
1 files changed, 183 insertions, 44 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index f0aa97738746..3c6aafb02183 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -61,6 +61,9 @@
61 61
62#include <asm/uaccess.h> 62#include <asm/uaccess.h>
63#include <asm/system.h> 63#include <asm/system.h>
64#ifdef CONFIG_IPV6_MROUTE
65#include <linux/mroute6.h>
66#endif
64 67
65MODULE_AUTHOR("Cast of dozens"); 68MODULE_AUTHOR("Cast of dozens");
66MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); 69MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
@@ -92,9 +95,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol)
92 int try_loading_module = 0; 95 int try_loading_module = 0;
93 int err; 96 int err;
94 97
95 if (net != &init_net)
96 return -EAFNOSUPPORT;
97
98 if (sock->type != SOCK_RAW && 98 if (sock->type != SOCK_RAW &&
99 sock->type != SOCK_DGRAM && 99 sock->type != SOCK_DGRAM &&
100 !inet_ehash_secret) 100 !inet_ehash_secret)
@@ -248,6 +248,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
248 struct sock *sk = sock->sk; 248 struct sock *sk = sock->sk;
249 struct inet_sock *inet = inet_sk(sk); 249 struct inet_sock *inet = inet_sk(sk);
250 struct ipv6_pinfo *np = inet6_sk(sk); 250 struct ipv6_pinfo *np = inet6_sk(sk);
251 struct net *net = sock_net(sk);
251 __be32 v4addr = 0; 252 __be32 v4addr = 0;
252 unsigned short snum; 253 unsigned short snum;
253 int addr_type = 0; 254 int addr_type = 0;
@@ -278,7 +279,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
278 /* Check if the address belongs to the host. */ 279 /* Check if the address belongs to the host. */
279 if (addr_type == IPV6_ADDR_MAPPED) { 280 if (addr_type == IPV6_ADDR_MAPPED) {
280 v4addr = addr->sin6_addr.s6_addr32[3]; 281 v4addr = addr->sin6_addr.s6_addr32[3];
281 if (inet_addr_type(&init_net, v4addr) != RTN_LOCAL) { 282 if (inet_addr_type(net, v4addr) != RTN_LOCAL) {
282 err = -EADDRNOTAVAIL; 283 err = -EADDRNOTAVAIL;
283 goto out; 284 goto out;
284 } 285 }
@@ -300,7 +301,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
300 err = -EINVAL; 301 err = -EINVAL;
301 goto out; 302 goto out;
302 } 303 }
303 dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); 304 dev = dev_get_by_index(net, sk->sk_bound_dev_if);
304 if (!dev) { 305 if (!dev) {
305 err = -ENODEV; 306 err = -ENODEV;
306 goto out; 307 goto out;
@@ -312,7 +313,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
312 */ 313 */
313 v4addr = LOOPBACK4_IPV6; 314 v4addr = LOOPBACK4_IPV6;
314 if (!(addr_type & IPV6_ADDR_MULTICAST)) { 315 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
315 if (!ipv6_chk_addr(&init_net, &addr->sin6_addr, 316 if (!ipv6_chk_addr(net, &addr->sin6_addr,
316 dev, 0)) { 317 dev, 0)) {
317 if (dev) 318 if (dev)
318 dev_put(dev); 319 dev_put(dev);
@@ -440,6 +441,7 @@ EXPORT_SYMBOL(inet6_getname);
440int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 441int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
441{ 442{
442 struct sock *sk = sock->sk; 443 struct sock *sk = sock->sk;
444 struct net *net = sock_net(sk);
443 445
444 switch(cmd) 446 switch(cmd)
445 { 447 {
@@ -452,14 +454,14 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
452 case SIOCADDRT: 454 case SIOCADDRT:
453 case SIOCDELRT: 455 case SIOCDELRT:
454 456
455 return(ipv6_route_ioctl(cmd,(void __user *)arg)); 457 return(ipv6_route_ioctl(net, cmd, (void __user *)arg));
456 458
457 case SIOCSIFADDR: 459 case SIOCSIFADDR:
458 return addrconf_add_ifaddr((void __user *) arg); 460 return addrconf_add_ifaddr(net, (void __user *) arg);
459 case SIOCDIFADDR: 461 case SIOCDIFADDR:
460 return addrconf_del_ifaddr((void __user *) arg); 462 return addrconf_del_ifaddr(net, (void __user *) arg);
461 case SIOCSIFDSTADDR: 463 case SIOCSIFDSTADDR:
462 return addrconf_set_dstaddr((void __user *) arg); 464 return addrconf_set_dstaddr(net, (void __user *) arg);
463 default: 465 default:
464 if (!sk->sk_prot->ioctl) 466 if (!sk->sk_prot->ioctl)
465 return -ENOIOCTLCMD; 467 return -ENOIOCTLCMD;
@@ -678,6 +680,129 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
678 680
679EXPORT_SYMBOL_GPL(ipv6_opt_accepted); 681EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
680 682
683static struct inet6_protocol *ipv6_gso_pull_exthdrs(struct sk_buff *skb,
684 int proto)
685{
686 struct inet6_protocol *ops = NULL;
687
688 for (;;) {
689 struct ipv6_opt_hdr *opth;
690 int len;
691
692 if (proto != NEXTHDR_HOP) {
693 ops = rcu_dereference(inet6_protos[proto]);
694
695 if (unlikely(!ops))
696 break;
697
698 if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
699 break;
700 }
701
702 if (unlikely(!pskb_may_pull(skb, 8)))
703 break;
704
705 opth = (void *)skb->data;
706 len = ipv6_optlen(opth);
707
708 if (unlikely(!pskb_may_pull(skb, len)))
709 break;
710
711 proto = opth->nexthdr;
712 __skb_pull(skb, len);
713 }
714
715 return ops;
716}
717
718static int ipv6_gso_send_check(struct sk_buff *skb)
719{
720 struct ipv6hdr *ipv6h;
721 struct inet6_protocol *ops;
722 int err = -EINVAL;
723
724 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
725 goto out;
726
727 ipv6h = ipv6_hdr(skb);
728 __skb_pull(skb, sizeof(*ipv6h));
729 err = -EPROTONOSUPPORT;
730
731 rcu_read_lock();
732 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
733 if (likely(ops && ops->gso_send_check)) {
734 skb_reset_transport_header(skb);
735 err = ops->gso_send_check(skb);
736 }
737 rcu_read_unlock();
738
739out:
740 return err;
741}
742
743static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
744{
745 struct sk_buff *segs = ERR_PTR(-EINVAL);
746 struct ipv6hdr *ipv6h;
747 struct inet6_protocol *ops;
748
749 if (!(features & NETIF_F_V6_CSUM))
750 features &= ~NETIF_F_SG;
751
752 if (unlikely(skb_shinfo(skb)->gso_type &
753 ~(SKB_GSO_UDP |
754 SKB_GSO_DODGY |
755 SKB_GSO_TCP_ECN |
756 SKB_GSO_TCPV6 |
757 0)))
758 goto out;
759
760 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
761 goto out;
762
763 ipv6h = ipv6_hdr(skb);
764 __skb_pull(skb, sizeof(*ipv6h));
765 segs = ERR_PTR(-EPROTONOSUPPORT);
766
767 rcu_read_lock();
768 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
769 if (likely(ops && ops->gso_segment)) {
770 skb_reset_transport_header(skb);
771 segs = ops->gso_segment(skb, features);
772 }
773 rcu_read_unlock();
774
775 if (unlikely(IS_ERR(segs)))
776 goto out;
777
778 for (skb = segs; skb; skb = skb->next) {
779 ipv6h = ipv6_hdr(skb);
780 ipv6h->payload_len = htons(skb->len - skb->mac_len -
781 sizeof(*ipv6h));
782 }
783
784out:
785 return segs;
786}
787
788static struct packet_type ipv6_packet_type = {
789 .type = __constant_htons(ETH_P_IPV6),
790 .func = ipv6_rcv,
791 .gso_send_check = ipv6_gso_send_check,
792 .gso_segment = ipv6_gso_segment,
793};
794
795static int __init ipv6_packet_init(void)
796{
797 dev_add_pack(&ipv6_packet_type);
798 return 0;
799}
800
801static void ipv6_packet_cleanup(void)
802{
803 dev_remove_pack(&ipv6_packet_type);
804}
805
681static int __init init_ipv6_mibs(void) 806static int __init init_ipv6_mibs(void)
682{ 807{
683 if (snmp_mib_init((void **)ipv6_statistics, 808 if (snmp_mib_init((void **)ipv6_statistics,
@@ -720,6 +845,8 @@ static void cleanup_ipv6_mibs(void)
720 845
721static int inet6_net_init(struct net *net) 846static int inet6_net_init(struct net *net)
722{ 847{
848 int err = 0;
849
723 net->ipv6.sysctl.bindv6only = 0; 850 net->ipv6.sysctl.bindv6only = 0;
724 net->ipv6.sysctl.flush_delay = 0; 851 net->ipv6.sysctl.flush_delay = 0;
725 net->ipv6.sysctl.ip6_rt_max_size = 4096; 852 net->ipv6.sysctl.ip6_rt_max_size = 4096;
@@ -731,12 +858,36 @@ static int inet6_net_init(struct net *net)
731 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; 858 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
732 net->ipv6.sysctl.icmpv6_time = 1*HZ; 859 net->ipv6.sysctl.icmpv6_time = 1*HZ;
733 860
734 return 0; 861#ifdef CONFIG_PROC_FS
862 err = udp6_proc_init(net);
863 if (err)
864 goto out;
865 err = tcp6_proc_init(net);
866 if (err)
867 goto proc_tcp6_fail;
868 err = ac6_proc_init(net);
869 if (err)
870 goto proc_ac6_fail;
871out:
872#endif
873 return err;
874
875#ifdef CONFIG_PROC_FS
876proc_ac6_fail:
877 tcp6_proc_exit(net);
878proc_tcp6_fail:
879 udp6_proc_exit(net);
880 goto out;
881#endif
735} 882}
736 883
737static void inet6_net_exit(struct net *net) 884static void inet6_net_exit(struct net *net)
738{ 885{
739 return; 886#ifdef CONFIG_PROC_FS
887 udp6_proc_exit(net);
888 tcp6_proc_exit(net);
889 ac6_proc_exit(net);
890#endif
740} 891}
741 892
742static struct pernet_operations inet6_net_ops = { 893static struct pernet_operations inet6_net_ops = {
@@ -802,19 +953,16 @@ static int __init inet6_init(void)
802 err = register_pernet_subsys(&inet6_net_ops); 953 err = register_pernet_subsys(&inet6_net_ops);
803 if (err) 954 if (err)
804 goto register_pernet_fail; 955 goto register_pernet_fail;
805 956 err = icmpv6_init();
806#ifdef CONFIG_SYSCTL
807 err = ipv6_sysctl_register();
808 if (err)
809 goto sysctl_fail;
810#endif
811 err = icmpv6_init(&inet6_family_ops);
812 if (err) 957 if (err)
813 goto icmp_fail; 958 goto icmp_fail;
814 err = ndisc_init(&inet6_family_ops); 959#ifdef CONFIG_IPV6_MROUTE
960 ip6_mr_init();
961#endif
962 err = ndisc_init();
815 if (err) 963 if (err)
816 goto ndisc_fail; 964 goto ndisc_fail;
817 err = igmp6_init(&inet6_family_ops); 965 err = igmp6_init();
818 if (err) 966 if (err)
819 goto igmp_fail; 967 goto igmp_fail;
820 err = ipv6_netfilter_init(); 968 err = ipv6_netfilter_init();
@@ -825,17 +973,10 @@ static int __init inet6_init(void)
825 err = -ENOMEM; 973 err = -ENOMEM;
826 if (raw6_proc_init()) 974 if (raw6_proc_init())
827 goto proc_raw6_fail; 975 goto proc_raw6_fail;
828 if (tcp6_proc_init())
829 goto proc_tcp6_fail;
830 if (udp6_proc_init())
831 goto proc_udp6_fail;
832 if (udplite6_proc_init()) 976 if (udplite6_proc_init())
833 goto proc_udplite6_fail; 977 goto proc_udplite6_fail;
834 if (ipv6_misc_proc_init()) 978 if (ipv6_misc_proc_init())
835 goto proc_misc6_fail; 979 goto proc_misc6_fail;
836
837 if (ac6_proc_init())
838 goto proc_anycast6_fail;
839 if (if6_proc_init()) 980 if (if6_proc_init())
840 goto proc_if6_fail; 981 goto proc_if6_fail;
841#endif 982#endif
@@ -874,9 +1015,19 @@ static int __init inet6_init(void)
874 err = ipv6_packet_init(); 1015 err = ipv6_packet_init();
875 if (err) 1016 if (err)
876 goto ipv6_packet_fail; 1017 goto ipv6_packet_fail;
1018
1019#ifdef CONFIG_SYSCTL
1020 err = ipv6_sysctl_register();
1021 if (err)
1022 goto sysctl_fail;
1023#endif
877out: 1024out:
878 return err; 1025 return err;
879 1026
1027#ifdef CONFIG_SYSCTL
1028sysctl_fail:
1029 ipv6_packet_cleanup();
1030#endif
880ipv6_packet_fail: 1031ipv6_packet_fail:
881 tcpv6_exit(); 1032 tcpv6_exit();
882tcpv6_fail: 1033tcpv6_fail:
@@ -897,16 +1048,10 @@ ip6_route_fail:
897#ifdef CONFIG_PROC_FS 1048#ifdef CONFIG_PROC_FS
898 if6_proc_exit(); 1049 if6_proc_exit();
899proc_if6_fail: 1050proc_if6_fail:
900 ac6_proc_exit();
901proc_anycast6_fail:
902 ipv6_misc_proc_exit(); 1051 ipv6_misc_proc_exit();
903proc_misc6_fail: 1052proc_misc6_fail:
904 udplite6_proc_exit(); 1053 udplite6_proc_exit();
905proc_udplite6_fail: 1054proc_udplite6_fail:
906 udp6_proc_exit();
907proc_udp6_fail:
908 tcp6_proc_exit();
909proc_tcp6_fail:
910 raw6_proc_exit(); 1055 raw6_proc_exit();
911proc_raw6_fail: 1056proc_raw6_fail:
912#endif 1057#endif
@@ -918,10 +1063,6 @@ igmp_fail:
918ndisc_fail: 1063ndisc_fail:
919 icmpv6_cleanup(); 1064 icmpv6_cleanup();
920icmp_fail: 1065icmp_fail:
921#ifdef CONFIG_SYSCTL
922 ipv6_sysctl_unregister();
923sysctl_fail:
924#endif
925 unregister_pernet_subsys(&inet6_net_ops); 1066 unregister_pernet_subsys(&inet6_net_ops);
926register_pernet_fail: 1067register_pernet_fail:
927 cleanup_ipv6_mibs(); 1068 cleanup_ipv6_mibs();
@@ -949,6 +1090,9 @@ static void __exit inet6_exit(void)
949 /* Disallow any further netlink messages */ 1090 /* Disallow any further netlink messages */
950 rtnl_unregister_all(PF_INET6); 1091 rtnl_unregister_all(PF_INET6);
951 1092
1093#ifdef CONFIG_SYSCTL
1094 ipv6_sysctl_unregister();
1095#endif
952 udpv6_exit(); 1096 udpv6_exit();
953 udplitev6_exit(); 1097 udplitev6_exit();
954 tcpv6_exit(); 1098 tcpv6_exit();
@@ -964,11 +1108,8 @@ static void __exit inet6_exit(void)
964 1108
965 /* Cleanup code parts. */ 1109 /* Cleanup code parts. */
966 if6_proc_exit(); 1110 if6_proc_exit();
967 ac6_proc_exit();
968 ipv6_misc_proc_exit(); 1111 ipv6_misc_proc_exit();
969 udplite6_proc_exit(); 1112 udplite6_proc_exit();
970 udp6_proc_exit();
971 tcp6_proc_exit();
972 raw6_proc_exit(); 1113 raw6_proc_exit();
973#endif 1114#endif
974 ipv6_netfilter_fini(); 1115 ipv6_netfilter_fini();
@@ -976,9 +1117,7 @@ static void __exit inet6_exit(void)
976 ndisc_cleanup(); 1117 ndisc_cleanup();
977 icmpv6_cleanup(); 1118 icmpv6_cleanup();
978 rawv6_exit(); 1119 rawv6_exit();
979#ifdef CONFIG_SYSCTL 1120
980 ipv6_sysctl_unregister();
981#endif
982 unregister_pernet_subsys(&inet6_net_ops); 1121 unregister_pernet_subsys(&inet6_net_ops);
983 cleanup_ipv6_mibs(); 1122 cleanup_ipv6_mibs();
984 proto_unregister(&rawv6_prot); 1123 proto_unregister(&rawv6_prot);