diff options
| author | Peter Zijlstra <peterz@infradead.org> | 2020-12-09 17:08:45 +0100 | 
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2020-12-09 17:08:45 +0100 | 
| commit | 2b3c99ee6389d33aff91d9e7a55465d7d1332bbd (patch) | |
| tree | 9e1e5d839d80c95854007c958f2c367290bf1090 /net/ipv6/tcp_ipv6.c | |
| parent | 97d62caa32d6d79dadae3f8d19af5c92ea9a589a (diff) | |
| parent | 31784cff7ee073b34d6eddabb95e3be2880a425c (diff) | |
Merge branch 'locking/rwsem'
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 26 | 
1 files changed, 21 insertions, 5 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 8db59f4e5f13..992cbf3eb9e3 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -527,15 +527,20 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,  		if (np->repflow && ireq->pktopts)  			fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); +		tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? +				tcp_rsk(req)->syn_tos & ~INET_ECN_MASK : +				np->tclass; + +		if (!INET_ECN_is_capable(tclass) && +		    tcp_bpf_ca_needs_ecn((struct sock *)req)) +			tclass |= INET_ECN_ECT_0; +  		rcu_read_lock();  		opt = ireq->ipv6_opt; -		tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ? -				tcp_rsk(req)->syn_tos : np->tclass;  		if (!opt)  			opt = rcu_dereference(np->opt);  		err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, -			       tclass & ~INET_ECN_MASK, -			       sk->sk_priority); +			       tclass, sk->sk_priority);  		rcu_read_unlock();  		err = net_xmit_eval(err);  	} @@ -1193,6 +1198,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *  	const struct ipv6_pinfo *np = tcp_inet6_sk(sk);  	struct ipv6_txoptions *opt;  	struct inet_sock *newinet; +	bool found_dup_sk = false;  	struct tcp_sock *newtp;  	struct sock *newsk;  #ifdef CONFIG_TCP_MD5SIG @@ -1368,7 +1374,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *  		tcp_done(newsk);  		goto out;  	} -	*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); +	*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), +				       &found_dup_sk);  	if (*own_req) {  		tcp_move_syn(newtp, req); @@ -1383,6 +1390,15 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *  				skb_set_owner_r(newnp->pktoptions, newsk);  			}  		} +	} else { +		if (!req_unhash && found_dup_sk) { +			/* This code path should only be executed in the +			 * syncookie case only +			 */ +			bh_unlock_sock(newsk); +			sock_put(newsk); +			newsk = NULL; +		}  	}  	return newsk;  | 
