Carrier-grade routing architectures that utilize Segment Routing over IPv6 (SRv6) End.B6-Redirection mechanisms allow core nodes to steer incoming packets into alternate SRv6 policy paths dynamically. To maintain cryptographic integrity across critical inter-domain BGP peers, networks implement TCP Authentication Option (TCP-AO, RFC 5925). However, during asynchronous key rollover sequences, asymmetric key states can cause MAC verification failures on incoming SYN-ACK packets, triggering retransmissions tracked via tcpi_retrans_synack in Linux struct tcp_info. Combined with receive window clamping under dynamic policy redirection, packets may be dropped unexpectedly in the kernel network stack. Diagnosing these subtle edge conditions requires low-overhead extended Berkeley Packet Filter (eBPF) tracing. This tutorial outlines how to author, compile, and run an eBPF tracing workflow for SRv6 End.B6-Redirection in Linux.
Kernel Fundamentals: TCP-AO and SRv6 End.B6-Redirection
Under modern Linux kernels (version 6.x+), TCP-AO validates segment authenticators against key configurations maintained in struct tcp_ao_info. During an asymmetric key transition, if the remote peer transmits an updated Key ID before the local kernel updates its active keychain, SYN-ACK verification fails. The connection stalls and retransmits according to kernel exponential backoff timers, incrementing tcpi_retrans_synack.
Concurrently, when an SRv6 router executes an End.B6-Redirection action (seg6_do_srh_redirect()), the segment routing header is rewritten to steer the packet toward a backup path. If the redirected path imposes lower MTU constraints or if packet reordering occurs, the TCP stack clamps the receive window (rcv_wnd) or drops segments inside seg6_lookup_nexthop(). Capturing both the socket state and segment routing actions in real time requires targeted eBPF kprobes.
Writing the eBPF Telemetry Program
Save the following source code as trace_srv6_b6_redirect_ao.bpf.c:
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>
char LICENSE[] SEC("license") = "Dual BSD/GPL";
struct drop_event {
__u32 saddr[4];
__u32 daddr[4];
__u16 sport;
__u16 dport;
__u8 retrans_synack;
__u32 snd_wnd;
__u32 rcv_wnd;
__u32 drop_reason;
};
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 1 << 24);
} events SEC(".maps");
SEC("kprobe/tcp_rtx_synack")
int BPF_KPROBE(trace_tcp_rtx_synack, struct sock *sk, struct request_sock *req)
{
struct tcp_sock *tp = (struct tcp_sock *)sk;
struct drop_event *e;
e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
if (!e)
return 0;
e->sport = BPF_CORE_READ(sk, __sk_common.skc_num);
e->dport = BPF_CORE_READ(sk, __sk_common.skc_dport);
e->retrans_synack = BPF_CORE_READ(tp, total_retrans);
e->snd_wnd = BPF_CORE_READ(tp, snd_wnd);
e->rcv_wnd = BPF_CORE_READ(tp, rcv_wnd);
e->drop_reason = 701; // Key rollover mismatch
bpf_ringbuf_submit(e, 0);
return 0;
}
SEC("kprobe/seg6_do_srh_redirect")
int BPF_KPROBE(trace_seg6_srh_redirect, struct sk_buff *skb)
{
__u32 len = BPF_CORE_READ(skb, len);
if (len > 1460) {
struct drop_event *e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
if (e) {
e->drop_reason = 802; // SRv6 End.B6-Redirection MTU breach
bpf_ringbuf_submit(e, 0);
}
}
return 0;
}
Compiling and Loading the eBPF Program
Compile the BPF object file using Clang and load it into the kernel via bpftool:
# Install build dependencies
sudo apt-get install -y clang llvm libbpf-dev linux-tools-common linux-tools-$(uname -r)
# Compile bytecode
clang -g -O2 -target bpf -D__TARGET_ARCH_x86 -c trace_srv6_b6_redirect_ao.bpf.c -o trace_srv6_b6_redirect_ao.bpf.o
# Load probe into kernel
bpftool prog load trace_srv6_b6_redirect_ao.bpf.o /sys/fs/bpf/trace_srv6_b6_redirect_ao type kprobe
Observing Kernel Ring Buffer Events
Stream decoded JSON events directly from the eBPF ring buffer:
# Stream decoded ringbuffer events
sudo bpftool map dump name events -j | jq '.[] | {sport: .value.sport, dport: .value.dport, retrans: .value.retrans_synack, reason: .value.drop_reason}'
Diagnostic Reference for SRv6 End.B6-Redirection Drops
| Observed Event | Probable Root Cause | Remediation Procedure |
|---|---|---|
| Reason 701 (SYN-ACK Retrans) | Asymmetric TCP-AO key negotiation discrepancy | Verify active keyrings in ip tcp_metrics and coordinate peer rollover |
| Reason 802 (Redirect MTU Drop) | Redirected SRv6 path imposes a smaller MTU boundary | Clamp TCP MSS to 1380 bytes using iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu |
| Receive window collapse | Buffer queue saturation during high redirection volume | Tune net.core.netdev_max_backlog and net.ipv4.tcp_rmem |
Using this eBPF tracing workflow provides clear operational visibility into cryptographic session maintenance and segment-routed packet processing on modern Linux distributions.