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.c221
1 files changed, 177 insertions, 44 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index f0aa97738746..1731b0abf7f5 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -92,9 +92,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol)
92 int try_loading_module = 0; 92 int try_loading_module = 0;
93 int err; 93 int err;
94 94
95 if (net != &init_net)
96 return -EAFNOSUPPORT;
97
98 if (sock->type != SOCK_RAW && 95 if (sock->type != SOCK_RAW &&
99 sock->type != SOCK_DGRAM && 96 sock->type != SOCK_DGRAM &&
100 !inet_ehash_secret) 97 !inet_ehash_secret)
@@ -248,6 +245,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
248 struct sock *sk = sock->sk; 245 struct sock *sk = sock->sk;
249 struct inet_sock *inet = inet_sk(sk); 246 struct inet_sock *inet = inet_sk(sk);
250 struct ipv6_pinfo *np = inet6_sk(sk); 247 struct ipv6_pinfo *np = inet6_sk(sk);
248 struct net *net = sock_net(sk);
251 __be32 v4addr = 0; 249 __be32 v4addr = 0;
252 unsigned short snum; 250 unsigned short snum;
253 int addr_type = 0; 251 int addr_type = 0;
@@ -278,7 +276,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
278 /* Check if the address belongs to the host. */ 276 /* Check if the address belongs to the host. */
279 if (addr_type == IPV6_ADDR_MAPPED) { 277 if (addr_type == IPV6_ADDR_MAPPED) {
280 v4addr = addr->sin6_addr.s6_addr32[3]; 278 v4addr = addr->sin6_addr.s6_addr32[3];
281 if (inet_addr_type(&init_net, v4addr) != RTN_LOCAL) { 279 if (inet_addr_type(net, v4addr) != RTN_LOCAL) {
282 err = -EADDRNOTAVAIL; 280 err = -EADDRNOTAVAIL;
283 goto out; 281 goto out;
284 } 282 }
@@ -300,7 +298,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
300 err = -EINVAL; 298 err = -EINVAL;
301 goto out; 299 goto out;
302 } 300 }
303 dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); 301 dev = dev_get_by_index(net, sk->sk_bound_dev_if);
304 if (!dev) { 302 if (!dev) {
305 err = -ENODEV; 303 err = -ENODEV;
306 goto out; 304 goto out;
@@ -312,7 +310,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
312 */ 310 */
313 v4addr = LOOPBACK4_IPV6; 311 v4addr = LOOPBACK4_IPV6;
314 if (!(addr_type & IPV6_ADDR_MULTICAST)) { 312 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
315 if (!ipv6_chk_addr(&init_net, &addr->sin6_addr, 313 if (!ipv6_chk_addr(net, &addr->sin6_addr,
316 dev, 0)) { 314 dev, 0)) {
317 if (dev) 315 if (dev)
318 dev_put(dev); 316 dev_put(dev);
@@ -440,6 +438,7 @@ EXPORT_SYMBOL(inet6_getname);
440int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 438int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
441{ 439{
442 struct sock *sk = sock->sk; 440 struct sock *sk = sock->sk;
441 struct net *net = sock_net(sk);
443 442
444 switch(cmd) 443 switch(cmd)
445 { 444 {
@@ -452,14 +451,14 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
452 case SIOCADDRT: 451 case SIOCADDRT:
453 case SIOCDELRT: 452 case SIOCDELRT:
454 453
455 return(ipv6_route_ioctl(cmd,(void __user *)arg)); 454 return(ipv6_route_ioctl(net, cmd, (void __user *)arg));
456 455
457 case SIOCSIFADDR: 456 case SIOCSIFADDR:
458 return addrconf_add_ifaddr((void __user *) arg); 457 return addrconf_add_ifaddr(net, (void __user *) arg);
459 case SIOCDIFADDR: 458 case SIOCDIFADDR:
460 return addrconf_del_ifaddr((void __user *) arg); 459 return addrconf_del_ifaddr(net, (void __user *) arg);
461 case SIOCSIFDSTADDR: 460 case SIOCSIFDSTADDR:
462 return addrconf_set_dstaddr((void __user *) arg); 461 return addrconf_set_dstaddr(net, (void __user *) arg);
463 default: 462 default:
464 if (!sk->sk_prot->ioctl) 463 if (!sk->sk_prot->ioctl)
465 return -ENOIOCTLCMD; 464 return -ENOIOCTLCMD;
@@ -678,6 +677,129 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
678 677
679EXPORT_SYMBOL_GPL(ipv6_opt_accepted); 678EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
680 679
680static struct inet6_protocol *ipv6_gso_pull_exthdrs(struct sk_buff *skb,
681 int proto)
682{
683 struct inet6_protocol *ops = NULL;
684
685 for (;;) {
686 struct ipv6_opt_hdr *opth;
687 int len;
688
689 if (proto != NEXTHDR_HOP) {
690 ops = rcu_dereference(inet6_protos[proto]);
691
692 if (unlikely(!ops))
693 break;
694
695 if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
696 break;
697 }
698
699 if (unlikely(!pskb_may_pull(skb, 8)))
700 break;
701
702 opth = (void *)skb->data;
703 len = ipv6_optlen(opth);
704
705 if (unlikely(!pskb_may_pull(skb, len)))
706 break;
707
708 proto = opth->nexthdr;
709 __skb_pull(skb, len);
710 }
711
712 return ops;
713}
714
715static int ipv6_gso_send_check(struct sk_buff *skb)
716{
717 struct ipv6hdr *ipv6h;
718 struct inet6_protocol *ops;
719 int err = -EINVAL;
720
721 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
722 goto out;
723
724 ipv6h = ipv6_hdr(skb);
725 __skb_pull(skb, sizeof(*ipv6h));
726 err = -EPROTONOSUPPORT;
727
728 rcu_read_lock();
729 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
730 if (likely(ops && ops->gso_send_check)) {
731 skb_reset_transport_header(skb);
732 err = ops->gso_send_check(skb);
733 }
734 rcu_read_unlock();
735
736out:
737 return err;
738}
739
740static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
741{
742 struct sk_buff *segs = ERR_PTR(-EINVAL);
743 struct ipv6hdr *ipv6h;
744 struct inet6_protocol *ops;
745
746 if (!(features & NETIF_F_V6_CSUM))
747 features &= ~NETIF_F_SG;
748
749 if (unlikely(skb_shinfo(skb)->gso_type &
750 ~(SKB_GSO_UDP |
751 SKB_GSO_DODGY |
752 SKB_GSO_TCP_ECN |
753 SKB_GSO_TCPV6 |
754 0)))
755 goto out;
756
757 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
758 goto out;
759
760 ipv6h = ipv6_hdr(skb);
761 __skb_pull(skb, sizeof(*ipv6h));
762 segs = ERR_PTR(-EPROTONOSUPPORT);
763
764 rcu_read_lock();
765 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
766 if (likely(ops && ops->gso_segment)) {
767 skb_reset_transport_header(skb);
768 segs = ops->gso_segment(skb, features);
769 }
770 rcu_read_unlock();
771
772 if (unlikely(IS_ERR(segs)))
773 goto out;
774
775 for (skb = segs; skb; skb = skb->next) {
776 ipv6h = ipv6_hdr(skb);
777 ipv6h->payload_len = htons(skb->len - skb->mac_len -
778 sizeof(*ipv6h));
779 }
780
781out:
782 return segs;
783}
784
785static struct packet_type ipv6_packet_type = {
786 .type = __constant_htons(ETH_P_IPV6),
787 .func = ipv6_rcv,
788 .gso_send_check = ipv6_gso_send_check,
789 .gso_segment = ipv6_gso_segment,
790};
791
792static int __init ipv6_packet_init(void)
793{
794 dev_add_pack(&ipv6_packet_type);
795 return 0;
796}
797
798static void ipv6_packet_cleanup(void)
799{
800 dev_remove_pack(&ipv6_packet_type);
801}
802
681static int __init init_ipv6_mibs(void) 803static int __init init_ipv6_mibs(void)
682{ 804{
683 if (snmp_mib_init((void **)ipv6_statistics, 805 if (snmp_mib_init((void **)ipv6_statistics,
@@ -720,6 +842,8 @@ static void cleanup_ipv6_mibs(void)
720 842
721static int inet6_net_init(struct net *net) 843static int inet6_net_init(struct net *net)
722{ 844{
845 int err = 0;
846
723 net->ipv6.sysctl.bindv6only = 0; 847 net->ipv6.sysctl.bindv6only = 0;
724 net->ipv6.sysctl.flush_delay = 0; 848 net->ipv6.sysctl.flush_delay = 0;
725 net->ipv6.sysctl.ip6_rt_max_size = 4096; 849 net->ipv6.sysctl.ip6_rt_max_size = 4096;
@@ -731,12 +855,36 @@ static int inet6_net_init(struct net *net)
731 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; 855 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
732 net->ipv6.sysctl.icmpv6_time = 1*HZ; 856 net->ipv6.sysctl.icmpv6_time = 1*HZ;
733 857
734 return 0; 858#ifdef CONFIG_PROC_FS
859 err = udp6_proc_init(net);
860 if (err)
861 goto out;
862 err = tcp6_proc_init(net);
863 if (err)
864 goto proc_tcp6_fail;
865 err = ac6_proc_init(net);
866 if (err)
867 goto proc_ac6_fail;
868out:
869#endif
870 return err;
871
872#ifdef CONFIG_PROC_FS
873proc_ac6_fail:
874 tcp6_proc_exit(net);
875proc_tcp6_fail:
876 udp6_proc_exit(net);
877 goto out;
878#endif
735} 879}
736 880
737static void inet6_net_exit(struct net *net) 881static void inet6_net_exit(struct net *net)
738{ 882{
739 return; 883#ifdef CONFIG_PROC_FS
884 udp6_proc_exit(net);
885 tcp6_proc_exit(net);
886 ac6_proc_exit(net);
887#endif
740} 888}
741 889
742static struct pernet_operations inet6_net_ops = { 890static struct pernet_operations inet6_net_ops = {
@@ -802,19 +950,13 @@ static int __init inet6_init(void)
802 err = register_pernet_subsys(&inet6_net_ops); 950 err = register_pernet_subsys(&inet6_net_ops);
803 if (err) 951 if (err)
804 goto register_pernet_fail; 952 goto register_pernet_fail;
805 953 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) 954 if (err)
813 goto icmp_fail; 955 goto icmp_fail;
814 err = ndisc_init(&inet6_family_ops); 956 err = ndisc_init();
815 if (err) 957 if (err)
816 goto ndisc_fail; 958 goto ndisc_fail;
817 err = igmp6_init(&inet6_family_ops); 959 err = igmp6_init();
818 if (err) 960 if (err)
819 goto igmp_fail; 961 goto igmp_fail;
820 err = ipv6_netfilter_init(); 962 err = ipv6_netfilter_init();
@@ -825,17 +967,10 @@ static int __init inet6_init(void)
825 err = -ENOMEM; 967 err = -ENOMEM;
826 if (raw6_proc_init()) 968 if (raw6_proc_init())
827 goto proc_raw6_fail; 969 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()) 970 if (udplite6_proc_init())
833 goto proc_udplite6_fail; 971 goto proc_udplite6_fail;
834 if (ipv6_misc_proc_init()) 972 if (ipv6_misc_proc_init())
835 goto proc_misc6_fail; 973 goto proc_misc6_fail;
836
837 if (ac6_proc_init())
838 goto proc_anycast6_fail;
839 if (if6_proc_init()) 974 if (if6_proc_init())
840 goto proc_if6_fail; 975 goto proc_if6_fail;
841#endif 976#endif
@@ -874,9 +1009,19 @@ static int __init inet6_init(void)
874 err = ipv6_packet_init(); 1009 err = ipv6_packet_init();
875 if (err) 1010 if (err)
876 goto ipv6_packet_fail; 1011 goto ipv6_packet_fail;
1012
1013#ifdef CONFIG_SYSCTL
1014 err = ipv6_sysctl_register();
1015 if (err)
1016 goto sysctl_fail;
1017#endif
877out: 1018out:
878 return err; 1019 return err;
879 1020
1021#ifdef CONFIG_SYSCTL
1022sysctl_fail:
1023 ipv6_packet_cleanup();
1024#endif
880ipv6_packet_fail: 1025ipv6_packet_fail:
881 tcpv6_exit(); 1026 tcpv6_exit();
882tcpv6_fail: 1027tcpv6_fail:
@@ -897,16 +1042,10 @@ ip6_route_fail:
897#ifdef CONFIG_PROC_FS 1042#ifdef CONFIG_PROC_FS
898 if6_proc_exit(); 1043 if6_proc_exit();
899proc_if6_fail: 1044proc_if6_fail:
900 ac6_proc_exit();
901proc_anycast6_fail:
902 ipv6_misc_proc_exit(); 1045 ipv6_misc_proc_exit();
903proc_misc6_fail: 1046proc_misc6_fail:
904 udplite6_proc_exit(); 1047 udplite6_proc_exit();
905proc_udplite6_fail: 1048proc_udplite6_fail:
906 udp6_proc_exit();
907proc_udp6_fail:
908 tcp6_proc_exit();
909proc_tcp6_fail:
910 raw6_proc_exit(); 1049 raw6_proc_exit();
911proc_raw6_fail: 1050proc_raw6_fail:
912#endif 1051#endif
@@ -918,10 +1057,6 @@ igmp_fail:
918ndisc_fail: 1057ndisc_fail:
919 icmpv6_cleanup(); 1058 icmpv6_cleanup();
920icmp_fail: 1059icmp_fail:
921#ifdef CONFIG_SYSCTL
922 ipv6_sysctl_unregister();
923sysctl_fail:
924#endif
925 unregister_pernet_subsys(&inet6_net_ops); 1060 unregister_pernet_subsys(&inet6_net_ops);
926register_pernet_fail: 1061register_pernet_fail:
927 cleanup_ipv6_mibs(); 1062 cleanup_ipv6_mibs();
@@ -949,6 +1084,9 @@ static void __exit inet6_exit(void)
949 /* Disallow any further netlink messages */ 1084 /* Disallow any further netlink messages */
950 rtnl_unregister_all(PF_INET6); 1085 rtnl_unregister_all(PF_INET6);
951 1086
1087#ifdef CONFIG_SYSCTL
1088 ipv6_sysctl_unregister();
1089#endif
952 udpv6_exit(); 1090 udpv6_exit();
953 udplitev6_exit(); 1091 udplitev6_exit();
954 tcpv6_exit(); 1092 tcpv6_exit();
@@ -964,11 +1102,8 @@ static void __exit inet6_exit(void)
964 1102
965 /* Cleanup code parts. */ 1103 /* Cleanup code parts. */
966 if6_proc_exit(); 1104 if6_proc_exit();
967 ac6_proc_exit();
968 ipv6_misc_proc_exit(); 1105 ipv6_misc_proc_exit();
969 udplite6_proc_exit(); 1106 udplite6_proc_exit();
970 udp6_proc_exit();
971 tcp6_proc_exit();
972 raw6_proc_exit(); 1107 raw6_proc_exit();
973#endif 1108#endif
974 ipv6_netfilter_fini(); 1109 ipv6_netfilter_fini();
@@ -976,9 +1111,7 @@ static void __exit inet6_exit(void)
976 ndisc_cleanup(); 1111 ndisc_cleanup();
977 icmpv6_cleanup(); 1112 icmpv6_cleanup();
978 rawv6_exit(); 1113 rawv6_exit();
979#ifdef CONFIG_SYSCTL 1114
980 ipv6_sysctl_unregister();
981#endif
982 unregister_pernet_subsys(&inet6_net_ops); 1115 unregister_pernet_subsys(&inet6_net_ops);
983 cleanup_ipv6_mibs(); 1116 cleanup_ipv6_mibs();
984 proto_unregister(&rawv6_prot); 1117 proto_unregister(&rawv6_prot);