Replacing TPROXY with eBPF
Joe Stringer, Lorenz Bauer
TPROXY use case: Cilium
Current approach with iptables (Cilium)
-j TPROXY --on-port 33683 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
TPROXY use case: Cloudflare Spectrum
| Single IP | Many subnets |
Single Port | bind() | SO_BINDTOPREFIX* |
Many Ports | TPROXY | TPROXY |
Cloudflare Goals
TPROXY magic sauce
ip_rcv
ip_rcv_core
skb_orphan: skb->sk = NULL
NF_HOOK(NF_INET_PRE_ROUTING) <- TPROXY added and removed here, skb->sk = sk
ip_rcv_finish
dst_input
...
tcp_v4_rcv
tcp_v4_rcv
__inet_lookup_skb
skb_steal_sock <- returns skb->sk from TPROXY
Idea #1: set_sk(skb) helper
Idea #2: Hook socket dispatch
Idea #3: Early demux from BPF
sk_lookup_* with SK_REUSEPORT
set_sk question: skb_orphan() in ip_rcv_core
set_sk: what kind of validation?
socket dispatch: how to prevent infinite loop?
socket dispatch: tied to network namespace?
redirect_sk: duplicate work
Question: what should ctx be?