netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] mptcp: add TCP_MAXSEG sockopt support
@ 2025-07-16 10:28 Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 1/4] mptcp: sockopt: drop redundant tcp_getsockopt Matthieu Baerts (NGI0)
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-07-16 10:28 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Neal Cardwell,
	Kuniyuki Iwashima, David Ahern
  Cc: netdev, linux-kernel, Matthieu Baerts (NGI0), moyuanhao,
	Geliang Tang

The TCP_MAXSEG socket option was not supported by MPTCP, mainly because
it has never been requested before. But there are still valid use-cases,
e.g. with HAProxy.

- Patch 1 is a small cleanup patch in the MPTCP sockopt file.

- Patch 2 expose some code from TCP, to avoid duplicating it in MPTCP.

- Patch 3 adds TCP_MAXSEG sockopt support in MPTCP.

- Patch 4 is not related to the others, it fixes a typo in a comment.

Note that the new TCP_MAXSEG sockopt support has been validated by a new
packetdrill script on the MPTCP CI:

  https://github.com/multipath-tcp/packetdrill/pull/161

Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Geliang Tang (3):
      mptcp: sockopt: drop redundant tcp_getsockopt
      tcp: add tcp_sock_set_maxseg
      mptcp: add TCP_MAXSEG sockopt support

moyuanhao (1):
      mptcp: fix typo in a comment

 include/linux/tcp.h  |  1 +
 net/ipv4/tcp.c       | 23 ++++++++++++++---------
 net/mptcp/protocol.c |  2 +-
 net/mptcp/protocol.h |  1 +
 net/mptcp/sockopt.c  | 33 +++++++++++++++++++++++++++++----
 5 files changed, 46 insertions(+), 14 deletions(-)
---
base-commit: c3886ccaadf8fdc2c91bfbdcdca36ccdc6ef8f70
change-id: 20250716-net-next-mptcp-tcp_maxseg-e7702891080d

Best regards,
-- 
Matthieu Baerts (NGI0) <matttbe@kernel.org>


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

