linux xdp简介
Posted rayylee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux xdp简介相关的知识,希望对你有一定的参考价值。
XDP是利用ebpf提供的全新内核网络性能提升方案,主要优势包括:
- 它不需要任何专门的硬件
- 它不需要内核绕过
- 它不会取代 TCP/IP 堆栈
- 它与 TCP/IP 堆栈以及 BPF 的所有优点协同工作
在没有引入XDP之前,原来是的内核网络数据包传输路径是这样的:
NIC > driver 驱动> tc流控 ==> netfilter ==> IP/TCP协议栈 ==> socket
启用XDP后,网络包传输路径是这样的:
①NIC > ②driver 驱动> ③Generic XDP==> tc流控 ==> netfilter ==> IP/TCP协议栈 ==> socket
① offload模式,NIC支持xdp程序的offload, XDP程序直接hook到可编程网卡硬件设备上,与其他两种模式相比,它的处理性能最强;由于处于数据链路的最前端,过滤效率也是最高的。如果需要使用这种模式,需要在加载程序时明确声明。目前支持这种模式的网卡设备不多,有一家叫netronome网卡。
② native 模式,XDP程序hook到网络设备的驱动上,它是XDP最原始的模式,因为还是先于操作系统进行数据处理,它的执行性能还是很高的,当然你的网络驱动需要支持,目前已知的有i40e, nfp, mlx系列和ixgbe系列。
③ generic模式,这是操作系统内核提供的通用XDP兼容模式,它可以在没有硬件或驱动程序支持的主机上执行XDP程序。在这种模式下,XDP的执行是由操作系统本身来完成的,以模拟native模式执行。好处是,只要内核够高,人人都能玩XDP;缺点是由于是仿真执行,需要分配额外的套接字缓冲区(SKB),导致处理性能下降,跟native模式在10倍左右的差距。
一、环境安装
环境信息:
[root@localhost xdp]# cat /etc/redhat-release
CentOS Linux release 8.4.2105
- 编译可能需要内核相关头文件,建议安装 内核相关包
yum install -y kernel-devel
yum install -y kernel-headers
- 编译bpf代码需要依赖下面的工具
- clang >= version 3.4.0
- llvm >= version 3.7.1
yum install -y clang
yum install -y llvm
- 加载和卸载xdp程序依赖于ip命令
yum install -y iproute
二、测试代码
#include <linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("xdp")
int xdp_hello_world(struct xdp_md *ctx)
// drop everything
return XDP_DROP;
char _license[] SEC("license") = "GPL";
该例子比较简单,把收到的报文都drop掉,加载这个例子需要实现的效果就是ping不通网口,卸载则能正常ping通
XDP 输入参数:
XDP暴露的钩子具有特定的输入上下文,它是单一输入参数。它的类型为 struct xdp_md,在内核头文件bpf.h 中定义,具体字段如下所示:
struct xdp_md
__u32 data;
__u32 data_end;
__u32 data_meta;
/* Below access go through struct xdp_rxq_info */
__u32 ingress_ifindex; /* rxq->dev->ifindex */
__u32 rx_queue_index; /* rxq->queue_index */
;
XDP 结果码:
使用 XDP 进行数据包处理,有 5 个返回码指示网络驱动处理数据包,内核头文件bpf.h 定义了以下5种动作类型:
- 丢弃(XDP_DROP)
- 转发(XDP_TX)
- 重定向(XDP_REDIRECT)
- 传递(XDP_PASS)
- 错误(XDP_ABORTED)
三、编译测试
编译
[root@localhost xdp]# clang -O2 -target bpf -c xdp-hello-world.c -o xdp-hello-world.o
加载
[root@localhost xdp]# ip link set dev ens19 xdp obj xdp_hello_world.o sec xdp
ip link set命令可以支持 ip link help查看帮助
ip link set [ xdp | xdpgeneric | xdpdrv | xdpoffload off |
object FILE [ section NAME ] [ verbose ] |
pinned FILE ]
sec [section name]
就是上文提到的通过Section来指定程序入口 SEC(“xdp”)
device name
是本机某个网卡设备的名称,可以通过ip a查看本机所有的网卡设备。一般可以选取本机对外的IP所在的网卡设备。
xdpgeneric
对应上面的generic模式
xdpdrv
对应上面的native模式
xdpoffload
对应上面的offload模式
卸载
ip link set dev ens19 xdp off
测试效果
- 加载xdp程序前
[localhost ~]$ ping 5.5.5.2
PING 5.5.5.2 (5.5.5.2) 56(84) bytes of data.
64 bytes from 5.5.5.2: icmp_seq=1 ttl=63 time=1.60 ms
64 bytes from 5.5.5.2: icmp_seq=2 ttl=63 time=6.09 ms
64 bytes from 5.5.5.2: icmp_seq=3 ttl=63 time=2.42 ms
64 bytes from 5.5.5.2: icmp_seq=4 ttl=63 time=2.53 ms
64 bytes from 5.5.5.2: icmp_seq=5 ttl=63 time=1.25 ms
64 bytes from 5.5.5.2: icmp_seq=6 ttl=63 time=4.25 ms
64 bytes from 5.5.5.2: icmp_seq=7 ttl=63 time=6.98 ms
64 bytes from 5.5.5.2: icmp_seq=8 ttl=63 time=2.98 ms
^C
--- 5.5.5.2 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 18ms
- 加载xdp程序后
[localhost ~]$ ping 5.5.5.2
PING 5.5.5.2 (5.5.5.2) 56(84) bytes of data.
64 bytes from 5.5.5.2: icmp_seq=1 ttl=63 time=1.53 ms
64 bytes from 5.5.5.2: icmp_seq=2 ttl=63 time=2.45 ms
64 bytes from 5.5.5.2: icmp_seq=3 ttl=63 time=3.62 ms
64 bytes from 5.5.5.2: icmp_seq=4 ttl=63 time=1.19 ms
^C
--- 5.5.5.2 ping statistics ---
20 packets transmitted, 4 received, 80% packet loss, time 393ms
rtt min/avg/max/mdev = 1.191/2.199/3.624/0.942 ms
- 卸载后则能正常ping通
四、XDP 和 DPDK
XDP 有时与 DPDK 并列,当两者都是完美的方法时。XDP 为希望获得性能同时仍然利用内核的可编程性的用户提供了另一种选择。XDP 提供的一些功能包括:
- 无需第三方代码和许可
- 允许选择忙轮询或中断驱动网络
- 无需分配大页面
- 无需专用 CPU,因为用户在 CPU 之间构建工作时有更多选择
- 无需从 3rd 方用户空间应用程序向内核注入数据包
- 无需为访问网络硬件定义新的安全模型
参考:
https://www.iovisor.org/technology/xdp
https://tonydeng.github.io/sdn-handbook/linux/XDP/
https://arthurchiao.art/blog/xdp-paper-acm-2018-zh/
https://cloud.tencent.com/developer/article/1626925
以上是关于linux xdp简介的主要内容,如果未能解决你的问题,请参考以下文章
深入浅出 eBPF: (Linux/Kernel/XDP/BCC/BPFTrace/Cillium)
Linux eBPF和XDP高速处理数据包;使用EBPF编写XDP网络过滤器;高性能ACL