diff options
| -rw-r--r-- | include/net/request_sock.h | 2 | ||||
| -rw-r--r-- | include/net/tcp.h | 2 | ||||
| -rw-r--r-- | net/ipv4/inet_connection_sock.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 18 | ||||
| -rw-r--r-- | net/ipv4/tcp_timer.c | 6 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 12 | 
6 files changed, 32 insertions, 10 deletions
diff --git a/include/net/request_sock.h b/include/net/request_sock.h index c9b50ebd9ce..99e6e19b57c 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -45,6 +45,8 @@ struct request_sock_ops {  	void		(*send_reset)(struct sock *sk,  				      struct sk_buff *skb);  	void		(*destructor)(struct request_sock *req); +	void		(*syn_ack_timeout)(struct sock *sk, +					   struct request_sock *req);  };  /* struct request_sock - mini sock to represent a connection request diff --git a/include/net/tcp.h b/include/net/tcp.h index 788c99f9859..87d164b9bd8 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -400,6 +400,8 @@ extern int			compat_tcp_setsockopt(struct sock *sk,  					int level, int optname,  					char __user *optval, unsigned int optlen);  extern void			tcp_set_keepalive(struct sock *sk, int val); +extern void			tcp_syn_ack_timeout(struct sock *sk, +						    struct request_sock *req);  extern int			tcp_recvmsg(struct kiocb *iocb, struct sock *sk,  					    struct msghdr *msg,  					    size_t len, int nonblock,  diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index ee16475f8fc..8da6429269d 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -529,6 +529,8 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,  				syn_ack_recalc(req, thresh, max_retries,  					       queue->rskq_defer_accept,  					       &expire, &resend); +				if (req->rsk_ops->syn_ack_timeout) +					req->rsk_ops->syn_ack_timeout(parent, req);  				if (!expire &&  				    (!resend ||  				     !req->rsk_ops->rtx_syn_ack(parent, req, NULL) || diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 382f667238e..356f544c4c1 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -742,9 +742,9 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,   *	This still operates on a request_sock only, not on a big   *	socket.   */ -static int __tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, -				struct request_sock *req, -				struct request_values *rvp) +static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, +			      struct request_sock *req, +			      struct request_values *rvp)  {  	const struct inet_request_sock *ireq = inet_rsk(req);  	int err = -1; @@ -775,10 +775,11 @@ static int __tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst,  	return err;  } -static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req, +static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req,  			      struct request_values *rvp)  { -	return __tcp_v4_send_synack(sk, NULL, req, rvp); +	TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); +	return tcp_v4_send_synack(sk, NULL, req, rvp);  }  /* @@ -1192,10 +1193,11 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)  struct request_sock_ops tcp_request_sock_ops __read_mostly = {  	.family		=	PF_INET,  	.obj_size	=	sizeof(struct tcp_request_sock), -	.rtx_syn_ack	=	tcp_v4_send_synack, +	.rtx_syn_ack	=	tcp_v4_rtx_synack,  	.send_ack	=	tcp_v4_reqsk_send_ack,  	.destructor	=	tcp_v4_reqsk_destructor,  	.send_reset	=	tcp_v4_send_reset, +	.syn_ack_timeout = 	tcp_syn_ack_timeout,  };  #ifdef CONFIG_TCP_MD5SIG @@ -1373,8 +1375,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)  	}  	tcp_rsk(req)->snt_isn = isn; -	if (__tcp_v4_send_synack(sk, dst, req, -				 (struct request_values *)&tmp_ext) || +	if (tcp_v4_send_synack(sk, dst, req, +			       (struct request_values *)&tmp_ext) ||  	    want_cookie)  		goto drop_and_free; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 8816a20c259..de7d1bf9114 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -474,6 +474,12 @@ static void tcp_synack_timer(struct sock *sk)  				   TCP_TIMEOUT_INIT, TCP_RTO_MAX);  } +void tcp_syn_ack_timeout(struct sock *sk, struct request_sock *req) +{ +	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEOUTS); +} +EXPORT_SYMBOL(tcp_syn_ack_timeout); +  void tcp_set_keepalive(struct sock *sk, int val)  {  	if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 1c832bf198b..82f2dea0e39 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -520,6 +520,13 @@ done:  	return err;  } +static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, +			     struct request_values *rvp) +{ +	TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); +	return tcp_v6_send_synack(sk, req, rvp); +} +  static inline void syn_flood_warning(struct sk_buff *skb)  {  #ifdef CONFIG_SYN_COOKIES @@ -890,10 +897,11 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)  struct request_sock_ops tcp6_request_sock_ops __read_mostly = {  	.family		=	AF_INET6,  	.obj_size	=	sizeof(struct tcp6_request_sock), -	.rtx_syn_ack	=	tcp_v6_send_synack, +	.rtx_syn_ack	=	tcp_v6_rtx_synack,  	.send_ack	=	tcp_v6_reqsk_send_ack,  	.destructor	=	tcp_v6_reqsk_destructor, -	.send_reset	=	tcp_v6_send_reset +	.send_reset	=	tcp_v6_send_reset, +	.syn_ack_timeout = 	tcp_syn_ack_timeout,  };  #ifdef CONFIG_TCP_MD5SIG  |