mptcp.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate"
@ 2021-07-11 15:15 Geliang Tang
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other" Geliang Tang
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Geliang Tang @ 2021-07-11 15:15 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

A small cleanup.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/pm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 30deb76fa5d0..1eeecd68f159 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -18,7 +18,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 {
 	u8 add_addr = READ_ONCE(msk->pm.addr_signal);
 
-	pr_debug("msk=%p, local_id=%d, echo:%d", msk, addr->id, echo);
+	pr_debug("msk=%p, local_id=%d, echo=%d", msk, addr->id, echo);
 
 	lockdep_assert_held(&msk->pm.lock);
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other"
  2021-07-11 15:15 [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Geliang Tang
@ 2021-07-11 15:15 ` Geliang Tang
  2021-07-12  9:55   ` Yonglong Li
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal" Geliang Tang
  2021-07-12 22:10 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Mat Martineau
  2 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2021-07-11 15:15 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

Add READ_ONCE() for reading msk->pm.addr_signal.

Use mptcp_pm_should_add_signal_echo instead of open coding.

Use '&=' to clear flag.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/pm.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index c9622696716e..be16da2dcb6b 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -257,6 +257,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 			      struct mptcp_addr_info *saddr, bool *echo, bool *port)
 {
 	int ret = false;
+	u8 add_addr;
 
 	spin_lock_bh(&msk->pm.lock);
 
@@ -271,10 +272,12 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 		goto out_unlock;
 
 	*saddr = msk->pm.local;
-	if ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)))
-		WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO));
+	add_addr = READ_ONCE(msk->pm.addr_signal);
+	if (mptcp_pm_should_add_signal_echo(msk))
+		add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
 	else
-		WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL));
+		add_addr &= ~BIT(MPTCP_ADD_ADDR_SIGNAL);
+	WRITE_ONCE(msk->pm.addr_signal, add_addr);
 	ret = true;
 
 out_unlock:
@@ -294,7 +297,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 	if (!mptcp_pm_should_rm_signal(msk))
 		goto out_unlock;
 
-	rm_addr = msk->pm.addr_signal & ~BIT(MPTCP_RM_ADDR_SIGNAL);
+	rm_addr = READ_ONCE(msk->pm.addr_signal);
+	rm_addr &= ~BIT(MPTCP_RM_ADDR_SIGNAL);
 	len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
 	if (len < 0) {
 		WRITE_ONCE(msk->pm.addr_signal, rm_addr);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-11 15:15 [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Geliang Tang
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other" Geliang Tang
@ 2021-07-11 15:15 ` Geliang Tang
  2021-07-12  1:34   ` Yonglong Li
  2021-07-12 22:10 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Mat Martineau
  2 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2021-07-11 15:15 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

I think there're still some issues in v8:

The remaining value is incorrect since "remaining += opt_size;" in the
"drop other suboptions" checks has been called twice in
mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.

opts->local and opts->remote in mptcp_pm_add_addr_signal need be
populate after the length chech, not before the check.

The squash-to patch keeped the more orignal code unchanged, and just do
the least, necessary modifications.

Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.

Change arguments of mptcp_pm_add_addr_signal.

Keep mptcp_add_addr_len unchanged.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 net/mptcp/options.c  | 35 +++++++++++++++++------------------
 net/mptcp/pm.c       | 23 +++++++++--------------
 net/mptcp/protocol.h | 27 +++++++++------------------
 3 files changed, 35 insertions(+), 50 deletions(-)

diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 5c0ad9b90866..93ad7b134f74 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
 	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
 	bool drop_other_suboptions = false;
 	unsigned int opt_size = *size;
-	u8 add_addr;
+	bool echo;
+	bool port;
+	u8 family;
 	int len;
 
-	if (!mptcp_pm_should_add_signal(msk) ||
-	    !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
-		return false;
-
-	if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
-	     ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
-	      (opts->local.family == AF_INET6 || opts->local.port))) &&
+	if ((mptcp_pm_should_add_signal_echo(msk) ||
+	     (mptcp_pm_should_add_signal_addr(msk) &&
+	      (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
 	    skb && skb_is_tcp_pure_ack(skb)) {
 		pr_debug("drop other suboptions");
 		opts->suboptions = 0;
@@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
 		drop_other_suboptions = true;
 	}
 
-	len = mptcp_add_addr_len(opts, add_addr);
+	if (!mptcp_pm_should_add_signal(msk) ||
+	    !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
+		return false;
+
+	family = echo ? opts->remote.family : opts->local.family;
+	len = mptcp_add_addr_len(family, echo, port);
 	if (remaining < len)
 		return false;
 
@@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
 	if (drop_other_suboptions)
 		*size -= opt_size;
 	opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
-	if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
-	    (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
+	if (!echo) {
 		opts->ahmac = add_addr_generate_hmac(msk->local_key,
 						     msk->remote_key,
 						     &opts->local);
 	}
-	pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
-		 add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
-		 ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
+	pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
+		 opts->local.id, ntohs(opts->local.port), opts->remote.id,
+		 ntohs(opts->remote.port), opts->ahmac, echo);
 
 	return true;
 }
@@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 
 mp_capable_done:
 	if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
-		struct mptcp_addr_info *addr = &opts->remote;
+		struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
 		u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
 		u8 echo = MPTCP_ADDR_ECHO;
 
-		if (opts->ahmac)
-			addr = &opts->local;
-
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
 		if (addr->family == AF_INET6)
 			len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 264f522af530..399b59cb7563 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
 
 /* path manager helpers */
 
-bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
-			      unsigned int opt_size, unsigned int remaining,
-			      struct mptcp_out_options *opts,  u8 *add_addr)
+bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
+			      struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
+			      bool *echo, bool *port)
 {
 	int ret = false;
 	u8 add_addr;
+	u8 family;
 
 	spin_lock_bh(&msk->pm.lock);
 
@@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
 	if (!mptcp_pm_should_add_signal(msk))
 		goto out_unlock;
 
-	opts->local = msk->pm.local;
-	opts->remote = msk->pm.remote;
-	*add_addr = msk->pm.addr_signal;
+	*echo = mptcp_pm_should_add_signal_echo(msk);
+	*port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
 
-	if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
-	     ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
-	      (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
-	    skb && skb_is_tcp_pure_ack(skb)) {
-		remaining += opt_size;
-	}
-
-	if (remaining < mptcp_add_addr_len(opts, *add_addr))
+	family = *echo ? msk->pm.remote.family : msk->pm.local.family;
+	if (remaining < mptcp_add_addr_len(family, *echo, *port))
 		goto out_unlock;
 
 	*saddr = msk->pm.local;
+	*daddr = msk->pm.remote;
 	add_addr = READ_ONCE(msk->pm.addr_signal);
 	if (mptcp_pm_should_add_signal_echo(msk))
 		add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 937e0309e340..4b63cc6079fa 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
 	return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
 }
 
-static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
-					      u8 add_addr)
+static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
 {
-	struct mptcp_addr_info *addr = &opts->remote;
-	u8 len = 0;
+	u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
 
-	if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
-	    (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
-		addr = &opts->local;
+	if (family == AF_INET6)
+		len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
+	if (!echo)
 		len += MPTCPOPT_THMAC_LEN;
-	}
-
-	if (addr->family == AF_INET6)
-		len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
-	else
-		len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
-
 	/* account for 2 trailing 'nop' options */
-	if (addr->port)
+	if (port)
 		len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
 
 	return len;
@@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
 	return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
 }
 
-bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
-			      unsigned int opt_size, unsigned int remaining,
-			      struct mptcp_out_options *opts,  u8 *add_addr);
+bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
+			      struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
+			      bool *echo, bool *port);
 bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 			     struct mptcp_rm_list *rm_list);
 int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal" Geliang Tang
@ 2021-07-12  1:34   ` Yonglong Li
  2021-07-12  7:33     ` Geliang Tang
  0 siblings, 1 reply; 17+ messages in thread
From: Yonglong Li @ 2021-07-12  1:34 UTC (permalink / raw)
  To: Geliang Tang, mptcp



On 2021/7/11 23:15, Geliang Tang wrote:
> I think there're still some issues in v8:
> 
> The remaining value is incorrect since "remaining += opt_size;" in the
> "drop other suboptions" checks has been called twice in
> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
> 
I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
mptcp_established_options_add_addr.

> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
> populate after the length chech, not before the check.]
> 
> The squash-to patch keeped the more orignal code unchanged, and just do
> the least, necessary modifications.
> 
Agree opts->local and opts->remote should be asigned after the length check.
But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
as orignal code, there is a race that:

==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
==> call mptcp_pm_add_addr_signal
==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
==> at this time opts->remote is empty and the length is incorrect.

So I think the orignal code is incorrect. WDYT?

> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
> 
> Change arguments of mptcp_pm_add_addr_signal.
> 
> Keep mptcp_add_addr_len unchanged.
> 
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
>  net/mptcp/pm.c       | 23 +++++++++--------------
>  net/mptcp/protocol.h | 27 +++++++++------------------
>  3 files changed, 35 insertions(+), 50 deletions(-)
> 
> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> index 5c0ad9b90866..93ad7b134f74 100644
> --- a/net/mptcp/options.c
> +++ b/net/mptcp/options.c
> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>  	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
>  	bool drop_other_suboptions = false;
>  	unsigned int opt_size = *size;
> -	u8 add_addr;
> +	bool echo;
> +	bool port;
> +	u8 family;
>  	int len;
>  
> -	if (!mptcp_pm_should_add_signal(msk) ||
> -	    !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
> -		return false;
> -
> -	if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> -	     ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> -	      (opts->local.family == AF_INET6 || opts->local.port))) &&
> +	if ((mptcp_pm_should_add_signal_echo(msk) ||
> +	     (mptcp_pm_should_add_signal_addr(msk) &&
> +	      (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>  	    skb && skb_is_tcp_pure_ack(skb)) {
>  		pr_debug("drop other suboptions");
>  		opts->suboptions = 0;
> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>  		drop_other_suboptions = true;
>  	}
>  
> -	len = mptcp_add_addr_len(opts, add_addr);
> +	if (!mptcp_pm_should_add_signal(msk) ||
> +	    !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
> +		return false;
> +
> +	family = echo ? opts->remote.family : opts->local.family;
> +	len = mptcp_add_addr_len(family, echo, port);
>  	if (remaining < len)
>  		return false;
>  
> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>  	if (drop_other_suboptions)
>  		*size -= opt_size;
>  	opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
> -	if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> -	    (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> +	if (!echo) {
>  		opts->ahmac = add_addr_generate_hmac(msk->local_key,
>  						     msk->remote_key,
>  						     &opts->local);
>  	}
> -	pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
> -		 add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
> -		 ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
> +	pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
> +		 opts->local.id, ntohs(opts->local.port), opts->remote.id,
> +		 ntohs(opts->remote.port), opts->ahmac, echo);
>  
>  	return true;
>  }
> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>  
>  mp_capable_done:
>  	if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
> -		struct mptcp_addr_info *addr = &opts->remote;
> +		struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
>  		u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>  		u8 echo = MPTCP_ADDR_ECHO;
>  
> -		if (opts->ahmac)
> -			addr = &opts->local;
> -
>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
>  		if (addr->family == AF_INET6)
>  			len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 264f522af530..399b59cb7563 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
>  
>  /* path manager helpers */
>  
> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> -			      unsigned int opt_size, unsigned int remaining,
> -			      struct mptcp_out_options *opts,  u8 *add_addr)
> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> +			      struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> +			      bool *echo, bool *port)
>  {
>  	int ret = false;
>  	u8 add_addr;
> +	u8 family;
>  
>  	spin_lock_bh(&msk->pm.lock);
>  
> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>  	if (!mptcp_pm_should_add_signal(msk))
>  		goto out_unlock;
>  
> -	opts->local = msk->pm.local;
> -	opts->remote = msk->pm.remote;
> -	*add_addr = msk->pm.addr_signal;
> +	*echo = mptcp_pm_should_add_signal_echo(msk);
> +	*port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
>  
> -	if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> -	     ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> -	      (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> -	    skb && skb_is_tcp_pure_ack(skb)) {
> -		remaining += opt_size;
> -	}
> -
> -	if (remaining < mptcp_add_addr_len(opts, *add_addr))
> +	family = *echo ? msk->pm.remote.family : msk->pm.local.family;
> +	if (remaining < mptcp_add_addr_len(family, *echo, *port))
>  		goto out_unlock;
>  
>  	*saddr = msk->pm.local;
> +	*daddr = msk->pm.remote;
>  	add_addr = READ_ONCE(msk->pm.addr_signal);
>  	if (mptcp_pm_should_add_signal_echo(msk))
>  		add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 937e0309e340..4b63cc6079fa 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
>  	return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
>  }
>  
> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
> -					      u8 add_addr)
> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
>  {
> -	struct mptcp_addr_info *addr = &opts->remote;
> -	u8 len = 0;
> +	u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>  
> -	if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> -	    (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> -		addr = &opts->local;
> +	if (family == AF_INET6)
> +		len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> +	if (!echo)
>  		len += MPTCPOPT_THMAC_LEN;
> -	}
> -
> -	if (addr->family == AF_INET6)
> -		len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> -	else
> -		len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
> -
>  	/* account for 2 trailing 'nop' options */
> -	if (addr->port)
> +	if (port)
>  		len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
>  
>  	return len;
> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
>  	return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
>  }
>  
> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> -			      unsigned int opt_size, unsigned int remaining,
> -			      struct mptcp_out_options *opts,  u8 *add_addr);
> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> +			      struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> +			      bool *echo, bool *port);
>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>  			     struct mptcp_rm_list *rm_list);
>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> 

