Commit a88d0092 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller
Browse files

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: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2bb9a37f
Loading
Loading
Loading
Loading
+13 −28
Original line number Diff line number Diff line
@@ -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;