diff options
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 143 |
1 files changed, 92 insertions, 51 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 688546dccd82..f90091a1b9ce 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -337,14 +337,14 @@ static int sctp_v4_cmp_addr(const union sctp_addr *addr1, | |||
337 | static void sctp_v4_inaddr_any(union sctp_addr *addr, __be16 port) | 337 | static void sctp_v4_inaddr_any(union sctp_addr *addr, __be16 port) |
338 | { | 338 | { |
339 | addr->v4.sin_family = AF_INET; | 339 | addr->v4.sin_family = AF_INET; |
340 | addr->v4.sin_addr.s_addr = INADDR_ANY; | 340 | addr->v4.sin_addr.s_addr = htonl(INADDR_ANY); |
341 | addr->v4.sin_port = port; | 341 | addr->v4.sin_port = port; |
342 | } | 342 | } |
343 | 343 | ||
344 | /* Is this a wildcard address? */ | 344 | /* Is this a wildcard address? */ |
345 | static int sctp_v4_is_any(const union sctp_addr *addr) | 345 | static int sctp_v4_is_any(const union sctp_addr *addr) |
346 | { | 346 | { |
347 | return INADDR_ANY == addr->v4.sin_addr.s_addr; | 347 | return htonl(INADDR_ANY) == addr->v4.sin_addr.s_addr; |
348 | } | 348 | } |
349 | 349 | ||
350 | /* This function checks if the address is a valid address to be used for | 350 | /* This function checks if the address is a valid address to be used for |
@@ -375,7 +375,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) | |||
375 | int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr); | 375 | int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr); |
376 | 376 | ||
377 | 377 | ||
378 | if (addr->v4.sin_addr.s_addr != INADDR_ANY && | 378 | if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) && |
379 | ret != RTN_LOCAL && | 379 | ret != RTN_LOCAL && |
380 | !sp->inet.freebind && | 380 | !sp->inet.freebind && |
381 | !sysctl_ip_nonlocal_bind) | 381 | !sysctl_ip_nonlocal_bind) |
@@ -628,6 +628,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | |||
628 | struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; | 628 | struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; |
629 | struct sctp_sockaddr_entry *addr = NULL; | 629 | struct sctp_sockaddr_entry *addr = NULL; |
630 | struct sctp_sockaddr_entry *temp; | 630 | struct sctp_sockaddr_entry *temp; |
631 | int found = 0; | ||
631 | 632 | ||
632 | switch (ev) { | 633 | switch (ev) { |
633 | case NETDEV_UP: | 634 | case NETDEV_UP: |
@@ -647,13 +648,14 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | |||
647 | list_for_each_entry_safe(addr, temp, | 648 | list_for_each_entry_safe(addr, temp, |
648 | &sctp_local_addr_list, list) { | 649 | &sctp_local_addr_list, list) { |
649 | if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { | 650 | if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { |
651 | found = 1; | ||
650 | addr->valid = 0; | 652 | addr->valid = 0; |
651 | list_del_rcu(&addr->list); | 653 | list_del_rcu(&addr->list); |
652 | break; | 654 | break; |
653 | } | 655 | } |
654 | } | 656 | } |
655 | spin_unlock_bh(&sctp_local_addr_lock); | 657 | spin_unlock_bh(&sctp_local_addr_lock); |
656 | if (addr && !addr->valid) | 658 | if (found) |
657 | call_rcu(&addr->rcu, sctp_local_addr_free); | 659 | call_rcu(&addr->rcu, sctp_local_addr_free); |
658 | break; | 660 | break; |
659 | } | 661 | } |
@@ -783,8 +785,8 @@ static int sctp_inet_cmp_addr(const union sctp_addr *addr1, | |||
783 | /* PF_INET only supports AF_INET addresses. */ | 785 | /* PF_INET only supports AF_INET addresses. */ |
784 | if (addr1->sa.sa_family != addr2->sa.sa_family) | 786 | if (addr1->sa.sa_family != addr2->sa.sa_family) |
785 | return 0; | 787 | return 0; |
786 | if (INADDR_ANY == addr1->v4.sin_addr.s_addr || | 788 | if (htonl(INADDR_ANY) == addr1->v4.sin_addr.s_addr || |
787 | INADDR_ANY == addr2->v4.sin_addr.s_addr) | 789 | htonl(INADDR_ANY) == addr2->v4.sin_addr.s_addr) |
788 | return 1; | 790 | return 1; |
789 | if (addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr) | 791 | if (addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr) |
790 | return 1; | 792 | return 1; |
@@ -990,6 +992,58 @@ static void cleanup_sctp_mibs(void) | |||
990 | free_percpu(sctp_statistics[1]); | 992 | free_percpu(sctp_statistics[1]); |
991 | } | 993 | } |
992 | 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 | |||
993 | /* Initialize the universe into something sensible. */ | 1047 | /* Initialize the universe into something sensible. */ |
994 | SCTP_STATIC __init int sctp_init(void) | 1048 | SCTP_STATIC __init int sctp_init(void) |
995 | { | 1049 | { |
@@ -1033,8 +1087,6 @@ SCTP_STATIC __init int sctp_init(void) | |||
1033 | /* Initialize object count debugging. */ | 1087 | /* Initialize object count debugging. */ |
1034 | sctp_dbg_objcnt_init(); | 1088 | sctp_dbg_objcnt_init(); |
1035 | 1089 | ||
1036 | /* Initialize the SCTP specific PF functions. */ | ||
1037 | sctp_register_pf(&sctp_pf_inet, PF_INET); | ||
1038 | /* | 1090 | /* |
1039 | * 14. Suggested SCTP Protocol Parameter Values | 1091 | * 14. Suggested SCTP Protocol Parameter Values |
1040 | */ | 1092 | */ |
@@ -1192,19 +1244,22 @@ SCTP_STATIC __init int sctp_init(void) | |||
1192 | sctp_sysctl_register(); | 1244 | sctp_sysctl_register(); |
1193 | 1245 | ||
1194 | INIT_LIST_HEAD(&sctp_address_families); | 1246 | INIT_LIST_HEAD(&sctp_address_families); |
1195 | sctp_register_af(&sctp_af_inet); | 1247 | sctp_v4_pf_init(); |
1248 | sctp_v6_pf_init(); | ||
1196 | 1249 | ||
1197 | status = proto_register(&sctp_prot, 1); | 1250 | /* Initialize the local address list. */ |
1198 | if (status) | 1251 | INIT_LIST_HEAD(&sctp_local_addr_list); |
1199 | goto err_proto_register; | 1252 | spin_lock_init(&sctp_local_addr_lock); |
1253 | sctp_get_local_addr_list(); | ||
1200 | 1254 | ||
1201 | /* Register SCTP(UDP and TCP style) with socket layer. */ | 1255 | status = sctp_v4_protosw_init(); |
1202 | inet_register_protosw(&sctp_seqpacket_protosw); | ||
1203 | inet_register_protosw(&sctp_stream_protosw); | ||
1204 | 1256 | ||
1205 | status = sctp_v6_init(); | ||
1206 | if (status) | 1257 | if (status) |
1207 | 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; | ||
1208 | 1263 | ||
1209 | /* Initialize the control inode/socket for handling OOTB packets. */ | 1264 | /* Initialize the control inode/socket for handling OOTB packets. */ |
1210 | if ((status = sctp_ctl_sock_init())) { | 1265 | if ((status = sctp_ctl_sock_init())) { |
@@ -1213,19 +1268,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
1213 | goto err_ctl_sock_init; | 1268 | goto err_ctl_sock_init; |
1214 | } | 1269 | } |
1215 | 1270 | ||
1216 | /* Initialize the local address list. */ | 1271 | status = sctp_v4_add_protocol(); |
1217 | INIT_LIST_HEAD(&sctp_local_addr_list); | 1272 | if (status) |
1218 | spin_lock_init(&sctp_local_addr_lock); | ||
1219 | sctp_get_local_addr_list(); | ||
1220 | |||
1221 | /* Register notifier for inet address additions/deletions. */ | ||
1222 | register_inetaddr_notifier(&sctp_inetaddr_notifier); | ||
1223 | |||
1224 | /* Register SCTP with inet layer. */ | ||
1225 | if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0) { | ||
1226 | status = -EAGAIN; | ||
1227 | goto err_add_protocol; | 1273 | goto err_add_protocol; |
1228 | } | ||
1229 | 1274 | ||
1230 | /* Register SCTP with inet6 layer. */ | 1275 | /* Register SCTP with inet6 layer. */ |
1231 | status = sctp_v6_add_protocol(); | 1276 | status = sctp_v6_add_protocol(); |
@@ -1236,18 +1281,18 @@ SCTP_STATIC __init int sctp_init(void) | |||
1236 | out: | 1281 | out: |
1237 | return status; | 1282 | return status; |
1238 | err_v6_add_protocol: | 1283 | err_v6_add_protocol: |
1239 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); | 1284 | sctp_v6_del_protocol(); |
1240 | unregister_inetaddr_notifier(&sctp_inetaddr_notifier); | ||
1241 | err_add_protocol: | 1285 | err_add_protocol: |
1242 | sctp_free_local_addr_list(); | 1286 | sctp_v4_del_protocol(); |
1243 | sock_release(sctp_ctl_socket); | 1287 | sock_release(sctp_ctl_socket); |
1244 | err_ctl_sock_init: | 1288 | err_ctl_sock_init: |
1245 | sctp_v6_exit(); | 1289 | sctp_v6_protosw_exit(); |
1246 | err_v6_init: | 1290 | err_v6_protosw_init: |
1247 | inet_unregister_protosw(&sctp_stream_protosw); | 1291 | sctp_v4_protosw_exit(); |
1248 | inet_unregister_protosw(&sctp_seqpacket_protosw); | 1292 | err_protosw_init: |
1249 | proto_unregister(&sctp_prot); | 1293 | sctp_free_local_addr_list(); |
1250 | err_proto_register: | 1294 | sctp_v4_pf_exit(); |
1295 | sctp_v6_pf_exit(); | ||
1251 | sctp_sysctl_unregister(); | 1296 | sctp_sysctl_unregister(); |
1252 | list_del(&sctp_af_inet.list); | 1297 | list_del(&sctp_af_inet.list); |
1253 | free_pages((unsigned long)sctp_port_hashtable, | 1298 | free_pages((unsigned long)sctp_port_hashtable, |
@@ -1280,23 +1325,21 @@ SCTP_STATIC __exit void sctp_exit(void) | |||
1280 | 1325 | ||
1281 | /* Unregister with inet6/inet layers. */ | 1326 | /* Unregister with inet6/inet layers. */ |
1282 | sctp_v6_del_protocol(); | 1327 | sctp_v6_del_protocol(); |
1283 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); | 1328 | sctp_v4_del_protocol(); |
1284 | |||
1285 | /* Unregister notifier for inet address additions/deletions. */ | ||
1286 | unregister_inetaddr_notifier(&sctp_inetaddr_notifier); | ||
1287 | |||
1288 | /* Free the local address list. */ | ||
1289 | sctp_free_local_addr_list(); | ||
1290 | 1329 | ||
1291 | /* Free the control endpoint. */ | 1330 | /* Free the control endpoint. */ |
1292 | sock_release(sctp_ctl_socket); | 1331 | sock_release(sctp_ctl_socket); |
1293 | 1332 | ||
1294 | /* Cleanup v6 initializations. */ | 1333 | /* Free protosw registrations */ |
1295 | 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(); | ||
1296 | 1339 | ||
1297 | /* Unregister with socket layer. */ | 1340 | /* Unregister with socket layer. */ |
1298 | inet_unregister_protosw(&sctp_stream_protosw); | 1341 | sctp_v6_pf_exit(); |
1299 | inet_unregister_protosw(&sctp_seqpacket_protosw); | 1342 | sctp_v4_pf_exit(); |
1300 | 1343 | ||
1301 | sctp_sysctl_unregister(); | 1344 | sctp_sysctl_unregister(); |
1302 | list_del(&sctp_af_inet.list); | 1345 | list_del(&sctp_af_inet.list); |
@@ -1315,8 +1358,6 @@ SCTP_STATIC __exit void sctp_exit(void) | |||
1315 | 1358 | ||
1316 | kmem_cache_destroy(sctp_chunk_cachep); | 1359 | kmem_cache_destroy(sctp_chunk_cachep); |
1317 | kmem_cache_destroy(sctp_bucket_cachep); | 1360 | kmem_cache_destroy(sctp_bucket_cachep); |
1318 | |||
1319 | proto_unregister(&sctp_prot); | ||
1320 | } | 1361 | } |
1321 | 1362 | ||
1322 | module_init(sctp_init); | 1363 | module_init(sctp_init); |