diff options
-rw-r--r-- | include/net/ipv6.h | 2 | ||||
-rw-r--r-- | include/net/transp_v6.h | 12 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 77 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 3 | ||||
-rw-r--r-- | net/ipv6/raw.c | 52 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 36 | ||||
-rw-r--r-- | net/ipv6/udp.c | 26 | ||||
-rw-r--r-- | net/ipv6/udplite.c | 25 |
8 files changed, 168 insertions, 65 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 4d9106580950..f2adedff927f 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -545,7 +545,7 @@ extern int compat_ipv6_getsockopt(struct sock *sk, | |||
545 | char __user *optval, | 545 | char __user *optval, |
546 | int __user *optlen); | 546 | int __user *optlen); |
547 | 547 | ||
548 | extern void ipv6_packet_init(void); | 548 | extern int ipv6_packet_init(void); |
549 | 549 | ||
550 | extern void ipv6_packet_cleanup(void); | 550 | extern void ipv6_packet_cleanup(void); |
551 | 551 | ||
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index aa9a4a6b99df..27394e0447d8 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h | |||
@@ -23,10 +23,14 @@ extern int ipv6_frag_init(void); | |||
23 | extern void ipv6_frag_exit(void); | 23 | extern void ipv6_frag_exit(void); |
24 | 24 | ||
25 | /* transport protocols */ | 25 | /* transport protocols */ |
26 | extern void rawv6_init(void); | 26 | extern int rawv6_init(void); |
27 | extern void udpv6_init(void); | 27 | extern void rawv6_exit(void); |
28 | extern void udplitev6_init(void); | 28 | extern int udpv6_init(void); |
29 | extern void tcpv6_init(void); | 29 | extern void udpv6_exit(void); |
30 | extern int udplitev6_init(void); | ||
31 | extern void udplitev6_exit(void); | ||
32 | extern int tcpv6_init(void); | ||
33 | extern void tcpv6_exit(void); | ||
30 | 34 | ||
31 | extern int udpv6_connect(struct sock *sk, | 35 | extern int udpv6_connect(struct sock *sk, |
32 | struct sockaddr *uaddr, | 36 | struct sockaddr *uaddr, |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 53b06de696bd..34c20533ba5d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -529,42 +529,6 @@ static struct net_proto_family inet6_family_ops = { | |||
529 | .owner = THIS_MODULE, | 529 | .owner = THIS_MODULE, |
530 | }; | 530 | }; |
531 | 531 | ||
532 | /* Same as inet6_dgram_ops, sans udp_poll. */ | ||
533 | static const struct proto_ops inet6_sockraw_ops = { | ||
534 | .family = PF_INET6, | ||
535 | .owner = THIS_MODULE, | ||
536 | .release = inet6_release, | ||
537 | .bind = inet6_bind, | ||
538 | .connect = inet_dgram_connect, /* ok */ | ||
539 | .socketpair = sock_no_socketpair, /* a do nothing */ | ||
540 | .accept = sock_no_accept, /* a do nothing */ | ||
541 | .getname = inet6_getname, | ||
542 | .poll = datagram_poll, /* ok */ | ||
543 | .ioctl = inet6_ioctl, /* must change */ | ||
544 | .listen = sock_no_listen, /* ok */ | ||
545 | .shutdown = inet_shutdown, /* ok */ | ||
546 | .setsockopt = sock_common_setsockopt, /* ok */ | ||
547 | .getsockopt = sock_common_getsockopt, /* ok */ | ||
548 | .sendmsg = inet_sendmsg, /* ok */ | ||
549 | .recvmsg = sock_common_recvmsg, /* ok */ | ||
550 | .mmap = sock_no_mmap, | ||
551 | .sendpage = sock_no_sendpage, | ||
552 | #ifdef CONFIG_COMPAT | ||
553 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
554 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
555 | #endif | ||
556 | }; | ||
557 | |||
558 | static struct inet_protosw rawv6_protosw = { | ||
559 | .type = SOCK_RAW, | ||
560 | .protocol = IPPROTO_IP, /* wild card */ | ||
561 | .prot = &rawv6_prot, | ||
562 | .ops = &inet6_sockraw_ops, | ||
563 | .capability = CAP_NET_RAW, | ||
564 | .no_check = UDP_CSUM_DEFAULT, | ||
565 | .flags = INET_PROTOSW_REUSE, | ||
566 | }; | ||
567 | |||
568 | int inet6_register_protosw(struct inet_protosw *p) | 532 | int inet6_register_protosw(struct inet_protosw *p) |
569 | { | 533 | { |
570 | struct list_head *lh; | 534 | struct list_head *lh; |
@@ -771,7 +735,6 @@ static int __init inet6_init(void) | |||
771 | __this_module.can_unload = &ipv6_unload; | 735 | __this_module.can_unload = &ipv6_unload; |
772 | #endif | 736 | #endif |
773 | #endif | 737 | #endif |
774 | |||
775 | err = proto_register(&tcpv6_prot, 1); | 738 | err = proto_register(&tcpv6_prot, 1); |
776 | if (err) | 739 | if (err) |
777 | goto out; | 740 | goto out; |
@@ -796,14 +759,16 @@ static int __init inet6_init(void) | |||
796 | /* We MUST register RAW sockets before we create the ICMP6, | 759 | /* We MUST register RAW sockets before we create the ICMP6, |
797 | * IGMP6, or NDISC control sockets. | 760 | * IGMP6, or NDISC control sockets. |
798 | */ | 761 | */ |
799 | inet6_register_protosw(&rawv6_protosw); | 762 | err = rawv6_init(); |
763 | if (err) | ||
764 | goto out_unregister_raw_proto; | ||
800 | 765 | ||
801 | /* Register the family here so that the init calls below will | 766 | /* Register the family here so that the init calls below will |
802 | * be able to create sockets. (?? is this dangerous ??) | 767 | * be able to create sockets. (?? is this dangerous ??) |
803 | */ | 768 | */ |
804 | err = sock_register(&inet6_family_ops); | 769 | err = sock_register(&inet6_family_ops); |
805 | if (err) | 770 | if (err) |
806 | goto out_unregister_raw_proto; | 771 | goto out_sock_register_fail; |
807 | 772 | ||
808 | /* Initialise ipv6 mibs */ | 773 | /* Initialise ipv6 mibs */ |
809 | err = init_ipv6_mibs(); | 774 | err = init_ipv6_mibs(); |
@@ -871,15 +836,32 @@ static int __init inet6_init(void) | |||
871 | goto ipv6_frag_fail; | 836 | goto ipv6_frag_fail; |
872 | 837 | ||
873 | /* Init v6 transport protocols. */ | 838 | /* Init v6 transport protocols. */ |
874 | udpv6_init(); | 839 | err = udpv6_init(); |
875 | udplitev6_init(); | 840 | if (err) |
876 | tcpv6_init(); | 841 | goto udpv6_fail; |
877 | 842 | ||
878 | ipv6_packet_init(); | 843 | err = udplitev6_init(); |
879 | err = 0; | 844 | if (err) |
845 | goto udplitev6_fail; | ||
846 | |||
847 | err = tcpv6_init(); | ||
848 | if (err) | ||
849 | goto tcpv6_fail; | ||
850 | |||
851 | err = ipv6_packet_init(); | ||
852 | if (err) | ||
853 | goto ipv6_packet_fail; | ||
880 | out: | 854 | out: |
881 | return err; | 855 | return err; |
882 | 856 | ||
857 | ipv6_packet_fail: | ||
858 | tcpv6_exit(); | ||
859 | tcpv6_fail: | ||
860 | udplitev6_exit(); | ||
861 | udplitev6_fail: | ||
862 | udpv6_exit(); | ||
863 | udpv6_fail: | ||
864 | ipv6_frag_exit(); | ||
883 | ipv6_frag_fail: | 865 | ipv6_frag_fail: |
884 | ipv6_exthdrs_exit(); | 866 | ipv6_exthdrs_exit(); |
885 | ipv6_exthdrs_fail: | 867 | ipv6_exthdrs_fail: |
@@ -920,6 +902,8 @@ icmp_fail: | |||
920 | out_unregister_sock: | 902 | out_unregister_sock: |
921 | sock_unregister(PF_INET6); | 903 | sock_unregister(PF_INET6); |
922 | rtnl_unregister_all(PF_INET6); | 904 | rtnl_unregister_all(PF_INET6); |
905 | out_sock_register_fail: | ||
906 | rawv6_exit(); | ||
923 | out_unregister_raw_proto: | 907 | out_unregister_raw_proto: |
924 | proto_unregister(&rawv6_prot); | 908 | proto_unregister(&rawv6_prot); |
925 | out_unregister_udplite_proto: | 909 | out_unregister_udplite_proto: |
@@ -939,6 +923,10 @@ static void __exit inet6_exit(void) | |||
939 | /* Disallow any further netlink messages */ | 923 | /* Disallow any further netlink messages */ |
940 | rtnl_unregister_all(PF_INET6); | 924 | rtnl_unregister_all(PF_INET6); |
941 | 925 | ||
926 | udpv6_exit(); | ||
927 | udplitev6_exit(); | ||
928 | tcpv6_exit(); | ||
929 | |||
942 | /* Cleanup code parts. */ | 930 | /* Cleanup code parts. */ |
943 | ipv6_packet_cleanup(); | 931 | ipv6_packet_cleanup(); |
944 | ipv6_frag_exit(); | 932 | ipv6_frag_exit(); |
@@ -961,6 +949,7 @@ static void __exit inet6_exit(void) | |||
961 | igmp6_cleanup(); | 949 | igmp6_cleanup(); |
962 | ndisc_cleanup(); | 950 | ndisc_cleanup(); |
963 | icmpv6_cleanup(); | 951 | icmpv6_cleanup(); |
952 | rawv6_exit(); | ||
964 | #ifdef CONFIG_SYSCTL | 953 | #ifdef CONFIG_SYSCTL |
965 | ipv6_sysctl_unregister(); | 954 | ipv6_sysctl_unregister(); |
966 | #endif | 955 | #endif |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 8c5f80fd03ad..20fece4ad3d8 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -1128,9 +1128,10 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1128 | EXPORT_SYMBOL(compat_ipv6_getsockopt); | 1128 | EXPORT_SYMBOL(compat_ipv6_getsockopt); |
1129 | #endif | 1129 | #endif |
1130 | 1130 | ||
1131 | void __init ipv6_packet_init(void) | 1131 | int __init ipv6_packet_init(void) |
1132 | { | 1132 | { |
1133 | dev_add_pack(&ipv6_packet_type); | 1133 | dev_add_pack(&ipv6_packet_type); |
1134 | return 0; | ||
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | void ipv6_packet_cleanup(void) | 1137 | void ipv6_packet_cleanup(void) |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index b34631e1b015..850b83e430bc 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1273,3 +1273,55 @@ void raw6_proc_exit(void) | |||
1273 | proc_net_remove(&init_net, "raw6"); | 1273 | proc_net_remove(&init_net, "raw6"); |
1274 | } | 1274 | } |
1275 | #endif /* CONFIG_PROC_FS */ | 1275 | #endif /* CONFIG_PROC_FS */ |
1276 | |||
1277 | /* Same as inet6_dgram_ops, sans udp_poll. */ | ||
1278 | static const struct proto_ops inet6_sockraw_ops = { | ||
1279 | .family = PF_INET6, | ||
1280 | .owner = THIS_MODULE, | ||
1281 | .release = inet6_release, | ||
1282 | .bind = inet6_bind, | ||
1283 | .connect = inet_dgram_connect, /* ok */ | ||
1284 | .socketpair = sock_no_socketpair, /* a do nothing */ | ||
1285 | .accept = sock_no_accept, /* a do nothing */ | ||
1286 | .getname = inet6_getname, | ||
1287 | .poll = datagram_poll, /* ok */ | ||
1288 | .ioctl = inet6_ioctl, /* must change */ | ||
1289 | .listen = sock_no_listen, /* ok */ | ||
1290 | .shutdown = inet_shutdown, /* ok */ | ||
1291 | .setsockopt = sock_common_setsockopt, /* ok */ | ||
1292 | .getsockopt = sock_common_getsockopt, /* ok */ | ||
1293 | .sendmsg = inet_sendmsg, /* ok */ | ||
1294 | .recvmsg = sock_common_recvmsg, /* ok */ | ||
1295 | .mmap = sock_no_mmap, | ||
1296 | .sendpage = sock_no_sendpage, | ||
1297 | #ifdef CONFIG_COMPAT | ||
1298 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
1299 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
1300 | #endif | ||
1301 | }; | ||
1302 | |||
1303 | static struct inet_protosw rawv6_protosw = { | ||
1304 | .type = SOCK_RAW, | ||
1305 | .protocol = IPPROTO_IP, /* wild card */ | ||
1306 | .prot = &rawv6_prot, | ||
1307 | .ops = &inet6_sockraw_ops, | ||
1308 | .capability = CAP_NET_RAW, | ||
1309 | .no_check = UDP_CSUM_DEFAULT, | ||
1310 | .flags = INET_PROTOSW_REUSE, | ||
1311 | }; | ||
1312 | |||
1313 | int __init rawv6_init(void) | ||
1314 | { | ||
1315 | int ret; | ||
1316 | |||
1317 | ret = inet6_register_protosw(&rawv6_protosw); | ||
1318 | if (ret) | ||
1319 | goto out; | ||
1320 | out: | ||
1321 | return ret; | ||
1322 | } | ||
1323 | |||
1324 | void __exit rawv6_exit(void) | ||
1325 | { | ||
1326 | inet6_unregister_protosw(&rawv6_protosw); | ||
1327 | } | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 93980c3b83e6..9544beb6d1ca 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -2166,14 +2166,36 @@ static struct inet_protosw tcpv6_protosw = { | |||
2166 | INET_PROTOSW_ICSK, | 2166 | INET_PROTOSW_ICSK, |
2167 | }; | 2167 | }; |
2168 | 2168 | ||
2169 | void __init tcpv6_init(void) | 2169 | int __init tcpv6_init(void) |
2170 | { | 2170 | { |
2171 | int ret; | ||
2172 | |||
2173 | ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP); | ||
2174 | if (ret) | ||
2175 | goto out; | ||
2176 | |||
2171 | /* register inet6 protocol */ | 2177 | /* register inet6 protocol */ |
2172 | if (inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP) < 0) | 2178 | ret = inet6_register_protosw(&tcpv6_protosw); |
2173 | printk(KERN_ERR "tcpv6_init: Could not register protocol\n"); | 2179 | if (ret) |
2174 | inet6_register_protosw(&tcpv6_protosw); | 2180 | goto out_tcpv6_protocol; |
2181 | |||
2182 | ret = inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, | ||
2183 | SOCK_RAW, IPPROTO_TCP); | ||
2184 | if (ret) | ||
2185 | goto out_tcpv6_protosw; | ||
2186 | out: | ||
2187 | return ret; | ||
2175 | 2188 | ||
2176 | if (inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, SOCK_RAW, | 2189 | out_tcpv6_protocol: |
2177 | IPPROTO_TCP) < 0) | 2190 | inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); |
2178 | panic("Failed to create the TCPv6 control socket.\n"); | 2191 | out_tcpv6_protosw: |
2192 | inet6_unregister_protosw(&tcpv6_protosw); | ||
2193 | goto out; | ||
2194 | } | ||
2195 | |||
2196 | void __exit tcpv6_exit(void) | ||
2197 | { | ||
2198 | sock_release(tcp6_socket); | ||
2199 | inet6_unregister_protosw(&tcpv6_protosw); | ||
2200 | inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); | ||
2179 | } | 2201 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fa640765385e..1e3bd39f54ec 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1016,9 +1016,27 @@ static struct inet_protosw udpv6_protosw = { | |||
1016 | }; | 1016 | }; |
1017 | 1017 | ||
1018 | 1018 | ||
1019 | void __init udpv6_init(void) | 1019 | int __init udpv6_init(void) |
1020 | { | 1020 | { |
1021 | if (inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP) < 0) | 1021 | int ret; |
1022 | printk(KERN_ERR "udpv6_init: Could not register protocol\n"); | 1022 | |
1023 | inet6_register_protosw(&udpv6_protosw); | 1023 | ret = inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP); |
1024 | if (ret) | ||
1025 | goto out; | ||
1026 | |||
1027 | ret = inet6_register_protosw(&udpv6_protosw); | ||
1028 | if (ret) | ||
1029 | goto out_udpv6_protocol; | ||
1030 | out: | ||
1031 | return ret; | ||
1032 | |||
1033 | out_udpv6_protocol: | ||
1034 | inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP); | ||
1035 | goto out; | ||
1036 | } | ||
1037 | |||
1038 | void __exit udpv6_exit(void) | ||
1039 | { | ||
1040 | inet6_unregister_protosw(&udpv6_protosw); | ||
1041 | inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP); | ||
1024 | } | 1042 | } |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 5a0379f71415..f20b376689fb 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -77,12 +77,29 @@ static struct inet_protosw udplite6_protosw = { | |||
77 | .flags = INET_PROTOSW_PERMANENT, | 77 | .flags = INET_PROTOSW_PERMANENT, |
78 | }; | 78 | }; |
79 | 79 | ||
80 | void __init udplitev6_init(void) | 80 | int __init udplitev6_init(void) |
81 | { | 81 | { |
82 | if (inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE) < 0) | 82 | int ret; |
83 | printk(KERN_ERR "%s: Could not register.\n", __FUNCTION__); | ||
84 | 83 | ||
85 | inet6_register_protosw(&udplite6_protosw); | 84 | ret = inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE); |
85 | if (ret) | ||
86 | goto out; | ||
87 | |||
88 | ret = inet6_register_protosw(&udplite6_protosw); | ||
89 | if (ret) | ||
90 | goto out_udplitev6_protocol; | ||
91 | out: | ||
92 | return ret; | ||
93 | |||
94 | out_udplitev6_protocol: | ||
95 | inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE); | ||
96 | goto out; | ||
97 | } | ||
98 | |||
99 | void __exit udplitev6_exit(void) | ||
100 | { | ||
101 | inet6_unregister_protosw(&udplite6_protosw); | ||
102 | inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE); | ||
86 | } | 103 | } |
87 | 104 | ||
88 | #ifdef CONFIG_PROC_FS | 105 | #ifdef CONFIG_PROC_FS |