๐Ÿ

eBPF Traffic Redirect โ€” Swapping Destinations at the Kernel Level

How Keploy, Cilium, and Istio control traffic without modifying app code

What is eBPF

eBPF (extended Berkeley Packet Filter) lets you run user-written programs inside the Linux kernel without modifying kernel code.

Used for network packet processing, syscall tracing, security policy enforcement. The key: it runs inside the kernel, with far less overhead than userspace.

connect() syscall and eBPF Hooks

What happens internally when an app connects to a DB:

1. App code: db.connect("postgres://localhost:5432")
2. Library (pg, psycopg2): socket() โ†’ connect() syscall
3. Kernel: TCP SYN โ†’ SYN-ACK โ†’ ACK (3-way handshake)
4. PostgreSQL wire protocol begins

eBPF hooks between steps 2-3. At the moment connect() executes, it checks the destination and swaps it to a different address if needed.

From the app's perspective, it connected to postgres:5432. The actual TCP packets go to 127.0.0.1:16789 (proxy). The app doesn't know.

eBPF Program Types and Hook Points

SockOps (BPF_PROG_TYPE_SOCK_OPS) โ€” monitors TCP events (connection establishment, teardown). Attaches to cgroups to select specific container TCP events.

connect4/connect6 (BPF_CGROUP_INET4_CONNECT) โ€” modifies destination IP:Port directly at connect() syscall entry. This is the core hook Keploy uses.

TC (Traffic Control) โ€” attaches to network interfaces. Per-packet filtering/redirect. Used by Cilium for pod traffic control.

XDP (eXpress Data Path) โ€” processes packets before they enter the kernel network stack at the NIC. Fastest but most constrained.

Try It Yourself

To see eBPF traffic redirect in action:

# 1. Trace connect() syscalls
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_connect {
  printf("%s[%d] โ†’ connect()\n", comm, pid);
}'

# 2. Trace TCP connection destinations
sudo bpftrace -e 'kprobe:tcp_v4_connect {
  printf("%s โ†’ %s:%d\n", comm,
    ntop(((struct sockaddr_in *)arg1)->sin_addr.s_addr),
    ntohs(((struct sockaddr_in *)arg1)->sin_port));
}'

With Keploy active, watch connect() destinations change from postgres:5432 to 127.0.0.1:proxyPort.

Quick Test with Keploy

curl -O -L https://keploy.io/install.sh && source install.sh
keploy record -c "docker compose up" --container-name my-app
keploy test -c "docker compose up" --container-name my-app

On macOS, only works on Docker Desktop โ€” eBPF is a Linux kernel feature.

How It Works

1

eBPF program loads into kernel โ€” intercepts connect() syscall via connect4 hook

2

App calls connect(postgres:5432) ๏ฟฝ๏ฟฝ eBPF modifies destination to proxy (127.0.0.1:proxyPort)

3

Proxy relays to real destination while recording (record) or returns recorded responses (replay)

4

App is unaware destination changed โ€” kernel-level transparent redirect

Use Cases

Keploy โ€” redirects DB/API traffic to proxy via connect4 hook, auto-generates tests Cilium โ€” controls Kubernetes pod traffic via TC hooks. Replaces iptables Istio ambient โ€” service mesh without sidecars via eBPF Beyla โ€” auto-detects HTTP/gRPC/SQL via XDP/TC, collects OpenTelemetry metrics