diff options
| author | Matthieu Baerts (NGI0) <matttbe@kernel.org> | 2026-06-05 12:21:50 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-12 01:33:38 +0300 |
| commit | 23eeaad0d89d7fd64e6164dde48e661ad237772e (patch) | |
| tree | 2747a5f2b67dfe57c90830137bfc7b37210ec051 | |
| parent | 1c3e7e0439773357e25d13d9cd56e5138593e5bd (diff) | |
| download | linux-23eeaad0d89d7fd64e6164dde48e661ad237772e.tar.xz | |
mptcp: pm: drop TCP TS with ADD_ADDRv6 + port
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@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260605-net-next-mptcp-add-addr6-port-ts-v2-6-758e7ca73f4d@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | net/mptcp/options.c | 9 | ||||
| -rw-r--r-- | net/mptcp/pm.c | 13 | ||||
| -rw-r--r-- | net/mptcp/protocol.h | 3 |
3 files changed, 21 insertions, 4 deletions
diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 95f16f9f0ce2..8d0680a588dd 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -659,11 +659,13 @@ 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 has_ts, struct mptcp_out_options *opts) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct mptcp_sock *msk = mptcp_sk(subflow->conn); struct mptcp_addr_info addr; + bool drop_ts = has_ts; bool echo; /* add addr will strip the existing options, be sure to avoid breaking @@ -672,11 +674,13 @@ 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)) || !skb || !skb_is_tcp_pure_ack(skb) || - !mptcp_pm_add_addr_signal(msk, size, remaining, &addr, &echo)) + !mptcp_pm_add_addr_signal(msk, size, remaining, &addr, &echo, + &drop_ts)) return false; pr_debug("drop other suboptions\n"); opts->suboptions = OPTION_MPTCP_ADD_ADDR; + opts->drop_ts = drop_ts; opts->addr = addr; if (!echo) { MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRTX); @@ -859,7 +863,8 @@ int mptcp_established_options(struct sock *sk, struct sk_buff *skb, total_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, + has_ts, opts)) { total_size += opt_size; remaining -= opt_size; ret = true; diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 59dc598d343d..ac7de4141738 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -903,7 +903,8 @@ static int mptcp_add_addr_len(int family, bool echo, bool port) } bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, int *size, int remaining, - struct mptcp_addr_info *addr, bool *echo) + struct mptcp_addr_info *addr, bool *echo, + bool *drop_ts) { bool skip_add_addr = false; bool ret = false; @@ -941,6 +942,13 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, int *size, int remaining, if (len > remaining) { struct net *net = sock_net((struct sock *)msk); + 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 { @@ -950,6 +958,9 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, int *size, int remaining, 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 b43dae72e7de..e69fcb4d48af 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1208,7 +1208,8 @@ static inline bool mptcp_pm_is_kernel(const struct mptcp_sock *msk) } bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, int *size, int remaining, - struct mptcp_addr_info *addr, bool *echo); + struct mptcp_addr_info *addr, bool *echo, + 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); |