-- 
Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  1:34   ` Yonglong Li
@ 2021-07-12  7:33     ` Geliang Tang
  2021-07-12  8:06       ` Yonglong Li
  0 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2021-07-12  7:33 UTC (permalink / raw)
  To: Yonglong Li; +Cc: mptcp

Hi Yonglong,

Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
>
>
>
> On 2021/7/11 23:15, Geliang Tang wrote:
> > I think there're still some issues in v8:
> >
> > The remaining value is incorrect since "remaining += opt_size;" in the
> > "drop other suboptions" checks has been called twice in
> > mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
> >
> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
> mptcp_established_options_add_addr.
>
> > opts->local and opts->remote in mptcp_pm_add_addr_signal need be
> > populate after the length chech, not before the check.]
> >
> > The squash-to patch keeped the more orignal code unchanged, and just do
> > the least, necessary modifications.
> >
> Agree opts->local and opts->remote should be asigned after the length check.
> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
> as orignal code, there is a race that:
>
> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> ==> call mptcp_pm_add_addr_signal
> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
> ==> at this time opts->remote is empty and the length is incorrect.
>

What will happen in v8 when this race occurs? How dose v8 deal with the
race?

> So I think the orignal code is incorrect. WDYT?
>
> > Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
> >
> > Change arguments of mptcp_pm_add_addr_signal.
> >
> > Keep mptcp_add_addr_len unchanged.
> >
> > Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> > ---
> >  net/mptcp/options.c  | 35 +++++++++++++++++------------------
> >  net/mptcp/pm.c       | 23 +++++++++--------------
> >  net/mptcp/protocol.h | 27 +++++++++------------------
> >  3 files changed, 35 insertions(+), 50 deletions(-)
> >
> > diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> > index 5c0ad9b90866..93ad7b134f74 100644
> > --- a/net/mptcp/options.c
> > +++ b/net/mptcp/options.c
> > @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> >       bool drop_other_suboptions = false;
> >       unsigned int opt_size = *size;
> > -     u8 add_addr;
> > +     bool echo;
> > +     bool port;
> > +     u8 family;
> >       int len;
> >
> > -     if (!mptcp_pm_should_add_signal(msk) ||
> > -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
> > -             return false;
> > -
> > -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> > -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> > -           (opts->local.family == AF_INET6 || opts->local.port))) &&
> > +     if ((mptcp_pm_should_add_signal_echo(msk) ||
> > +          (mptcp_pm_should_add_signal_addr(msk) &&
> > +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >           skb && skb_is_tcp_pure_ack(skb)) {
> >               pr_debug("drop other suboptions");
> >               opts->suboptions = 0;
> > @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >               drop_other_suboptions = true;
> >       }
> >
> > -     len = mptcp_add_addr_len(opts, add_addr);
> > +     if (!mptcp_pm_should_add_signal(msk) ||
> > +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
> > +             return false;
> > +
> > +     family = echo ? opts->remote.family : opts->local.family;
> > +     len = mptcp_add_addr_len(family, echo, port);
> >       if (remaining < len)
> >               return false;
> >
> > @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >       if (drop_other_suboptions)
> >               *size -= opt_size;
> >       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
> > -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> > -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> > +     if (!echo) {
> >               opts->ahmac = add_addr_generate_hmac(msk->local_key,
> >                                                    msk->remote_key,
> >                                                    &opts->local);
> >       }
> > -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
> > -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
> > -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
> > +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
> > +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
> > +              ntohs(opts->remote.port), opts->ahmac, echo);
> >
> >       return true;
> >  }
> > @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
> >
> >  mp_capable_done:
> >       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
> > -             struct mptcp_addr_info *addr = &opts->remote;
> > +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
> >               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >               u8 echo = MPTCP_ADDR_ECHO;
> >
> > -             if (opts->ahmac)
> > -                     addr = &opts->local;
> > -
> >  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> >               if (addr->family == AF_INET6)
> >                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> > index 264f522af530..399b59cb7563 100644
> > --- a/net/mptcp/pm.c
> > +++ b/net/mptcp/pm.c
> > @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
> >
> >  /* path manager helpers */
> >
> > -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> > -                           unsigned int opt_size, unsigned int remaining,
> > -                           struct mptcp_out_options *opts,  u8 *add_addr)
> > +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> > +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> > +                           bool *echo, bool *port)
> >  {
> >       int ret = false;
> >       u8 add_addr;
> > +     u8 family;
> >
> >       spin_lock_bh(&msk->pm.lock);
> >
> > @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >       if (!mptcp_pm_should_add_signal(msk))
> >               goto out_unlock;
> >
> > -     opts->local = msk->pm.local;
> > -     opts->remote = msk->pm.remote;
> > -     *add_addr = msk->pm.addr_signal;
> > +     *echo = mptcp_pm_should_add_signal_echo(msk);
> > +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
> >
> > -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> > -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> > -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> > -         skb && skb_is_tcp_pure_ack(skb)) {
> > -             remaining += opt_size;
> > -     }
> > -
> > -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
> > +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
> > +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
> >               goto out_unlock;
> >
> >       *saddr = msk->pm.local;
> > +     *daddr = msk->pm.remote;
> >       add_addr = READ_ONCE(msk->pm.addr_signal);
> >       if (mptcp_pm_should_add_signal_echo(msk))
> >               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> > index 937e0309e340..4b63cc6079fa 100644
> > --- a/net/mptcp/protocol.h
> > +++ b/net/mptcp/protocol.h
> > @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
> >       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
> >  }
> >
> > -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
> > -                                           u8 add_addr)
> > +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
> >  {
> > -     struct mptcp_addr_info *addr = &opts->remote;
> > -     u8 len = 0;
> > +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >
> > -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> > -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> > -             addr = &opts->local;
> > +     if (family == AF_INET6)
> > +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> > +     if (!echo)
> >               len += MPTCPOPT_THMAC_LEN;
> > -     }
> > -
> > -     if (addr->family == AF_INET6)
> > -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> > -     else
> > -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
> > -
> >       /* account for 2 trailing 'nop' options */
> > -     if (addr->port)
> > +     if (port)
> >               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
> >
> >       return len;
> > @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
> >       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
> >  }
> >
> > -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> > -                           unsigned int opt_size, unsigned int remaining,
> > -                           struct mptcp_out_options *opts,  u8 *add_addr);
> > +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> > +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> > +                           bool *echo, bool *port);
> >  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >                            struct mptcp_rm_list *rm_list);
> >  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> >
>
> --
> Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  7:33     ` Geliang Tang
@ 2021-07-12  8:06       ` Yonglong Li
  2021-07-12  8:44         ` Geliang Tang
  0 siblings, 1 reply; 17+ messages in thread
From: Yonglong Li @ 2021-07-12  8:06 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp



On 2021/7/12 15:33, Geliang Tang wrote:
> Hi Yonglong,
> 
> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
>>
>>
>>
>> On 2021/7/11 23:15, Geliang Tang wrote:
>>> I think there're still some issues in v8:
>>>
>>> The remaining value is incorrect since "remaining += opt_size;" in the
>>> "drop other suboptions" checks has been called twice in
>>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
>>>
>> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
>> mptcp_established_options_add_addr.
>>
>>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
>>> populate after the length chech, not before the check.]
>>>
>>> The squash-to patch keeped the more orignal code unchanged, and just do
>>> the least, necessary modifications.
>>>
>> Agree opts->local and opts->remote should be asigned after the length check.
>> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
>> as orignal code, there is a race that:
>>
>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>> ==> call mptcp_pm_add_addr_signal
>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
>> ==> at this time opts->remote is empty and the length is incorrect.
>>
> 
> What will happen in v8 when this race occurs? How dose v8 deal with the
> race?
Hi Geliang, thinks for your patience.

I think v8 doesn't have this issue:
==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
==> use add_addr and opts to check length.
==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.

> 
>> So I think the orignal code is incorrect. WDYT?
>>
>>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
>>>
>>> Change arguments of mptcp_pm_add_addr_signal.
>>>
>>> Keep mptcp_add_addr_len unchanged.
>>>
>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
>>> ---
>>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
>>>  net/mptcp/pm.c       | 23 +++++++++--------------
>>>  net/mptcp/protocol.h | 27 +++++++++------------------
>>>  3 files changed, 35 insertions(+), 50 deletions(-)
>>>
>>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>>> index 5c0ad9b90866..93ad7b134f74 100644
>>> --- a/net/mptcp/options.c
>>> +++ b/net/mptcp/options.c
>>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
>>>       bool drop_other_suboptions = false;
>>>       unsigned int opt_size = *size;
>>> -     u8 add_addr;
>>> +     bool echo;
>>> +     bool port;
>>> +     u8 family;
>>>       int len;
>>>
>>> -     if (!mptcp_pm_should_add_signal(msk) ||
>>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
>>> -             return false;
>>> -
>>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
>>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
>>> +          (mptcp_pm_should_add_signal_addr(msk) &&
>>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>           skb && skb_is_tcp_pure_ack(skb)) {
>>>               pr_debug("drop other suboptions");
>>>               opts->suboptions = 0;
>>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>               drop_other_suboptions = true;
>>>       }
>>>
>>> -     len = mptcp_add_addr_len(opts, add_addr);
>>> +     if (!mptcp_pm_should_add_signal(msk) ||
>>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
>>> +             return false;
>>> +
>>> +     family = echo ? opts->remote.family : opts->local.family;
>>> +     len = mptcp_add_addr_len(family, echo, port);
>>>       if (remaining < len)
>>>               return false;
>>>
>>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>       if (drop_other_suboptions)
>>>               *size -= opt_size;
>>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>> +     if (!echo) {
>>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
>>>                                                    msk->remote_key,
>>>                                                    &opts->local);
>>>       }
>>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
>>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
>>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
>>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
>>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
>>> +              ntohs(opts->remote.port), opts->ahmac, echo);
>>>
>>>       return true;
>>>  }
>>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>>
>>>  mp_capable_done:
>>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
>>> -             struct mptcp_addr_info *addr = &opts->remote;
>>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
>>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>               u8 echo = MPTCP_ADDR_ECHO;
>>>
>>> -             if (opts->ahmac)
>>> -                     addr = &opts->local;
>>> -
>>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
>>>               if (addr->family == AF_INET6)
>>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
>>> index 264f522af530..399b59cb7563 100644
>>> --- a/net/mptcp/pm.c
>>> +++ b/net/mptcp/pm.c
>>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
>>>
>>>  /* path manager helpers */
>>>
>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>> -                           unsigned int opt_size, unsigned int remaining,
>>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>> +                           bool *echo, bool *port)
>>>  {
>>>       int ret = false;
>>>       u8 add_addr;
>>> +     u8 family;
>>>
>>>       spin_lock_bh(&msk->pm.lock);
>>>
>>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>       if (!mptcp_pm_should_add_signal(msk))
>>>               goto out_unlock;
>>>
>>> -     opts->local = msk->pm.local;
>>> -     opts->remote = msk->pm.remote;
>>> -     *add_addr = msk->pm.addr_signal;
>>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
>>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
>>>
>>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>> -         skb && skb_is_tcp_pure_ack(skb)) {
>>> -             remaining += opt_size;
>>> -     }
>>> -
>>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
>>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
>>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
>>>               goto out_unlock;
>>>
>>>       *saddr = msk->pm.local;
>>> +     *daddr = msk->pm.remote;
>>>       add_addr = READ_ONCE(msk->pm.addr_signal);
>>>       if (mptcp_pm_should_add_signal_echo(msk))
>>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>>> index 937e0309e340..4b63cc6079fa 100644
>>> --- a/net/mptcp/protocol.h
>>> +++ b/net/mptcp/protocol.h
>>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
>>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
>>>  }
>>>
>>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
>>> -                                           u8 add_addr)
>>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
>>>  {
>>> -     struct mptcp_addr_info *addr = &opts->remote;
>>> -     u8 len = 0;
>>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>
>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>> -             addr = &opts->local;
>>> +     if (family == AF_INET6)
>>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>> +     if (!echo)
>>>               len += MPTCPOPT_THMAC_LEN;
>>> -     }
>>> -
>>> -     if (addr->family == AF_INET6)
>>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>> -     else
>>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>> -
>>>       /* account for 2 trailing 'nop' options */
>>> -     if (addr->port)
>>> +     if (port)
>>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
>>>
>>>       return len;
>>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
>>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
>>>  }
>>>
>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>> -                           unsigned int opt_size, unsigned int remaining,
>>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>> +                           bool *echo, bool *port);
>>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>                            struct mptcp_rm_list *rm_list);
>>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
>>>
>>
>> --
>> Li YongLong
> 

