Zero-Copy L4 Load Balancing and Socket Splicing with eBPF SOCKMAP and sk_msg
In multi-tenant edge architectures, it is common to place a Layer-4 SNI router (such as HAProxy in mode tcp or Nginx stream) in front of specialized backend daemons bound to loopback addresses (127.0.0.1). While convenient operationally, each loopback hop traditionally traverses the TCP/IP stack twice per packet.
1. Anatomy of Loopback Overhead
Without kernel bypass or splice assistance, forwarding a single 16 KB TLS record from a public NIC socket to a local backend socket requires:
- Copying payload bytes from the ingress socket receive queue into userspace memory (or pipe page buffers via
splice(2)). - Writing those bytes into the loopback egress socket, allocating a new
sk_buff, and scheduling softirqNET_RX_SOFTIRQoverlo. - Waking the target daemon blocked on
epoll_wait(2).
2. Short-Circuiting Local Sockets with BPF_MAP_TYPE_SOCKHASH
By attaching a BPF_PROG_TYPE_SOCK_OPS program to the cgroup root, the kernel notifies our eBPF program whenever a TCP connection transitions to BPF_TCP_ESTABLISHED. We key the 4-tuple into a SOCKHASH map and attach a BPF_PROG_TYPE_SK_SKB verdict program:
SEC("sk_skb/stream_verdict")
int bpf_sockmap_verdict(struct __sk_buff *skb) {
struct sock_key key = {};
extract_key4_from_skb(skb, &key);
return bpf_sk_redirect_hash(skb, &sock_ops_map, &key, BPF_F_INGRESS);
}
Even when eBPF SOCKMAP is not deployed, modern userspace proxies running on Linux 6.12 achieve near-zero-copy throughput by combining splice(2) between sockets with direct packet forwarding once the inner handshake completes, keeping CPU utilization below 2% at 1 Gbps line rate.