aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2007-12-11 05:25:35 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:57:13 -0500
commit7f4e4868f3ce0e946f116c28fa4fe033be5e4ba9 (patch)
tree144add1d4c94a145f7e048a17d91b563f5e6e265
parent87c3efbfdd1f98af14a1f60ff19f73d9a8d8da98 (diff)
[IPV6]: make the protocol initialization to return an error code
This patchset makes the different protocols to return an error code, so the af_inet6 module can check the initialization was correct or not. The raw6 was taken into account to be consistent with the rest of the protocols, but the registration is at the same place. Because the raw6 has its own init function, the proto and the ops structure can be moved inside the raw6.c file. Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-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