-- 
Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  8:06       ` Yonglong Li
@ 2021-07-12  8:44         ` Geliang Tang
  2021-07-12  9:07           ` Geliang Tang
  2021-07-12  9:14           ` Yonglong Li
  0 siblings, 2 replies; 17+ messages in thread
From: Geliang Tang @ 2021-07-12  8:44 UTC (permalink / raw)
  To: Yonglong Li; +Cc: mptcp

Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
>
>
>
> On 2021/7/12 15:33, Geliang Tang wrote:
> > Hi Yonglong,
> >
> > Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
> >>
> >>
> >>
> >> On 2021/7/11 23:15, Geliang Tang wrote:
> >>> I think there're still some issues in v8:
> >>>
> >>> The remaining value is incorrect since "remaining += opt_size;" in the
> >>> "drop other suboptions" checks has been called twice in
> >>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
> >>>
> >> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
> >> mptcp_established_options_add_addr.
> >>
> >>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
> >>> populate after the length chech, not before the check.]
> >>>
> >>> The squash-to patch keeped the more orignal code unchanged, and just do
> >>> the least, necessary modifications.
> >>>
> >> Agree opts->local and opts->remote should be asigned after the length check.
> >> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
> >> as orignal code, there is a race that:
> >>
> >> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >> ==> call mptcp_pm_add_addr_signal
> >> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
> >> ==> at this time opts->remote is empty and the length is incorrect.
> >>
> >
> > What will happen in v8 when this race occurs? How dose v8 deal with the
> > race?
> Hi Geliang, thinks for your patience.
>
> I think v8 doesn't have this issue:
> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
> ==> use add_addr and opts to check length.
> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.

Thanks for your explanation.

I think this squash-to patch did the same thing:

==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
'echo' (echo = false), save the port number to 'port', and save addr
in opts under pm.lock
==> an echo add addr event trigger (pm.addr_signal ==
MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
==> use 'echo' to get the address family, use 'family', 'echo' and
'port' to check length.
==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.

Do you think so?

>
> >
> >> So I think the orignal code is incorrect. WDYT?
> >>
> >>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
> >>>
> >>> Change arguments of mptcp_pm_add_addr_signal.
> >>>
> >>> Keep mptcp_add_addr_len unchanged.
> >>>
> >>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> >>> ---
> >>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
> >>>  net/mptcp/pm.c       | 23 +++++++++--------------
> >>>  net/mptcp/protocol.h | 27 +++++++++------------------
> >>>  3 files changed, 35 insertions(+), 50 deletions(-)
> >>>
> >>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> >>> index 5c0ad9b90866..93ad7b134f74 100644
> >>> --- a/net/mptcp/options.c
> >>> +++ b/net/mptcp/options.c
> >>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> >>>       bool drop_other_suboptions = false;
> >>>       unsigned int opt_size = *size;
> >>> -     u8 add_addr;
> >>> +     bool echo;
> >>> +     bool port;
> >>> +     u8 family;
> >>>       int len;
> >>>
> >>> -     if (!mptcp_pm_should_add_signal(msk) ||
> >>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
> >>> -             return false;
> >>> -
> >>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> >>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> >>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
> >>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
> >>> +          (mptcp_pm_should_add_signal_addr(msk) &&
> >>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >>>           skb && skb_is_tcp_pure_ack(skb)) {
> >>>               pr_debug("drop other suboptions");
> >>>               opts->suboptions = 0;
> >>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>               drop_other_suboptions = true;
> >>>       }
> >>>
> >>> -     len = mptcp_add_addr_len(opts, add_addr);
> >>> +     if (!mptcp_pm_should_add_signal(msk) ||
> >>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
> >>> +             return false;
> >>> +
> >>> +     family = echo ? opts->remote.family : opts->local.family;
> >>> +     len = mptcp_add_addr_len(family, echo, port);
> >>>       if (remaining < len)
> >>>               return false;
> >>>
> >>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>       if (drop_other_suboptions)
> >>>               *size -= opt_size;
> >>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
> >>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> >>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> >>> +     if (!echo) {
> >>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
> >>>                                                    msk->remote_key,
> >>>                                                    &opts->local);
> >>>       }
> >>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
> >>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
> >>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
> >>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
> >>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
> >>> +              ntohs(opts->remote.port), opts->ahmac, echo);
> >>>
> >>>       return true;
> >>>  }
> >>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
> >>>
> >>>  mp_capable_done:
> >>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
> >>> -             struct mptcp_addr_info *addr = &opts->remote;
> >>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
> >>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>               u8 echo = MPTCP_ADDR_ECHO;
> >>>
> >>> -             if (opts->ahmac)
> >>> -                     addr = &opts->local;
> >>> -
> >>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> >>>               if (addr->family == AF_INET6)
> >>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> >>> index 264f522af530..399b59cb7563 100644
> >>> --- a/net/mptcp/pm.c
> >>> +++ b/net/mptcp/pm.c
> >>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
> >>>
> >>>  /* path manager helpers */
> >>>
> >>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>> -                           unsigned int opt_size, unsigned int remaining,
> >>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
> >>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> >>> +                           bool *echo, bool *port)
> >>>  {
> >>>       int ret = false;
> >>>       u8 add_addr;
> >>> +     u8 family;
> >>>
> >>>       spin_lock_bh(&msk->pm.lock);
> >>>
> >>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>       if (!mptcp_pm_should_add_signal(msk))
> >>>               goto out_unlock;
> >>>
> >>> -     opts->local = msk->pm.local;
> >>> -     opts->remote = msk->pm.remote;
> >>> -     *add_addr = msk->pm.addr_signal;
> >>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
> >>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
> >>>
> >>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> >>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> >>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >>> -         skb && skb_is_tcp_pure_ack(skb)) {
> >>> -             remaining += opt_size;
> >>> -     }
> >>> -
> >>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
> >>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
> >>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
> >>>               goto out_unlock;
> >>>
> >>>       *saddr = msk->pm.local;
> >>> +     *daddr = msk->pm.remote;
> >>>       add_addr = READ_ONCE(msk->pm.addr_signal);
> >>>       if (mptcp_pm_should_add_signal_echo(msk))
> >>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> >>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> >>> index 937e0309e340..4b63cc6079fa 100644
> >>> --- a/net/mptcp/protocol.h
> >>> +++ b/net/mptcp/protocol.h
> >>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
> >>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
> >>>  }
> >>>
> >>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
> >>> -                                           u8 add_addr)
> >>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
> >>>  {
> >>> -     struct mptcp_addr_info *addr = &opts->remote;
> >>> -     u8 len = 0;
> >>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>
> >>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> >>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> >>> -             addr = &opts->local;
> >>> +     if (family == AF_INET6)
> >>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>> +     if (!echo)
> >>>               len += MPTCPOPT_THMAC_LEN;
> >>> -     }
> >>> -
> >>> -     if (addr->family == AF_INET6)
> >>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>> -     else
> >>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>> -
> >>>       /* account for 2 trailing 'nop' options */
> >>> -     if (addr->port)
> >>> +     if (port)
> >>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
> >>>
> >>>       return len;
> >>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
> >>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
> >>>  }
> >>>
> >>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>> -                           unsigned int opt_size, unsigned int remaining,
> >>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
> >>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> >>> +                           bool *echo, bool *port);
> >>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>                            struct mptcp_rm_list *rm_list);
> >>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> >>>
> >>
> >> --
> >> Li YongLong
> >
>
> --
> Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  8:44         ` Geliang Tang
@ 2021-07-12  9:07           ` Geliang Tang
  2021-07-12  9:21             ` Yonglong Li
  2021-07-12  9:14           ` Yonglong Li
  1 sibling, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2021-07-12  9:07 UTC (permalink / raw)
  To: Yonglong Li; +Cc: mptcp

Geliang Tang <geliangtang@gmail.com> 于2021年7月12日周一 下午4:44写道:
>
> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
> >
> >
> >
> > On 2021/7/12 15:33, Geliang Tang wrote:
> > > Hi Yonglong,
> > >
> > > Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
> > >>
> > >>
> > >>
> > >> On 2021/7/11 23:15, Geliang Tang wrote:
> > >>> I think there're still some issues in v8:
> > >>>
> > >>> The remaining value is incorrect since "remaining += opt_size;" in the
> > >>> "drop other suboptions" checks has been called twice in
> > >>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
> > >>>
> > >> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
> > >> mptcp_established_options_add_addr.
> > >>
> > >>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
> > >>> populate after the length chech, not before the check.]
> > >>>
> > >>> The squash-to patch keeped the more orignal code unchanged, and just do
> > >>> the least, necessary modifications.
> > >>>
> > >> Agree opts->local and opts->remote should be asigned after the length check.
> > >> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
> > >> as orignal code, there is a race that:
> > >>
> > >> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> > >> ==> call mptcp_pm_add_addr_signal
> > >> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
> > >> ==> at this time opts->remote is empty and the length is incorrect.
> > >>
> > >
> > > What will happen in v8 when this race occurs? How dose v8 deal with the
> > > race?
> > Hi Geliang, thinks for your patience.
> >
> > I think v8 doesn't have this issue:
> > ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> > ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
> > ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
> > ==> use add_addr and opts to check length.
> > ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
>
> Thanks for your explanation.
>
> I think this squash-to patch did the same thing:
>
> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> ==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
> 'echo' (echo = false), save the port number to 'port', and save addr
> in opts under pm.lock
> ==> an echo add addr event trigger (pm.addr_signal ==
> MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
> ==> use 'echo' to get the address family, use 'family', 'echo' and
> 'port' to check length.
> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
>
> Do you think so?

And one more thing. How do you test this "mptcp: fix conflicts when using
pm.add_signal in ADD_ADDR/echo and RM_ADDR process" series? Do you use our
mptcp_join.sh to test it, or you did some special tests? Does this race
scenario mentioned above easy to reproduce?

I just did the mptcp_join.sh tests for my squash-to patches, and everything
looks fine. If you have some special tests, could you please help me to test
these squash-to patches too? Hope it works in the race scenario.

Thanks.
-Geliang



>
> >
> > >
> > >> So I think the orignal code is incorrect. WDYT?
> > >>
> > >>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
> > >>>
> > >>> Change arguments of mptcp_pm_add_addr_signal.
> > >>>
> > >>> Keep mptcp_add_addr_len unchanged.
> > >>>
> > >>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> > >>> ---
> > >>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
> > >>>  net/mptcp/pm.c       | 23 +++++++++--------------
> > >>>  net/mptcp/protocol.h | 27 +++++++++------------------
> > >>>  3 files changed, 35 insertions(+), 50 deletions(-)
> > >>>
> > >>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> > >>> index 5c0ad9b90866..93ad7b134f74 100644
> > >>> --- a/net/mptcp/options.c
> > >>> +++ b/net/mptcp/options.c
> > >>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> > >>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> > >>>       bool drop_other_suboptions = false;
> > >>>       unsigned int opt_size = *size;
> > >>> -     u8 add_addr;
> > >>> +     bool echo;
> > >>> +     bool port;
> > >>> +     u8 family;
> > >>>       int len;
> > >>>
> > >>> -     if (!mptcp_pm_should_add_signal(msk) ||
> > >>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
> > >>> -             return false;
> > >>> -
> > >>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> > >>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> > >>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
> > >>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
> > >>> +          (mptcp_pm_should_add_signal_addr(msk) &&
> > >>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> > >>>           skb && skb_is_tcp_pure_ack(skb)) {
> > >>>               pr_debug("drop other suboptions");
> > >>>               opts->suboptions = 0;
> > >>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> > >>>               drop_other_suboptions = true;
> > >>>       }
> > >>>
> > >>> -     len = mptcp_add_addr_len(opts, add_addr);
> > >>> +     if (!mptcp_pm_should_add_signal(msk) ||
> > >>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
> > >>> +             return false;
> > >>> +
> > >>> +     family = echo ? opts->remote.family : opts->local.family;
> > >>> +     len = mptcp_add_addr_len(family, echo, port);
> > >>>       if (remaining < len)
> > >>>               return false;
> > >>>
> > >>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> > >>>       if (drop_other_suboptions)
> > >>>               *size -= opt_size;
> > >>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
> > >>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> > >>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> > >>> +     if (!echo) {
> > >>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
> > >>>                                                    msk->remote_key,
> > >>>                                                    &opts->local);
> > >>>       }
> > >>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
> > >>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
> > >>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
> > >>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
> > >>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
> > >>> +              ntohs(opts->remote.port), opts->ahmac, echo);
> > >>>
> > >>>       return true;
> > >>>  }
> > >>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
> > >>>
> > >>>  mp_capable_done:
> > >>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
> > >>> -             struct mptcp_addr_info *addr = &opts->remote;
> > >>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
> > >>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> > >>>               u8 echo = MPTCP_ADDR_ECHO;
> > >>>
> > >>> -             if (opts->ahmac)
> > >>> -                     addr = &opts->local;
> > >>> -
> > >>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> > >>>               if (addr->family == AF_INET6)
> > >>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> > >>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> > >>> index 264f522af530..399b59cb7563 100644
> > >>> --- a/net/mptcp/pm.c
> > >>> +++ b/net/mptcp/pm.c
> > >>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
> > >>>
> > >>>  /* path manager helpers */
> > >>>
> > >>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> > >>> -                           unsigned int opt_size, unsigned int remaining,
> > >>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
> > >>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> > >>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> > >>> +                           bool *echo, bool *port)
> > >>>  {
> > >>>       int ret = false;
> > >>>       u8 add_addr;
> > >>> +     u8 family;
> > >>>
> > >>>       spin_lock_bh(&msk->pm.lock);
> > >>>
> > >>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> > >>>       if (!mptcp_pm_should_add_signal(msk))
> > >>>               goto out_unlock;
> > >>>
> > >>> -     opts->local = msk->pm.local;
> > >>> -     opts->remote = msk->pm.remote;
> > >>> -     *add_addr = msk->pm.addr_signal;
> > >>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
> > >>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
> > >>>
> > >>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> > >>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> > >>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> > >>> -         skb && skb_is_tcp_pure_ack(skb)) {
> > >>> -             remaining += opt_size;
> > >>> -     }
> > >>> -
> > >>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
> > >>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
> > >>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
> > >>>               goto out_unlock;
> > >>>
> > >>>       *saddr = msk->pm.local;
> > >>> +     *daddr = msk->pm.remote;
> > >>>       add_addr = READ_ONCE(msk->pm.addr_signal);
> > >>>       if (mptcp_pm_should_add_signal_echo(msk))
> > >>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> > >>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> > >>> index 937e0309e340..4b63cc6079fa 100644
> > >>> --- a/net/mptcp/protocol.h
> > >>> +++ b/net/mptcp/protocol.h
> > >>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
> > >>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
> > >>>  }
> > >>>
> > >>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
> > >>> -                                           u8 add_addr)
> > >>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
> > >>>  {
> > >>> -     struct mptcp_addr_info *addr = &opts->remote;
> > >>> -     u8 len = 0;
> > >>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> > >>>
> > >>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> > >>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> > >>> -             addr = &opts->local;
> > >>> +     if (family == AF_INET6)
> > >>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> > >>> +     if (!echo)
> > >>>               len += MPTCPOPT_THMAC_LEN;
> > >>> -     }
> > >>> -
> > >>> -     if (addr->family == AF_INET6)
> > >>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> > >>> -     else
> > >>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
> > >>> -
> > >>>       /* account for 2 trailing 'nop' options */
> > >>> -     if (addr->port)
> > >>> +     if (port)
> > >>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
> > >>>
> > >>>       return len;
> > >>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
> > >>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
> > >>>  }
> > >>>
> > >>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> > >>> -                           unsigned int opt_size, unsigned int remaining,
> > >>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
> > >>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> > >>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> > >>> +                           bool *echo, bool *port);
> > >>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> > >>>                            struct mptcp_rm_list *rm_list);
> > >>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> > >>>
> > >>
> > >> --
> > >> Li YongLong
> > >
> >
> > --
> > Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  8:44         ` Geliang Tang
  2021-07-12  9:07           ` Geliang Tang
