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

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: default avatarGeliang Tang <geliang.tang@suse.com>
Signed-off-by: default avatarGeliang Tang <geliang.tang@suse.com>
Co-developed-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 58cd405b
Loading
Loading
Loading
Loading
+45 −12
Original line number Diff line number Diff line
@@ -768,6 +768,28 @@ static noinline bool mptcp_established_options_rst(struct sock *sk, struct sk_bu
	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,
					      unsigned int *size,
					      unsigned int remaining,
@@ -806,10 +828,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
		return false;

	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;
			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)) {
			*size += opt_size;
			remaining -= opt_size;
@@ -1251,17 +1275,8 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
		ptr += 2;
	}

	/* RST is mutually exclusive with everything else */
	if (unlikely(OPTION_MPTCP_RST & opts->suboptions)) {
		*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*()
	/* DSS, MPC, MPJ, ADD_ADDR, FASTCLOSE and RST are mutually exclusive,
	 * see mptcp_established_options*()
	 */
	if (likely(OPTION_MPTCP_DSS & opts->suboptions)) {
		struct mptcp_ext *mpext = &opts->ext_copy;
@@ -1447,6 +1462,24 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
				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) {
+1 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ struct mptcp_subflow_context {
		backup : 1,
		send_mp_prio : 1,
		send_mp_fail : 1,
		send_fastclose : 1,
		rx_eof : 1,
		can_ack : 1,        /* only after processing the remote a key */
		disposable : 1,	    /* ctx can be free at ulp release time */