diff options
author | Sridhar Samudrala <sri@us.ibm.com> | 2007-05-04 16:36:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-05-04 16:36:30 -0400 |
commit | 827bf12236fbafc02bc899aec1b37c342c8cf4e5 (patch) | |
tree | 41101b0d866629b3cc3341712996f11e655f6250 /net/sctp/ipv6.c | |
parent | ce5325c1338acf965f4300f4976eac2129aeb439 (diff) |
[SCTP]: Re-order SCTP initializations to avoid race with sctp_rcv()
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/ipv6.c')
-rw-r--r-- | net/sctp/ipv6.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index ca527a27dd05..84cd53635fe8 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -992,45 +992,52 @@ static struct sctp_pf sctp_pf_inet6_specific = { | |||
992 | .af = &sctp_ipv6_specific, | 992 | .af = &sctp_ipv6_specific, |
993 | }; | 993 | }; |
994 | 994 | ||
995 | /* Initialize IPv6 support and register with inet6 stack. */ | 995 | /* Initialize IPv6 support and register with socket layer. */ |
996 | int sctp_v6_init(void) | 996 | int sctp_v6_init(void) |
997 | { | 997 | { |
998 | int rc = proto_register(&sctpv6_prot, 1); | 998 | int rc; |
999 | 999 | ||
1000 | /* Register the SCTP specific PF_INET6 functions. */ | ||
1001 | sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6); | ||
1002 | |||
1003 | /* Register the SCTP specific AF_INET6 functions. */ | ||
1004 | sctp_register_af(&sctp_ipv6_specific); | ||
1005 | |||
1006 | rc = proto_register(&sctpv6_prot, 1); | ||
1000 | if (rc) | 1007 | if (rc) |
1001 | goto out; | 1008 | return rc; |
1002 | /* Register inet6 protocol. */ | ||
1003 | rc = -EAGAIN; | ||
1004 | if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0) | ||
1005 | goto out_unregister_sctp_proto; | ||
1006 | 1009 | ||
1007 | /* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */ | 1010 | /* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */ |
1008 | inet6_register_protosw(&sctpv6_seqpacket_protosw); | 1011 | inet6_register_protosw(&sctpv6_seqpacket_protosw); |
1009 | inet6_register_protosw(&sctpv6_stream_protosw); | 1012 | inet6_register_protosw(&sctpv6_stream_protosw); |
1010 | 1013 | ||
1011 | /* Register the SCTP specific PF_INET6 functions. */ | 1014 | return 0; |
1012 | sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6); | 1015 | } |
1013 | |||
1014 | /* Register the SCTP specific AF_INET6 functions. */ | ||
1015 | sctp_register_af(&sctp_ipv6_specific); | ||
1016 | 1016 | ||
1017 | /* Register with inet6 layer. */ | ||
1018 | int sctp_v6_add_protocol(void) | ||
1019 | { | ||
1017 | /* Register notifier for inet6 address additions/deletions. */ | 1020 | /* Register notifier for inet6 address additions/deletions. */ |
1018 | register_inet6addr_notifier(&sctp_inet6addr_notifier); | 1021 | register_inet6addr_notifier(&sctp_inet6addr_notifier); |
1019 | rc = 0; | 1022 | |
1020 | out: | 1023 | if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0) |
1021 | return rc; | 1024 | return -EAGAIN; |
1022 | out_unregister_sctp_proto: | 1025 | |
1023 | proto_unregister(&sctpv6_prot); | 1026 | return 0; |
1024 | goto out; | ||
1025 | } | 1027 | } |
1026 | 1028 | ||
1027 | /* IPv6 specific exit support. */ | 1029 | /* IPv6 specific exit support. */ |
1028 | void sctp_v6_exit(void) | 1030 | void sctp_v6_exit(void) |
1029 | { | 1031 | { |
1030 | list_del(&sctp_ipv6_specific.list); | ||
1031 | inet6_del_protocol(&sctpv6_protocol, IPPROTO_SCTP); | ||
1032 | inet6_unregister_protosw(&sctpv6_seqpacket_protosw); | 1032 | inet6_unregister_protosw(&sctpv6_seqpacket_protosw); |
1033 | inet6_unregister_protosw(&sctpv6_stream_protosw); | 1033 | inet6_unregister_protosw(&sctpv6_stream_protosw); |
1034 | unregister_inet6addr_notifier(&sctp_inet6addr_notifier); | ||
1035 | proto_unregister(&sctpv6_prot); | 1034 | proto_unregister(&sctpv6_prot); |
1035 | list_del(&sctp_ipv6_specific.list); | ||
1036 | } | ||
1037 | |||
1038 | /* Unregister with inet6 layer. */ | ||
1039 | void sctp_v6_del_protocol(void) | ||
1040 | { | ||
1041 | inet6_del_protocol(&sctpv6_protocol, IPPROTO_SCTP); | ||
1042 | unregister_inet6addr_notifier(&sctp_inet6addr_notifier); | ||
1036 | } | 1043 | } |