How to Trace TCP Duplicate SACK (D-SACK) Packet Delivery in Linux Using eBPF

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_nxt or 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 invokes tcp_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.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.