diff options
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 129 |
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 | ||
998 | static 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 | |||
1005 | static void sctp_v4_pf_exit(void) | ||
1006 | { | ||
1007 | list_del(&sctp_af_inet.list); | ||
1008 | } | ||
1009 | |||
1010 | static 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 | |||
1025 | static 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 | |||
1032 | static 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 | |||
1044 | static 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. */ |
999 | SCTP_STATIC __init int sctp_init(void) | 1051 | SCTP_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) | |||
1241 | out: | 1284 | out: |
1242 | return status; | 1285 | return status; |
1243 | err_v6_add_protocol: | 1286 | err_v6_add_protocol: |
1244 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); | 1287 | sctp_v6_del_protocol(); |
1245 | unregister_inetaddr_notifier(&sctp_inetaddr_notifier); | ||
1246 | err_add_protocol: | 1288 | err_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); |
1249 | err_ctl_sock_init: | 1291 | err_ctl_sock_init: |
1250 | sctp_v6_exit(); | 1292 | sctp_v6_protosw_exit(); |
1251 | err_v6_init: | 1293 | err_v6_protosw_init: |
1252 | inet_unregister_protosw(&sctp_stream_protosw); | 1294 | sctp_v4_protosw_exit(); |
1253 | inet_unregister_protosw(&sctp_seqpacket_protosw); | 1295 | err_protosw_init: |
1254 | proto_unregister(&sctp_prot); | 1296 | sctp_free_local_addr_list(); |
1255 | err_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 | ||
1327 | module_init(sctp_init); | 1366 | module_init(sctp_init); |