* [PATCH net-next 1/4] mptcp: sockopt: drop redundant tcp_getsockopt
  2025-07-16 10:28 [PATCH net-next 0/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
@ 2025-07-16 10:28 ` Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 2/4] tcp: add tcp_sock_set_maxseg Matthieu Baerts (NGI0)
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-07-16 10:28 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Neal Cardwell,
	Kuniyuki Iwashima, David Ahern
  Cc: netdev, linux-kernel, Matthieu Baerts (NGI0), Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

tcp_getsockopt() is called twice in mptcp_getsockopt_first_sf_only() in
different conditions, which makes the code a bit redundant.

The first call to tcp_getsockopt() when the first subflow exists can be
replaced by going to a new label "get" before the second call.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
 net/mptcp/sockopt.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 3caa0a9d3b3885ce6399570f2d98a2e8f103638d..afa54fba51e215bc2efb21f16ed7d0a0fb120972 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -914,10 +914,8 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
 
 	lock_sock(sk);
 	ssk = msk->first;
-	if (ssk) {
-		ret = tcp_getsockopt(ssk, level, optname, optval, optlen);
-		goto out;
-	}
+	if (ssk)
+		goto get;
 
 	ssk = __mptcp_nmpc_sk(msk);
 	if (IS_ERR(ssk)) {
@@ -925,6 +923,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
 		goto out;
 	}
 
+get:
 	ret = tcp_getsockopt(ssk, level, optname, optval, optlen);
 
 out:

-- 
2.48.1


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

* [PATCH net-next 2/4] tcp: add tcp_sock_set_maxseg
  2025-07-16 10:28 [PATCH net-next 0/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 1/4] mptcp: sockopt: drop redundant tcp_getsockopt Matthieu Baerts (NGI0)
@ 2025-07-16 10:28 ` Matthieu Baerts (NGI0)
  2025-07-17  1:25   ` Geliang Tang
  2025-07-16 10:28 ` [PATCH net-next 3/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 4/4] mptcp: fix typo in a comment Matthieu Baerts (NGI0)
  3 siblings, 1 reply; 6+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-07-16 10:28 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Neal Cardwell,
	Kuniyuki Iwashima, David Ahern
  Cc: netdev, linux-kernel, Matthieu Baerts (NGI0), Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add a helper tcp_sock_set_maxseg() to directly set the TCP_MAXSEG
sockopt from kernel space.

This new helper will be used in the following patch from MPTCP.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
 include/linux/tcp.h |  1 +
 net/ipv4/tcp.c      | 23 ++++++++++++++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 1a5737b3753d06165bc71e257a261bcd7a0085ce..57e478bfaef20369f5dba1cff540e52c9302ebf4 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -621,6 +621,7 @@ void tcp_sock_set_nodelay(struct sock *sk);
 void tcp_sock_set_quickack(struct sock *sk, int val);
 int tcp_sock_set_syncnt(struct sock *sk, int val);
 int tcp_sock_set_user_timeout(struct sock *sk, int val);
+int tcp_sock_set_maxseg(struct sock *sk, int val);
 
 static inline bool dst_tcp_usec_ts(const struct dst_entry *dst)
 {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 31149a0ac849192b46c67dd569efeeeb0a041a0b..c9cdc4e99c4f11a75471b8895b9c52ad8da3a7ff 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3751,6 +3751,19 @@ int tcp_set_window_clamp(struct sock *sk, int val)
 	return 0;
 }
 
+int tcp_sock_set_maxseg(struct sock *sk, int val)
+{
+	/* Values greater than interface MTU won't take effect. However
+	 * at the point when this call is done we typically don't yet
+	 * know which interface is going to be used
+	 */
+	if (val && (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW))
+		return -EINVAL;
+
+	tcp_sk(sk)->rx_opt.user_mss = val;
+	return 0;
+}
+
 /*
  *	Socket option code for TCP.
  */
@@ -3883,15 +3896,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 
 	switch (optname) {
 	case TCP_MAXSEG:
-		/* Values greater than interface MTU won't take effect. However
-		 * at the point when this call is done we typically don't yet
-		 * know which interface is going to be used
-		 */
-		if (val && (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW)) {
-			err = -EINVAL;
-			break;
-		}
-		tp->rx_opt.user_mss = val;
+		tcp_sock_set_maxseg(sk, val);
 		break;
 
 	case TCP_NODELAY:

-- 
2.48.1


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

* [PATCH net-next 3/4] mptcp: add TCP_MAXSEG sockopt support
  2025-07-16 10:28 [PATCH net-next 0/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 1/4] mptcp: sockopt: drop redundant tcp_getsockopt Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 2/4] tcp: add tcp_sock_set_maxseg Matthieu Baerts (NGI0)
@ 2025-07-16 10:28 ` Matthieu Baerts (NGI0)
  2025-07-16 10:28 ` [PATCH net-next 4/4] mptcp: fix typo in a comment Matthieu Baerts (NGI0)
  3 siblings, 0 replies; 6+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-07-16 10:28 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Neal Cardwell,
	Kuniyuki Iwashima, David Ahern
  Cc: netdev, linux-kernel, Matthieu Baerts (NGI0), Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

The TCP_MAXSEG socket option is currently not supported by MPTCP, mainly
because it has never been requested before. But there are still valid
use-cases, e.g. with HAProxy.

This patch adds its support in MPTCP by propagating the value to all
subflows. The get part looks at the value on the first subflow, to be as
closed as possible to TCP. Only one value can be returned for the cached
MSS, so this can come only from one subflow.

Similar to mptcp_setsockopt_first_sf_only(), a generic helper
mptcp_setsockopt_all_subflows() is added to set sockopt for each
subflows of the mptcp socket.

Add a new member for struct mptcp_sock to store the TCP_MAXSEG value,
and return this value in getsockopt.

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/515
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
 net/mptcp/protocol.h |  1 +
 net/mptcp/sockopt.c  | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 3dd11dd3ba16e8c1d3741b6eb5b526bb4beae15b..9c43a1f037e71243e202f907608ad42086dbde4b 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -326,6 +326,7 @@ struct mptcp_sock {
 	int		keepalive_cnt;
 	int		keepalive_idle;
 	int		keepalive_intvl;
+	int		maxseg;
 	struct work_struct work;
 	struct sk_buff  *ooo_last_skb;
 	struct rb_root  out_of_order_queue;
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index afa54fba51e215bc2efb21f16ed7d0a0fb120972..379a02a46b7bf706480cf66a88c6cf2357d2a62b 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -798,6 +798,23 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
 	return ret;
 }
 
+static int mptcp_setsockopt_all_sf(struct mptcp_sock *msk, int level,
+				   int optname, sockptr_t optval,
+				   unsigned int optlen)
+{
+	struct mptcp_subflow_context *subflow;
+
+	mptcp_for_each_subflow(msk, subflow) {
+		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+		int ret = 0;
+
+		ret = tcp_setsockopt(ssk, level, optname, optval, optlen);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
 static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
 				    sockptr_t optval, unsigned int optlen)
 {
@@ -859,6 +876,11 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
 						 &msk->keepalive_cnt,
 						 val);
 		break;
+	case TCP_MAXSEG:
+		msk->maxseg = val;
+		ret = mptcp_setsockopt_all_sf(msk, SOL_TCP, optname, optval,
+					      optlen);
+		break;
 	default:
 		ret = -ENOPROTOOPT;
 	}
@@ -1406,6 +1428,9 @@ static int mptcp_getsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
 		return mptcp_put_int_option(msk, optval, optlen, msk->notsent_lowat);
 	case TCP_IS_MPTCP:
 		return mptcp_put_int_option(msk, optval, optlen, 1);
+	case TCP_MAXSEG:
+		return mptcp_getsockopt_first_sf_only(msk, SOL_TCP, optname,
+						      optval, optlen);
 	}
 	return -EOPNOTSUPP;
 }