@ 2021-07-12  9:14           ` Yonglong Li
  2021-07-12  9:29             ` Geliang Tang
  1 sibling, 1 reply; 17+ messages in thread
From: Yonglong Li @ 2021-07-12  9:14 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp



On 2021/7/12 16:44, Geliang Tang wrote:
> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
>>
>>
>>
>> On 2021/7/12 15:33, Geliang Tang wrote:
>>> Hi Yonglong,
>>>
>>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
>>>>
>>>>
>>>>
>>>> On 2021/7/11 23:15, Geliang Tang wrote:
>>>>> I think there're still some issues in v8:
>>>>>
>>>>> The remaining value is incorrect since "remaining += opt_size;" in the
>>>>> "drop other suboptions" checks has been called twice in
>>>>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
>>>>>
>>>> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
>>>> mptcp_established_options_add_addr.
>>>>
>>>>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
>>>>> populate after the length chech, not before the check.]
>>>>>
>>>>> The squash-to patch keeped the more orignal code unchanged, and just do
>>>>> the least, necessary modifications.
>>>>>
>>>> Agree opts->local and opts->remote should be asigned after the length check.
>>>> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
>>>> as orignal code, there is a race that:
>>>>
>>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>>>> ==> call mptcp_pm_add_addr_signal
>>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
>>>> ==> at this time opts->remote is empty and the length is incorrect.
>>>>
>>>
>>> What will happen in v8 when this race occurs? How dose v8 deal with the
>>> race?
>> Hi Geliang, thinks for your patience.
>>
>> I think v8 doesn't have this issue:
>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>> ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
>> ==> use add_addr and opts to check length.
>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
> 
> Thanks for your explanation.
> 
> I think this squash-to patch did the same thing:
> 
> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> ==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
> 'echo' (echo = false), save the port number to 'port', and save addr
> in opts under pm.lock
> ==> an echo add addr event trigger (pm.addr_signal ==
> MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
> ==> use 'echo' to get the address family, use 'family', 'echo' and
> 'port' to check length.
> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
> 
> Do you think so?
yep. In this case the squash-to patch is ok. But I think between "drop other suboptions" checks and
mptcp_pm_add_addr_signal the race still exist.

==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
==> "drop other suboptions" checks will use MPTCP_ADD_ADDR_SIGNAL to check
==> an echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL | MPTCP_ADD_ADDR_ECHO )
==> call mptcp_pm_add_addr_signal, MPTCP_ADD_ADDR_ECHO will be clear in pm.addr_signal
==> process MPTCP_ADD_ADDR_ECHO event.

WDYT?

> 
>>
>>>
>>>> So I think the orignal code is incorrect. WDYT?
>>>>
>>>>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
>>>>>
>>>>> Change arguments of mptcp_pm_add_addr_signal.
>>>>>
>>>>> Keep mptcp_add_addr_len unchanged.
>>>>>
>>>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
>>>>> ---
>>>>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
>>>>>  net/mptcp/pm.c       | 23 +++++++++--------------
>>>>>  net/mptcp/protocol.h | 27 +++++++++------------------
>>>>>  3 files changed, 35 insertions(+), 50 deletions(-)
>>>>>
>>>>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>>>>> index 5c0ad9b90866..93ad7b134f74 100644
>>>>> --- a/net/mptcp/options.c
>>>>> +++ b/net/mptcp/options.c
>>>>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
>>>>>       bool drop_other_suboptions = false;
>>>>>       unsigned int opt_size = *size;
>>>>> -     u8 add_addr;
>>>>> +     bool echo;
>>>>> +     bool port;
>>>>> +     u8 family;
>>>>>       int len;
>>>>>
>>>>> -     if (!mptcp_pm_should_add_signal(msk) ||
>>>>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
>>>>> -             return false;
>>>>> -
>>>>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>>>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>>>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
>>>>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
>>>>> +          (mptcp_pm_should_add_signal_addr(msk) &&
>>>>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>>>           skb && skb_is_tcp_pure_ack(skb)) {
>>>>>               pr_debug("drop other suboptions");
>>>>>               opts->suboptions = 0;
>>>>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>               drop_other_suboptions = true;
>>>>>       }
>>>>>
>>>>> -     len = mptcp_add_addr_len(opts, add_addr);
>>>>> +     if (!mptcp_pm_should_add_signal(msk) ||
>>>>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
>>>>> +             return false;
>>>>> +
>>>>> +     family = echo ? opts->remote.family : opts->local.family;
>>>>> +     len = mptcp_add_addr_len(family, echo, port);
>>>>>       if (remaining < len)
>>>>>               return false;
>>>>>
>>>>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>       if (drop_other_suboptions)
>>>>>               *size -= opt_size;
>>>>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>>>> +     if (!echo) {
>>>>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
>>>>>                                                    msk->remote_key,
>>>>>                                                    &opts->local);
>>>>>       }
>>>>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
>>>>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
>>>>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
>>>>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
>>>>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
>>>>> +              ntohs(opts->remote.port), opts->ahmac, echo);
>>>>>
>>>>>       return true;
>>>>>  }
>>>>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>>>>
>>>>>  mp_capable_done:
>>>>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
>>>>> -             struct mptcp_addr_info *addr = &opts->remote;
>>>>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
>>>>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>               u8 echo = MPTCP_ADDR_ECHO;
>>>>>
>>>>> -             if (opts->ahmac)
>>>>> -                     addr = &opts->local;
>>>>> -
>>>>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
>>>>>               if (addr->family == AF_INET6)
>>>>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
>>>>> index 264f522af530..399b59cb7563 100644
>>>>> --- a/net/mptcp/pm.c
>>>>> +++ b/net/mptcp/pm.c
>>>>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
>>>>>
>>>>>  /* path manager helpers */
>>>>>
>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>> -                           unsigned int opt_size, unsigned int remaining,
>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>>>> +                           bool *echo, bool *port)
>>>>>  {
>>>>>       int ret = false;
>>>>>       u8 add_addr;
>>>>> +     u8 family;
>>>>>
>>>>>       spin_lock_bh(&msk->pm.lock);
>>>>>
>>>>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>       if (!mptcp_pm_should_add_signal(msk))
>>>>>               goto out_unlock;
>>>>>
>>>>> -     opts->local = msk->pm.local;
>>>>> -     opts->remote = msk->pm.remote;
>>>>> -     *add_addr = msk->pm.addr_signal;
>>>>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
>>>>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
>>>>>
>>>>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>>>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>>>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>>> -         skb && skb_is_tcp_pure_ack(skb)) {
>>>>> -             remaining += opt_size;
>>>>> -     }
>>>>> -
>>>>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
>>>>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
>>>>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
>>>>>               goto out_unlock;
>>>>>
>>>>>       *saddr = msk->pm.local;
>>>>> +     *daddr = msk->pm.remote;
>>>>>       add_addr = READ_ONCE(msk->pm.addr_signal);
>>>>>       if (mptcp_pm_should_add_signal_echo(msk))
>>>>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
>>>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>>>>> index 937e0309e340..4b63cc6079fa 100644
>>>>> --- a/net/mptcp/protocol.h
>>>>> +++ b/net/mptcp/protocol.h
>>>>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
>>>>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
>>>>>  }
>>>>>
>>>>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
>>>>> -                                           u8 add_addr)
>>>>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
>>>>>  {
>>>>> -     struct mptcp_addr_info *addr = &opts->remote;
>>>>> -     u8 len = 0;
>>>>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>
>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>>>> -             addr = &opts->local;
>>>>> +     if (family == AF_INET6)
>>>>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>> +     if (!echo)
>>>>>               len += MPTCPOPT_THMAC_LEN;
>>>>> -     }
>>>>> -
>>>>> -     if (addr->family == AF_INET6)
>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>> -     else
>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>> -
>>>>>       /* account for 2 trailing 'nop' options */
>>>>> -     if (addr->port)
>>>>> +     if (port)
>>>>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
>>>>>
>>>>>       return len;
>>>>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
>>>>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
>>>>>  }
>>>>>
>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>> -                           unsigned int opt_size, unsigned int remaining,
>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>>>> +                           bool *echo, bool *port);
>>>>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>                            struct mptcp_rm_list *rm_list);
>>>>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
>>>>>
>>>>
>>>> --
>>>> Li YongLong
>>>
>>
>> --
>> Li YongLong
> 
> 

-- 
Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  9:07           ` Geliang Tang
@ 2021-07-12  9:21             ` Yonglong Li
  0 siblings, 0 replies; 17+ messages in thread
From: Yonglong Li @ 2021-07-12  9:21 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp



