v1.3.0 — 2026-06-17
Primarily a correctness release. An adversarial review of the substrate against its
primary references (the RFCs, Linux sch_cake.c, the reference DualPI2, and the
fair-queueing papers) found and fixed a set of behavioural defects, each pinned by a
regression test. It also adds one backward-compatible option — a configurable TSW
averaging-window length (hence a minor, not a patch, release). No breaking API
changes. The most significant changes are the WFQ scheduler losing weighted fairness
after a full drain and reactivation, and the L4S queue now applying its congestion
signal at dequeue from each packet's own sojourn time; both alter the output of
affected simulations.
Schedulers
- WFQ: fixed a virtual-time blow-up after the busy set fully drains and a flow
reactivates. With non-integer weights the running weight sum retained a
one-ULP floating-point residue, which drove the virtual time to roughly 1e16 on
the next arrival and collapsed weighted service to strict priority by queue
index. The weight sum is now pinned to zero whenever the queue empties (Parekh &
Gallager 1993). - LLQ: the priority-lane rate cap now engages and releases correctly. The inner
priority scheduler never observed its own departures, and its lone queue's
work-conserving fallback served the priority lane even over the cap; the lane is
now policed to its configured rate and is served again once its measured rate
decays back under the cap (RFC 3246). - Hybrid-LLQ across-tin DRR: the round-robin cursor now advances off a slot
that drains to empty (matching the pure-DRR sibling and Linuxcake_dequeue), so
a flow that bounces on and off empty no longer monopolises service.
CAKE
- ACK filter: a data-bearing (piggybacked) ACK, or one carrying an unknown,
malformed, or truncated TCP option, is now a valid filtering trigger, matching
sch_cake.c; the pure-ACK and option checks apply to the queued drop candidates,
not the triggering packet. - Autorate-ingress: the rate reconfigure now fires on each measurement-window
close after the shaper warm-up, matching the kernel's effective cadence, instead
of on a rolling per-packet timer; the window byte count uses the raw packet
length, as the kernel does. - diffserv4 DSCP map (rate-based shaper): corrected the tin mapping for four
code points (DSCP 4, 10, 12, 14) to match the Linuxdiffserv4[]table the
default composition already uses. - diffserv-precedence DRR weights: the per-tin weights now follow the Linux
sch_cakeprecedence quantum ladder; the earlier weights were ordered against
the kernel's.
L4S
- Dequeue-time marking: the L4S congestion signal is now applied at dequeue,
from each packet's own queue-sojourn time, rather than at enqueue from the
head-of-queue packet; the coupled mark and drop are suppressed while the standing
queue is below two MTUs. This matches the reference DualPI2. - DualPI2 controller: the proportional term is now applied against an initial
previous-queue of zero on the first controller tick, matching the reference
DualPI2 implementation and the RFC 9332 pseudocode.
Meters and edge
- Flow-weighted meter: the deterministic, probabilistic, and periodic penalty
modes are now honoured on the classification path (previously every configuration
behaved deterministically). - DSCP routing: the code-point index is masked to six bits on the enqueue path
so a misconfigured value cannot read past the routing table. - RED / RIO sub-queue: the per-precedence state array is now bounds-checked on
the RIO and PHB paths, closing a latent out-of-bounds access from a misconfigured
precedence index. - TSW meters: the averaging-window length is now configurable through the
helper (previously fixed at one second).
Tests
- Host-isolation jitter-floor test: re-grounded a fragile single-replica band
to the mean of five jitter replicas (a single replica of this chaotic scenario
is not portable across hosts). Behaviour is unchanged; the band is now derived
from the measured ensemble rather than one low replica.