sctp: lack the check for ports in sctp_v6_cmp_addr
[firefly-linux-kernel-4.4.55.git] / net / sctp / ipv6.c
index d28c0b4c9128949bcd193a815ef6ed2c705fe677..ce46f1c7f133ad5b114e4c2cd571d26c2b9ee901 100644 (file)
@@ -526,6 +526,8 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
                }
                return 0;
        }
+       if (addr1->v6.sin6_port != addr2->v6.sin6_port)
+               return 0;
        if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
                return 0;
        /* If this is a linklocal address, compare the scope_id. */
@@ -641,6 +643,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
        struct sock *newsk;
        struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
        struct sctp6_sock *newsctp6sk;
+       struct ipv6_txoptions *opt;
 
        newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, 0);
        if (!newsk)
@@ -660,6 +663,13 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
 
        memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
+       rcu_read_lock();
+       opt = rcu_dereference(np->opt);
+       if (opt)
+               opt = ipv6_dup_options(newsk, opt);
+       RCU_INIT_POINTER(newnp->opt, opt);
+       rcu_read_unlock();
+
        /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
         * and getpeername().
         */