forked from mirrors/linux
		
	mptcp: consolidate synack processing.
Currently the MPTCP code uses 2 hooks to process syn-ack packets, mptcp_rcv_synsent() and the sk_rx_dst_set() callback. We can drop the first, moving the relevant code into the latter, reducing the hooking into the TCP code. This is also needed by the next patch. v1 -> v2: - use local tcp sock ptr instead of casting the sk variable several times - DaveM Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									30724ccbfc
								
							
						
					
					
						commit
						263e1201a2
					
				
					 4 changed files with 24 additions and 29 deletions
				
			
		|  | @ -72,7 +72,6 @@ void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, | ||||||
| 			int opsize, struct tcp_options_received *opt_rx); | 			int opsize, struct tcp_options_received *opt_rx); | ||||||
| bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, | bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, | ||||||
| 		       unsigned int *size, struct mptcp_out_options *opts); | 		       unsigned int *size, struct mptcp_out_options *opts); | ||||||
| void mptcp_rcv_synsent(struct sock *sk); |  | ||||||
| bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, | bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, | ||||||
| 			  struct mptcp_out_options *opts); | 			  struct mptcp_out_options *opts); | ||||||
| bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, | bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, | ||||||
|  |  | ||||||
|  | @ -5990,9 +5990,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | ||||||
| 		tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); | 		tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); | ||||||
| 		tcp_initialize_rcv_mss(sk); | 		tcp_initialize_rcv_mss(sk); | ||||||
| 
 | 
 | ||||||
| 		if (sk_is_mptcp(sk)) |  | ||||||
| 			mptcp_rcv_synsent(sk); |  | ||||||
| 
 |  | ||||||
| 		/* Remember, tcp_poll() does not lock socket!
 | 		/* Remember, tcp_poll() does not lock socket!
 | ||||||
| 		 * Change state from SYN-SENT only after copied_seq | 		 * Change state from SYN-SENT only after copied_seq | ||||||
| 		 * is initialized. */ | 		 * is initialized. */ | ||||||
|  |  | ||||||
|  | @ -344,28 +344,6 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void mptcp_rcv_synsent(struct sock *sk) |  | ||||||
| { |  | ||||||
| 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); |  | ||||||
| 	struct tcp_sock *tp = tcp_sk(sk); |  | ||||||
| 
 |  | ||||||
| 	if (subflow->request_mptcp && tp->rx_opt.mptcp.mp_capable) { |  | ||||||
| 		subflow->mp_capable = 1; |  | ||||||
| 		subflow->can_ack = 1; |  | ||||||
| 		subflow->remote_key = tp->rx_opt.mptcp.sndr_key; |  | ||||||
| 		pr_debug("subflow=%p, remote_key=%llu", subflow, |  | ||||||
| 			 subflow->remote_key); |  | ||||||
| 	} else if (subflow->request_join && tp->rx_opt.mptcp.mp_join) { |  | ||||||
| 		subflow->mp_join = 1; |  | ||||||
| 		subflow->thmac = tp->rx_opt.mptcp.thmac; |  | ||||||
| 		subflow->remote_nonce = tp->rx_opt.mptcp.nonce; |  | ||||||
| 		pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow, |  | ||||||
| 			 subflow->thmac, subflow->remote_nonce); |  | ||||||
| 	} else if (subflow->request_mptcp) { |  | ||||||
| 		tcp_sk(sk)->is_mptcp = 0; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* MP_JOIN client subflow must wait for 4th ack before sending any data:
 | /* MP_JOIN client subflow must wait for 4th ack before sending any data:
 | ||||||
|  * TCP can't schedule delack timer before the subflow is fully established. |  * TCP can't schedule delack timer before the subflow is fully established. | ||||||
|  * MPTCP uses the delack timer to do 3rd ack retransmissions |  * MPTCP uses the delack timer to do 3rd ack retransmissions | ||||||
|  |  | ||||||
|  | @ -222,6 +222,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) | ||||||
| { | { | ||||||
| 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); | 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); | ||||||
| 	struct sock *parent = subflow->conn; | 	struct sock *parent = subflow->conn; | ||||||
|  | 	struct tcp_sock *tp = tcp_sk(sk); | ||||||
| 
 | 
 | ||||||
| 	subflow->icsk_af_ops->sk_rx_dst_set(sk, skb); | 	subflow->icsk_af_ops->sk_rx_dst_set(sk, skb); | ||||||
| 
 | 
 | ||||||
|  | @ -230,14 +231,35 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) | ||||||
| 		parent->sk_state_change(parent); | 		parent->sk_state_change(parent); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (subflow->conn_finished || !tcp_sk(sk)->is_mptcp) | 	/* be sure no special action on any packet other than syn-ack */ | ||||||
|  | 	if (subflow->conn_finished) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	subflow->conn_finished = 1; | ||||||
|  | 
 | ||||||
|  | 	if (subflow->request_mptcp && tp->rx_opt.mptcp.mp_capable) { | ||||||
|  | 		subflow->mp_capable = 1; | ||||||
|  | 		subflow->can_ack = 1; | ||||||
|  | 		subflow->remote_key = tp->rx_opt.mptcp.sndr_key; | ||||||
|  | 		pr_debug("subflow=%p, remote_key=%llu", subflow, | ||||||
|  | 			 subflow->remote_key); | ||||||
|  | 	} else if (subflow->request_join && tp->rx_opt.mptcp.mp_join) { | ||||||
|  | 		subflow->mp_join = 1; | ||||||
|  | 		subflow->thmac = tp->rx_opt.mptcp.thmac; | ||||||
|  | 		subflow->remote_nonce = tp->rx_opt.mptcp.nonce; | ||||||
|  | 		pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow, | ||||||
|  | 			 subflow->thmac, subflow->remote_nonce); | ||||||
|  | 	} else if (subflow->request_mptcp) { | ||||||
|  | 		tp->is_mptcp = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!tp->is_mptcp) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	if (subflow->mp_capable) { | 	if (subflow->mp_capable) { | ||||||
| 		pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk), | 		pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk), | ||||||
| 			 subflow->remote_key); | 			 subflow->remote_key); | ||||||
| 		mptcp_finish_connect(sk); | 		mptcp_finish_connect(sk); | ||||||
| 		subflow->conn_finished = 1; |  | ||||||
| 
 | 
 | ||||||
| 		if (skb) { | 		if (skb) { | ||||||
| 			pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq); | 			pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq); | ||||||
|  | @ -264,7 +286,6 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) | ||||||
| 		if (!mptcp_finish_join(sk)) | 		if (!mptcp_finish_join(sk)) | ||||||
| 			goto do_reset; | 			goto do_reset; | ||||||
| 
 | 
 | ||||||
| 		subflow->conn_finished = 1; |  | ||||||
| 		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); | 		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); | ||||||
| 	} else { | 	} else { | ||||||
| do_reset: | do_reset: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Paolo Abeni
						Paolo Abeni