forked from mirrors/linux
		
	mptcp: simplify subflow_syn_recv_sock()
Postpone the msk cloning to the child process creation so that we can avoid a bunch of conditionals. Link: https://github.com/multipath-tcp/mptcp_net-next/issues/61 Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									2bb9a37f0e
								
							
						
					
					
						commit
						a88d0092b2
					
				
					 1 changed files with 13 additions and 28 deletions
				
			
		|  | @ -696,14 +696,6 @@ static bool subflow_hmac_valid(const struct request_sock *req, | |||
| 	return !crypto_memneq(hmac, mp_opt->hmac, MPTCPOPT_HMAC_LEN); | ||||
| } | ||||
| 
 | ||||
| static void mptcp_force_close(struct sock *sk) | ||||
| { | ||||
| 	/* the msk is not yet exposed to user-space, and refcount is 2 */ | ||||
| 	inet_sk_state_store(sk, TCP_CLOSE); | ||||
| 	sk_common_release(sk); | ||||
| 	sock_put(sk); | ||||
| } | ||||
| 
 | ||||
| static void subflow_ulp_fallback(struct sock *sk, | ||||
| 				 struct mptcp_subflow_context *old_ctx) | ||||
| { | ||||
|  | @ -755,7 +747,6 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, | |||
| 	struct mptcp_subflow_request_sock *subflow_req; | ||||
| 	struct mptcp_options_received mp_opt; | ||||
| 	bool fallback, fallback_is_fatal; | ||||
| 	struct sock *new_msk = NULL; | ||||
| 	struct mptcp_sock *owner; | ||||
| 	struct sock *child; | ||||
| 
 | ||||
|  | @ -784,14 +775,9 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, | |||
| 		 * options. | ||||
| 		 */ | ||||
| 		mptcp_get_options(skb, &mp_opt); | ||||
| 		if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) { | ||||
| 		if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) | ||||
| 			fallback = true; | ||||
| 			goto create_child; | ||||
| 		} | ||||
| 
 | ||||
| 		new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); | ||||
| 		if (!new_msk) | ||||
| 			fallback = true; | ||||
| 	} else if (subflow_req->mp_join) { | ||||
| 		mptcp_get_options(skb, &mp_opt); | ||||
| 		if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) || | ||||
|  | @ -820,21 +806,23 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, | |||
| 				subflow_add_reset_reason(skb, MPTCP_RST_EMPTCP); | ||||
| 				goto dispose_child; | ||||
| 			} | ||||
| 
 | ||||
| 			mptcp_subflow_drop_ctx(child); | ||||
| 			goto out; | ||||
| 			goto fallback; | ||||
| 		} | ||||
| 
 | ||||
| 		/* ssk inherits options of listener sk */ | ||||
| 		ctx->setsockopt_seq = listener->setsockopt_seq; | ||||
| 
 | ||||
| 		if (ctx->mp_capable) { | ||||
| 			owner = mptcp_sk(new_msk); | ||||
| 			ctx->conn = mptcp_sk_clone(listener->conn, &mp_opt, req); | ||||
| 			if (!ctx->conn) | ||||
| 				goto fallback; | ||||
| 
 | ||||
| 			owner = mptcp_sk(ctx->conn); | ||||
| 
 | ||||
| 			/* this can't race with mptcp_close(), as the msk is
 | ||||
| 			 * not yet exposted to user-space | ||||
| 			 */ | ||||
| 			inet_sk_state_store((void *)new_msk, TCP_ESTABLISHED); | ||||
| 			inet_sk_state_store(ctx->conn, TCP_ESTABLISHED); | ||||
| 
 | ||||
| 			/* record the newly created socket as the first msk
 | ||||
| 			 * subflow, but don't link it yet into conn_list | ||||
|  | @ -844,11 +832,9 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, | |||
| 			/* new mpc subflow takes ownership of the newly
 | ||||
| 			 * created mptcp socket | ||||
| 			 */ | ||||
| 			mptcp_sk(new_msk)->setsockopt_seq = ctx->setsockopt_seq; | ||||
| 			owner->setsockopt_seq = ctx->setsockopt_seq; | ||||
| 			mptcp_pm_new_connection(owner, child, 1); | ||||
| 			mptcp_token_accept(subflow_req, owner); | ||||
| 			ctx->conn = new_msk; | ||||
| 			new_msk = NULL; | ||||
| 
 | ||||
| 			/* set msk addresses early to ensure mptcp_pm_get_local_id()
 | ||||
| 			 * uses the correct data | ||||
|  | @ -898,11 +884,6 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	/* dispose of the left over mptcp master, if any */ | ||||
| 	if (unlikely(new_msk)) | ||||
| 		mptcp_force_close(new_msk); | ||||
| 
 | ||||
| 	/* check for expected invariant - should never trigger, just help
 | ||||
| 	 * catching eariler subtle bugs | ||||
| 	 */ | ||||
|  | @ -920,6 +901,10 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, | |||
| 
 | ||||
| 	/* The last child reference will be released by the caller */ | ||||
| 	return child; | ||||
| 
 | ||||
| fallback: | ||||
| 	mptcp_subflow_drop_ctx(child); | ||||
| 	return child; | ||||
| } | ||||
| 
 | ||||
| static struct inet_connection_sock_af_ops subflow_specific __ro_after_init; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Paolo Abeni
						Paolo Abeni