Network path latency jitter frequently causes transmitted TCP segments to arrive out of sequence. If a sender’s retransmission timer fires prematurely or duplicate acknowledgments trigger fast retransmission before the original delayed segment arrives, the receiver ends up receiving duplicate packets. Duplicate SACK (D-SACK, RFC 2883) allows the receiver to report duplicate packet deliveries back to the sender. Senders use D-SACK feedback to undo unnecessary Congestion Window (CWND) reductions via Forward RTO-Recovery (F-RTO). Tracing D-SACK with eBPF isolates spurious retransmission events.
Understanding Linux Kernel D-SACK Mechanics
The Linux TCP implementation handles D-SACK evaluation inside acknowledgment pipelines:
- D-SACK Generation: When an incoming packet’s sequence range falls below
tp->rcv_nxtor matches an already acknowledged SACK block, the receiver embeds a D-SACK block in its acknowledgment header. - Spurious Loss Undo: Upon parsing a D-SACK option inside
tcp_check_dsack(), the sender recognizes that the packet was delayed rather than dropped. It invokestcp_undo_cwr()to restore CWND to pre-congestion dimensions. - Metrics Impact: High D-SACK frequencies indicate network path packet reordering or overly aggressive retransmission timeout timers rather than physical packet drops.
Tracing D-SACK Events in Real Time with bpftrace
Using bpftrace, monitor when the Linux kernel processes incoming D-SACK blocks:
sudo bpftrace -e '
#include <net/sock.h>
#include <linux/tcp.h>
kprobe:tcp_check_dsack {
$sk = (struct sock *)arg0;
$inet = (struct inet_sock *)arg0;
$daddr = ntop($inet->inet_daddr);
$dport = bswap($inet->inet_dport);
printf("D-SACK Received (Spurious Retransmission): remote=%s:%d comm=%s\n",
$daddr, $dport, comm);
@dsack_by_peer[$daddr] = count();
}'
This script logs every socket event where incoming acknowledgments report duplicate data reception, isolating endpoints experiencing spurious retransmissions.
Monitoring Congestion Window Undo Operations
To inspect how frequently D-SACK successfully restores CWND dimensions:
sudo bpftrace -e '
kprobe:tcp_undo_cwr {
@cwnd_undos[comm] = count();
}
interval:s:10 {
print(@dsack_by_peer);
print(@cwnd_undos);
clear(@dsack_by_peer);
clear(@cwnd_undos);
}'
Detecting high D-SACK and undo counts confirms that network interfaces are suffering packet reordering rather than loss, indicating an opportunity to tune net.ipv4.tcp_reordering parameters.