Skip to content

Commit

Permalink
mptcp: simplify subflow_syn_recv_sock()
Browse files Browse the repository at this point in the history
Postpone the msk cloning to the child process creation
so that we can avoid a bunch of conditionals.

Closes: #61
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
  • Loading branch information
Paolo Abeni authored and matttbe committed Mar 9, 2023
1 parent 11ae51c commit c9b47ea
Showing 1 changed file with 13 additions and 28 deletions.
41 changes: 13 additions & 28 deletions net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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) ||
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
*/
Expand All @@ -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;
Expand Down

0 comments on commit c9b47ea

Please sign in to comment.