]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/ipv6.c
autofs4: deadlock during create
[linux-2.6-omap-h63xx.git] / net / sctp / ipv6.c
index ca527a27dd05d2a42b87c69d72ebfac36037120b..f8aa23dda1c16a30ba07832b526b2904af3adba2 100644 (file)
@@ -641,6 +641,8 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
        newsctp6sk = (struct sctp6_sock *)newsk;
        inet_sk(newsk)->pinet6 = &newsctp6sk->inet6;
 
+       sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped;
+
        newinet = inet_sk(newsk);
        newnp = inet6_sk(newsk);
 
@@ -844,6 +846,10 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
                        dev = dev_get_by_index(addr->v6.sin6_scope_id);
                        if (!dev)
                                return 0;
+                       if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
+                               dev_put(dev);
+                               return 0;
+                       }
                        dev_put(dev);
                }
                af = opt->pf->af;
@@ -992,45 +998,52 @@ static struct sctp_pf sctp_pf_inet6_specific = {
        .af            = &sctp_ipv6_specific,
 };
 
-/* Initialize IPv6 support and register with inet6 stack.  */
+/* Initialize IPv6 support and register with socket layer.  */
 int sctp_v6_init(void)
 {
-       int rc = proto_register(&sctpv6_prot, 1);
+       int rc;
+
+       /* Register the SCTP specific PF_INET6 functions. */
+       sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6);
+
+       /* Register the SCTP specific AF_INET6 functions. */
+       sctp_register_af(&sctp_ipv6_specific);
 
+       rc = proto_register(&sctpv6_prot, 1);
        if (rc)
-               goto out;
-       /* Register inet6 protocol. */
-       rc = -EAGAIN;
-       if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0)
-               goto out_unregister_sctp_proto;
+               return rc;
 
        /* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */
        inet6_register_protosw(&sctpv6_seqpacket_protosw);
        inet6_register_protosw(&sctpv6_stream_protosw);
 
-       /* Register the SCTP specific PF_INET6 functions. */
-       sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6);
-
-       /* Register the SCTP specific AF_INET6 functions. */
-       sctp_register_af(&sctp_ipv6_specific);
+       return 0;
+}
 
+/* Register with inet6 layer. */
+int sctp_v6_add_protocol(void)
+{
        /* Register notifier for inet6 address additions/deletions. */
        register_inet6addr_notifier(&sctp_inet6addr_notifier);
-       rc = 0;
-out:
-       return rc;
-out_unregister_sctp_proto:
-       proto_unregister(&sctpv6_prot);
-       goto out;
+
+       if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0)
+               return -EAGAIN;
+
+       return 0;
 }
 
 /* IPv6 specific exit support. */
 void sctp_v6_exit(void)
 {
-       list_del(&sctp_ipv6_specific.list);
-       inet6_del_protocol(&sctpv6_protocol, IPPROTO_SCTP);
        inet6_unregister_protosw(&sctpv6_seqpacket_protosw);
        inet6_unregister_protosw(&sctpv6_stream_protosw);
-       unregister_inet6addr_notifier(&sctp_inet6addr_notifier);
        proto_unregister(&sctpv6_prot);
+       list_del(&sctp_ipv6_specific.list);
+}
+
+/* Unregister with inet6 layer. */
+void sctp_v6_del_protocol(void)
+{
+       inet6_del_protocol(&sctpv6_protocol, IPPROTO_SCTP);
+       unregister_inet6addr_notifier(&sctp_inet6addr_notifier);
 }