net/mptcp/protocol.c | 4 ++++ net/mptcp/protocol.h | 2 ++ net/mptcp/sockopt.c | 14 ++++++++++---- net/mptcp/subflow.c | 5 ++++- 4 files changed, 20 insertions(+), 5 deletions(-)
Report sequence numbers relative to their initial data sequence
numbers instead of exposing the raw connection-level values.
Keep the sequence-number baselines in the MPTCP socket so diagnostic
reporting does not depend on a subflow context that may be reset.
Link: https://github.com/multipath-tcp/mptcp_net-next/issues/445
Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
---
Changes since v8:
- Keep local and remote IDSN baselines in the MPTCP socket, so reporting does not depend on a subflow context that may be reset.
- Normalize mptcpi_write_seq, mptcpi_snd_una, and mptcpi_rcv_nxt relative to their IDSN baselines.
- Initialize the MPTCP_INFO output structure to zero.
v8: https://lore.kernel.org/all/20261014130809.1874184-1-kalpan.jani@mpiricsoftware.com/
---
net/mptcp/protocol.c | 4 ++++
net/mptcp/protocol.h | 2 ++
net/mptcp/sockopt.c | 14 ++++++++++----
net/mptcp/subflow.c | 5 ++++-
4 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index b474d03620a75..fb47384ace9c6 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3178,6 +3178,8 @@ static void __mptcp_init_sock(struct sock *sk)
INIT_WORK(&msk->work, mptcp_worker);
msk->out_of_order_queue = RB_ROOT;
msk->first_pending = NULL;
+ WRITE_ONCE(msk->local_idsn, 0);
+ WRITE_ONCE(msk->remote_idsn, 0);
/* msk does not go through tcp_init_sock(); seed RTO bounds. */
icsk->icsk_rto_min =
@@ -3722,6 +3724,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
msk = mptcp_sk(nsk);
WRITE_ONCE(msk->local_key, subflow_req->local_key);
+ WRITE_ONCE(msk->local_idsn, subflow_req->idsn);
WRITE_ONCE(msk->token, subflow_req->token);
msk->in_accept_queue = 1;
WRITE_ONCE(msk->fully_established, false);
@@ -4160,6 +4163,7 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
MPTCP_MIB_TOKENFALLBACKINIT);
}
+ WRITE_ONCE(msk->local_idsn, subflow->idsn);
WRITE_ONCE(msk->write_seq, subflow->idsn);
WRITE_ONCE(msk->snd_nxt, subflow->idsn);
WRITE_ONCE(msk->snd_una, subflow->idsn);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 06a107d4e8392..9238031f3adb0 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -286,6 +286,8 @@ struct mptcp_sock {
* lockless access read
*/
u64 remote_key; /* same as above */
+ u64 local_idsn;
+ u64 remote_idsn;
u64 write_seq;
u64 bytes_sent;
u64 snd_nxt;
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index fcf6feb2a9eb5..b1e41c967157e 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -971,6 +971,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
{
struct sock *sk = (struct sock *)msk;
+ u64 local_idsn = 0, remote_idsn = 0;
u32 flags = 0;
bool slow;
u32 now;
@@ -1008,9 +1009,11 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
info->mptcpi_flags = flags;
slow = lock_sock_fast(sk);
+ local_idsn = READ_ONCE(msk->local_idsn);
+
info->mptcpi_csum_enabled = READ_ONCE(msk->csum_enabled);
info->mptcpi_token = msk->token;
- info->mptcpi_write_seq = msk->write_seq;
+ info->mptcpi_write_seq = msk->write_seq - local_idsn;
info->mptcpi_retransmits = inet_csk(sk)->icsk_retransmits;
info->mptcpi_bytes_sent = msk->bytes_sent;
info->mptcpi_bytes_received = msk->bytes_received;
@@ -1023,17 +1026,20 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
unlock_sock_fast(sk, slow);
mptcp_data_lock(sk);
+ if (READ_ONCE(msk->can_ack))
+ remote_idsn = READ_ONCE(msk->remote_idsn);
info->mptcpi_last_ack_recv = jiffies_to_msecs(now - msk->last_ack_recv);
- info->mptcpi_snd_una = msk->snd_una;
- info->mptcpi_rcv_nxt = msk->ack_seq;
+ info->mptcpi_snd_una = msk->snd_una - local_idsn;
+ info->mptcpi_rcv_nxt = msk->ack_seq - remote_idsn;
info->mptcpi_bytes_acked = msk->bytes_acked;
mptcp_data_unlock(sk);
+
}
EXPORT_SYMBOL_GPL(mptcp_diag_fill_info);
static int mptcp_getsockopt_info(struct mptcp_sock *msk, char __user *optval, int __user *optlen)
{
- struct mptcp_info m_info;
+ struct mptcp_info m_info = {};
int len;
if (get_user(len, optlen))
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index af81ad5e699d1..cfc703bd5dd69 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -481,7 +481,6 @@ static void subflow_set_remote_key(struct mptcp_sock *msk,
if (subflow->remote_key_valid)
return;
- subflow->remote_key_valid = 1;
subflow->remote_key = mp_opt->sndr_key;
mptcp_crypto_key_sha(subflow->remote_key, NULL, &subflow->iasn);
subflow->iasn++;
@@ -490,9 +489,13 @@ static void subflow_set_remote_key(struct mptcp_sock *msk,
subflow->map_seq = subflow->iasn;
WRITE_ONCE(msk->remote_key, subflow->remote_key);
+ WRITE_ONCE(msk->remote_idsn, subflow->iasn - 1);
WRITE_ONCE(msk->ack_seq, subflow->iasn);
WRITE_ONCE(msk->can_ack, true);
atomic64_set(&msk->rcv_wnd_sent, subflow->iasn);
+
+ /* publish last, once iasn and the fields above are fully populated */
+ subflow->remote_key_valid = 1;
}
static void mptcp_propagate_state(struct sock *sk, struct sock *ssk,
--
2.43.0
Hi Kalpan,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Perf: Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/38721441830
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/1a9206c4d367
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1186354
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
© 2016 - 2026 Red Hat, Inc.