Skip to content

Commit

Permalink
mptcp: add new sock flag to deal with join subflows
Browse files Browse the repository at this point in the history
MP_JOIN subflows must not land into the accept queue.
Currently tcp_check_req() calls an mptcp specific helper
to detect such scenario.

Such helper leverages the subflow context to check for
MP_JOIN subflows. We need to deal also with MP JOIN
failures, even when the subflow context is not available
due allocation failure.

A possible solution would be changing the syn_recv_sock()
signature to allow returning a more descriptive action/
error code and deal with that in tcp_check_req().

Since the above need is MPTCP specific, this patch instead
uses a TCP request socket hole to add a MPTCP specific flag.
Such flag is used by the MPTCP syn_recv_sock() to tell
tcp_check_req() how to deal with the request socket.

This change is a no-op for !MPTCP build, and makes the
MPTCP code simpler. It allows also the next patch to deal
correctly with MP JOIN failure.

v1 -> v2:
 - be more conservative on drop_req initialization (Mat)

RFC -> v1:
 - move the drop_req bit inside tcp_request_sock (Eric)

Signed-off-by: Paolo Abeni <[email protected]>
Reviewed-by: Mat Martineau <[email protected]>
Reviewed-by: Christoph Paasch <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Paolo Abeni authored and davem330 committed May 15, 2020
1 parent ca1c933 commit 90bf451
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 15 deletions.
3 changes: 3 additions & 0 deletions include/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ struct tcp_request_sock {
u64 snt_synack; /* first SYNACK sent time */
bool tfo_listener;
bool is_mptcp;
#if IS_ENABLED(CONFIG_MPTCP)
bool drop_req;
#endif
u32 txhash;
u32 rcv_isn;
u32 snt_isn;
Expand Down
17 changes: 10 additions & 7 deletions include/net/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ static inline bool rsk_is_mptcp(const struct request_sock *req)
return tcp_rsk(req)->is_mptcp;
}

static inline bool rsk_drop_req(const struct request_sock *req)
{
return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req;
}

void mptcp_space(const struct sock *ssk, int *space, int *full_space);
bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
unsigned int *size, struct mptcp_out_options *opts);
Expand Down Expand Up @@ -121,8 +126,6 @@ static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
skb_ext_find(from, SKB_EXT_MPTCP));
}

bool mptcp_sk_is_subflow(const struct sock *sk);

void mptcp_seq_show(struct seq_file *seq);
#else

Expand All @@ -140,6 +143,11 @@ static inline bool rsk_is_mptcp(const struct request_sock *req)
return false;
}

static inline bool rsk_drop_req(const struct request_sock *req)
{
return false;
}

static inline void mptcp_parse_option(const struct sk_buff *skb,
const unsigned char *ptr, int opsize,
struct tcp_options_received *opt_rx)
Expand Down Expand Up @@ -190,11 +198,6 @@ static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
return true;
}

static inline bool mptcp_sk_is_subflow(const struct sock *sk)
{
return false;
}

static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { }
static inline void mptcp_seq_show(struct seq_file *seq) { }
#endif /* CONFIG_MPTCP */
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
if (!child)
goto listen_overflow;

if (own_req && sk_is_mptcp(child) && mptcp_sk_is_subflow(child)) {
if (own_req && rsk_drop_req(req)) {
reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
inet_csk_reqsk_queue_drop_and_put(sk, req);
return child;
Expand Down
7 changes: 0 additions & 7 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -1638,13 +1638,6 @@ bool mptcp_finish_join(struct sock *sk)
return ret;
}

bool mptcp_sk_is_subflow(const struct sock *sk)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);

return subflow->mp_join == 1;
}

static bool mptcp_memory_free(const struct sock *sk, int wake)
{
struct mptcp_sock *msk = mptcp_sk(sk);
Expand Down
3 changes: 3 additions & 0 deletions net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
if (child && *own_req) {
struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(child);

tcp_rsk(req)->drop_req = false;

/* we need to fallback on ctx allocation failure and on pre-reqs
* checking above. In the latter scenario we additionally need
* to reset the context to non MPTCP status.
Expand Down Expand Up @@ -512,6 +514,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
goto close_child;

SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKRX);
tcp_rsk(req)->drop_req = true;
}
}

Expand Down

0 comments on commit 90bf451

Please sign in to comment.