On 2021/7/12 17:07, Geliang Tang wrote:
> Geliang Tang <geliangtang@gmail.com> 于2021年7月12日周一 下午4:44写道:
>>
>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
>>>
>>>
>>>
>>> On 2021/7/12 15:33, Geliang Tang wrote:
>>>> Hi Yonglong,
>>>>
>>>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
>>>>>
>>>>>
>>>>>
>>>>> On 2021/7/11 23:15, Geliang Tang wrote:
>>>>>> I think there're still some issues in v8:
>>>>>>
>>>>>> The remaining value is incorrect since "remaining += opt_size;" in the
>>>>>> "drop other suboptions" checks has been called twice in
>>>>>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
>>>>>>
>>>>> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
>>>>> mptcp_established_options_add_addr.
>>>>>
>>>>>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
>>>>>> populate after the length chech, not before the check.]
>>>>>>
>>>>>> The squash-to patch keeped the more orignal code unchanged, and just do
>>>>>> the least, necessary modifications.
>>>>>>
>>>>> Agree opts->local and opts->remote should be asigned after the length check.
>>>>> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
>>>>> as orignal code, there is a race that:
>>>>>
>>>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>>>>> ==> call mptcp_pm_add_addr_signal
>>>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
>>>>> ==> at this time opts->remote is empty and the length is incorrect.
>>>>>
>>>>
>>>> What will happen in v8 when this race occurs? How dose v8 deal with the
>>>> race?
>>> Hi Geliang, thinks for your patience.
>>>
>>> I think v8 doesn't have this issue:
>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>>> ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
>>> ==> use add_addr and opts to check length.
>>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
>>
>> Thanks for your explanation.
>>
>> I think this squash-to patch did the same thing:
>>
>> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>> ==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
>> 'echo' (echo = false), save the port number to 'port', and save addr
>> in opts under pm.lock
>> ==> an echo add addr event trigger (pm.addr_signal ==
>> MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
>> ==> use 'echo' to get the address family, use 'family', 'echo' and
>> 'port' to check length.
>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
>>
>> Do you think so?
> 
> And one more thing. How do you test this "mptcp: fix conflicts when using
> pm.add_signal in ADD_ADDR/echo and RM_ADDR process" series? Do you use our
> mptcp_join.sh to test it, or you did some special tests? Does this race
> scenario mentioned above easy to reproduce?
> 
> I just did the mptcp_join.sh tests for my squash-to patches, and everything
> looks fine. If you have some special tests, could you please help me to test
> these squash-to patches too? Hope it works in the race scenario.
> 
> Thanks.
> -Geliang
> 
OK. I will try to test the squash-to patches.
The race scenario is not easy to reproduce. :(
A loop script will try many times to reproduce.

> 
> 
>>
>>>
>>>>
>>>>> So I think the orignal code is incorrect. WDYT?
>>>>>
>>>>>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
>>>>>>
>>>>>> Change arguments of mptcp_pm_add_addr_signal.
>>>>>>
>>>>>> Keep mptcp_add_addr_len unchanged.
>>>>>>
>>>>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
>>>>>> ---
>>>>>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
>>>>>>  net/mptcp/pm.c       | 23 +++++++++--------------
>>>>>>  net/mptcp/protocol.h | 27 +++++++++------------------
>>>>>>  3 files changed, 35 insertions(+), 50 deletions(-)
>>>>>>
>>>>>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>>>>>> index 5c0ad9b90866..93ad7b134f74 100644
>>>>>> --- a/net/mptcp/options.c
>>>>>> +++ b/net/mptcp/options.c
>>>>>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
>>>>>>       bool drop_other_suboptions = false;
>>>>>>       unsigned int opt_size = *size;
>>>>>> -     u8 add_addr;
>>>>>> +     bool echo;
>>>>>> +     bool port;
>>>>>> +     u8 family;
>>>>>>       int len;
>>>>>>
>>>>>> -     if (!mptcp_pm_should_add_signal(msk) ||
>>>>>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
>>>>>> -             return false;
>>>>>> -
>>>>>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>>>>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>>>>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
>>>>>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
>>>>>> +          (mptcp_pm_should_add_signal_addr(msk) &&
>>>>>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>>>>           skb && skb_is_tcp_pure_ack(skb)) {
>>>>>>               pr_debug("drop other suboptions");
>>>>>>               opts->suboptions = 0;
>>>>>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>>               drop_other_suboptions = true;
>>>>>>       }
>>>>>>
>>>>>> -     len = mptcp_add_addr_len(opts, add_addr);
>>>>>> +     if (!mptcp_pm_should_add_signal(msk) ||
>>>>>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
>>>>>> +             return false;
>>>>>> +
>>>>>> +     family = echo ? opts->remote.family : opts->local.family;
>>>>>> +     len = mptcp_add_addr_len(family, echo, port);
>>>>>>       if (remaining < len)
>>>>>>               return false;
>>>>>>
>>>>>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>>       if (drop_other_suboptions)
>>>>>>               *size -= opt_size;
>>>>>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
>>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>>>>> +     if (!echo) {
>>>>>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
>>>>>>                                                    msk->remote_key,
>>>>>>                                                    &opts->local);
>>>>>>       }
>>>>>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
>>>>>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
>>>>>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
>>>>>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
>>>>>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
>>>>>> +              ntohs(opts->remote.port), opts->ahmac, echo);
>>>>>>
>>>>>>       return true;
>>>>>>  }
>>>>>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>>>>>
>>>>>>  mp_capable_done:
>>>>>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
>>>>>> -             struct mptcp_addr_info *addr = &opts->remote;
>>>>>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
>>>>>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>>               u8 echo = MPTCP_ADDR_ECHO;
>>>>>>
>>>>>> -             if (opts->ahmac)
>>>>>> -                     addr = &opts->local;
>>>>>> -
>>>>>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
>>>>>>               if (addr->family == AF_INET6)
>>>>>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
>>>>>> index 264f522af530..399b59cb7563 100644
>>>>>> --- a/net/mptcp/pm.c
>>>>>> +++ b/net/mptcp/pm.c
>>>>>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
>>>>>>
>>>>>>  /* path manager helpers */
>>>>>>
>>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>> -                           unsigned int opt_size, unsigned int remaining,
>>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
>>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>>>>> +                           bool *echo, bool *port)
>>>>>>  {
>>>>>>       int ret = false;
>>>>>>       u8 add_addr;
>>>>>> +     u8 family;
>>>>>>
>>>>>>       spin_lock_bh(&msk->pm.lock);
>>>>>>
>>>>>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>>       if (!mptcp_pm_should_add_signal(msk))
>>>>>>               goto out_unlock;
>>>>>>
>>>>>> -     opts->local = msk->pm.local;
>>>>>> -     opts->remote = msk->pm.remote;
>>>>>> -     *add_addr = msk->pm.addr_signal;
>>>>>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
>>>>>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
>>>>>>
>>>>>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>>>>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>>>>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>>>> -         skb && skb_is_tcp_pure_ack(skb)) {
>>>>>> -             remaining += opt_size;
>>>>>> -     }
>>>>>> -
>>>>>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
>>>>>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
>>>>>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
>>>>>>               goto out_unlock;
>>>>>>
>>>>>>       *saddr = msk->pm.local;
>>>>>> +     *daddr = msk->pm.remote;
>>>>>>       add_addr = READ_ONCE(msk->pm.addr_signal);
>>>>>>       if (mptcp_pm_should_add_signal_echo(msk))
>>>>>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
>>>>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>>>>>> index 937e0309e340..4b63cc6079fa 100644
>>>>>> --- a/net/mptcp/protocol.h
>>>>>> +++ b/net/mptcp/protocol.h
>>>>>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
>>>>>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
>>>>>>  }
>>>>>>
>>>>>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
>>>>>> -                                           u8 add_addr)
>>>>>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
>>>>>>  {
>>>>>> -     struct mptcp_addr_info *addr = &opts->remote;
>>>>>> -     u8 len = 0;
>>>>>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>>
>>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>>>>> -             addr = &opts->local;
>>>>>> +     if (family == AF_INET6)
>>>>>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>>> +     if (!echo)
>>>>>>               len += MPTCPOPT_THMAC_LEN;
>>>>>> -     }
>>>>>> -
>>>>>> -     if (addr->family == AF_INET6)
>>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>>> -     else
>>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>> -
>>>>>>       /* account for 2 trailing 'nop' options */
>>>>>> -     if (addr->port)
>>>>>> +     if (port)
>>>>>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
>>>>>>
>>>>>>       return len;
>>>>>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
>>>>>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
>>>>>>  }
>>>>>>
>>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>> -                           unsigned int opt_size, unsigned int remaining,
>>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
>>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>>>>> +                           bool *echo, bool *port);
>>>>>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>>                            struct mptcp_rm_list *rm_list);
>>>>>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
>>>>>>
>>>>>
>>>>> --
>>>>> Li YongLong
>>>>
>>>
>>> --
>>> Li YongLong
> 

-- 
Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  9:14           ` Yonglong Li
@ 2021-07-12  9:29             ` Geliang Tang
  2021-07-12  9:44               ` Yonglong Li
  0 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2021-07-12  9:29 UTC (permalink / raw)
  To: Yonglong Li; +Cc: mptcp

Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午5:14写道:
>
>
>
> On 2021/7/12 16:44, Geliang Tang wrote:
> > Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
> >>
> >>
> >>
> >> On 2021/7/12 15:33, Geliang Tang wrote:
> >>> Hi Yonglong,
> >>>
> >>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
> >>>>
> >>>>
> >>>>
> >>>> On 2021/7/11 23:15, Geliang Tang wrote:
> >>>>> I think there're still some issues in v8:
> >>>>>
> >>>>> The remaining value is incorrect since "remaining += opt_size;" in the
> >>>>> "drop other suboptions" checks has been called twice in
> >>>>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
> >>>>>
> >>>> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
> >>>> mptcp_established_options_add_addr.
> >>>>
> >>>>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
> >>>>> populate after the length chech, not before the check.]
> >>>>>
> >>>>> The squash-to patch keeped the more orignal code unchanged, and just do
> >>>>> the least, necessary modifications.
> >>>>>
> >>>> Agree opts->local and opts->remote should be asigned after the length check.
> >>>> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
> >>>> as orignal code, there is a race that:
> >>>>
> >>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >>>> ==> call mptcp_pm_add_addr_signal
> >>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
> >>>> ==> at this time opts->remote is empty and the length is incorrect.
> >>>>
> >>>
> >>> What will happen in v8 when this race occurs? How dose v8 deal with the
> >>> race?
> >> Hi Geliang, thinks for your patience.
> >>
> >> I think v8 doesn't have this issue:
> >> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >> ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
> >> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
> >> ==> use add_addr and opts to check length.
> >> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
> >
> > Thanks for your explanation.
> >
> > I think this squash-to patch did the same thing:
> >
> > ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> > ==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
> > 'echo' (echo = false), save the port number to 'port', and save addr
> > in opts under pm.lock
> > ==> an echo add addr event trigger (pm.addr_signal ==
> > MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
> > ==> use 'echo' to get the address family, use 'family', 'echo' and
> > 'port' to check length.
> > ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
> >
> > Do you think so?
> yep. In this case the squash-to patch is ok. But I think between "drop other suboptions" checks and
> mptcp_pm_add_addr_signal the race still exist.
>

I think this is easy to fix:

Add a new argument "drop_other_suboptions" for mptcp_pm_add_addr_signal,
move this "drop other suboptions" check code into mptcp_pm_add_addr_signal,
I'll sent a v2 later.

Thanks,
-Geliang

> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> ==> "drop other suboptions" checks will use MPTCP_ADD_ADDR_SIGNAL to check
> ==> an echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL | MPTCP_ADD_ADDR_ECHO )
> ==> call mptcp_pm_add_addr_signal, MPTCP_ADD_ADDR_ECHO will be clear in pm.addr_signal
> ==> process MPTCP_ADD_ADDR_ECHO event.
>
> WDYT?
>
> >
> >>
> >>>
> >>>> So I think the orignal code is incorrect. WDYT?
> >>>>
> >>>>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
> >>>>>
> >>>>> Change arguments of mptcp_pm_add_addr_signal.
> >>>>>
> >>>>> Keep mptcp_add_addr_len unchanged.
> >>>>>
> >>>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> >>>>> ---
> >>>>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
> >>>>>  net/mptcp/pm.c       | 23 +++++++++--------------
> >>>>>  net/mptcp/protocol.h | 27 +++++++++------------------
> >>>>>  3 files changed, 35 insertions(+), 50 deletions(-)
> >>>>>
> >>>>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> >>>>> index 5c0ad9b90866..93ad7b134f74 100644
> >>>>> --- a/net/mptcp/options.c
> >>>>> +++ b/net/mptcp/options.c
> >>>>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> >>>>>       bool drop_other_suboptions = false;
> >>>>>       unsigned int opt_size = *size;
> >>>>> -     u8 add_addr;
> >>>>> +     bool echo;
> >>>>> +     bool port;
> >>>>> +     u8 family;
> >>>>>       int len;
> >>>>>
> >>>>> -     if (!mptcp_pm_should_add_signal(msk) ||
> >>>>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
> >>>>> -             return false;
> >>>>> -
> >>>>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> >>>>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> >>>>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
> >>>>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
> >>>>> +          (mptcp_pm_should_add_signal_addr(msk) &&
> >>>>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >>>>>           skb && skb_is_tcp_pure_ack(skb)) {
> >>>>>               pr_debug("drop other suboptions");
> >>>>>               opts->suboptions = 0;
> >>>>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>>>               drop_other_suboptions = true;
> >>>>>       }
> >>>>>
> >>>>> -     len = mptcp_add_addr_len(opts, add_addr);
> >>>>> +     if (!mptcp_pm_should_add_signal(msk) ||
> >>>>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
> >>>>> +             return false;
> >>>>> +
> >>>>> +     family = echo ? opts->remote.family : opts->local.family;
> >>>>> +     len = mptcp_add_addr_len(family, echo, port);
> >>>>>       if (remaining < len)
> >>>>>               return false;
> >>>>>
> >>>>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>>>       if (drop_other_suboptions)
> >>>>>               *size -= opt_size;
> >>>>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
> >>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> >>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> >>>>> +     if (!echo) {
> >>>>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
> >>>>>                                                    msk->remote_key,
> >>>>>                                                    &opts->local);
> >>>>>       }
> >>>>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
> >>>>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
> >>>>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
> >>>>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
> >>>>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
> >>>>> +              ntohs(opts->remote.port), opts->ahmac, echo);
> >>>>>
> >>>>>       return true;
> >>>>>  }
> >>>>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
> >>>>>
> >>>>>  mp_capable_done:
> >>>>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
> >>>>> -             struct mptcp_addr_info *addr = &opts->remote;
> >>>>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
> >>>>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>>>               u8 echo = MPTCP_ADDR_ECHO;
> >>>>>
> >>>>> -             if (opts->ahmac)
> >>>>> -                     addr = &opts->local;
> >>>>> -
> >>>>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> >>>>>               if (addr->family == AF_INET6)
> >>>>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> >>>>> index 264f522af530..399b59cb7563 100644
> >>>>> --- a/net/mptcp/pm.c
> >>>>> +++ b/net/mptcp/pm.c
> >>>>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
> >>>>>
> >>>>>  /* path manager helpers */
> >>>>>
> >>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>>> -                           unsigned int opt_size, unsigned int remaining,
> >>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
> >>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> >>>>> +                           bool *echo, bool *port)
> >>>>>  {
> >>>>>       int ret = false;
> >>>>>       u8 add_addr;
> >>>>> +     u8 family;
> >>>>>
> >>>>>       spin_lock_bh(&msk->pm.lock);
> >>>>>
> >>>>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>>>       if (!mptcp_pm_should_add_signal(msk))
> >>>>>               goto out_unlock;
> >>>>>
> >>>>> -     opts->local = msk->pm.local;
> >>>>> -     opts->remote = msk->pm.remote;
> >>>>> -     *add_addr = msk->pm.addr_signal;
> >>>>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
> >>>>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
> >>>>>
> >>>>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> >>>>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> >>>>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >>>>> -         skb && skb_is_tcp_pure_ack(skb)) {
> >>>>> -             remaining += opt_size;
> >>>>> -     }
> >>>>> -
> >>>>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
> >>>>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
> >>>>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
> >>>>>               goto out_unlock;
> >>>>>
> >>>>>       *saddr = msk->pm.local;
> >>>>> +     *daddr = msk->pm.remote;
> >>>>>       add_addr = READ_ONCE(msk->pm.addr_signal);
> >>>>>       if (mptcp_pm_should_add_signal_echo(msk))
> >>>>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> >>>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> >>>>> index 937e0309e340..4b63cc6079fa 100644
> >>>>> --- a/net/mptcp/protocol.h
> >>>>> +++ b/net/mptcp/protocol.h
> >>>>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
> >>>>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
> >>>>>  }
> >>>>>
> >>>>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
> >>>>> -                                           u8 add_addr)
> >>>>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
> >>>>>  {
> >>>>> -     struct mptcp_addr_info *addr = &opts->remote;
> >>>>> -     u8 len = 0;
> >>>>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>>>
> >>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> >>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> >>>>> -             addr = &opts->local;
> >>>>> +     if (family == AF_INET6)
> >>>>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>>>> +     if (!echo)
> >>>>>               len += MPTCPOPT_THMAC_LEN;
> >>>>> -     }
> >>>>> -
> >>>>> -     if (addr->family == AF_INET6)
> >>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>>>> -     else
> >>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>>> -
> >>>>>       /* account for 2 trailing 'nop' options */
> >>>>> -     if (addr->port)
> >>>>> +     if (port)
> >>>>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
> >>>>>
> >>>>>       return len;
> >>>>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
> >>>>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
> >>>>>  }
> >>>>>
> >>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>>> -                           unsigned int opt_size, unsigned int remaining,
> >>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
> >>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> >>>>> +                           bool *echo, bool *port);
> >>>>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>>>                            struct mptcp_rm_list *rm_list);
> >>>>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> >>>>>
> >>>>
> >>>> --
> >>>> Li YongLong
> >>>
> >>
> >> --
> >> Li YongLong
> >
> >
>
> --
> Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  9:29             ` Geliang Tang
@ 2021-07-12  9:44               ` Yonglong Li
  2021-07-12 10:34                 ` Geliang Tang
  0 siblings, 1 reply; 17+ messages in thread
