[PATCH net v2 0/4] sctp: fix I-FORWARD-TSN handling with user message interleaving
From: Tim Budding
Date: Thu Nov 05 2026 - 00:04:03 EST
With user message interleaving (RFC 8260), fragments of messages on
different streams share the TSN space. When a PR-SCTP message is
abandoned, the receiver still frees queued fragments by the
I-FORWARD-TSN's New Cumulative TSN, which loses fragments of messages
still being received on other streams:
TSN stream MID
0 0 0 B 64KB reliable message on stream 0
...
5 0 0
6 1 0 BE PR-SCTP message on stream 1, lost, abandoned
7 0 0
...
I-FORWARD-TSN new_cum=6 skip=[sid=1 mid=0]
The stream 0 fragments with TSNs 0-5 are freed with the abandoned
message, are never retransmitted, and stream 0 stays blocked.
Patch 3 frees fragments by the skip entries instead of by TSN, and no
longer treats an I-FORWARD-TSN that reaches the highest TSN seen as a
reset. Such an I-FORWARD-TSN is then handled by sctp_intl_skip() alone,
which has two partial delivery bugs of its own: an unordered partial
delivery is not aborted when its own message is skipped, and
PARTIAL_DELIVERY_ABORTED reports the highest skipped MID rather than
the one being delivered. Patches 1 and 2 fix these first, so the three
fixes should be backported together and in order. Patch 4 adds a
selftest.
Patch 3 has a cost, as discussed on v1 [2]: an unordered fragment of an
abandoned message that first arrives after the last I-FORWARD-TSN
naming that message is no longer freed by a later, unrelated
I-FORWARD-TSN. It keeps its rwnd and receive buffer charge until a
later unordered skip on its stream, a reset, or teardown. Dropping such
fragments on arrival needs new per-stream state and is left to a
follow-up [3].
Changes since v1 [1]:
- Fold "sctp: don't treat an I-FORWARD-TSN as an association reset"
into the purge patch, now patch 3, as Xin suggested [3].
- New patch 2, from Sashiko's review of v1 patch 3.
- Move the unordered partial delivery fix first.
- Selftest: add leading_edge_nopd, reset_pending_srv/cli and
pdapi/pdapi_uo; wait for conditions rather than fixed times,
including all data being acked before the queue check.
Tested with the new selftest, sctp_vrf.sh and the lksctp-tools
functional tests, also on a kernel with KASAN, lockdep and kmemleak.
W=1 and sparse show no new warnings.
Initial bug observed in use, root cause identified with AI-assisted code
inspection. Related bugs found and fixes implemented with AI assistance.
All reviewed and tested by me.
[1] https://lore.kernel.org/all/20261024120627.837568-1-tim.budding@xxxxxxxxx/
[2] https://lore.kernel.org/all/20261026052706.187296-1-tim.budding@xxxxxxxxx/
[3] https://lore.kernel.org/all/CADvbK_du=-oT19kKBKYSjFKYscnQSH1mekRKMXgmLPMXTEH_=w@xxxxxxxxxxxxxx/
Tim Budding (4):
sctp: abort unordered partial delivery when its message is skipped
sctp: report the partially delivered MID in PARTIAL_DELIVERY_ABORTED
sctp: fix I-FORWARD-TSN handling of fragments on other streams
selftests: net: add SCTP I-FORWARD-TSN tests with message interleaving
net/sctp/stream.c | 2 +
net/sctp/stream_interleave.c | 38 +-
tools/testing/selftests/net/.gitignore | 1 +
tools/testing/selftests/net/Makefile | 2 +
tools/testing/selftests/net/sctp_ifwdtsn.c | 699 ++++++++++++++++++++
tools/testing/selftests/net/sctp_ifwdtsn.sh | 233 +++++++
6 files changed, 951 insertions(+), 24 deletions(-)
create mode 100644 tools/testing/selftests/net/sctp_ifwdtsn.c
create mode 100755 tools/testing/selftests/net/sctp_ifwdtsn.sh
base-commit: 6baae996ecf6a3f57b08ea6f6786e29af9260f51
--
2.34.1