Linux eBPF 的 XDP vs TC vs socket filter 的网络性能优化层级对比

2次阅读

xdp是运行在网卡驱动收包最早环节的极速过滤层,直接操作原始dma缓冲区,无需分配skb,适用于ddos防御、负载均衡入口过滤等超低延迟高吞吐场景。

Linux eBPF 的 XDP vs TC vs socket filter 的网络性能优化层级对比

XDP:网络最前端的极速过滤层

XDP(express Data Path)运行在网卡驱动收包的最早环节,数据帧还没进内核协议栈,甚至没分配 skb 结构体。它直接操作原始 DMA 缓冲区,适合做极低延迟、超高吞吐的场景,比如 DDoS 防御、负载均衡入口过滤、L2/L3 快速转发。

优势明显:单核轻松处理 10M+ PPS,延迟通常

  • 不能修改包长(无法分片或添加封装),只能丢弃、透传或重写已存在字段(如 MAC/IP/Port)
  • 不支持 helper 函数访问 socket、路由表、conntrack 等高层状态
  • 需网卡驱动显式支持(如 ixgbe、i40e、mlx5、virtio_net 等主流驱动已支持)

TC(Traffic Control):协议栈入口处的灵活控制层

TC eBPF 程序挂载在内核 qdisc 层(如 cls_bpf),位于 XDP 之后、IP 协议栈之前。此时 skb 已创建,具备完整元数据(如 ingress_ifindex、tc_index),可安全访问部分内核辅助函数(bpf_skb_load_bytes、bpf_skb_store_bytes、bpf_skb_change_head 等)。

这是生产环境最常用的位置,兼顾性能与功能:

  • 支持修改包内容(包括增删头部、调整长度)、重定向到其他设备或 CPU 队列
  • 可与 clsact qdisc 配合实现入口(ingress)和出口(egress)双向控制
  • 能结合 map 做动态策略(如基于五元组限速、标记流量类别供后续 QoS 处理)
  • 性能略低于 XDP(约 2–5M PPS/核),但远高于传统 iptables/nftables

Socket Filter(SO_ATTACH_BPF):应用侧的细粒度流控层

这类 eBPF 程序绑定到具体 socket(TCP/udp),在数据拷贝到用户态前最后一刻执行。它看到的是已解析完成的传输层 payload,上下文包含完整的 socket 信息(如 sk、cgroup、netns)。

典型用途是应用感知型优化:

  • 按进程/容器/用户 ID 过滤或采样流量(配合 cgroup v2)
  • 对特定 socket 的收发行为做审计、延迟注入或协议识别(如 TLS 握手检测)
  • 无法影响包转发路径,也不参与路由决策,纯属“事后”干预
  • 性能开销最大(每包触发一次,且依赖 socket 锁),适合低频策略而非高吞吐场景

选型关键看目标和约束

想在 10G+ 线速下硬防 SYN Flood?XDP 是唯一选择。要做服务网格的透明流量镜像+标签注入?TC 更合适。需要给某个 nginx 实例单独限速并记录连接来源?socket filter 加 cgroup 匹配更精准。三者不是替代关系,而是逐层下沉的协同链路:XDP 做粗筛 → TC 做中转调度 → socket filter 做终端定制。

实际部署中,XDP 和 TC 可共存(XDP 丢恶意包,TC 做正常流量整形),而 socket filter 通常独立使用,避免跨层级耦合。

text=ZqhQzanResources