From: Yonglong Li @ 2021-07-12  9:44 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp



On 2021/7/12 17:29, Geliang Tang wrote:
> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午5:14写道:
>>
>>
>>
>> On 2021/7/12 16:44, Geliang Tang wrote:
>>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
>>>>
>>>>
>>>>
>>>> On 2021/7/12 15:33, Geliang Tang wrote:
>>>>> Hi Yonglong,
>>>>>
>>>>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2021/7/11 23:15, Geliang Tang wrote:
>>>>>>> I think there're still some issues in v8:
>>>>>>>
>>>>>>> The remaining value is incorrect since "remaining += opt_size;" in the
>>>>>>> "drop other suboptions" checks has been called twice in
>>>>>>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
>>>>>>>
>>>>>> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
>>>>>> mptcp_established_options_add_addr.
>>>>>>
>>>>>>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
>>>>>>> populate after the length chech, not before the check.]
>>>>>>>
>>>>>>> The squash-to patch keeped the more orignal code unchanged, and just do
>>>>>>> the least, necessary modifications.
>>>>>>>
>>>>>> Agree opts->local and opts->remote should be asigned after the length check.
>>>>>> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
>>>>>> as orignal code, there is a race that:
>>>>>>
>>>>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>>>>>> ==> call mptcp_pm_add_addr_signal
>>>>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
>>>>>> ==> at this time opts->remote is empty and the length is incorrect.
>>>>>>
>>>>>
>>>>> What will happen in v8 when this race occurs? How dose v8 deal with the
>>>>> race?
>>>> Hi Geliang, thinks for your patience.
>>>>
>>>> I think v8 doesn't have this issue:
>>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>>>> ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
>>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
>>>> ==> use add_addr and opts to check length.
>>>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
>>>
>>> Thanks for your explanation.
>>>
>>> I think this squash-to patch did the same thing:
>>>
>>> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>>> ==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
>>> 'echo' (echo = false), save the port number to 'port', and save addr
>>> in opts under pm.lock
>>> ==> an echo add addr event trigger (pm.addr_signal ==
>>> MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
>>> ==> use 'echo' to get the address family, use 'family', 'echo' and
>>> 'port' to check length.
>>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
>>>
>>> Do you think so?
>> yep. In this case the squash-to patch is ok. But I think between "drop other suboptions" checks and
>> mptcp_pm_add_addr_signal the race still exist.
>>
> 
> I think this is easy to fix:
> 
> Add a new argument "drop_other_suboptions" for mptcp_pm_add_addr_signal,
> move this "drop other suboptions" check code into mptcp_pm_add_addr_signal,
> I'll sent a v2 later.

Thanks. And the v8 do the same thing. Why not use v8 directly :)

> 
> Thanks,
> -Geliang
> 
>> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
>> ==> "drop other suboptions" checks will use MPTCP_ADD_ADDR_SIGNAL to check
>> ==> an echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL | MPTCP_ADD_ADDR_ECHO )
>> ==> call mptcp_pm_add_addr_signal, MPTCP_ADD_ADDR_ECHO will be clear in pm.addr_signal
>> ==> process MPTCP_ADD_ADDR_ECHO event.
>>
>> WDYT?
>>
>>>
>>>>
>>>>>
>>>>>> So I think the orignal code is incorrect. WDYT?
>>>>>>
>>>>>>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
>>>>>>>
>>>>>>> Change arguments of mptcp_pm_add_addr_signal.
>>>>>>>
>>>>>>> Keep mptcp_add_addr_len unchanged.
>>>>>>>
>>>>>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
>>>>>>> ---
>>>>>>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
>>>>>>>  net/mptcp/pm.c       | 23 +++++++++--------------
>>>>>>>  net/mptcp/protocol.h | 27 +++++++++------------------
>>>>>>>  3 files changed, 35 insertions(+), 50 deletions(-)
>>>>>>>
>>>>>>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>>>>>>> index 5c0ad9b90866..93ad7b134f74 100644
>>>>>>> --- a/net/mptcp/options.c
>>>>>>> +++ b/net/mptcp/options.c
>>>>>>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
>>>>>>>       bool drop_other_suboptions = false;
>>>>>>>       unsigned int opt_size = *size;
>>>>>>> -     u8 add_addr;
>>>>>>> +     bool echo;
>>>>>>> +     bool port;
>>>>>>> +     u8 family;
>>>>>>>       int len;
>>>>>>>
>>>>>>> -     if (!mptcp_pm_should_add_signal(msk) ||
>>>>>>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
>>>>>>> -             return false;
>>>>>>> -
>>>>>>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>>>>>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>>>>>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
>>>>>>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
>>>>>>> +          (mptcp_pm_should_add_signal_addr(msk) &&
>>>>>>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>>>>>           skb && skb_is_tcp_pure_ack(skb)) {
>>>>>>>               pr_debug("drop other suboptions");
>>>>>>>               opts->suboptions = 0;
>>>>>>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>>>               drop_other_suboptions = true;
>>>>>>>       }
>>>>>>>
>>>>>>> -     len = mptcp_add_addr_len(opts, add_addr);
>>>>>>> +     if (!mptcp_pm_should_add_signal(msk) ||
>>>>>>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
>>>>>>> +             return false;
>>>>>>> +
>>>>>>> +     family = echo ? opts->remote.family : opts->local.family;
>>>>>>> +     len = mptcp_add_addr_len(family, echo, port);
>>>>>>>       if (remaining < len)
>>>>>>>               return false;
>>>>>>>
>>>>>>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
>>>>>>>       if (drop_other_suboptions)
>>>>>>>               *size -= opt_size;
>>>>>>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
>>>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>>>>>> +     if (!echo) {
>>>>>>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
>>>>>>>                                                    msk->remote_key,
>>>>>>>                                                    &opts->local);
>>>>>>>       }
>>>>>>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
>>>>>>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
>>>>>>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
>>>>>>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
>>>>>>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
>>>>>>> +              ntohs(opts->remote.port), opts->ahmac, echo);
>>>>>>>
>>>>>>>       return true;
>>>>>>>  }
>>>>>>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>>>>>>
>>>>>>>  mp_capable_done:
>>>>>>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
>>>>>>> -             struct mptcp_addr_info *addr = &opts->remote;
>>>>>>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
>>>>>>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>>>               u8 echo = MPTCP_ADDR_ECHO;
>>>>>>>
>>>>>>> -             if (opts->ahmac)
>>>>>>> -                     addr = &opts->local;
>>>>>>> -
>>>>>>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
>>>>>>>               if (addr->family == AF_INET6)
>>>>>>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
>>>>>>> index 264f522af530..399b59cb7563 100644
>>>>>>> --- a/net/mptcp/pm.c
>>>>>>> +++ b/net/mptcp/pm.c
>>>>>>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
>>>>>>>
>>>>>>>  /* path manager helpers */
>>>>>>>
>>>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>>> -                           unsigned int opt_size, unsigned int remaining,
>>>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
>>>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>>>>>> +                           bool *echo, bool *port)
>>>>>>>  {
>>>>>>>       int ret = false;
>>>>>>>       u8 add_addr;
>>>>>>> +     u8 family;
>>>>>>>
>>>>>>>       spin_lock_bh(&msk->pm.lock);
>>>>>>>
>>>>>>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>>>       if (!mptcp_pm_should_add_signal(msk))
>>>>>>>               goto out_unlock;
>>>>>>>
>>>>>>> -     opts->local = msk->pm.local;
>>>>>>> -     opts->remote = msk->pm.remote;
>>>>>>> -     *add_addr = msk->pm.addr_signal;
>>>>>>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
>>>>>>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
>>>>>>>
>>>>>>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
>>>>>>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
>>>>>>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
>>>>>>> -         skb && skb_is_tcp_pure_ack(skb)) {
>>>>>>> -             remaining += opt_size;
>>>>>>> -     }
>>>>>>> -
>>>>>>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
>>>>>>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
>>>>>>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
>>>>>>>               goto out_unlock;
>>>>>>>
>>>>>>>       *saddr = msk->pm.local;
>>>>>>> +     *daddr = msk->pm.remote;
>>>>>>>       add_addr = READ_ONCE(msk->pm.addr_signal);
>>>>>>>       if (mptcp_pm_should_add_signal_echo(msk))
>>>>>>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
>>>>>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>>>>>>> index 937e0309e340..4b63cc6079fa 100644
>>>>>>> --- a/net/mptcp/protocol.h
>>>>>>> +++ b/net/mptcp/protocol.h
>>>>>>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
>>>>>>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
>>>>>>>  }
>>>>>>>
>>>>>>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
>>>>>>> -                                           u8 add_addr)
>>>>>>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
>>>>>>>  {
>>>>>>> -     struct mptcp_addr_info *addr = &opts->remote;
>>>>>>> -     u8 len = 0;
>>>>>>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>>>
>>>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
>>>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
>>>>>>> -             addr = &opts->local;
>>>>>>> +     if (family == AF_INET6)
>>>>>>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>>>> +     if (!echo)
>>>>>>>               len += MPTCPOPT_THMAC_LEN;
>>>>>>> -     }
>>>>>>> -
>>>>>>> -     if (addr->family == AF_INET6)
>>>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
>>>>>>> -     else
>>>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
>>>>>>> -
>>>>>>>       /* account for 2 trailing 'nop' options */
>>>>>>> -     if (addr->port)
>>>>>>> +     if (port)
>>>>>>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
>>>>>>>
>>>>>>>       return len;
>>>>>>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
>>>>>>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
>>>>>>>  }
>>>>>>>
>>>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
>>>>>>> -                           unsigned int opt_size, unsigned int remaining,
>>>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
>>>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
>>>>>>> +                           bool *echo, bool *port);
>>>>>>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>>>>>                            struct mptcp_rm_list *rm_list);
>>>>>>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> Li YongLong
>>>>>
>>>>
>>>> --
>>>> Li YongLong
>>>
>>>
>>
>> --
>> Li YongLong
> 

