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);
 | 
						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,
 | 
					static void subflow_ulp_fallback(struct sock *sk,
 | 
				
			||||||
				 struct mptcp_subflow_context *old_ctx)
 | 
									 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_subflow_request_sock *subflow_req;
 | 
				
			||||||
	struct mptcp_options_received mp_opt;
 | 
						struct mptcp_options_received mp_opt;
 | 
				
			||||||
	bool fallback, fallback_is_fatal;
 | 
						bool fallback, fallback_is_fatal;
 | 
				
			||||||
	struct sock *new_msk = NULL;
 | 
					 | 
				
			||||||
	struct mptcp_sock *owner;
 | 
						struct mptcp_sock *owner;
 | 
				
			||||||
	struct sock *child;
 | 
						struct sock *child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -784,14 +775,9 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
 | 
				
			||||||
		 * options.
 | 
							 * options.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		mptcp_get_options(skb, &mp_opt);
 | 
							mptcp_get_options(skb, &mp_opt);
 | 
				
			||||||
		if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) {
 | 
							if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC))
 | 
				
			||||||
			fallback = true;
 | 
								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) {
 | 
						} else if (subflow_req->mp_join) {
 | 
				
			||||||
		mptcp_get_options(skb, &mp_opt);
 | 
							mptcp_get_options(skb, &mp_opt);
 | 
				
			||||||
		if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) ||
 | 
							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);
 | 
									subflow_add_reset_reason(skb, MPTCP_RST_EMPTCP);
 | 
				
			||||||
				goto dispose_child;
 | 
									goto dispose_child;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								goto fallback;
 | 
				
			||||||
			mptcp_subflow_drop_ctx(child);
 | 
					 | 
				
			||||||
			goto out;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* ssk inherits options of listener sk */
 | 
							/* ssk inherits options of listener sk */
 | 
				
			||||||
		ctx->setsockopt_seq = listener->setsockopt_seq;
 | 
							ctx->setsockopt_seq = listener->setsockopt_seq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ctx->mp_capable) {
 | 
							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
 | 
								/* this can't race with mptcp_close(), as the msk is
 | 
				
			||||||
			 * not yet exposted to user-space
 | 
								 * 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
 | 
								/* record the newly created socket as the first msk
 | 
				
			||||||
			 * subflow, but don't link it yet into conn_list
 | 
								 * 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
 | 
								/* new mpc subflow takes ownership of the newly
 | 
				
			||||||
			 * created mptcp socket
 | 
								 * 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_pm_new_connection(owner, child, 1);
 | 
				
			||||||
			mptcp_token_accept(subflow_req, owner);
 | 
								mptcp_token_accept(subflow_req, owner);
 | 
				
			||||||
			ctx->conn = new_msk;
 | 
					 | 
				
			||||||
			new_msk = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* set msk addresses early to ensure mptcp_pm_get_local_id()
 | 
								/* set msk addresses early to ensure mptcp_pm_get_local_id()
 | 
				
			||||||
			 * uses the correct data
 | 
								 * 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
 | 
						/* check for expected invariant - should never trigger, just help
 | 
				
			||||||
	 * catching eariler subtle bugs
 | 
						 * 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 */
 | 
						/* The last child reference will be released by the caller */
 | 
				
			||||||
	return child;
 | 
						return child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fallback:
 | 
				
			||||||
 | 
						mptcp_subflow_drop_ctx(child);
 | 
				
			||||||
 | 
						return child;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct inet_connection_sock_af_ops subflow_specific __ro_after_init;
 | 
					static struct inet_connection_sock_af_ops subflow_specific __ro_after_init;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue