[PATCH net-next 06/11] mptcp: pm: drop TCP TS with ADD_ADDRv6 + port
From: Matthieu Baerts (NGI0)
Date: Mon Jun 01 2026 - 01:28:08 EST
With TCP-timestamps (padded) taking 12 bytes and ADD_ADDR IPv6 + port
taking 30 bytes, the 40-byte limit for the TCP options is reached. In
this case, it is then not possible to send the signal.
To be able to send this ADD_ADDR, the TCP timestamps option can now be
dropped. This is done, when needed by setting the *drop_ts parameter
from mptcp_established_options. This feature is controlled by a new
net.mptcp.add_addr_v6_port_drop_ts sysctl knob, enabled by default.
It is important to keep in mind that dropping the TCP timestamps option
for one packet of the connection could eventually disrupt some
middleboxes: even if it should be unlikely, they could drop the packet
or even block the connection. That's why this new feature can be
controlled by a sysctl knob.
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/448
Reviewed-by: Mat Martineau <martineau@xxxxxxxxxx>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@xxxxxxxxxx>
---
net/mptcp/options.c | 8 ++++++--
net/mptcp/pm.c | 12 +++++++++++-
net/mptcp/protocol.h | 2 +-
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index ccb5ac0aa729..02336d1c1550 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -652,6 +652,7 @@ static u64 add_addr_generate_hmac(u64 key1, u64 key2,
static bool mptcp_established_options_add_addr(struct sock *sk,
struct sk_buff *skb, int *size,
unsigned int remaining,
+ bool *drop_ts,
struct mptcp_out_options *opts)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
@@ -666,7 +667,7 @@ static bool mptcp_established_options_add_addr(struct sock *sk,
if (!mptcp_pm_should_add_signal(msk) ||
(opts->suboptions & (OPTION_MPTCP_MPJ_ACK | OPTION_MPTCP_MPC_ACK)) ||
!mptcp_pm_add_addr_signal(msk, skb, size, remaining, &addr, &echo,
- &drop_other_suboptions))
+ &drop_other_suboptions, drop_ts))
return false;
/*
@@ -819,6 +820,7 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+ bool add_addr_drop_ts = *drop_ts;
bool snd_data_fin;
bool ret = false;
int opt_size = 0;
@@ -869,10 +871,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
*size += opt_size;
remaining -= opt_size;
- if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining, opts)) {
+ if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining,
+ &add_addr_drop_ts, opts)) {
*size += opt_size;
remaining -= opt_size;
ret = true;
+ *drop_ts = add_addr_drop_ts;
} else if (mptcp_established_options_rm_addr(sk, &opt_size, remaining, opts)) {
*size += opt_size;
remaining -= opt_size;
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 6a2cbe8616d3..b1b3f7482f7c 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -905,7 +905,7 @@ static int mptcp_add_addr_len(int family, bool echo, bool port)
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
int *size, int remaining,
struct mptcp_addr_info *addr, bool *echo,
- bool *drop_other_suboptions)
+ bool *drop_other_suboptions, bool *drop_ts)
{
bool skip_add_addr = false;
bool ret = false;
@@ -949,6 +949,13 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
if (!*drop_other_suboptions)
goto out_unlock;
+ if (*drop_ts && mptcp_add_addr_v6_port_drop_ts(net)) {
+ /* OK without TCP Timestamps? */
+ len -= TCPOLEN_TSTAMP_ALIGNED;
+ if (len <= remaining)
+ goto enough_space;
+ }
+
if (*echo) {
MPTCP_INC_STATS(net, MPTCP_MIB_ECHOADDTXDROP);
} else {
@@ -958,6 +965,9 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
goto drop_signal_mark;
}
+ *drop_ts = false;
+
+enough_space:
ret = true;
*size = len;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index f4276980d78a..50c3205cab46 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1210,7 +1210,7 @@ static inline bool mptcp_pm_is_kernel(const struct mptcp_sock *msk)
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
int *size, int remaining,
struct mptcp_addr_info *addr, bool *echo,
- bool *drop_other_suboptions);
+ bool *drop_other_suboptions, bool *drop_ts);
bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
struct mptcp_rm_list *rm_list, int *len);
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
--
2.53.0