-- 
Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other"
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other" Geliang Tang
@ 2021-07-12  9:55   ` Yonglong Li
  2021-07-12 10:34     ` Geliang Tang
  0 siblings, 1 reply; 17+ messages in thread
From: Yonglong Li @ 2021-07-12  9:55 UTC (permalink / raw)
  To: Geliang Tang, mptcp, Paolo Abeni



On 2021/7/11 23:15, Geliang Tang wrote:
> Add READ_ONCE() for reading msk->pm.addr_signal.
> 
> Use mptcp_pm_should_add_signal_echo instead of open coding.
> 
> Use '&=' to clear flag.
> 
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
>  net/mptcp/pm.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index c9622696716e..be16da2dcb6b 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -257,6 +257,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>  			      struct mptcp_addr_info *saddr, bool *echo, bool *port)
>  {
>  	int ret = false;
> +	u8 add_addr;
>  
>  	spin_lock_bh(&msk->pm.lock);
>  
> @@ -271,10 +272,12 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>  		goto out_unlock;
>  
>  	*saddr = msk->pm.local;
> -	if ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)))
> -		WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO));
> +	add_addr = READ_ONCE(msk->pm.addr_signal);
> +	if (mptcp_pm_should_add_signal_echo(msk))
> +		add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
>  	else
> -		WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL));
> +		add_addr &= ~BIT(MPTCP_ADD_ADDR_SIGNAL);
> +	WRITE_ONCE(msk->pm.addr_signal, add_addr);
>  	ret = true;
>  
>  out_unlock:
> @@ -294,7 +297,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>  	if (!mptcp_pm_should_rm_signal(msk))
>  		goto out_unlock;
>  
> -	rm_addr = msk->pm.addr_signal & ~BIT(MPTCP_RM_ADDR_SIGNAL);
> +	rm_addr = READ_ONCE(msk->pm.addr_signal);
> +	rm_addr &= ~BIT(MPTCP_RM_ADDR_SIGNAL);
>  	len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
>  	if (len < 0) {
>  		WRITE_ONCE(msk->pm.addr_signal, rm_addr);
> 

These chunk of code is under the pm.lock so It is no need to use READ_ONCE() as Paolo saied before.

-- 
Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal"
  2021-07-12  9:44               ` Yonglong Li
@ 2021-07-12 10:34                 ` Geliang Tang
  0 siblings, 0 replies; 17+ messages in thread
From: Geliang Tang @ 2021-07-12 10:34 UTC (permalink / raw)
  To: Yonglong Li; +Cc: mptcp

Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午5:44写道:
>
>
>
> On 2021/7/12 17:29, Geliang Tang wrote:
> > Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午5:14写道:
> >>
> >>
> >>
> >> On 2021/7/12 16:44, Geliang Tang wrote:
> >>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午4:07写道:
> >>>>
> >>>>
> >>>>
> >>>> On 2021/7/12 15:33, Geliang Tang wrote:
> >>>>> Hi Yonglong,
> >>>>>
> >>>>> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 上午9:34写道:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 2021/7/11 23:15, Geliang Tang wrote:
> >>>>>>> I think there're still some issues in v8:
> >>>>>>>
> >>>>>>> The remaining value is incorrect since "remaining += opt_size;" in the
> >>>>>>> "drop other suboptions" checks has been called twice in
> >>>>>>> mptcp_pm_add_addr_signal and mptcp_established_options_add_addr.
> >>>>>>>
> >>>>>> I think "remaining" in mptcp_pm_add_addr_signal does not touch "remaining" in
> >>>>>> mptcp_established_options_add_addr.
> >>>>>>
> >>>>>>> opts->local and opts->remote in mptcp_pm_add_addr_signal need be
> >>>>>>> populate after the length chech, not before the check.]
> >>>>>>>
> >>>>>>> The squash-to patch keeped the more orignal code unchanged, and just do
> >>>>>>> the least, necessary modifications.
> >>>>>>>
> >>>>>> Agree opts->local and opts->remote should be asigned after the length check.
> >>>>>> But if keep the length check out of mptcp_pm_add_addr_signal (out of pm lock )
> >>>>>> as orignal code, there is a race that:
> >>>>>>
> >>>>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >>>>>> ==> call mptcp_pm_add_addr_signal
> >>>>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO|MPTCP_ADD_ADDR_SIGNAL)
> >>>>>> ==> at this time opts->remote is empty and the length is incorrect.
> >>>>>>
> >>>>>
> >>>>> What will happen in v8 when this race occurs? How dose v8 deal with the
> >>>>> race?
> >>>> Hi Geliang, thinks for your patience.
> >>>>
> >>>> I think v8 doesn't have this issue:
> >>>> ==> a add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >>>> ==> call mptcp_pm_add_addr_signal, save pm.addr_signal to add_addr and save addr in opts under pm.lock
> >>>> ==> a echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_ECHO), but add_addr doesn't changed.
> >>>> ==> use add_addr and opts to check length.
> >>>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
> >>>
> >>> Thanks for your explanation.
> >>>
> >>> I think this squash-to patch did the same thing:
> >>>
> >>> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >>> ==> call mptcp_pm_add_addr_signal, save echo bit of pm.addr_signal to
> >>> 'echo' (echo = false), save the port number to 'port', and save addr
> >>> in opts under pm.lock
> >>> ==> an echo add addr event trigger (pm.addr_signal ==
> >>> MPTCP_ADD_ADDR_ECHO), but 'echo' and 'port' don't changed.
> >>> ==> use 'echo' to get the address family, use 'family', 'echo' and
> >>> 'port' to check length.
> >>> ==> next send ack process will deal with MPTCP_ADD_ADDR_ECHO event.
> >>>
> >>> Do you think so?
> >> yep. In this case the squash-to patch is ok. But I think between "drop other suboptions" checks and
> >> mptcp_pm_add_addr_signal the race still exist.
> >>
> >
> > I think this is easy to fix:
> >
> > Add a new argument "drop_other_suboptions" for mptcp_pm_add_addr_signal,
> > move this "drop other suboptions" check code into mptcp_pm_add_addr_signal,
> > I'll sent a v2 later.
>
> Thanks. And the v8 do the same thing. Why not use v8 directly :)
>

You'll see the difference later. :)

