aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h2
-rw-r--r--include/net/transp_v6.h12
-rw-r--r--net/ipv6/af_inet6.c77
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/raw.c52
-rw-r--r--net/ipv6/tcp_ipv6.c36
-rw-r--r--net/ipv6/udp.c26
-rw-r--r--net/ipv6/udplite.c25
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
548extern void ipv6_packet_init(void); 548extern int ipv6_packet_init(void);
549 549
550extern void ipv6_packet_cleanup(void); 550extern 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);
23extern void ipv6_frag_exit(void); 23extern void ipv6_frag_exit(void);
24 24
25/* transport protocols */ 25/* transport protocols */
26extern void rawv6_init(void); 26extern int rawv6_init(void);
27extern void udpv6_init(void); 27extern void rawv6_exit(void);
28extern void udplitev6_init(void); 28extern int udpv6_init(void);
29extern void tcpv6_init(void); 29extern void udpv6_exit(void);
30extern int udplitev6_init(void);
31extern void udplitev6_exit(void);
32extern int tcpv6_init(void);
33extern void tcpv6_exit(void);
30 34
31extern int udpv6_connect(struct sock *sk, 35extern 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. */
533static 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
558static 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
568int inet6_register_protosw(struct inet_protosw *p) 532int 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;
880out: 854out:
881 return err; 855 return err;
882 856
857ipv6_packet_fail:
858 tcpv6_exit();
859tcpv6_fail:
860 udplitev6_exit();
861udplitev6_fail:
862 udpv6_exit();
863udpv6_fail:
864 ipv6_frag_exit();
883ipv6_frag_fail: 865ipv6_frag_fail:
884 ipv6_exthdrs_exit(); 866 ipv6_exthdrs_exit();
885ipv6_exthdrs_fail: 867ipv6_exthdrs_fail:
@@ -920,6 +902,8 @@ icmp_fail:
920out_unregister_sock: 902out_unregister_sock:
921 sock_unregister(PF_INET6); 903 sock_unregister(PF_INET6);
922 rtnl_unregister_all(PF_INET6); 904 rtnl_unregister_all(PF_INET6);
905out_sock_register_fail:
906 rawv6_exit();
923out_unregister_raw_proto: 907out_unregister_raw_proto:
924 proto_unregister(&rawv6_prot); 908 proto_unregister(&rawv6_prot);
925out_unregister_udplite_proto: 909out_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,
1128EXPORT_SYMBOL(compat_ipv6_getsockopt); 1128EXPORT_SYMBOL(compat_ipv6_getsockopt);
1129#endif 1129#endif
1130 1130
1131void __init ipv6_packet_init(void) 1131int __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
1136void ipv6_packet_cleanup(void) 1137void 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. */
1278static 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
1303static 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
1313int __init rawv6_init(void)
1314{
1315 int ret;
1316
1317 ret = inet6_register_protosw(&rawv6_protosw);
1318 if (ret)
1319 goto out;
1320out:
1321 return ret;
1322}
1323
1324void __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
2169void __init tcpv6_init(void) 2169int __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;
2186out:
2187 return ret;
2175 2188
2176 if (inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, SOCK_RAW, 2189out_tcpv6_protocol:
2177 IPPROTO_TCP) < 0) 2190 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2178 panic("Failed to create the TCPv6 control socket.\n"); 2191out_tcpv6_protosw:
2192 inet6_unregister_protosw(&tcpv6_protosw);
2193 goto out;
2194}
2195
2196void __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
1019void __init udpv6_init(void) 1019int __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;
1030out:
1031 return ret;
1032
1033out_udpv6_protocol:
1034 inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP);
1035 goto out;
1036}
1037
1038void __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
80void __init udplitev6_init(void) 80int __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;
91out:
92 return ret;
93
94out_udplitev6_protocol:
95 inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
96 goto out;
97}
98
99void __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