XDP

XDP 或 eXpress Data Path 在 Linux 内核中提供高性能、可编程的网络数据路径。

XDP 在软件堆栈的最低点提供裸机数据包处理,这使得它非常适合在不影响可编程性的情况下提高速度。

无需修改内核即可通过集成的快速路径动态实现新功能。

XDP 数据包进程包括一个内核组件,该组件通过功能接口直接从驱动程序处理 RX 数据包页面,而无需提前分配 skbuff 或软件队列。 通常,每个 RX 队列分配一个 CPU,但在此模型中,没有锁定 RX 队列,CPU 可以专用于忙轮询或中断模型。

BPF 程序执行诸如数据包解析、表查找、创建/管理有状态过滤器、封装/去封装数据包等处理。

BPF 的可扩展性与数据包检查和操作功能、流和表查找以及利用可移植到用户空间和其他操作系统的 BPF 程序的应用程序处理保持完整。

用例包括

○ 堆栈前处理,如过滤以进行 DOS 缓解

○ 转发和负载均衡

○ 批处理技术,例如通用接收卸载

○ 流量采样、监测

○ ULP 处理(例如消息描述)

如果传统的内核网络堆栈是高速公路,则内核旁路是建立高速列车基础设施的建议,而 XDP 是在高速公路上增加拼车车道的建议。

提高性能的技术

  • 无锁
  • 批量 I/O 操作
  • 忙轮询
  • 直接队列访问
  • 页面回收,尽可能避免页面分配/空闲
  • 无元数据(skbuff)分配的数据包处理
  • 高效的表(流状态)查找
  • 数据包导向
  • 孤立处理,最大限度地减少跨 CPU/NUMA 节点操作
  • RX 流哈希
  • 常见的 NIC 卸载
  • 明智的缓存预取,DDIO

一些硬件要求

  • 多队列网卡
  • 通用协议通用卸载

○ TX/RX 校验和卸载

○ 接收端缩放 (RSS)

○ 传输分段卸载 (TSO)

  • LRO、aRFS、来自设备的流散列是“不错的选择”

XDP数据包处理器:

  • 在处理 RX 数据包的内核组件中
  • 直接从驱动程序处理 RX “packet-pages”

○ 功能界面

○ 没有提前分配 skbuff,没有 SW 队列

  • 名义上为每个 RX 队列分配一个 CPU

○ 无锁RX队列

○ CPU 可以专用于忙轮询或使用中断模式

  • BPF 程序执行处理

○ 解析数据包

○ 执行表查找,创建/管理有状态过滤器

○ 操作数据包(例如用于封装/去封装)

○ 退货操作

 

基本的 XDP 数据包处理器操作

  • 转发

○ 可能在数据包修改之后(例如 NAT、ILA 路由器)

○ TX 队列是同一个 CPU 独占的,所以不需要锁

  • 丢弃

○ 只是从函数中返回错误

○ 驱动回收页

  • 正常接收

○ 分配 skbuff 并接收到堆栈

○ 将数据包转向另一个 CPU 进行处理

○ 允许用户空间的“原始”接口,如 AF_PACKET、netmap

  • 通用接收卸载

○ 合并相同连接的数据包

○ 执行大数据包的接收

 

可编程性

  • 数据包检查,BPF 程序发现的动作

○ 灵活(无循环)协议头解析

○ 可能由于流查找而有状态

○ 简单的包字段重写(encap/decap)

  • 优化查找

○ 流查找(例如使用设备提供的流哈希)

○ 固定长度查找(例如,ILA 的 64 位标识符查找)

○ 有状态,使临时状态(例如 GRO 需要)

  • 可扩展模型

○ 应用程序处理(例如应用层协议 GRO)

○ 利用正在进行的工作将 BPF 卸载到 HW

○ BPF 程序可以移植到用户空间或其他操作系统

 

 

依赖关系

主要依赖项是 libbpf、llvm、clang 和 libelf。 LLVM+clang 将我们的受限 C 程序编译成 BPF 字节代码,该代码存储在一个 ELF 目标文件 (libelf) 中,由 libbpf 通过 bpf 系统调用加载到内核中。 一些课程还使用 perf 实用程序通过跟踪点跟踪内核行为。