Commit 38f75922 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mptcp-C-flag-and-fixes'



Mat Martineau says:

====================
mptcp: Connection-time 'C' flag and two fixes

Here are six more patches from the MPTCP tree.

Most of them add support for the 'C' flag in the MPTCP connection-time
option headers. This flag affects how the initial address and port are
treated by each peer. Normally one peer may send MP_JOIN requests to the
remote address and port that were used when initiating the MPTCP
connection. The 'C' bit indicates that MP_JOINs should only be sent to
remote addresses that have been advertised with ADD_ADDR.

The other two patches are unrelated improvements.

Patches 1-4: Add the 'C' flag feature, a sysctl to optionally enable it,
and a selftest.

Patch 5: Adjust rp_filter settings in a selftest.

Patch 6: Improve rbuf cleanup for MPTCP sockets.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a432c771 fde56eea
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -32,3 +32,16 @@ checksum_enabled - BOOLEAN
	per-namespace sysctl.

	Default: 0

allow_join_initial_addr_port - BOOLEAN
	Allow peers to send join requests to the IP address and port number used
	by the initial subflow if the value is 1. This controls a flag that is
	sent to the peer at connection time, and whether such join requests are
	accepted or denied.

	Joins to addresses advertised with ADD_ADDR are not affected by this
	value.

	This is a per-namespace sysctl.

	Default: 1
+2 −1
Original line number Diff line number Diff line
@@ -67,7 +67,8 @@ struct mptcp_out_options {
	u8 backup;
	u8 reset_reason:4,
	   reset_transient:1,
	   csum_reqd:1;
	   csum_reqd:1,
	   allow_join_id0:1;
	u32 nonce;
	u64 thmac;
	u32 token;
+16 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ struct mptcp_pernet {
	u8 mptcp_enabled;
	unsigned int add_addr_timeout;
	u8 checksum_enabled;
	u8 allow_join_initial_addr_port;
};

static struct mptcp_pernet *mptcp_get_pernet(struct net *net)
@@ -46,11 +47,17 @@ int mptcp_is_checksum_enabled(struct net *net)
	return mptcp_get_pernet(net)->checksum_enabled;
}

int mptcp_allow_join_id0(struct net *net)
{
	return mptcp_get_pernet(net)->allow_join_initial_addr_port;
}

static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
{
	pernet->mptcp_enabled = 1;
	pernet->add_addr_timeout = TCP_RTO_MAX;
	pernet->checksum_enabled = 0;
	pernet->allow_join_initial_addr_port = 1;
}

#ifdef CONFIG_SYSCTL
@@ -80,6 +87,14 @@ static struct ctl_table mptcp_sysctl_table[] = {
		.extra1       = SYSCTL_ZERO,
		.extra2       = SYSCTL_ONE
	},
	{
		.procname = "allow_join_initial_addr_port",
		.maxlen = sizeof(u8),
		.mode = 0644,
		.proc_handler = proc_dou8vec_minmax,
		.extra1       = SYSCTL_ZERO,
		.extra2       = SYSCTL_ONE
	},
	{}
};

@@ -98,6 +113,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
	table[0].data = &pernet->mptcp_enabled;
	table[1].data = &pernet->add_addr_timeout;
	table[2].data = &pernet->checksum_enabled;
	table[3].data = &pernet->allow_join_initial_addr_port;

	hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table);
	if (!hdr)
+13 −0
Original line number Diff line number Diff line
@@ -83,6 +83,9 @@ static void mptcp_parse_option(const struct sk_buff *skb,
		if (flags & MPTCP_CAP_CHECKSUM_REQD)
			mp_opt->csum_reqd = 1;

		if (flags & MPTCP_CAP_DENY_JOIN_ID0)
			mp_opt->deny_join_id0 = 1;

		mp_opt->mp_capable = 1;
		if (opsize >= TCPOLEN_MPTCP_MPC_SYNACK) {
			mp_opt->sndr_key = get_unaligned_be64(ptr);
@@ -360,6 +363,7 @@ void mptcp_get_options(const struct sock *sk,
	mp_opt->mp_prio = 0;
	mp_opt->reset = 0;
	mp_opt->csum_reqd = READ_ONCE(msk->csum_enabled);
	mp_opt->deny_join_id0 = 0;

	length = (th->doff * 4) - sizeof(struct tcphdr);
	ptr = (const unsigned char *)(th + 1);
@@ -402,6 +406,7 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
	if (subflow->request_mptcp) {
		opts->suboptions = OPTION_MPTCP_MPC_SYN;
		opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
		opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk));
		*size = TCPOLEN_MPTCP_MPC_SYN;
		return true;
	} else if (subflow->request_join) {
@@ -490,6 +495,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
		opts->sndr_key = subflow->local_key;
		opts->rcvr_key = subflow->remote_key;
		opts->csum_reqd = READ_ONCE(msk->csum_enabled);
		opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk));

		/* Section 3.1.
		 * The MP_CAPABLE option is carried on the SYN, SYN/ACK, and ACK
@@ -827,6 +833,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
		opts->suboptions = OPTION_MPTCP_MPC_SYNACK;
		opts->sndr_key = subflow_req->local_key;
		opts->csum_reqd = subflow_req->csum_reqd;
		opts->allow_join_id0 = subflow_req->allow_join_id0;
		*size = TCPOLEN_MPTCP_MPC_SYNACK;
		pr_debug("subflow_req=%p, local_key=%llu",
			 subflow_req, subflow_req->local_key);
@@ -905,6 +912,9 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
		return false;
	}

	if (mp_opt->deny_join_id0)
		WRITE_ONCE(msk->pm.remote_deny_join_id0, true);

	if (unlikely(!READ_ONCE(msk->pm.server_side)))
		pr_warn_once("bogus mpc option on established client sk");
	mptcp_subflow_fully_established(subflow, mp_opt);
@@ -1201,6 +1211,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
		if (opts->csum_reqd)
			flag |= MPTCP_CAP_CHECKSUM_REQD;

		if (!opts->allow_join_id0)
			flag |= MPTCP_CAP_DENY_JOIN_ID0;

		*ptr++ = mptcp_option(MPTCPOPT_MP_CAPABLE, len,
				      MPTCP_SUPPORTED_VERSION,
				      flag);
+1 −0
Original line number Diff line number Diff line
@@ -320,6 +320,7 @@ void mptcp_pm_data_init(struct mptcp_sock *msk)
	WRITE_ONCE(msk->pm.addr_signal, 0);
	WRITE_ONCE(msk->pm.accept_addr, false);
	WRITE_ONCE(msk->pm.accept_subflow, false);
	WRITE_ONCE(msk->pm.remote_deny_join_id0, false);
	msk->pm.status = 0;

	spin_lock_init(&msk->pm.lock);
Loading