diff options
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 29 | 
1 files changed, 25 insertions, 4 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index cb95d88497ae..79f30f026d89 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -247,10 +247,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)  {  	const struct inet_connection_sock *icsk = inet_csk(sk);  	const struct tcp_sock *tp = tcp_sk(sk); +	struct net *net = sock_net(sk);  	struct inet_timewait_sock *tw; -	struct inet_timewait_death_row *tcp_death_row = sock_net(sk)->ipv4.tcp_death_row; -	tw = inet_twsk_alloc(sk, tcp_death_row, state); +	tw = inet_twsk_alloc(sk, &net->ipv4.tcp_death_row, state);  	if (tw) {  		struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); @@ -319,14 +319,14 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)  		/* Linkage updates.  		 * Note that access to tw after this point is illegal.  		 */ -		inet_twsk_hashdance(tw, sk, &tcp_hashinfo); +		inet_twsk_hashdance(tw, sk, net->ipv4.tcp_death_row.hashinfo);  		local_bh_enable();  	} else {  		/* Sorry, if we're out of memory, just CLOSE this  		 * socket up.  We've got bigger problems than  		 * non-graceful socket closings.  		 */ -		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); +		NET_INC_STATS(net, LINUX_MIB_TCPTIMEWAITOVERFLOW);  	}  	tcp_update_metrics(sk); @@ -347,6 +347,26 @@ void tcp_twsk_destructor(struct sock *sk)  }  EXPORT_SYMBOL_GPL(tcp_twsk_destructor); +void tcp_twsk_purge(struct list_head *net_exit_list, int family) +{ +	bool purged_once = false; +	struct net *net; + +	list_for_each_entry(net, net_exit_list, exit_list) { +		/* The last refcount is decremented in tcp_sk_exit_batch() */ +		if (refcount_read(&net->ipv4.tcp_death_row.tw_refcount) == 1) +			continue; + +		if (net->ipv4.tcp_death_row.hashinfo->pernet) { +			inet_twsk_purge(net->ipv4.tcp_death_row.hashinfo, family); +		} else if (!purged_once) { +			inet_twsk_purge(&tcp_hashinfo, family); +			purged_once = true; +		} +	} +} +EXPORT_SYMBOL_GPL(tcp_twsk_purge); +  /* Warning : This function is called without sk_listener being locked.   * Be sure to read socket fields once, as their value could change under us.   */ @@ -541,6 +561,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,  	newtp->fastopen_req = NULL;  	RCU_INIT_POINTER(newtp->fastopen_rsk, NULL); +	newtp->bpf_chg_cc_inprogress = 0;  	tcp_bpf_clone(sk, newsk);  	__TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS);  |