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
58KB
1K SLoC
AFXDP-rs
此模块提供了AF_XDP的Rust接口,它包装了基于libbpf-sys构建的libbpf。
作者: Dan Siemon <[email protected]>
AF_XDP (XSK)
本库的目标依次是
- 正确性
- 性能
- 易用性
当前状态
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