aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
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 7a7646a9565c..f90091a1b9ce 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -992,6 +992,58 @@ static void cleanup_sctp_mibs(void)
992 free_percpu(sctp_statistics[1]); 992 free_percpu(sctp_statistics[1]);
993} 993}
994 994
995static void sctp_v4_pf_init(void)
996{
997 /* Initialize the SCTP specific PF functions. */
998 sctp_register_pf(&sctp_pf_inet, PF_INET);
999 sctp_register_af(&sctp_af_inet);
1000}
1001
1002static void sctp_v4_pf_exit(void)
1003{
1004 list_del(&sctp_af_inet.list);
1005}
1006
1007static int sctp_v4_protosw_init(void)
1008{
1009 int rc;
1010
1011 rc = proto_register(&sctp_prot, 1);
1012 if (rc)
1013 return rc;
1014
1015 /* Register SCTP(UDP and TCP style) with socket layer. */
1016 inet_register_protosw(&sctp_seqpacket_protosw);
1017 inet_register_protosw(&sctp_stream_protosw);
1018
1019 return 0;
1020}
1021
1022static void sctp_v4_protosw_exit(void)
1023{
1024 inet_unregister_protosw(&sctp_stream_protosw);
1025 inet_unregister_protosw(&sctp_seqpacket_protosw);
1026 proto_unregister(&sctp_prot);
1027}
1028
1029static int sctp_v4_add_protocol(void)
1030{
1031 /* Register notifier for inet address additions/deletions. */
1032 register_inetaddr_notifier(&sctp_inetaddr_notifier);
1033
1034 /* Register SCTP with inet layer. */
1035 if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0)
1036 return -EAGAIN;
1037
1038 return 0;
1039}
1040
1041static void sctp_v4_del_protocol(void)
1042{
1043 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
1044 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1045}
1046
995/* Initialize the universe into something sensible. */ 1047/* Initialize the universe into something sensible. */
996SCTP_STATIC __init int sctp_init(void) 1048SCTP_STATIC __init int sctp_init(void)
997{ 1049{
@@ -1035,8 +1087,6 @@ SCTP_STATIC __init int sctp_init(void)
1035 /* Initialize object count debugging. */ 1087 /* Initialize object count debugging. */
1036 sctp_dbg_objcnt_init(); 1088 sctp_dbg_objcnt_init();
1037 1089
1038 /* Initialize the SCTP specific PF functions. */
1039 sctp_register_pf(&sctp_pf_inet, PF_INET);
1040 /* 1090 /*
1041 * 14. Suggested SCTP Protocol Parameter Values 1091 * 14. Suggested SCTP Protocol Parameter Values
1042 */ 1092 */
@@ -1194,19 +1244,22 @@ SCTP_STATIC __init int sctp_init(void)
1194 sctp_sysctl_register(); 1244 sctp_sysctl_register();
1195 1245
1196 INIT_LIST_HEAD(&sctp_address_families); 1246 INIT_LIST_HEAD(&sctp_address_families);
1197 sctp_register_af(&sctp_af_inet); 1247 sctp_v4_pf_init();
1248 sctp_v6_pf_init();
1198 1249
1199 status = proto_register(&sctp_prot, 1); 1250 /* Initialize the local address list. */
1200 if (status) 1251 INIT_LIST_HEAD(&sctp_local_addr_list);
1201 goto err_proto_register; 1252 spin_lock_init(&sctp_local_addr_lock);
1253 sctp_get_local_addr_list();
1202 1254
1203 /* Register SCTP(UDP and TCP style) with socket layer. */ 1255 status = sctp_v4_protosw_init();
1204 inet_register_protosw(&sctp_seqpacket_protosw);
1205 inet_register_protosw(&sctp_stream_protosw);
1206 1256
1207 status = sctp_v6_init();
1208 if (status) 1257 if (status)
1209 goto err_v6_init; 1258 goto err_protosw_init;
1259
1260 status = sctp_v6_protosw_init();
1261 if (status)
1262 goto err_v6_protosw_init;
1210 1263
1211 /* Initialize the control inode/socket for handling OOTB packets. */ 1264 /* Initialize the control inode/socket for handling OOTB packets. */
1212 if ((status = sctp_ctl_sock_init())) { 1265 if ((status = sctp_ctl_sock_init())) {
@@ -1215,19 +1268,9 @@ SCTP_STATIC __init int sctp_init(void)
1215 goto err_ctl_sock_init; 1268 goto err_ctl_sock_init;
1216 } 1269 }
1217 1270
1218 /* Initialize the local address list. */ 1271 status = sctp_v4_add_protocol();
1219 INIT_LIST_HEAD(&sctp_local_addr_list); 1272 if (status)
1220 spin_lock_init(&sctp_local_addr_lock);
1221 sctp_get_local_addr_list();
1222
1223 /* Register notifier for inet address additions/deletions. */
1224 register_inetaddr_notifier(&sctp_inetaddr_notifier);
1225
1226 /* Register SCTP with inet layer. */
1227 if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0) {
1228 status = -EAGAIN;
1229 goto err_add_protocol; 1273 goto err_add_protocol;
1230 }
1231 1274
1232 /* Register SCTP with inet6 layer. */ 1275 /* Register SCTP with inet6 layer. */
1233 status = sctp_v6_add_protocol(); 1276 status = sctp_v6_add_protocol();
@@ -1238,18 +1281,18 @@ SCTP_STATIC __init int sctp_init(void)
1238out: 1281out:
1239 return status; 1282 return status;
1240err_v6_add_protocol: 1283err_v6_add_protocol:
1241 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); 1284 sctp_v6_del_protocol();
1242 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1243err_add_protocol: 1285err_add_protocol:
1244 sctp_free_local_addr_list(); 1286 sctp_v4_del_protocol();
1245 sock_release(sctp_ctl_socket); 1287 sock_release(sctp_ctl_socket);
1246err_ctl_sock_init: 1288err_ctl_sock_init:
1247 sctp_v6_exit(); 1289 sctp_v6_protosw_exit();
1248err_v6_init: 1290err_v6_protosw_init:
1249 inet_unregister_protosw(&sctp_stream_protosw); 1291 sctp_v4_protosw_exit();
1250 inet_unregister_protosw(&sctp_seqpacket_protosw); 1292err_protosw_init:
1251 proto_unregister(&sctp_prot); 1293 sctp_free_local_addr_list();
1252err_proto_register: 1294 sctp_v4_pf_exit();
1295 sctp_v6_pf_exit();
1253 sctp_sysctl_unregister(); 1296 sctp_sysctl_unregister();
1254 list_del(&sctp_af_inet.list); 1297 list_del(&sctp_af_inet.list);
1255 free_pages((unsigned long)sctp_port_hashtable, 1298 free_pages((unsigned long)sctp_port_hashtable,
@@ -1282,23 +1325,21 @@ SCTP_STATIC __exit void sctp_exit(void)
1282 1325
1283 /* Unregister with inet6/inet layers. */ 1326 /* Unregister with inet6/inet layers. */
1284 sctp_v6_del_protocol(); 1327 sctp_v6_del_protocol();
1285 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); 1328 sctp_v4_del_protocol();
1286
1287 /* Unregister notifier for inet address additions/deletions. */
1288 unregister_inetaddr_notifier(&sctp_inetaddr_notifier);
1289
1290 /* Free the local address list. */
1291 sctp_free_local_addr_list();
1292 1329
1293 /* Free the control endpoint. */ 1330 /* Free the control endpoint. */
1294 sock_release(sctp_ctl_socket); 1331 sock_release(sctp_ctl_socket);
1295 1332
1296 /* Cleanup v6 initializations. */ 1333 /* Free protosw registrations */
1297 sctp_v6_exit(); 1334 sctp_v6_protosw_exit();
1335 sctp_v4_protosw_exit();
1336
1337 /* Free the local address list. */
1338 sctp_free_local_addr_list();
1298 1339
1299 /* Unregister with socket layer. */ 1340 /* Unregister with socket layer. */
1300 inet_unregister_protosw(&sctp_stream_protosw); 1341 sctp_v6_pf_exit();
1301 inet_unregister_protosw(&sctp_seqpacket_protosw); 1342 sctp_v4_pf_exit();
1302 1343
1303 sctp_sysctl_unregister(); 1344 sctp_sysctl_unregister();
1304 list_del(&sctp_af_inet.list); 1345 list_del(&sctp_af_inet.list);
@@ -1317,8 +1358,6 @@ SCTP_STATIC __exit void sctp_exit(void)
1317 1358
1318 kmem_cache_destroy(sctp_chunk_cachep); 1359 kmem_cache_destroy(sctp_chunk_cachep);
1319 kmem_cache_destroy(sctp_bucket_cachep); 1360 kmem_cache_destroy(sctp_bucket_cachep);
1320
1321 proto_unregister(&sctp_prot);
1322} 1361}
1323 1362
1324module_init(sctp_init); 1363module_init(sctp_init);