mirror of
https://github.com/torvalds/linux
synced 2024-10-18 09:18:26 +00:00
mptcp: implement fastclose xmit path
Allow the MPTCP xmit path to add MP_FASTCLOSE suboption on RST egress packets. Additionally reorder related options writing to reduce the number of conditionals required in the fast path. Co-developed-by: Geliang Tang <geliang.tang@suse.com> Signed-off-by: Geliang Tang <geliang.tang@suse.com> Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
58cd405b83
commit
f284c0c773
|
@ -768,6 +768,28 @@ static noinline bool mptcp_established_options_rst(struct sock *sk, struct sk_bu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mptcp_established_options_fastclose(struct sock *sk,
|
||||||
|
unsigned int *size,
|
||||||
|
unsigned int remaining,
|
||||||
|
struct mptcp_out_options *opts)
|
||||||
|
{
|
||||||
|
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
|
||||||
|
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
|
||||||
|
|
||||||
|
if (likely(!subflow->send_fastclose))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (remaining < TCPOLEN_MPTCP_FASTCLOSE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*size = TCPOLEN_MPTCP_FASTCLOSE;
|
||||||
|
opts->suboptions |= OPTION_MPTCP_FASTCLOSE;
|
||||||
|
opts->rcvr_key = msk->remote_key;
|
||||||
|
|
||||||
|
pr_debug("FASTCLOSE key=%llu", opts->rcvr_key);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool mptcp_established_options_mp_fail(struct sock *sk,
|
static bool mptcp_established_options_mp_fail(struct sock *sk,
|
||||||
unsigned int *size,
|
unsigned int *size,
|
||||||
unsigned int remaining,
|
unsigned int remaining,
|
||||||
|
@ -806,10 +828,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
|
if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
|
||||||
if (mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) {
|
if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) ||
|
||||||
|
mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) {
|
||||||
*size += opt_size;
|
*size += opt_size;
|
||||||
remaining -= opt_size;
|
remaining -= opt_size;
|
||||||
}
|
}
|
||||||
|
/* MP_RST can be used with MP_FASTCLOSE and MP_FAIL if there is room */
|
||||||
if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) {
|
if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) {
|
||||||
*size += opt_size;
|
*size += opt_size;
|
||||||
remaining -= opt_size;
|
remaining -= opt_size;
|
||||||
|
@ -1251,17 +1275,8 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RST is mutually exclusive with everything else */
|
/* DSS, MPC, MPJ, ADD_ADDR, FASTCLOSE and RST are mutually exclusive,
|
||||||
if (unlikely(OPTION_MPTCP_RST & opts->suboptions)) {
|
* see mptcp_established_options*()
|
||||||
*ptr++ = mptcp_option(MPTCPOPT_RST,
|
|
||||||
TCPOLEN_MPTCP_RST,
|
|
||||||
opts->reset_transient,
|
|
||||||
opts->reset_reason);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DSS, MPC, MPJ and ADD_ADDR are mutually exclusive, see
|
|
||||||
* mptcp_established_options*()
|
|
||||||
*/
|
*/
|
||||||
if (likely(OPTION_MPTCP_DSS & opts->suboptions)) {
|
if (likely(OPTION_MPTCP_DSS & opts->suboptions)) {
|
||||||
struct mptcp_ext *mpext = &opts->ext_copy;
|
struct mptcp_ext *mpext = &opts->ext_copy;
|
||||||
|
@ -1447,6 +1462,24 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (unlikely(OPTION_MPTCP_FASTCLOSE & opts->suboptions)) {
|
||||||
|
/* FASTCLOSE is mutually exclusive with others except RST */
|
||||||
|
*ptr++ = mptcp_option(MPTCPOPT_MP_FASTCLOSE,
|
||||||
|
TCPOLEN_MPTCP_FASTCLOSE,
|
||||||
|
0, 0);
|
||||||
|
put_unaligned_be64(opts->rcvr_key, ptr);
|
||||||
|
ptr += 2;
|
||||||
|
|
||||||
|
if (OPTION_MPTCP_RST & opts->suboptions)
|
||||||
|
goto mp_rst;
|
||||||
|
return;
|
||||||
|
} else if (unlikely(OPTION_MPTCP_RST & opts->suboptions)) {
|
||||||
|
mp_rst:
|
||||||
|
*ptr++ = mptcp_option(MPTCPOPT_RST,
|
||||||
|
TCPOLEN_MPTCP_RST,
|
||||||
|
opts->reset_transient,
|
||||||
|
opts->reset_reason);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OPTION_MPTCP_PRIO & opts->suboptions) {
|
if (OPTION_MPTCP_PRIO & opts->suboptions) {
|
||||||
|
|
|
@ -423,6 +423,7 @@ struct mptcp_subflow_context {
|
||||||
backup : 1,
|
backup : 1,
|
||||||
send_mp_prio : 1,
|
send_mp_prio : 1,
|
||||||
send_mp_fail : 1,
|
send_mp_fail : 1,
|
||||||
|
send_fastclose : 1,
|
||||||
rx_eof : 1,
|
rx_eof : 1,
|
||||||
can_ack : 1, /* only after processing the remote a key */
|
can_ack : 1, /* only after processing the remote a key */
|
||||||
disposable : 1, /* ctx can be free at ulp release time */
|
disposable : 1, /* ctx can be free at ulp release time */
|
||||||
|
|
Loading…
Reference in a new issue