* [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-08-25 11:33 [PATCH net-next] " Kalpan Jani
@ 2026-08-26 6:03 ` Kalpan Jani
2026-08-26 7:26 ` MPTCP CI
2026-08-26 9:48 ` Kalpan Jani
0 siblings, 2 replies; 10+ messages in thread
From: Kalpan Jani @ 2026-08-26 6:03 UTC (permalink / raw)
To: mptcp
Cc: matttbe, martineau, pabeni, shardul.b, janak, kalpanjani009,
Kalpan Jani
mptcpi_write_seq, mptcpi_snd_una and mptcpi_rcv_nxt report the raw
64-bit data sequence numbers, seeded from the connection's IDSN/IASN.
Since the IDSN/IASN come from mptcp_crypto_key_sha(), these fields
carry an effectively random offset and are not useful to userspace as
absolute values: a caller has to snapshot two getsockopt(MPTCP_INFO)
calls and subtract to get anything meaningful, which is exactly what
tools/testing/selftests/net/mptcp/mptcp_sockopt.c already does.
mptcp_info also reports mptcpi_bytes_sent, mptcpi_bytes_received and
mptcpi_bytes_acked, which give the same information as a plain byte
count starting at 0. The snapshot-and-diff workaround for the seq
fields is redundant once those are available.
Cache the local and remote initial sequence numbers on the
mptcp_sock the same way ->token already is, and subtract them in
mptcp_diag_fill_info(), so mptcpi_write_seq, mptcpi_snd_una and
mptcpi_rcv_nxt also start near 0 for a freshly established
connection.
msk->local_idsn is set at every place write_seq is seeded from
subflow->idsn: the provisional value in __mptcp_sync_state() at
TCP_SYN_SENT, the authoritative one in mptcp_connect(), and the
passive/accept-side value in mptcp_sk_clone_init(). Missing the
first of these would leave a window where a concurrent
getsockopt(MPTCP_INFO) still saw the raw, un-normalized write_seq.
msk->remote_idsn is cached from subflow->iasn in
subflow_set_remote_key() before iasn is incremented for the peer's
virtual SYN, so it lines up with the point local_idsn is cached
relative to write_seq's own +1.
The TCP-fallback path never negotiates an IASN, so msk->remote_idsn
stays at its zero-initialized default there, which is a no-op for
the subtraction and leaves mptcpi_rcv_nxt reporting the plain TCP
sequence number as before.
Link: https://github.com/multipath-tcp/mptcp_net-next/issues/445
Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
---
Changes since v1:
- cached msk->remote_idsn before subflow->iasn++ instead of after:
the increment accounts for the peer's virtual SYN, and caching
remote_idsn post-increment left mptcpi_rcv_nxt starting at 0 while
mptcpi_write_seq/mptcpi_snd_una started at 1 for the same
connection.
v1: https://lore.kernel.org/all/20260825113355.3573376-1-kalpan.jani@mpiricsoftware.com/
---
net/mptcp/protocol.c | 3 +++
net/mptcp/protocol.h | 7 +++++++
net/mptcp/sockopt.c | 6 +++---
net/mptcp/subflow.c | 2 ++
4 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index f22d64ab1c53b..47faece545f15 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3764,6 +3764,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->token, subflow_req->token);
+ WRITE_ONCE(msk->local_idsn, subflow_req->idsn);
msk->in_accept_queue = 1;
WRITE_ONCE(msk->fully_established, false);
if (mp_opt->suboptions & OPTION_MPTCP_CSUMREQD)
@@ -4204,6 +4205,8 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
WRITE_ONCE(msk->write_seq, subflow->idsn);
WRITE_ONCE(msk->snd_nxt, subflow->idsn);
WRITE_ONCE(msk->snd_una, subflow->idsn);
+ WRITE_ONCE(msk->local_idsn, subflow->idsn);
+
if (likely(!__mptcp_check_fallback(msk)))
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 3d250e8204d52..c1a709b2287f0 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -306,6 +306,13 @@ struct mptcp_sock {
u64 bytes_acked;
u64 snd_una;
u64 wnd_end;
+ /*
+ * cached IDSN/IASN, so mptcp_diag_fill_info() can report
+ * write_seq/snd_una/rcv_nxt normalized to start near 0
+ * instead of the raw, crypto-derived initial values.
+ */
+ u64 local_idsn;
+ u64 remote_idsn;
u32 last_data_sent;
u32 last_data_recv;
u32 last_ack_recv;
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 922f6ae5c80cb..fb3dfa88eba5a 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -1086,7 +1086,7 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
slow = lock_sock_fast(sk);
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 - msk->local_idsn;
info->mptcpi_retransmits = inet_csk(sk)->icsk_retransmits;
info->mptcpi_bytes_sent = msk->bytes_sent;
info->mptcpi_bytes_received = msk->bytes_received;
@@ -1100,8 +1100,8 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
mptcp_data_lock(sk);
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 - msk->local_idsn;
+ info->mptcpi_rcv_nxt = msk->ack_seq - msk->remote_idsn;
info->mptcpi_bytes_acked = msk->bytes_acked;
mptcp_data_unlock(sk);
}
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 2d7ccb01d2342..9a4a818552290 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -466,6 +466,7 @@ void __mptcp_sync_state(struct sock *sk, int state)
* even for the FASTOPEN scenarios
*/
WRITE_ONCE(msk->write_seq, subflow->idsn + 1);
+ WRITE_ONCE(msk->local_idsn, subflow->idsn);
WRITE_ONCE(msk->snd_nxt, msk->write_seq);
mptcp_set_state(sk, state);
sk->sk_state_change(sk);
@@ -485,6 +486,7 @@ static void subflow_set_remote_key(struct mptcp_sock *msk,
subflow->remote_key_valid = 1;
subflow->remote_key = mp_opt->sndr_key;
mptcp_crypto_key_sha(subflow->remote_key, NULL, &subflow->iasn);
+ WRITE_ONCE(msk->remote_idsn, subflow->iasn);
subflow->iasn++;
/* for fallback's sake */
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-08-26 6:03 ` [PATCH net-next v2] " Kalpan Jani
@ 2026-08-26 7:26 ` MPTCP CI
2026-08-26 9:48 ` Kalpan Jani
1 sibling, 0 replies; 10+ messages in thread
From: MPTCP CI @ 2026-08-26 7:26 UTC (permalink / raw)
To: Kalpan Jani; +Cc: mptcp
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! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/32938236918
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/10bc5a274e67
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1151847
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)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-08-26 6:03 ` [PATCH net-next v2] " Kalpan Jani
2026-08-26 7:26 ` MPTCP CI
@ 2026-08-26 9:48 ` Kalpan Jani
1 sibling, 0 replies; 10+ messages in thread
From: Kalpan Jani @ 2026-08-26 9:48 UTC (permalink / raw)
To: Kalpan Jani
Cc: mptcp, matttbe, martineau, pabeni, shardul.b, janak,
kalpanjani009
Hi All,
I sent the v2 patch in the same thread as v1, and I think that may
be why Sashiko hasn't reviewed it yet.
I'll resend v2 within the next 24 hours to make sure it gets picked
up for review.
Cheers,
Kalpan Jani
From: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
To: <mptcp@lists.linux.dev>
Cc: <matttbe@kernel.org>, <martineau@kernel.org>, <pabeni@redhat.com>, <shardul.b@mpiricsoftware.com>, <janak@mpiric.us>, <kalpanjani009@gmail.com>, "Kalpan Jani"<kalpan.jani@mpiricsoftware.com>
Date: Wed, 26 Aug 2026 11:33:18 +0530
Subject: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
> mptcpi_write_seq, mptcpi_snd_una and mptcpi_rcv_nxt report the raw
> 64-bit data sequence numbers, seeded from the connection's IDSN/IASN.
> Since the IDSN/IASN come from mptcp_crypto_key_sha(), these fields
> carry an effectively random offset and are not useful to userspace as
> absolute values: a caller has to snapshot two getsockopt(MPTCP_INFO)
> calls and subtract to get anything meaningful, which is exactly what
> tools/testing/selftests/net/mptcp/mptcp_sockopt.c already does.
>
> mptcp_info also reports mptcpi_bytes_sent, mptcpi_bytes_received and
> mptcpi_bytes_acked, which give the same information as a plain byte
> count starting at 0. The snapshot-and-diff workaround for the seq
> fields is redundant once those are available.
>
> Cache the local and remote initial sequence numbers on the
> mptcp_sock the same way ->token already is, and subtract them in
> mptcp_diag_fill_info(), so mptcpi_write_seq, mptcpi_snd_una and
> mptcpi_rcv_nxt also start near 0 for a freshly established
> connection.
>
> msk->local_idsn is set at every place write_seq is seeded from
> subflow->idsn: the provisional value in __mptcp_sync_state() at
> TCP_SYN_SENT, the authoritative one in mptcp_connect(), and the
> passive/accept-side value in mptcp_sk_clone_init(). Missing the
> first of these would leave a window where a concurrent
> getsockopt(MPTCP_INFO) still saw the raw, un-normalized write_seq.
>
> msk->remote_idsn is cached from subflow->iasn in
> subflow_set_remote_key() before iasn is incremented for the peer's
> virtual SYN, so it lines up with the point local_idsn is cached
> relative to write_seq's own +1.
>
> The TCP-fallback path never negotiates an IASN, so msk->remote_idsn
> stays at its zero-initialized default there, which is a no-op for
> the subtraction and leaves mptcpi_rcv_nxt reporting the plain TCP
> sequence number as before.
>
> Link: https://github.com/multipath-tcp/mptcp_net-next/issues/445
> Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
> ---
>
> Changes since v1:
> - cached msk->remote_idsn before subflow->iasn++ instead of after:
> the increment accounts for the peer's virtual SYN, and caching
> remote_idsn post-increment left mptcpi_rcv_nxt starting at 0 while
> mptcpi_write_seq/mptcpi_snd_una started at 1 for the same
> connection.
>
> v1: https://lore.kernel.org/all/20260825113355.3573376-1-kalpan.jani@mpiricsoftware.com/
>
> ---
> net/mptcp/protocol.c | 3 +++
> net/mptcp/protocol.h | 7 +++++++
> net/mptcp/sockopt.c | 6 +++---
> net/mptcp/subflow.c | 2 ++
> 4 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index f22d64ab1c53b..47faece545f15 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -3764,6 +3764,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->token, subflow_req->token);
> + WRITE_ONCE(msk->local_idsn, subflow_req->idsn);
> msk->in_accept_queue = 1;
> WRITE_ONCE(msk->fully_established, false);
> if (mp_opt->suboptions & OPTION_MPTCP_CSUMREQD)
> @@ -4204,6 +4205,8 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
> WRITE_ONCE(msk->write_seq, subflow->idsn);
> WRITE_ONCE(msk->snd_nxt, subflow->idsn);
> WRITE_ONCE(msk->snd_una, subflow->idsn);
> + WRITE_ONCE(msk->local_idsn, subflow->idsn);
> +
> if (likely(!__mptcp_check_fallback(msk)))
> MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE);
>
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 3d250e8204d52..c1a709b2287f0 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -306,6 +306,13 @@ struct mptcp_sock {
> u64 bytes_acked;
> u64 snd_una;
> u64 wnd_end;
> + /*
> + * cached IDSN/IASN, so mptcp_diag_fill_info() can report
> + * write_seq/snd_una/rcv_nxt normalized to start near 0
> + * instead of the raw, crypto-derived initial values.
> + */
> + u64 local_idsn;
> + u64 remote_idsn;
> u32 last_data_sent;
> u32 last_data_recv;
> u32 last_ack_recv;
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index 922f6ae5c80cb..fb3dfa88eba5a 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -1086,7 +1086,7 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
> slow = lock_sock_fast(sk);
> 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 - msk->local_idsn;
> info->mptcpi_retransmits = inet_csk(sk)->icsk_retransmits;
> info->mptcpi_bytes_sent = msk->bytes_sent;
> info->mptcpi_bytes_received = msk->bytes_received;
> @@ -1100,8 +1100,8 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
>
> mptcp_data_lock(sk);
> 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 - msk->local_idsn;
> + info->mptcpi_rcv_nxt = msk->ack_seq - msk->remote_idsn;
> info->mptcpi_bytes_acked = msk->bytes_acked;
> mptcp_data_unlock(sk);
> }
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index 2d7ccb01d2342..9a4a818552290 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -466,6 +466,7 @@ void __mptcp_sync_state(struct sock *sk, int state)
> * even for the FASTOPEN scenarios
> */
> WRITE_ONCE(msk->write_seq, subflow->idsn + 1);
> + WRITE_ONCE(msk->local_idsn, subflow->idsn);
> WRITE_ONCE(msk->snd_nxt, msk->write_seq);
> mptcp_set_state(sk, state);
> sk->sk_state_change(sk);
> @@ -485,6 +486,7 @@ static void subflow_set_remote_key(struct mptcp_sock *msk,
> subflow->remote_key_valid = 1;
> subflow->remote_key = mp_opt->sndr_key;
> mptcp_crypto_key_sha(subflow->remote_key, NULL, &subflow->iasn);
> + WRITE_ONCE(msk->remote_idsn, subflow->iasn);
> subflow->iasn++;
>
> /* for fallback's sake */
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
@ 2026-08-27 4:10 Kalpan Jani
2026-08-27 5:15 ` MPTCP CI
2026-08-31 10:29 ` Matthieu Baerts
0 siblings, 2 replies; 10+ messages in thread
From: Kalpan Jani @ 2026-08-27 4:10 UTC (permalink / raw)
To: mptcp
Cc: matttbe, martineau, pabeni, shardul.b, janak, kalpanjani009,
Kalpan Jani
mptcpi_write_seq, mptcpi_snd_una and mptcpi_rcv_nxt report the raw
64-bit data sequence numbers, seeded from the connection's IDSN/IASN.
Since the IDSN/IASN come from mptcp_crypto_key_sha(), these fields
carry an effectively random offset and are not useful to userspace as
absolute values: a caller has to snapshot two getsockopt(MPTCP_INFO)
calls and subtract to get anything meaningful, which is exactly what
tools/testing/selftests/net/mptcp/mptcp_sockopt.c already does.
mptcp_info also reports mptcpi_bytes_sent, mptcpi_bytes_received and
mptcpi_bytes_acked, which give the same information as a plain byte
count starting at 0. The snapshot-and-diff workaround for the seq
fields is redundant once those are available.
Cache the local and remote initial sequence numbers on the
mptcp_sock the same way ->token already is, and subtract them in
mptcp_diag_fill_info(), so mptcpi_write_seq, mptcpi_snd_una and
mptcpi_rcv_nxt also start near 0 for a freshly established
connection.
msk->local_idsn is set at every place write_seq is seeded from
subflow->idsn: the provisional value in __mptcp_sync_state() at
TCP_SYN_SENT, the authoritative one in mptcp_connect(), and the
passive/accept-side value in mptcp_sk_clone_init(). Missing the
first of these would leave a window where a concurrent
getsockopt(MPTCP_INFO) still saw the raw, un-normalized write_seq.
msk->remote_idsn is cached from subflow->iasn in
subflow_set_remote_key() before iasn is incremented for the peer's
virtual SYN, so it lines up with the point local_idsn is cached
relative to write_seq's own +1.
The TCP-fallback path never negotiates an IASN, so msk->remote_idsn
stays at its zero-initialized default there, which is a no-op for
the subtraction and leaves mptcpi_rcv_nxt reporting the plain TCP
sequence number as before.
Link: https://github.com/multipath-tcp/mptcp_net-next/issues/445
Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
---
Changes since v1:
- cached msk->remote_idsn before subflow->iasn++ instead of after:
the increment accounts for the peer's virtual SYN, and caching
remote_idsn post-increment left mptcpi_rcv_nxt starting at 0 while
mptcpi_write_seq/mptcpi_snd_una started at 1 for the same
connection.
v1: https://lore.kernel.org/all/20260825113355.3573376-1-kalpan.jani@mpiricsoftware.com/
---
net/mptcp/protocol.c | 3 +++
net/mptcp/protocol.h | 7 +++++++
net/mptcp/sockopt.c | 6 +++---
net/mptcp/subflow.c | 2 ++
4 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index f22d64ab1c53b..47faece545f15 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3764,6 +3764,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->token, subflow_req->token);
+ WRITE_ONCE(msk->local_idsn, subflow_req->idsn);
msk->in_accept_queue = 1;
WRITE_ONCE(msk->fully_established, false);
if (mp_opt->suboptions & OPTION_MPTCP_CSUMREQD)
@@ -4204,6 +4205,8 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
WRITE_ONCE(msk->write_seq, subflow->idsn);
WRITE_ONCE(msk->snd_nxt, subflow->idsn);
WRITE_ONCE(msk->snd_una, subflow->idsn);
+ WRITE_ONCE(msk->local_idsn, subflow->idsn);
+
if (likely(!__mptcp_check_fallback(msk)))
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 3d250e8204d52..c1a709b2287f0 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -306,6 +306,13 @@ struct mptcp_sock {
u64 bytes_acked;
u64 snd_una;
u64 wnd_end;
+ /*
+ * cached IDSN/IASN, so mptcp_diag_fill_info() can report
+ * write_seq/snd_una/rcv_nxt normalized to start near 0
+ * instead of the raw, crypto-derived initial values.
+ */
+ u64 local_idsn;
+ u64 remote_idsn;
u32 last_data_sent;
u32 last_data_recv;
u32 last_ack_recv;
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 922f6ae5c80cb..fb3dfa88eba5a 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -1086,7 +1086,7 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
slow = lock_sock_fast(sk);
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 - msk->local_idsn;
info->mptcpi_retransmits = inet_csk(sk)->icsk_retransmits;
info->mptcpi_bytes_sent = msk->bytes_sent;
info->mptcpi_bytes_received = msk->bytes_received;
@@ -1100,8 +1100,8 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
mptcp_data_lock(sk);
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 - msk->local_idsn;
+ info->mptcpi_rcv_nxt = msk->ack_seq - msk->remote_idsn;
info->mptcpi_bytes_acked = msk->bytes_acked;
mptcp_data_unlock(sk);
}
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 2d7ccb01d2342..9a4a818552290 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -466,6 +466,7 @@ void __mptcp_sync_state(struct sock *sk, int state)
* even for the FASTOPEN scenarios
*/
WRITE_ONCE(msk->write_seq, subflow->idsn + 1);
+ WRITE_ONCE(msk->local_idsn, subflow->idsn);
WRITE_ONCE(msk->snd_nxt, msk->write_seq);
mptcp_set_state(sk, state);
sk->sk_state_change(sk);
@@ -485,6 +486,7 @@ static void subflow_set_remote_key(struct mptcp_sock *msk,
subflow->remote_key_valid = 1;
subflow->remote_key = mp_opt->sndr_key;
mptcp_crypto_key_sha(subflow->remote_key, NULL, &subflow->iasn);
+ WRITE_ONCE(msk->remote_idsn, subflow->iasn);
subflow->iasn++;
/* for fallback's sake */
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-08-27 4:10 [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info Kalpan Jani
@ 2026-08-27 5:15 ` MPTCP CI
2026-08-31 10:29 ` Matthieu Baerts
1 sibling, 0 replies; 10+ messages in thread
From: MPTCP CI @ 2026-08-27 5:15 UTC (permalink / raw)
To: Kalpan Jani; +Cc: mptcp
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! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/33039401339
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/842add44df40
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1152387
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)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-08-27 4:10 [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info Kalpan Jani
2026-08-27 5:15 ` MPTCP CI
@ 2026-08-31 10:29 ` Matthieu Baerts
2026-09-01 5:19 ` Kalpan Jani
1 sibling, 1 reply; 10+ messages in thread
From: Matthieu Baerts @ 2026-08-31 10:29 UTC (permalink / raw)
To: Kalpan Jani, mptcp; +Cc: martineau, pabeni, shardul.b, janak, kalpanjani009
Hi Kalpan,
On 27/08/2026 06:10, Kalpan Jani wrote:
> mptcpi_write_seq, mptcpi_snd_una and mptcpi_rcv_nxt report the raw
> 64-bit data sequence numbers, seeded from the connection's IDSN/IASN.
> Since the IDSN/IASN come from mptcp_crypto_key_sha(), these fields
> carry an effectively random offset and are not useful to userspace as
> absolute values: a caller has to snapshot two getsockopt(MPTCP_INFO)
> calls and subtract to get anything meaningful, which is exactly what
> tools/testing/selftests/net/mptcp/mptcp_sockopt.c already does.
>
> mptcp_info also reports mptcpi_bytes_sent, mptcpi_bytes_received and
> mptcpi_bytes_acked, which give the same information as a plain byte
> count starting at 0. The snapshot-and-diff workaround for the seq
> fields is redundant once those are available.
Thank you for looking at this!
> Cache the local and remote initial sequence numbers on the
> mptcp_sock the same way ->token already is, and subtract them in
> mptcp_diag_fill_info(), so mptcpi_write_seq, mptcpi_snd_una and
> mptcpi_rcv_nxt also start near 0 for a freshly established
> connection.
Not to increase msk's size for these fields only used in the diag side
(under the msk lock I think), couldn't you get the info from the first
subflow instead? It should always be available (except when being
disconnected, but the other fields should be 0 in this case, no?)
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-08-31 10:29 ` Matthieu Baerts
@ 2026-09-01 5:19 ` Kalpan Jani
2026-09-01 5:55 ` Matthieu Baerts
0 siblings, 1 reply; 10+ messages in thread
From: Kalpan Jani @ 2026-09-01 5:19 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: mptcp, martineau, pabeni, shardul.b, janak, kalpanjani009
Hey Matt,
Thanks for the suggestion. I dug into msk->first before reworking it.
Turns out it's only ever set once (either connect side or accept side) and never reassigned to a different subflow after that, so at least we don't have to worry about picking up idsn from the wrong one later.
But it does go NULL independent of whether other subflows are still around, and it's not even a rare thing. I added a debug print in __mptcp_close_ssk() and ran mptcp_join.sh, and it happens constantly with other subflows still in the list. I couldn't find anywhere that write_seq/snd_una/ack_seq get reset in that case either, so reading idsn/iasn straight off msk->first in mptcp_diag_fill_info() would need a NULL check, otherwise it'd crash pretty often during normal multi-subflow use.
Happy to add that check and go with your approach for v3, just wanted to confirm first since it looked like a common path rather than an edge case.
Cheers,
Kalpan Jani
From: Matthieu Baerts <matttbe@kernel.org>
To: "Kalpan Jani"<kalpan.jani@mpiricsoftware.com>, <mptcp@lists.linux.dev>
Cc: <martineau@kernel.org>, <pabeni@redhat.com>, <shardul.b@mpiricsoftware.com>, <janak@mpiric.us>, <kalpanjani009@gmail.com>
Date: Mon, 31 Aug 2026 15:59:46 +0530
Subject: Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
> Hi Kalpan,
>
> On 27/08/2026 06:10, Kalpan Jani wrote:
> > mptcpi_write_seq, mptcpi_snd_una and mptcpi_rcv_nxt report the raw
> > 64-bit data sequence numbers, seeded from the connection's IDSN/IASN.
> > Since the IDSN/IASN come from mptcp_crypto_key_sha(), these fields
> > carry an effectively random offset and are not useful to userspace as
> > absolute values: a caller has to snapshot two getsockopt(MPTCP_INFO)
> > calls and subtract to get anything meaningful, which is exactly what
> > tools/testing/selftests/net/mptcp/mptcp_sockopt.c already does.
> >
> > mptcp_info also reports mptcpi_bytes_sent, mptcpi_bytes_received and
> > mptcpi_bytes_acked, which give the same information as a plain byte
> > count starting at 0. The snapshot-and-diff workaround for the seq
> > fields is redundant once those are available.
>
> Thank you for looking at this!
>
> > Cache the local and remote initial sequence numbers on the
> > mptcp_sock the same way ->token already is, and subtract them in
> > mptcp_diag_fill_info(), so mptcpi_write_seq, mptcpi_snd_una and
> > mptcpi_rcv_nxt also start near 0 for a freshly established
> > connection.
> Not to increase msk's size for these fields only used in the diag side
> (under the msk lock I think), couldn't you get the info from the first
> subflow instead? It should always be available (except when being
> disconnected, but the other fields should be 0 in this case, no?)
>
> Cheers,
> Matt
> --
> Sponsored by the NGI0 Core fund.
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-09-01 5:19 ` Kalpan Jani
@ 2026-09-01 5:55 ` Matthieu Baerts
2026-09-02 6:48 ` Kalpan Jani
0 siblings, 1 reply; 10+ messages in thread
From: Matthieu Baerts @ 2026-09-01 5:55 UTC (permalink / raw)
To: Kalpan Jani; +Cc: mptcp, martineau, pabeni, shardul.b, janak, kalpanjani009
Hi Kalpan,
01 Sept 2026 07:19:21 Kalpan Jani <kalpan.jani@mpiricsoftware.com>:
> Hey Matt,
>
> Thanks for the suggestion. I dug into msk->first before reworking it.
>
> Turns out it's only ever set once (either connect side or accept side) and never reassigned to a different subflow after that, so at least we don't have to worry about picking up idsn from the wrong one later.
>
> But it does go NULL independent of whether other subflows are still around, and it's not even a rare thing. I added a debug print in __mptcp_close_ssk() and ran mptcp_join.sh, and it happens constantly with other subflows still in the list. I couldn't find anywhere that write_seq/snd_una/ack_seq get reset in that case either, so reading idsn/iasn straight off msk->first in mptcp_diag_fill_info() would need a NULL check, otherwise it'd crash pretty often during normal multi-subflow use.
Thank you for having checked.
Is it not only set to NULL when the whole msk is being destroyed? So
yes, it could be set to NULL first while closing all the subflows, but is it
an issue at that stage? Maybe you will need to add an extra check to
avoid a crash, but (I didn't check) maybe there are already protections
in place and it cannot race.
(Note: I'm not on my laptop, I didn't verify this)
Cheers,
Matt
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-09-01 5:55 ` Matthieu Baerts
@ 2026-09-02 6:48 ` Kalpan Jani
2026-09-02 7:46 ` Matthieu Baerts
0 siblings, 1 reply; 10+ messages in thread
From: Kalpan Jani @ 2026-09-02 6:48 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: mptcp, martineau, pabeni, shardul.b, janak, kalpanjani009
Hi Matt,
You were right, thanks for pushing back on that. I added msk_state to the same debug print and reran mptcp_join.sh - every single instance of msk->first going NULL shows msk_state=7 (TCP_CLOSE), no exceptions across several hundred hits. So it really is only happening as part of the whole msk already being torn down, like you said, not during a live connection.
I'll rework v3 to read idsn/iasn straight off msk->first instead of adding the two new fields, per your suggestion.
Cheers,
Kalpan Jani
From: Matthieu Baerts <matttbe@kernel.org>
To: "Kalpan Jani"<kalpan.jani@mpiricsoftware.com>
Cc: "mptcp"<mptcp@lists.linux.dev>, "martineau"<martineau@kernel.org>, "pabeni"<pabeni@redhat.com>, "shardul.b"<shardul.b@mpiricsoftware.com>, "janak"<janak@mpiric.us>, "kalpanjani009"<kalpanjani009@gmail.com>
Date: Tue, 01 Sep 2026 11:25:08 +0530
Subject: Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
> Hi Kalpan,
>
> 01 Sept 2026 07:19:21 Kalpan Jani <kalpan.jani@mpiricsoftware.com>:
>
> > Hey Matt,
> >
> > Thanks for the suggestion. I dug into msk->first before reworking it.
> >
> > Turns out it's only ever set once (either connect side or accept side) and never reassigned to a different subflow after that, so at least we don't have to worry about picking up idsn from the wrong one later.
> >
> > But it does go NULL independent of whether other subflows are still around, and it's not even a rare thing. I added a debug print in __mptcp_close_ssk() and ran mptcp_join.sh, and it happens constantly with other subflows still in the list. I couldn't find anywhere that write_seq/snd_una/ack_seq get reset in that case either, so reading idsn/iasn straight off msk->first in mptcp_diag_fill_info() would need a NULL check, otherwise it'd crash pretty often during normal multi-subflow use.
>
> Thank you for having checked.
>
> Is it not only set to NULL when the whole msk is being destroyed? So
> yes, it could be set to NULL first while closing all the subflows, but is it
> an issue at that stage? Maybe you will need to add an extra check to
> avoid a crash, but (I didn't check) maybe there are already protections
> in place and it cannot race.
>
> (Note: I'm not on my laptop, I didn't verify this)
>
> Cheers,
> Matt
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info
2026-09-02 6:48 ` Kalpan Jani
@ 2026-09-02 7:46 ` Matthieu Baerts
0 siblings, 0 replies; 10+ messages in thread
From: Matthieu Baerts @ 2026-09-02 7:46 UTC (permalink / raw)
To: Kalpan Jani; +Cc: mptcp, shardul.b, janak, kalpanjani009
Hi Kalpan,
On 02/09/2026 08:48, Kalpan Jani wrote:
> Hi Matt,
>
> You were right, thanks for pushing back on that. I added msk_state to the same debug print and reran mptcp_join.sh - every single instance of msk->first going NULL shows msk_state=7 (TCP_CLOSE), no exceptions across several hundred hits. So it really is only happening as part of the whole msk already being torn down, like you said, not during a live connection.
>
> I'll rework v3 to read idsn/iasn straight off msk->first instead of adding the two new fields, per your suggestion.
Great, thank you for having checked and working on a v3.
BTW, a "detail", but top-posting is not recommended on (kernel) mailing
lists:
https://subspace.kernel.org/etiquette.html#do-not-top-post-when-replying
Also, here, no need to include MPTCP people in cc (Paolo, Mat, myself),
we get such emails via the mailing list.
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-09-02 7:46 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-27 4:10 [PATCH net-next v2] mptcp: normalize seq numbers reported in mptcp_info Kalpan Jani
2026-08-27 5:15 ` MPTCP CI
2026-08-31 10:29 ` Matthieu Baerts
2026-09-01 5:19 ` Kalpan Jani
2026-09-01 5:55 ` Matthieu Baerts
2026-09-02 6:48 ` Kalpan Jani
2026-09-02 7:46 ` Matthieu Baerts
-- strict thread matches above, loose matches on Subject: below --
2026-08-25 11:33 [PATCH net-next] " Kalpan Jani
2026-08-26 6:03 ` [PATCH net-next v2] " Kalpan Jani
2026-08-26 7:26 ` MPTCP CI
2026-08-26 9:48 ` Kalpan Jani
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox