forked from mirrors/linux
		
	tcp: move duplicate code from tcp_v4_init_sock()/tcp_v6_init_sock()
This commit moves the (substantial) common code shared between tcp_v4_init_sock() and tcp_v6_init_sock() to a new address-family independent function, tcp_init_sock(). Centralizing this functionality should help avoid drift issues, e.g. where the IPv4 side is updated without a corresponding update to IPv6. There was already some drift: IPv4 initialized snd_cwnd to TCP_INIT_CWND, while the IPv6 side was still initializing snd_cwnd to 2 (in this case it should not matter, since snd_cwnd is also initialized in tcp_init_metrics(), but the general risks and maintenance overhead remain). When diffing the old and new code, note that new tcp_init_sock() function uses the order of steps from the tcp_v4_init_sock() implementation (the order is slightly different in tcp_v6_init_sock()). Signed-off-by: Neal Cardwell <ncardwell@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									e66e9a3147
								
							
						
					
					
						commit
						900f65d361
					
				
					 4 changed files with 68 additions and 99 deletions
				
			
		|  | @ -395,6 +395,7 @@ extern void tcp_enter_loss(struct sock *sk, int how); | ||||||
| extern void tcp_clear_retrans(struct tcp_sock *tp); | extern void tcp_clear_retrans(struct tcp_sock *tp); | ||||||
| extern void tcp_update_metrics(struct sock *sk); | extern void tcp_update_metrics(struct sock *sk); | ||||||
| extern void tcp_close(struct sock *sk, long timeout); | extern void tcp_close(struct sock *sk, long timeout); | ||||||
|  | extern void tcp_init_sock(struct sock *sk); | ||||||
| extern unsigned int tcp_poll(struct file * file, struct socket *sock, | extern unsigned int tcp_poll(struct file * file, struct socket *sock, | ||||||
| 			     struct poll_table_struct *wait); | 			     struct poll_table_struct *wait); | ||||||
| extern int tcp_getsockopt(struct sock *sk, int level, int optname, | extern int tcp_getsockopt(struct sock *sk, int level, int optname, | ||||||
|  |  | ||||||
|  | @ -363,6 +363,70 @@ static int retrans_to_secs(u8 retrans, int timeout, int rto_max) | ||||||
| 	return period; | 	return period; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Address-family independent initialization for a tcp_sock.
 | ||||||
|  |  * | ||||||
|  |  * NOTE: A lot of things set to zero explicitly by call to | ||||||
|  |  *       sk_alloc() so need not be done here. | ||||||
|  |  */ | ||||||
|  | void tcp_init_sock(struct sock *sk) | ||||||
|  | { | ||||||
|  | 	struct inet_connection_sock *icsk = inet_csk(sk); | ||||||
|  | 	struct tcp_sock *tp = tcp_sk(sk); | ||||||
|  | 
 | ||||||
|  | 	skb_queue_head_init(&tp->out_of_order_queue); | ||||||
|  | 	tcp_init_xmit_timers(sk); | ||||||
|  | 	tcp_prequeue_init(tp); | ||||||
|  | 
 | ||||||
|  | 	icsk->icsk_rto = TCP_TIMEOUT_INIT; | ||||||
|  | 	tp->mdev = TCP_TIMEOUT_INIT; | ||||||
|  | 
 | ||||||
|  | 	/* So many TCP implementations out there (incorrectly) count the
 | ||||||
|  | 	 * initial SYN frame in their delayed-ACK and congestion control | ||||||
|  | 	 * algorithms that we must have the following bandaid to talk | ||||||
|  | 	 * efficiently to them.  -DaveM | ||||||
|  | 	 */ | ||||||
|  | 	tp->snd_cwnd = TCP_INIT_CWND; | ||||||
|  | 
 | ||||||
|  | 	/* See draft-stevens-tcpca-spec-01 for discussion of the
 | ||||||
|  | 	 * initialization of these values. | ||||||
|  | 	 */ | ||||||
|  | 	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; | ||||||
|  | 	tp->snd_cwnd_clamp = ~0; | ||||||
|  | 	tp->mss_cache = TCP_MSS_DEFAULT; | ||||||
|  | 
 | ||||||
|  | 	tp->reordering = sysctl_tcp_reordering; | ||||||
|  | 	icsk->icsk_ca_ops = &tcp_init_congestion_ops; | ||||||
|  | 
 | ||||||
|  | 	sk->sk_state = TCP_CLOSE; | ||||||
|  | 
 | ||||||
|  | 	sk->sk_write_space = sk_stream_write_space; | ||||||
|  | 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | ||||||
|  | 
 | ||||||
|  | 	icsk->icsk_sync_mss = tcp_sync_mss; | ||||||
|  | 
 | ||||||
|  | 	/* TCP Cookie Transactions */ | ||||||
|  | 	if (sysctl_tcp_cookie_size > 0) { | ||||||
|  | 		/* Default, cookies without s_data_payload. */ | ||||||
|  | 		tp->cookie_values = | ||||||
|  | 			kzalloc(sizeof(*tp->cookie_values), | ||||||
|  | 				sk->sk_allocation); | ||||||
|  | 		if (tp->cookie_values != NULL) | ||||||
|  | 			kref_init(&tp->cookie_values->kref); | ||||||
|  | 	} | ||||||
|  | 	/* Presumed zeroed, in order of appearance:
 | ||||||
|  | 	 *	cookie_in_always, cookie_out_never, | ||||||
|  | 	 *	s_data_constant, s_data_in, s_data_out | ||||||
|  | 	 */ | ||||||
|  | 	sk->sk_sndbuf = sysctl_tcp_wmem[1]; | ||||||
|  | 	sk->sk_rcvbuf = sysctl_tcp_rmem[1]; | ||||||
|  | 
 | ||||||
|  | 	local_bh_disable(); | ||||||
|  | 	sock_update_memcg(sk); | ||||||
|  | 	sk_sockets_allocated_inc(sk); | ||||||
|  | 	local_bh_enable(); | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(tcp_init_sock); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  *	Wait for a TCP event. |  *	Wait for a TCP event. | ||||||
|  * |  * | ||||||
|  |  | ||||||
|  | @ -1890,62 +1890,14 @@ static int tcp_v4_init_sock(struct sock *sk) | ||||||
| 	struct inet_connection_sock *icsk = inet_csk(sk); | 	struct inet_connection_sock *icsk = inet_csk(sk); | ||||||
| 	struct tcp_sock *tp = tcp_sk(sk); | 	struct tcp_sock *tp = tcp_sk(sk); | ||||||
| 
 | 
 | ||||||
| 	skb_queue_head_init(&tp->out_of_order_queue); | 	tcp_init_sock(sk); | ||||||
| 	tcp_init_xmit_timers(sk); |  | ||||||
| 	tcp_prequeue_init(tp); |  | ||||||
| 
 |  | ||||||
| 	icsk->icsk_rto = TCP_TIMEOUT_INIT; |  | ||||||
| 	tp->mdev = TCP_TIMEOUT_INIT; |  | ||||||
| 
 |  | ||||||
| 	/* So many TCP implementations out there (incorrectly) count the
 |  | ||||||
| 	 * initial SYN frame in their delayed-ACK and congestion control |  | ||||||
| 	 * algorithms that we must have the following bandaid to talk |  | ||||||
| 	 * efficiently to them.  -DaveM |  | ||||||
| 	 */ |  | ||||||
| 	tp->snd_cwnd = TCP_INIT_CWND; |  | ||||||
| 
 |  | ||||||
| 	/* See draft-stevens-tcpca-spec-01 for discussion of the
 |  | ||||||
| 	 * initialization of these values. |  | ||||||
| 	 */ |  | ||||||
| 	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; |  | ||||||
| 	tp->snd_cwnd_clamp = ~0; |  | ||||||
| 	tp->mss_cache = TCP_MSS_DEFAULT; |  | ||||||
| 
 |  | ||||||
| 	tp->reordering = sysctl_tcp_reordering; |  | ||||||
| 	icsk->icsk_ca_ops = &tcp_init_congestion_ops; |  | ||||||
| 
 |  | ||||||
| 	sk->sk_state = TCP_CLOSE; |  | ||||||
| 
 |  | ||||||
| 	sk->sk_write_space = sk_stream_write_space; |  | ||||||
| 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |  | ||||||
| 
 | 
 | ||||||
| 	icsk->icsk_af_ops = &ipv4_specific; | 	icsk->icsk_af_ops = &ipv4_specific; | ||||||
| 	icsk->icsk_sync_mss = tcp_sync_mss; | 
 | ||||||
| #ifdef CONFIG_TCP_MD5SIG | #ifdef CONFIG_TCP_MD5SIG | ||||||
| 	tp->af_specific = &tcp_sock_ipv4_specific; | 	tp->af_specific = &tcp_sock_ipv4_specific; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	/* TCP Cookie Transactions */ |  | ||||||
| 	if (sysctl_tcp_cookie_size > 0) { |  | ||||||
| 		/* Default, cookies without s_data_payload. */ |  | ||||||
| 		tp->cookie_values = |  | ||||||
| 			kzalloc(sizeof(*tp->cookie_values), |  | ||||||
| 				sk->sk_allocation); |  | ||||||
| 		if (tp->cookie_values != NULL) |  | ||||||
| 			kref_init(&tp->cookie_values->kref); |  | ||||||
| 	} |  | ||||||
| 	/* Presumed zeroed, in order of appearance:
 |  | ||||||
| 	 *	cookie_in_always, cookie_out_never, |  | ||||||
| 	 *	s_data_constant, s_data_in, s_data_out |  | ||||||
| 	 */ |  | ||||||
| 	sk->sk_sndbuf = sysctl_tcp_wmem[1]; |  | ||||||
| 	sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |  | ||||||
| 
 |  | ||||||
| 	local_bh_disable(); |  | ||||||
| 	sock_update_memcg(sk); |  | ||||||
| 	sk_sockets_allocated_inc(sk); |  | ||||||
| 	local_bh_enable(); |  | ||||||
| 
 |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1831,62 +1831,14 @@ static int tcp_v6_init_sock(struct sock *sk) | ||||||
| 	struct inet_connection_sock *icsk = inet_csk(sk); | 	struct inet_connection_sock *icsk = inet_csk(sk); | ||||||
| 	struct tcp_sock *tp = tcp_sk(sk); | 	struct tcp_sock *tp = tcp_sk(sk); | ||||||
| 
 | 
 | ||||||
| 	skb_queue_head_init(&tp->out_of_order_queue); | 	tcp_init_sock(sk); | ||||||
| 	tcp_init_xmit_timers(sk); |  | ||||||
| 	tcp_prequeue_init(tp); |  | ||||||
| 
 |  | ||||||
| 	icsk->icsk_rto = TCP_TIMEOUT_INIT; |  | ||||||
| 	tp->mdev = TCP_TIMEOUT_INIT; |  | ||||||
| 
 |  | ||||||
| 	/* So many TCP implementations out there (incorrectly) count the
 |  | ||||||
| 	 * initial SYN frame in their delayed-ACK and congestion control |  | ||||||
| 	 * algorithms that we must have the following bandaid to talk |  | ||||||
| 	 * efficiently to them.  -DaveM |  | ||||||
| 	 */ |  | ||||||
| 	tp->snd_cwnd = 2; |  | ||||||
| 
 |  | ||||||
| 	/* See draft-stevens-tcpca-spec-01 for discussion of the
 |  | ||||||
| 	 * initialization of these values. |  | ||||||
| 	 */ |  | ||||||
| 	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; |  | ||||||
| 	tp->snd_cwnd_clamp = ~0; |  | ||||||
| 	tp->mss_cache = TCP_MSS_DEFAULT; |  | ||||||
| 
 |  | ||||||
| 	tp->reordering = sysctl_tcp_reordering; |  | ||||||
| 
 |  | ||||||
| 	sk->sk_state = TCP_CLOSE; |  | ||||||
| 
 | 
 | ||||||
| 	icsk->icsk_af_ops = &ipv6_specific; | 	icsk->icsk_af_ops = &ipv6_specific; | ||||||
| 	icsk->icsk_ca_ops = &tcp_init_congestion_ops; |  | ||||||
| 	icsk->icsk_sync_mss = tcp_sync_mss; |  | ||||||
| 	sk->sk_write_space = sk_stream_write_space; |  | ||||||
| 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |  | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_TCP_MD5SIG | #ifdef CONFIG_TCP_MD5SIG | ||||||
| 	tp->af_specific = &tcp_sock_ipv6_specific; | 	tp->af_specific = &tcp_sock_ipv6_specific; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	/* TCP Cookie Transactions */ |  | ||||||
| 	if (sysctl_tcp_cookie_size > 0) { |  | ||||||
| 		/* Default, cookies without s_data_payload. */ |  | ||||||
| 		tp->cookie_values = |  | ||||||
| 			kzalloc(sizeof(*tp->cookie_values), |  | ||||||
| 				sk->sk_allocation); |  | ||||||
| 		if (tp->cookie_values != NULL) |  | ||||||
| 			kref_init(&tp->cookie_values->kref); |  | ||||||
| 	} |  | ||||||
| 	/* Presumed zeroed, in order of appearance:
 |  | ||||||
| 	 *	cookie_in_always, cookie_out_never, |  | ||||||
| 	 *	s_data_constant, s_data_in, s_data_out |  | ||||||
| 	 */ |  | ||||||
| 	sk->sk_sndbuf = sysctl_tcp_wmem[1]; |  | ||||||
| 	sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |  | ||||||
| 
 |  | ||||||
| 	local_bh_disable(); |  | ||||||
| 	sock_update_memcg(sk); |  | ||||||
| 	sk_sockets_allocated_inc(sk); |  | ||||||
| 	local_bh_enable(); |  | ||||||
| 
 |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Neal Cardwell
						Neal Cardwell