@@ -1552,6 +1577,7 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
 	tcp_sock_set_keepidle_locked(ssk, msk->keepalive_idle);
 	tcp_sock_set_keepintvl(ssk, msk->keepalive_intvl);
 	tcp_sock_set_keepcnt(ssk, msk->keepalive_cnt);
+	tcp_sock_set_maxseg(ssk, msk->maxseg);
 
 	inet_assign_bit(TRANSPARENT, ssk, inet_test_bit(TRANSPARENT, sk));
 	inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk));

-- 
2.48.1


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

* [PATCH net-next 4/4] mptcp: fix typo in a comment
  2025-07-16 10:28 [PATCH net-next 0/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
                   ` (2 preceding siblings ...)
  2025-07-16 10:28 ` [PATCH net-next 3/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
@ 2025-07-16 10:28 ` Matthieu Baerts (NGI0)
  3 siblings, 0 replies; 6+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-07-16 10:28 UTC (permalink / raw)
  To: mptcp, Mat Martineau, Geliang Tang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Neal Cardwell,
	Kuniyuki Iwashima, David Ahern
  Cc: netdev, linux-kernel, Matthieu Baerts (NGI0), moyuanhao

From: moyuanhao <moyuanhao3676@163.com>

This patch fixes the follow spelling mistake in a comment:

  greter -> greater

Signed-off-by: moyuanhao <moyuanhao3676@163.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Notes:
 - The same patch has already been sent to the netdev ML, but when
   net-next was closed:
   https://lore.kernel.org/20250530181004.261417-1-moyuanhao3676@163.com
---
 net/mptcp/protocol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5f904fc5ac4c63e8b6c7c9aa79f17e8dcdf1a007..fe3135cd778a98d4f270d684c101af30d261ee71 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1377,7 +1377,7 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk)
 	 * - estimate the faster flow linger time
 	 * - use the above to estimate the amount of byte transferred
 	 *   by the faster flow
-	 * - check that the amount of queued data is greter than the above,
+	 * - check that the amount of queued data is greater than the above,
 	 *   otherwise do not use the picked, slower, subflow
 	 * We select the subflow with the shorter estimated time to flush
 	 * the queued mem, which basically ensure the above. We just need

-- 
2.48.1


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

* Re: [PATCH net-next 2/4] tcp: add tcp_sock_set_maxseg
  2025-07-16 10:28 ` [PATCH net-next 2/4] tcp: add tcp_sock_set_maxseg Matthieu Baerts (NGI0)
@ 2025-07-17  1:25   ` Geliang Tang
  0 siblings, 0 replies; 6+ messages in thread
From: Geliang Tang @ 2025-07-17  1:25 UTC (permalink / raw)
  To: Matthieu Baerts (NGI0), mptcp, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Neal Cardwell, Kuniyuki Iwashima, David Ahern
  Cc: netdev, linux-kernel

Hi Matt,

On Wed, 2025-07-16 at 12:28 +0200, Matthieu Baerts (NGI0) wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> Add a helper tcp_sock_set_maxseg() to directly set the TCP_MAXSEG
> sockopt from kernel space.
> 
> This new helper will be used in the following patch from MPTCP.
> 
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
>  include/linux/tcp.h |  1 +
>  net/ipv4/tcp.c      | 23 ++++++++++++++---------
>  2 files changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/include/linux/tcp.h b/include/linux/tcp.h
> index
> 1a5737b3753d06165bc71e257a261bcd7a0085ce..57e478bfaef20369f5dba1cff54
> 0e52c9302ebf4 100644
> --- a/include/linux/tcp.h
> +++ b/include/linux/tcp.h
> @@ -621,6 +621,7 @@ void tcp_sock_set_nodelay(struct sock *sk);
>  void tcp_sock_set_quickack(struct sock *sk, int val);
>  int tcp_sock_set_syncnt(struct sock *sk, int val);
>  int tcp_sock_set_user_timeout(struct sock *sk, int val);
> +int tcp_sock_set_maxseg(struct sock *sk, int val);
>  
>  static inline bool dst_tcp_usec_ts(const struct dst_entry *dst)
>  {
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index
> 31149a0ac849192b46c67dd569efeeeb0a041a0b..c9cdc4e99c4f11a75471b8895b9
> c52ad8da3a7ff 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -3751,6 +3751,19 @@ int tcp_set_window_clamp(struct sock *sk, int
> val)
>  	return 0;
>  }
>  
> +int tcp_sock_set_maxseg(struct sock *sk, int val)
> +{
> +	/* Values greater than interface MTU won't take effect.
> However
> +	 * at the point when this call is done we typically don't
> yet
> +	 * know which interface is going to be used
> +	 */
> +	if (val && (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW))
> +		return -EINVAL;
> +
> +	tcp_sk(sk)->rx_opt.user_mss = val;
> +	return 0;
> +}
> +
>  /*
>   *	Socket option code for TCP.
>   */
> @@ -3883,15 +3896,7 @@ int do_tcp_setsockopt(struct sock *sk, int
> level, int optname,
>  
>  	switch (optname) {
>  	case TCP_MAXSEG:
> -		/* Values greater than interface MTU won't take
> effect. However
> -		 * at the point when this call is done we typically
> don't yet
> -		 * know which interface is going to be used
> -		 */
> -		if (val && (val < TCP_MIN_MSS || val >
> MAX_TCP_WINDOW)) {
> -			err = -EINVAL;
> -			break;
> -		}
> -		tp->rx_opt.user_mss = val;
> +		tcp_sock_set_maxseg(sk, val);

Sorry, I forgot to set the return value here, it should be:

		err = tcp_sock_set_maxseg(sk, val);

I'll send a squash-to patch to fix this.

Thanks,
-Geliang

>  		break;
>  
>  	case TCP_NODELAY:

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

end of thread, other threads:[~2025-07-17  1:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-16 10:28 [PATCH net-next 0/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
2025-07-16 10:28 ` [PATCH net-next 1/4] mptcp: sockopt: drop redundant tcp_getsockopt Matthieu Baerts (NGI0)
2025-07-16 10:28 ` [PATCH net-next 2/4] tcp: add tcp_sock_set_maxseg Matthieu Baerts (NGI0)
2025-07-17  1:25   ` Geliang Tang
2025-07-16 10:28 ` [PATCH net-next 3/4] mptcp: add TCP_MAXSEG sockopt support Matthieu Baerts (NGI0)
2025-07-16 10:28 ` [PATCH net-next 4/4] mptcp: fix typo in a comment Matthieu Baerts (NGI0)

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).