mptcp: add new sock flag to deal with join subflows
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 <pabeni@redhat.com> Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Reviewed-by: Christoph Paasch <cpaasch@apple.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ca1c933bce
commit
90bf45134d
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user