aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-03-21 06:42:24 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-21 06:42:24 -0400
commita25606c845856e5ca5ed54d23cab077e3a49bf10 (patch)
tree1721e46532d6f48d605d401d7cee83f78f551c45 /net/sctp/protocol.c
parent938b93adb2642885e688390396472d22a7548748 (diff)
parent94833dfb8c98ed4ca1944dd2c1339d88a2d1c758 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c129
1 files changed, 84 insertions, 45 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 25be8f04de6e..beea2fb18b15 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -995,6 +995,58 @@ static void cleanup_sctp_mibs(void)
995 free_percpu(sctp_statistics[1]); 995 free_percpu(sctp_statistics[1]);
996} 996}
997 997
998static void sctp_v4_pf_init(void)
999{
1000 /* Initialize the SCTP specific PF functions. */
1001 sctp_register_pf(&sctp_pf_inet, PF_INET);
1002 sctp_register_af(&sctp_af_inet);
1003}
1004
1005static void sctp_v4_pf_exit(void)
1006{
1007 list_del(&sctp_af_inet.list);
1008}
1009
1010static int sctp_v4_protosw_init(void)
1011{
1012 int rc;
1013
1014 rc = proto_register(&sctp_prot, 1);
1015 if (rc)
1016 return rc;
1017
1018 /* Register SCTP(UDP and TCP style) with socket layer. */
1019 inet_register_protosw(&sctp_seqpacket_protosw);
1020 inet_register_protosw(&sctp_stream_protosw);
1021
1022 return 0;
1023}
1024
1025static void sctp_v4_protosw_exit(void)
1026{
1027 inet_unregister_protosw(&sctp_stream_protosw);
1028 inet_unregister_protosw(&sctp_seqpacket_protosw);
1029 proto_unregister(&sctp_prot);
1030}
1031
1032static int sctp_v4_add_protocol(void)
1033{
1034 /* Register notifier for inet address additions/deletions. */
1035 register_inetaddr_notifier(&sctp_inetaddr_notifier);
1036
1037 /* Register SCTP with inet layer. */
1038 if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0)
1039 return -EAGAIN;
1040
1041 return 0;
1042}
1043
1044static void sctp_v4_del_protocol(void)
1045{
1046 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
1047 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1048}
1049
998/* Initialize the universe into something sensible. */ 1050/* Initialize the universe into something sensible. */
999SCTP_STATIC __init int sctp_init(void) 1051SCTP_STATIC __init int sctp_init(void)
1000{ 1052{
@@ -1038,8 +1090,6 @@ SCTP_STATIC __init int sctp_init(void)
1038 /* Initialize object count debugging. */ 1090 /* Initialize object count debugging. */
1039 sctp_dbg_objcnt_init(); 1091 sctp_dbg_objcnt_init();
1040 1092
1041 /* Initialize the SCTP specific PF functions. */
1042 sctp_register_pf(&sctp_pf_inet, PF_INET);
1043 /* 1093 /*
1044 * 14. Suggested SCTP Protocol Parameter Values 1094 * 14. Suggested SCTP Protocol Parameter Values
1045 */ 1095 */
@@ -1197,19 +1247,22 @@ SCTP_STATIC __init int sctp_init(void)
1197 sctp_sysctl_register(); 1247 sctp_sysctl_register();
1198 1248
1199 INIT_LIST_HEAD(&sctp_address_families); 1249 INIT_LIST_HEAD(&sctp_address_families);
1200 sctp_register_af(&sctp_af_inet); 1250 sctp_v4_pf_init();
1251 sctp_v6_pf_init();
1201 1252
1202 status = proto_register(&sctp_prot, 1); 1253 /* Initialize the local address list. */
1203 if (status) 1254 INIT_LIST_HEAD(&sctp_local_addr_list);
1204 goto err_proto_register; 1255 spin_lock_init(&sctp_local_addr_lock);
1256 sctp_get_local_addr_list();
1205 1257
1206 /* Register SCTP(UDP and TCP style) with socket layer. */ 1258 status = sctp_v4_protosw_init();
1207 inet_register_protosw(&sctp_seqpacket_protosw);
1208 inet_register_protosw(&sctp_stream_protosw);
1209 1259
1210 status = sctp_v6_init();
1211 if (status) 1260 if (status)
1212 goto err_v6_init; 1261 goto err_protosw_init;
1262
1263 status = sctp_v6_protosw_init();
1264 if (status)
1265 goto err_v6_protosw_init;
1213 1266
1214 /* Initialize the control inode/socket for handling OOTB packets. */ 1267 /* Initialize the control inode/socket for handling OOTB packets. */
1215 if ((status = sctp_ctl_sock_init())) { 1268 if ((status = sctp_ctl_sock_init())) {
@@ -1218,19 +1271,9 @@ SCTP_STATIC __init int sctp_init(void)
1218 goto err_ctl_sock_init; 1271 goto err_ctl_sock_init;
1219 } 1272 }
1220 1273
1221 /* Initialize the local address list. */ 1274 status = sctp_v4_add_protocol();
1222 INIT_LIST_HEAD(&sctp_local_addr_list); 1275 if (status)
1223 spin_lock_init(&sctp_local_addr_lock);
1224 sctp_get_local_addr_list();
1225
1226 /* Register notifier for inet address additions/deletions. */
1227 register_inetaddr_notifier(&sctp_inetaddr_notifier);
1228
1229 /* Register SCTP with inet layer. */
1230 if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0) {
1231 status = -EAGAIN;
1232 goto err_add_protocol; 1276 goto err_add_protocol;
1233 }
1234 1277
1235 /* Register SCTP with inet6 layer. */ 1278 /* Register SCTP with inet6 layer. */
1236 status = sctp_v6_add_protocol(); 1279 status = sctp_v6_add_protocol();
@@ -1241,18 +1284,18 @@ SCTP_STATIC __init int sctp_init(void)
1241out: 1284out:
1242 return status; 1285 return status;
1243err_v6_add_protocol: 1286err_v6_add_protocol:
1244 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); 1287 sctp_v6_del_protocol();
1245 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1246err_add_protocol: 1288err_add_protocol:
1247 sctp_free_local_addr_list(); 1289 sctp_v4_del_protocol();
1248 sock_release(sctp_ctl_socket); 1290 sock_release(sctp_ctl_socket);
1249err_ctl_sock_init: 1291err_ctl_sock_init:
1250 sctp_v6_exit(); 1292 sctp_v6_protosw_exit();
1251err_v6_init: 1293err_v6_protosw_init:
1252 inet_unregister_protosw(&sctp_stream_protosw); 1294 sctp_v4_protosw_exit();
1253 inet_unregister_protosw(&sctp_seqpacket_protosw); 1295err_protosw_init:
1254 proto_unregister(&sctp_prot); 1296 sctp_free_local_addr_list();
1255err_proto_register: 1297 sctp_v4_pf_exit();
1298 sctp_v6_pf_exit();
1256 sctp_sysctl_unregister(); 1299 sctp_sysctl_unregister();
1257 list_del(&sctp_af_inet.list); 1300 list_del(&sctp_af_inet.list);
1258 free_pages((unsigned long)sctp_port_hashtable, 1301 free_pages((unsigned long)sctp_port_hashtable,
@@ -1285,23 +1328,21 @@ SCTP_STATIC __exit void sctp_exit(void)
1285 1328
1286 /* Unregister with inet6/inet layers. */ 1329 /* Unregister with inet6/inet layers. */
1287 sctp_v6_del_protocol(); 1330 sctp_v6_del_protocol();
1288 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); 1331 sctp_v4_del_protocol();
1289
1290 /* Unregister notifier for inet address additions/deletions. */
1291 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1292
1293 /* Free the local address list. */
1294 sctp_free_local_addr_list();
1295 1332
1296 /* Free the control endpoint. */ 1333 /* Free the control endpoint. */
1297 sock_release(sctp_ctl_socket); 1334 sock_release(sctp_ctl_socket);
1298 1335
1299 /* Cleanup v6 initializations. */ 1336 /* Free protosw registrations */
1300 sctp_v6_exit(); 1337 sctp_v6_protosw_exit();
1338 sctp_v4_protosw_exit();
1339
1340 /* Free the local address list. */
1341 sctp_free_local_addr_list();
1301 1342
1302 /* Unregister with socket layer. */ 1343 /* Unregister with socket layer. */
1303 inet_unregister_protosw(&sctp_stream_protosw); 1344 sctp_v6_pf_exit();
1304 inet_unregister_protosw(&sctp_seqpacket_protosw); 1345 sctp_v4_pf_exit();
1305 1346
1306 sctp_sysctl_unregister(); 1347 sctp_sysctl_unregister();
1307 list_del(&sctp_af_inet.list); 1348 list_del(&sctp_af_inet.list);
@@ -1320,8 +1361,6 @@ SCTP_STATIC __exit void sctp_exit(void)
1320 1361
1321 kmem_cache_destroy(sctp_chunk_cachep); 1362 kmem_cache_destroy(sctp_chunk_cachep);
1322 kmem_cache_destroy(sctp_bucket_cachep); 1363 kmem_cache_destroy(sctp_bucket_cachep);
1323
1324 proto_unregister(&sctp_prot);
1325} 1364}
1326 1365
1327module_init(sctp_init); 1366module_init(sctp_init);