> >
> > Thanks,
> > -Geliang
> >
> >> ==> an add addr event (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL)
> >> ==> "drop other suboptions" checks will use MPTCP_ADD_ADDR_SIGNAL to check
> >> ==> an echo add addr event trigger (pm.addr_signal == MPTCP_ADD_ADDR_SIGNAL | MPTCP_ADD_ADDR_ECHO )
> >> ==> call mptcp_pm_add_addr_signal, MPTCP_ADD_ADDR_ECHO will be clear in pm.addr_signal
> >> ==> process MPTCP_ADD_ADDR_ECHO event.
> >>
> >> WDYT?
> >>
> >>>
> >>>>
> >>>>>
> >>>>>> So I think the orignal code is incorrect. WDYT?
> >>>>>>
> >>>>>>> Drop the "drop other suboptions" check in mptcp_pm_add_addr_signal.
> >>>>>>>
> >>>>>>> Change arguments of mptcp_pm_add_addr_signal.
> >>>>>>>
> >>>>>>> Keep mptcp_add_addr_len unchanged.
> >>>>>>>
> >>>>>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> >>>>>>> ---
> >>>>>>>  net/mptcp/options.c  | 35 +++++++++++++++++------------------
> >>>>>>>  net/mptcp/pm.c       | 23 +++++++++--------------
> >>>>>>>  net/mptcp/protocol.h | 27 +++++++++------------------
> >>>>>>>  3 files changed, 35 insertions(+), 50 deletions(-)
> >>>>>>>
> >>>>>>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> >>>>>>> index 5c0ad9b90866..93ad7b134f74 100644
> >>>>>>> --- a/net/mptcp/options.c
> >>>>>>> +++ b/net/mptcp/options.c
> >>>>>>> @@ -663,16 +663,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>>>>>       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> >>>>>>>       bool drop_other_suboptions = false;
> >>>>>>>       unsigned int opt_size = *size;
> >>>>>>> -     u8 add_addr;
> >>>>>>> +     bool echo;
> >>>>>>> +     bool port;
> >>>>>>> +     u8 family;
> >>>>>>>       int len;
> >>>>>>>
> >>>>>>> -     if (!mptcp_pm_should_add_signal(msk) ||
> >>>>>>> -         !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, opts, &add_addr))
> >>>>>>> -             return false;
> >>>>>>> -
> >>>>>>> -     if (((add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> >>>>>>> -          ((add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> >>>>>>> -           (opts->local.family == AF_INET6 || opts->local.port))) &&
> >>>>>>> +     if ((mptcp_pm_should_add_signal_echo(msk) ||
> >>>>>>> +          (mptcp_pm_should_add_signal_addr(msk) &&
> >>>>>>> +           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >>>>>>>           skb && skb_is_tcp_pure_ack(skb)) {
> >>>>>>>               pr_debug("drop other suboptions");
> >>>>>>>               opts->suboptions = 0;
> >>>>>>> @@ -682,7 +680,12 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>>>>>               drop_other_suboptions = true;
> >>>>>>>       }
> >>>>>>>
> >>>>>>> -     len = mptcp_add_addr_len(opts, add_addr);
> >>>>>>> +     if (!mptcp_pm_should_add_signal(msk) ||
> >>>>>>> +         !mptcp_pm_add_addr_signal(msk, remaining, &opts->local, &opts->remote, &echo, &port))
> >>>>>>> +             return false;
> >>>>>>> +
> >>>>>>> +     family = echo ? opts->remote.family : opts->local.family;
> >>>>>>> +     len = mptcp_add_addr_len(family, echo, port);
> >>>>>>>       if (remaining < len)
> >>>>>>>               return false;
> >>>>>>>
> >>>>>>> @@ -690,15 +693,14 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff *
> >>>>>>>       if (drop_other_suboptions)
> >>>>>>>               *size -= opt_size;
> >>>>>>>       opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
> >>>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> >>>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> >>>>>>> +     if (!echo) {
> >>>>>>>               opts->ahmac = add_addr_generate_hmac(msk->local_key,
> >>>>>>>                                                    msk->remote_key,
> >>>>>>>                                                    &opts->local);
> >>>>>>>       }
> >>>>>>> -     pr_debug("addr_signal:%x, echo=%d, local_addr_id=%d, ahmac=%llu, local_port=%d, remote_addr_id=%d, remote_port=%d",
> >>>>>>> -              add_addr, (opts->ahmac == 0), opts->local.id, opts->ahmac,
> >>>>>>> -              ntohs(opts->local.port), opts->remote.id, ntohs(opts->remote.port));
> >>>>>>> +     pr_debug("local_id=%d, local_port=%d, remote_id=%d, remote_port=%d, ahmac=%llu, echo=%d",
> >>>>>>> +              opts->local.id, ntohs(opts->local.port), opts->remote.id,
> >>>>>>> +              ntohs(opts->remote.port), opts->ahmac, echo);
> >>>>>>>
> >>>>>>>       return true;
> >>>>>>>  }
> >>>>>>> @@ -1253,13 +1255,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
> >>>>>>>
> >>>>>>>  mp_capable_done:
> >>>>>>>       if (OPTION_MPTCP_ADD_ADDR & opts->suboptions) {
> >>>>>>> -             struct mptcp_addr_info *addr = &opts->remote;
> >>>>>>> +             struct mptcp_addr_info *addr = opts->ahmac ? &opts->local : &opts->remote;
> >>>>>>>               u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>>>>>               u8 echo = MPTCP_ADDR_ECHO;
> >>>>>>>
> >>>>>>> -             if (opts->ahmac)
> >>>>>>> -                     addr = &opts->local;
> >>>>>>> -
> >>>>>>>  #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> >>>>>>>               if (addr->family == AF_INET6)
> >>>>>>>                       len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>>>>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> >>>>>>> index 264f522af530..399b59cb7563 100644
> >>>>>>> --- a/net/mptcp/pm.c
> >>>>>>> +++ b/net/mptcp/pm.c
> >>>>>>> @@ -253,12 +253,13 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
> >>>>>>>
> >>>>>>>  /* path manager helpers */
> >>>>>>>
> >>>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>>>>> -                           unsigned int opt_size, unsigned int remaining,
> >>>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr)
> >>>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> >>>>>>> +                           bool *echo, bool *port)
> >>>>>>>  {
> >>>>>>>       int ret = false;
> >>>>>>>       u8 add_addr;
> >>>>>>> +     u8 family;
> >>>>>>>
> >>>>>>>       spin_lock_bh(&msk->pm.lock);
> >>>>>>>
> >>>>>>> @@ -266,21 +267,15 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>>>>>       if (!mptcp_pm_should_add_signal(msk))
> >>>>>>>               goto out_unlock;
> >>>>>>>
> >>>>>>> -     opts->local = msk->pm.local;
> >>>>>>> -     opts->remote = msk->pm.remote;
> >>>>>>> -     *add_addr = msk->pm.addr_signal;
> >>>>>>> +     *echo = mptcp_pm_should_add_signal_echo(msk);
> >>>>>>> +     *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
> >>>>>>>
> >>>>>>> -     if (((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)) ||
> >>>>>>> -          ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) &&
> >>>>>>> -           (msk->pm.local.family == AF_INET6 || msk->pm.local.port))) &&
> >>>>>>> -         skb && skb_is_tcp_pure_ack(skb)) {
> >>>>>>> -             remaining += opt_size;
> >>>>>>> -     }
> >>>>>>> -
> >>>>>>> -     if (remaining < mptcp_add_addr_len(opts, *add_addr))
> >>>>>>> +     family = *echo ? msk->pm.remote.family : msk->pm.local.family;
> >>>>>>> +     if (remaining < mptcp_add_addr_len(family, *echo, *port))
> >>>>>>>               goto out_unlock;
> >>>>>>>
> >>>>>>>       *saddr = msk->pm.local;
> >>>>>>> +     *daddr = msk->pm.remote;
> >>>>>>>       add_addr = READ_ONCE(msk->pm.addr_signal);
> >>>>>>>       if (mptcp_pm_should_add_signal_echo(msk))
> >>>>>>>               add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> >>>>>>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> >>>>>>> index 937e0309e340..4b63cc6079fa 100644
> >>>>>>> --- a/net/mptcp/protocol.h
> >>>>>>> +++ b/net/mptcp/protocol.h
> >>>>>>> @@ -766,25 +766,16 @@ static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
> >>>>>>>       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
> >>>>>>>  }
> >>>>>>>
> >>>>>>> -static inline unsigned int mptcp_add_addr_len(struct mptcp_out_options *opts,
> >>>>>>> -                                           u8 add_addr)
> >>>>>>> +static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
> >>>>>>>  {
> >>>>>>> -     struct mptcp_addr_info *addr = &opts->remote;
> >>>>>>> -     u8 len = 0;
> >>>>>>> +     u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>>>>>
> >>>>>>> -     if (!(add_addr & BIT(MPTCP_ADD_ADDR_ECHO)) &&
> >>>>>>> -         (add_addr & BIT(MPTCP_ADD_ADDR_SIGNAL))) {
> >>>>>>> -             addr = &opts->local;
> >>>>>>> +     if (family == AF_INET6)
> >>>>>>> +             len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>>>>>> +     if (!echo)
> >>>>>>>               len += MPTCPOPT_THMAC_LEN;
> >>>>>>> -     }
> >>>>>>> -
> >>>>>>> -     if (addr->family == AF_INET6)
> >>>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR6_BASE;
> >>>>>>> -     else
> >>>>>>> -             len += TCPOLEN_MPTCP_ADD_ADDR_BASE;
> >>>>>>> -
> >>>>>>>       /* account for 2 trailing 'nop' options */
> >>>>>>> -     if (addr->port)
> >>>>>>> +     if (port)
> >>>>>>>               len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
> >>>>>>>
> >>>>>>>       return len;
> >>>>>>> @@ -798,9 +789,9 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
> >>>>>>>       return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
> >>>>>>>  }
> >>>>>>>
> >>>>>>> -bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
> >>>>>>> -                           unsigned int opt_size, unsigned int remaining,
> >>>>>>> -                           struct mptcp_out_options *opts,  u8 *add_addr);
> >>>>>>> +bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>>>>> +                           struct mptcp_addr_info *saddr, struct mptcp_addr_info *daddr,
> >>>>>>> +                           bool *echo, bool *port);
> >>>>>>>  bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >>>>>>>                            struct mptcp_rm_list *rm_list);
> >>>>>>>  int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
> >>>>>>>
> >>>>>>
> >>>>>> --
> >>>>>> Li YongLong
> >>>>>
> >>>>
> >>>> --
> >>>> Li YongLong
> >>>
> >>>
> >>
> >> --
> >> Li YongLong
> >
>
> --
> Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other"
  2021-07-12  9:55   ` Yonglong Li
@ 2021-07-12 10:34     ` Geliang Tang
  2021-07-12 22:27       ` Mat Martineau
  0 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2021-07-12 10:34 UTC (permalink / raw)
  To: Yonglong Li; +Cc: mptcp, Paolo Abeni

Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午5:55写道:
>
>
>
> On 2021/7/11 23:15, Geliang Tang wrote:
> > Add READ_ONCE() for reading msk->pm.addr_signal.
> >
> > Use mptcp_pm_should_add_signal_echo instead of open coding.
> >
> > Use '&=' to clear flag.
> >
> > Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> > ---
> >  net/mptcp/pm.c | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> >
> > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> > index c9622696716e..be16da2dcb6b 100644
> > --- a/net/mptcp/pm.c
> > +++ b/net/mptcp/pm.c
> > @@ -257,6 +257,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >                             struct mptcp_addr_info *saddr, bool *echo, bool *port)
> >  {
> >       int ret = false;
> > +     u8 add_addr;
> >
> >       spin_lock_bh(&msk->pm.lock);
> >
> > @@ -271,10 +272,12 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >               goto out_unlock;
> >
> >       *saddr = msk->pm.local;
> > -     if ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)))
> > -             WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO));
> > +     add_addr = READ_ONCE(msk->pm.addr_signal);
> > +     if (mptcp_pm_should_add_signal_echo(msk))
> > +             add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
> >       else
> > -             WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL));
> > +             add_addr &= ~BIT(MPTCP_ADD_ADDR_SIGNAL);
> > +     WRITE_ONCE(msk->pm.addr_signal, add_addr);
> >       ret = true;
> >
> >  out_unlock:
> > @@ -294,7 +297,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
> >       if (!mptcp_pm_should_rm_signal(msk))
> >               goto out_unlock;
> >
> > -     rm_addr = msk->pm.addr_signal & ~BIT(MPTCP_RM_ADDR_SIGNAL);
> > +     rm_addr = READ_ONCE(msk->pm.addr_signal);
> > +     rm_addr &= ~BIT(MPTCP_RM_ADDR_SIGNAL);
> >       len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
> >       if (len < 0) {
> >               WRITE_ONCE(msk->pm.addr_signal, rm_addr);
> >
>
> These chunk of code is under the pm.lock so It is no need to use READ_ONCE() as Paolo saied before.

I'll drop this READ_ONCE() in v2.

>
> --
> Li YongLong

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate"
  2021-07-11 15:15 [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Geliang Tang
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other" Geliang Tang
  2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal" Geliang Tang
@ 2021-07-12 22:10 ` Mat Martineau
  2 siblings, 0 replies; 17+ messages in thread
From: Mat Martineau @ 2021-07-12 22:10 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp

On Sun, 11 Jul 2021, Geliang Tang wrote:

> A small cleanup.
>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
> net/mptcp/pm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 30deb76fa5d0..1eeecd68f159 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -18,7 +18,7 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
> {
> 	u8 add_addr = READ_ONCE(msk->pm.addr_signal);
>
> -	pr_debug("msk=%p, local_id=%d, echo:%d", msk, addr->id, echo);
> +	pr_debug("msk=%p, local_id=%d, echo=%d", msk, addr->id, echo);
>
> 	lockdep_assert_held(&msk->pm.lock);
>
> -- 
> 2.31.1

Thanks for catching this detail!

Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other"
  2021-07-12 10:34     ` Geliang Tang
@ 2021-07-12 22:27       ` Mat Martineau
  0 siblings, 0 replies; 17+ messages in thread
From: Mat Martineau @ 2021-07-12 22:27 UTC (permalink / raw)
  To: Geliang Tang; +Cc: Yonglong Li, mptcp, Paolo Abeni

[-- Attachment #1: Type: text/plain, Size: 2499 bytes --]

On Mon, 12 Jul 2021, Geliang Tang wrote:

> Yonglong Li <liyonglong@chinatelecom.cn> 于2021年7月12日周一 下午5:55写道:
>>
>>
>>
>> On 2021/7/11 23:15, Geliang Tang wrote:
>>> Add READ_ONCE() for reading msk->pm.addr_signal.
>>>
>>> Use mptcp_pm_should_add_signal_echo instead of open coding.
>>>
>>> Use '&=' to clear flag.
>>>
>>> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
>>> ---
>>>  net/mptcp/pm.c | 12 ++++++++----
>>>  1 file changed, 8 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
>>> index c9622696716e..be16da2dcb6b 100644
>>> --- a/net/mptcp/pm.c
>>> +++ b/net/mptcp/pm.c
>>> @@ -257,6 +257,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>                             struct mptcp_addr_info *saddr, bool *echo, bool *port)
>>>  {
>>>       int ret = false;
>>> +     u8 add_addr;
>>>
>>>       spin_lock_bh(&msk->pm.lock);
>>>
>>> @@ -271,10 +272,12 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>               goto out_unlock;
>>>
>>>       *saddr = msk->pm.local;
>>> -     if ((msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_ECHO)))
>>> -             WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO));
>>> +     add_addr = READ_ONCE(msk->pm.addr_signal);

Like below, pm.lock is held here so READ_ONCE() isn't needed.

>>> +     if (mptcp_pm_should_add_signal_echo(msk))
>>> +             add_addr &= ~BIT(MPTCP_ADD_ADDR_ECHO);
>>>       else
>>> -             WRITE_ONCE(msk->pm.addr_signal, msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL));
>>> +             add_addr &= ~BIT(MPTCP_ADD_ADDR_SIGNAL);
>>> +     WRITE_ONCE(msk->pm.addr_signal, add_addr);
>>>       ret = true;
>>>
>>>  out_unlock:
>>> @@ -294,7 +297,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
>>>       if (!mptcp_pm_should_rm_signal(msk))
>>>               goto out_unlock;
>>>
>>> -     rm_addr = msk->pm.addr_signal & ~BIT(MPTCP_RM_ADDR_SIGNAL);
>>> +     rm_addr = READ_ONCE(msk->pm.addr_signal);
>>> +     rm_addr &= ~BIT(MPTCP_RM_ADDR_SIGNAL);
>>>       len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
>>>       if (len < 0) {
>>>               WRITE_ONCE(msk->pm.addr_signal, rm_addr);
>>>
>>
>> These chunk of code is under the pm.lock so It is no need to use READ_ONCE() as Paolo saied before.
>
> I'll drop this READ_ONCE() in v2.
>
>>
>> --
>> Li YongLong
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-07-12 22:27 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-11 15:15 [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Geliang Tang
2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: fix ADD_ADDR and RM_ADDR maybe flush addr_signal each other" Geliang Tang
2021-07-12  9:55   ` Yonglong Li
2021-07-12 10:34     ` Geliang Tang
2021-07-12 22:27       ` Mat Martineau
2021-07-11 15:15 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: build ADD_ADDR/echo-ADD_ADDR option according pm.add_signal" Geliang Tang
2021-07-12  1:34   ` Yonglong Li
2021-07-12  7:33     ` Geliang Tang
2021-07-12  8:06       ` Yonglong Li
2021-07-12  8:44         ` Geliang Tang
2021-07-12  9:07           ` Geliang Tang
2021-07-12  9:21             ` Yonglong Li
2021-07-12  9:14           ` Yonglong Li
2021-07-12  9:29             ` Geliang Tang
2021-07-12  9:44               ` Yonglong Li
2021-07-12 10:34                 ` Geliang Tang
2021-07-12 22:10 ` [MPTCP][PATCH mptcp-next] Squash to "mptcp: make MPTCP_ADD_ADDR_SIGNAL and MPTCP_ADD_ADDR_ECHO separate" Mat Martineau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).