Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/selinux into next
[cascardo/linux.git] / net / ipv6 / tcp_ipv6.c
index 79e33e0..818b3b5 100644 (file)
@@ -443,6 +443,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
 {
        struct inet_request_sock *ireq = inet_rsk(req);
        struct ipv6_pinfo *np = inet6_sk(sk);
+       struct ipv6_txoptions *opt;
        struct flowi6 *fl6 = &fl->u.ip6;
        struct sk_buff *skb;
        int err = -ENOMEM;
@@ -463,8 +464,10 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
                        fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
 
                rcu_read_lock();
-               err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
-                              np->tclass);
+               opt = ireq->ipv6_opt;
+               if (!opt)
+                       opt = rcu_dereference(np->opt);
+               err = ip6_xmit(sk, skb, fl6, opt, np->tclass);
                rcu_read_unlock();
                err = net_xmit_eval(err);
        }
@@ -476,6 +479,7 @@ done:
 
 static void tcp_v6_reqsk_destructor(struct request_sock *req)
 {
+       kfree(inet_rsk(req)->ipv6_opt);
        kfree_skb(inet_rsk(req)->pktopts);
 }
 
@@ -1109,7 +1113,9 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
           but we make one more one thing there: reattach optmem
           to newsk.
         */
-       opt = rcu_dereference(np->opt);
+       opt = ireq->ipv6_opt;
+       if (!opt)
+               opt = rcu_dereference(np->opt);
        if (opt) {
                opt = ipv6_dup_options(newsk, opt);
                RCU_INIT_POINTER(newnp->opt, opt);