diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/ipv6.c | 32 | ||||
-rw-r--r-- | net/sctp/protocol.c | 129 |
2 files changed, 104 insertions, 57 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 9aa0733aee87..b1e05d719f9b 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -1014,15 +1014,24 @@ static struct sctp_pf sctp_pf_inet6 = { | |||
1014 | }; | 1014 | }; |
1015 | 1015 | ||
1016 | /* Initialize IPv6 support and register with socket layer. */ | 1016 | /* Initialize IPv6 support and register with socket layer. */ |
1017 | int sctp_v6_init(void) | 1017 | void sctp_v6_pf_init(void) |
1018 | { | 1018 | { |
1019 | int rc; | ||
1020 | |||
1021 | /* Register the SCTP specific PF_INET6 functions. */ | 1019 | /* Register the SCTP specific PF_INET6 functions. */ |
1022 | sctp_register_pf(&sctp_pf_inet6, PF_INET6); | 1020 | sctp_register_pf(&sctp_pf_inet6, PF_INET6); |
1023 | 1021 | ||
1024 | /* Register the SCTP specific AF_INET6 functions. */ | 1022 | /* Register the SCTP specific AF_INET6 functions. */ |
1025 | sctp_register_af(&sctp_af_inet6); | 1023 | sctp_register_af(&sctp_af_inet6); |
1024 | } | ||
1025 | |||
1026 | void sctp_v6_pf_exit(void) | ||
1027 | { | ||
1028 | list_del(&sctp_af_inet6.list); | ||
1029 | } | ||
1030 | |||
1031 | /* Initialize IPv6 support and register with socket layer. */ | ||
1032 | int sctp_v6_protosw_init(void) | ||
1033 | { | ||
1034 | int rc; | ||
1026 | 1035 | ||
1027 | rc = proto_register(&sctpv6_prot, 1); | 1036 | rc = proto_register(&sctpv6_prot, 1); |
1028 | if (rc) | 1037 | if (rc) |
@@ -1035,6 +1044,14 @@ int sctp_v6_init(void) | |||
1035 | return 0; | 1044 | return 0; |
1036 | } | 1045 | } |
1037 | 1046 | ||
1047 | void sctp_v6_protosw_exit(void) | ||
1048 | { | ||
1049 | inet6_unregister_protosw(&sctpv6_seqpacket_protosw); | ||
1050 | inet6_unregister_protosw(&sctpv6_stream_protosw); | ||
1051 | proto_unregister(&sctpv6_prot); | ||
1052 | } | ||
1053 | |||
1054 | |||
1038 | /* Register with inet6 layer. */ | 1055 | /* Register with inet6 layer. */ |
1039 | int sctp_v6_add_protocol(void) | 1056 | int sctp_v6_add_protocol(void) |
1040 | { | 1057 | { |
@@ -1047,15 +1064,6 @@ int sctp_v6_add_protocol(void) | |||
1047 | return 0; | 1064 | return 0; |
1048 | } | 1065 | } |
1049 | 1066 | ||
1050 | /* IPv6 specific exit support. */ | ||
1051 | void sctp_v6_exit(void) | ||
1052 | { | ||
1053 | inet6_unregister_protosw(&sctpv6_seqpacket_protosw); | ||
1054 | inet6_unregister_protosw(&sctpv6_stream_protosw); | ||
1055 | proto_unregister(&sctpv6_prot); | ||
1056 | list_del(&sctp_af_inet6.list); | ||
1057 | } | ||
1058 | |||
1059 | /* Unregister with inet6 layer. */ | 1067 | /* Unregister with inet6 layer. */ |
1060 | void sctp_v6_del_protocol(void) | 1068 | void sctp_v6_del_protocol(void) |
1061 | { | 1069 | { |
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 | ||
995 | static 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 | |||
1002 | static void sctp_v4_pf_exit(void) | ||
1003 | { | ||
1004 | list_del(&sctp_af_inet.list); | ||
1005 | } | ||
1006 | |||
1007 | static 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 | |||
1022 | static 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 | |||
1029 | static 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 | |||
1041 | static 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. */ |
996 | SCTP_STATIC __init int sctp_init(void) | 1048 | SCTP_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) | |||
1238 | out: | 1281 | out: |
1239 | return status; | 1282 | return status; |
1240 | err_v6_add_protocol: | 1283 | err_v6_add_protocol: |
1241 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); | 1284 | sctp_v6_del_protocol(); |
1242 | unregister_inetaddr_notifier(&sctp_inetaddr_notifier); | ||
1243 | err_add_protocol: | 1285 | err_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); |
1246 | err_ctl_sock_init: | 1288 | err_ctl_sock_init: |
1247 | sctp_v6_exit(); | 1289 | sctp_v6_protosw_exit(); |
1248 | err_v6_init: | 1290 | err_v6_protosw_init: |
1249 | inet_unregister_protosw(&sctp_stream_protosw); | 1291 | sctp_v4_protosw_exit(); |
1250 | inet_unregister_protosw(&sctp_seqpacket_protosw); | 1292 | err_protosw_init: |
1251 | proto_unregister(&sctp_prot); | 1293 | sctp_free_local_addr_list(); |
1252 | err_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 | ||
1324 | module_init(sctp_init); | 1363 | module_init(sctp_init); |