summaryrefslogtreecommitdiff
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2016-07-07 00:15:34 (GMT)
committerJames Morris <james.l.morris@oracle.com>2016-07-07 00:15:34 (GMT)
commitd011a4d861ce583466a8ae72a0c8e7f51c8cba4e (patch)
tree1ff8dfe7d486f5648e69ee85e54cde1987d8296a /net/ipv6/tcp_ipv6.c
parent544e1cea03e6674e3c12a3b8e8cc507c3dbeaf0c (diff)
parent3f09354ac84c6904787189d85fb306bf60f714b8 (diff)
downloadlinux-d011a4d861ce583466a8ae72a0c8e7f51c8cba4e.tar.xz
Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 79e33e0..818b3b5 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -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);