diff mbox series

[v8,mptcp-next,3/4] mptcp: add deny_join_id0 in mptcp_options_received

Message ID 5111dfce361c87c83e5355e78e55b6f593bac55b.1621933974.git.geliangtang@gmail.com (mailing list archive)
State Accepted, archived
Commit ef3b48916d09144c36d065c9c01338f1425283f4
Delegated to: Matthieu Baerts
Headers show
Series add MP_CAPABLE 'C' flag | expand

Commit Message

Geliang Tang May 25, 2021, 9:17 a.m. UTC
This patch added a new flag named deny_join_id0 in struct
mptcp_options_received. Set it when MP_CAPABLE with the flag
MPTCP_CAP_DENYJOIN_ID0 is received.

Also add a new flag remote_deny_join_id0 in struct mptcp_pm_data. When the
flag deny_join_id0 is set, set this remote_deny_join_id0 flag.

In mptcp_pm_create_subflow_or_signal_addr, if the remote_deny_join_id0 flag
is set, and the remote address id is zero, stop this connection.

Suggested-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c    | 6 ++++++
 net/mptcp/pm.c         | 1 +
 net/mptcp/pm_netlink.c | 3 ++-
 net/mptcp/protocol.h   | 4 +++-
 net/mptcp/subflow.c    | 2 ++
 5 files changed, 14 insertions(+), 2 deletions(-)

Comments

Paolo Abeni June 9, 2021, 5:01 p.m. UTC | #1
Hello,

On Tue, 2021-05-25 at 17:17 +0800, Geliang Tang wrote:
> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> index 1e921b5103bf..0d30008f0313 100644
> --- a/net/mptcp/options.c
> +++ b/net/mptcp/options.c
> @@ -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);
> @@ -1047,6 +1051,8 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
>  	}
>  
>  	mptcp_get_options(sk, skb, &mp_opt);
> +	if (mp_opt.deny_join_id0)
> +		WRITE_ONCE(msk->pm.remote_deny_join_id0, true);

I'm sorry for the long delay. Overall LGTM. The only thing I see worth
mentioning is the above test: is done for each incoming packet, but we
really need to check it for MPC ACK packet, right? if so the test
should be probably moved into the suitable section of
check_fully_established() - e.g. after the 'if (!mp_opt->mp_capable) {'
block.

No need for a resend, a squash-to patch will suffice  - if my above
assumption is correct.

BTW it looks like there are no check for the C bit being unmodified
between MPC syn and MPC ack, and AFAICS the RFC don't mention that
case. I think/guess we can simply fetch the MPC ack value.

Cheers,

Paolo

p.s. this really means acked-by ;)
diff mbox series

Patch

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 1e921b5103bf..0d30008f0313 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -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);
@@ -1047,6 +1051,8 @@  void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
 	}
 
 	mptcp_get_options(sk, skb, &mp_opt);
+	if (mp_opt.deny_join_id0)
+		WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
 	if (!check_fully_established(msk, sk, subflow, skb, &mp_opt))
 		return;
 
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 9d00fa6d22e9..639271e09604 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -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);
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 09722598994d..e6a3f0a550bf 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -451,7 +451,8 @@  static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 
 	/* check if should create a new subflow */
 	if (msk->pm.local_addr_used < local_addr_max &&
-	    msk->pm.subflows < subflows_max) {
+	    msk->pm.subflows < subflows_max &&
+	    !READ_ONCE(msk->pm.remote_deny_join_id0)) {
 		local = select_local_address(pernet, msk);
 		if (local) {
 			struct mptcp_addr_info remote = { 0 };
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 1201ab04bcdf..bdf4a832975d 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -138,7 +138,8 @@  struct mptcp_options_received {
 		mp_prio : 1,
 		echo : 1,
 		csum_reqd : 1,
-		backup : 1;
+		backup : 1,
+		deny_join_id0 : 1;
 	u32	token;
 	u32	nonce;
 	u64	thmac;
@@ -193,6 +194,7 @@  struct mptcp_pm_data {
 	bool		work_pending;
 	bool		accept_addr;
 	bool		accept_subflow;
+	bool		remote_deny_join_id0;
 	u8		add_addr_signaled;
 	u8		add_addr_accepted;
 	u8		local_addr_used;
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 0f4dc708e9b2..629be94f4d75 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -408,6 +408,8 @@  static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
 
 		if (mp_opt.csum_reqd)
 			WRITE_ONCE(mptcp_sk(parent)->csum_enabled, true);
+		if (mp_opt.deny_join_id0)
+			WRITE_ONCE(mptcp_sk(parent)->pm.remote_deny_join_id0, true);
 		subflow->mp_capable = 1;
 		subflow->can_ack = 1;
 		subflow->remote_key = mp_opt.sndr_key;