6个版本 (3个重大更新)

0.4.0 2021年3月14日
0.3.0 2021年2月16日
0.2.0 2020年4月10日
0.1.2 2020年1月16日

#xdp中排名第4

Apache-2.0

58KB
1K SLoC

AFXDP-rs

此模块提供了AF_XDP的Rust接口,它包装了基于libbpf-sys构建的libbpf

作者: Dan Siemon <[email protected]>

docs.rs

AF_XDP (XSK)

本库的目标依次是

  1. 正确性
  2. 性能
  3. 易用性

当前状态

API适用于我的当前用例,但预计它将发生变化以实现更高的性能和更好的可用性。

如果您了解Rust FFI和Rust的一般不安全特性,我将非常感谢您对该库进行审计,因为我在这方面的经验有限。

示例程序

examples/中有几个程序

  • l2fwd-1link:在一个链路/队列上接收帧,交换MAC地址并写回相同的链路/队列。这大致类似于l2fwd模式下的内核xdpsock_user.c示例程序。
  • l2fwd-2link:从两个链路/队列对(单独的设备)接收帧并将帧转发到对面的链路。
  • l2fwd-2link-multicore:l2fwd-2link的多核/多队列版本。
  • dump:在一个链路/队列上接收帧,使用Pnet解析并打印数据包。
  • rxdrop:在一个或多个链路和队列上接收数据包,并计数和打印数据包速率。

您可以使用以下命令运行示例程序:cargo run --release --example <example_name> -- [example options] 查看选项列表,运行 cargo run --release --example <example_name> -- --help

性能

测试系统

  • 英特尔® 至强® CPU E5-2680 v4 @ 2.40GHz
  • 单个X710(4个物理10G端口)(i40e)
  • 内核:5.4.2-300.fc31.x86_64
  • 内核引导参数:skew_tick=1 mitigations=off selinux=0 isolcpus=4-27 nohz_full=4-27 rcu_nobcs=4-27 default_hugepagesz=1G hugepagesz=1G hugepages=4

流量生成器

  • 英特尔® 酷睿™ i7-7700 CPU @ 3.60GHz
  • 单个X710(4个物理10G端口)(i40e)
  • 流量从一个端口出发,通过测试系统到达同一X710的第二个端口
  • T-Rex流量生成器(https://trex-tgn.cisco.com/)(DPDK)
  • 64字节UDP数据包

场景1:单个核心上运行的l2fwd-2link用户空间和NAPI

大约在6.5M PPS单向和6.0M PPS双向(每方向3M)时开始出现少量数据包丢失。

对优化投入的努力不多,因此我预计有一些简单的性能提升。

支持的功能

  • HUGE TLB标志到mmap区域:可选(示例程序中的命令行参数)

必需的AF_XDP功能

  • 需要唤醒标志(意味着Linux >= 5.4)
  • 对齐块模式

支持的功能AF_XDP

  • ZEROCOPY标志:可选(示例程序中的命令行参数)
  • 对齐块模式

不支持的功能AF_XDP(目前)

  • 未对齐块模式
  • 共享UMem(Linux 5.10中新增)
  • 忙轮询(Linux 5.11中引入)
  • 非零预留空间

待办事项

  • 目前,此模块不安全,因为Buf可能超出其关联的内存池。我相信解决这个问题需要为每个Buf添加Arc。我还没有时间确定这种修改的性能影响,并欢迎任何其他想法。
  • 所有与Tx、Rx、填充和完成队列的交互都使用C函数完成,这些函数封装了libbpf中的内联函数。我相信这意味着这些热点函数不能在Rust中内联。在中期,我们应该构建纯Rust函数,以便它们可以内联。
  • 可以通过直接与内核通信而不是包装libbpf函数来构建更符合Rust习惯的接口。
  • 调查是否有必要有一个非忙轮询接口。这对于像tcpdump这样的应用程序可能很有用,在这些应用程序中,分配核心/线程并不理想。

依赖关系

~8.5MB
~196K SLoC