Labs 导读
随着1000Mbps/10Gbps/40Gbps高速率网卡的普及,Linux内核协议栈在海量数据、低时延的场景下显得力不从心,其复杂冗余的包处理逻辑,使得性能瓶颈变的尤为突出。故而针对内核协议栈的各种优化接踵而来,但实际效果却不明显,于是乎kernel bypass技术应运而生,而DPDK就是其高性能网络应用开发解决方案中的佼佼者,并逐渐成为了独树一帜的成熟技术体系。但是DPDK并不能与Linux Kernel的技术生态很好的结合,与现有操作系统集成的难度较大。
Part 01、XDP概述
XDP(eXpress Data Path,快速数据面)是近些年兴起的网络数据面技术,为Linux内核提供高性能、可编程的网络数据包处理框架。本质上是Linux Kernel中的一个eBPF Hook(钩子),可以动态挂载,使得ebpf程序能够在数据报文到达网络驱动层时提前进行针对性的高速处理。XDP可以与内核协同工作,既可以绕过繁琐的TCP/IP协议栈,也可以复用TCP/IP协议栈以及内核基础设施。由于其较早的收包路径,对于快速识别丢弃报文具有很高的性能,广泛应用于DDoS防御、防火墙、负载均衡等领域。
而AF_XDP作为一种内核的协议族可以与XDP进行交互,实现XDP收包重定向至AF_XDP指定的UMEM,使得用户态应用可以通过AF_XDP Socket完成数据帧的读取和写入。
Part 02、XDP架构设计
XDP系统主要有五个组成部分:
1️⃣XDP driver hook
即网卡驱动中的一个XDP程序的挂载点,运行于网络设备驱动中,由于其驻留在内核空间,无需上下文切换,更加安全、快速,每当网卡接收到一个数据包就会执行这个XDP程序。XDP程序可以对数据包进行逐层解析、按规则进行过滤,或者对数据包进行封装、解封装、转发等。根据不同的工作模式其挂载点也不同,如下图所示,根据网卡支持情况有三处挂载点(蓝色方框内):
图片
- Native XDP(默认):即驱动模式,在这种模式中,XDP BPF 程序直接运行在网络驱动的早期接收路径上,需要驱动支持。
- Offloaded XDP:在该模式下XDP BPF程序直接offload到网卡,相较于Native,具有更高的性能,需要网卡支持。
- Generic XDP:对于还没有实现Native或Offloaded XDP的驱动,内核提供了一个Generic XDP选项。该模式下的XDP BPF Program运行于驱动程序之后的位置,无需驱动程序的支持,但性能较差,主要面向测试程序的开发者。
2️⃣eBPF虚拟机
XDP程序通过Clang编译成BPF字节码,而BPF字节码加载到内核中是运行在eBPF虚拟机上,eBPF VM支持XDP程序的动态加载和卸载。
3️⃣BPF maps
内核中的key/value存储,作为图中各系统的主要通信通道,类似于进程间通信的共享内存访问。用户态程序可以在BPF Maps中预定义规则,XDP程序可以匹配Maps中的规则对数据包进行过滤等;XDP程序也可以将数据包统计信息等存入Maps,用户态程序可访问Maps获取数据包统计信息。
4️⃣eBPF verifier
由于eBPF代码直接运行在内核地址空间,此它能直接访问(破坏)任何内存。为防止这种情况发生,Verifier(程序校验器)需要在XDP字节码加载到内核之前对字节码进行安全检查。
5️⃣XDP Action
XDP程序对于报文的处理有如下几种方式:
- XDP_DROP:在驱动层丢弃报文,通常用于实现DDos或防火墙。
- XDP_PASS:允许报文上送到内核网络栈,同时处理该报文的CPU会分配并填充一个skb,将其传递到内核协议栈。
- XDP_TX:从当前网卡发送出去。
- XDP_REDIRECT:将包重定向到其他网络接口(包括虚拟机的虚拟网卡),或者通过AF_XDP socket重定向到用户空间。
- XDP_ABORTED:表示程序产生了异常,其行为和XDP_DROP相同,但XDP_ABORTED会经过trace_xdp_exception tracepoint,因此可以通过tracing工具来监控这种非正常行为。
下图基于XDP/AF_XDP系统数据流示例图。实线为数据面流向,虚线的控制面流向。
网卡收到包之后,会先执行挂载的XDP eBPF程序,用户态应用在此之前通过bpf map下放规则,XDP收到数据包之后读取bpf map中的规则实现数据包的过滤分发,即xdp action处理,是DROP,重定向到AF_XDP,还是PASS到内核协议栈。
从图中可以看出,不同eBPF程序之间可以通过BPF maps进行通信,并且内核态也可以通过BPF map与用户态应用进行交互,从而实现数据共享。
Part 03、VPP的扩展性
XDP专为高性能而设计,相较与DPDK来说,具有以下优点:
- 无需专门硬件,无需大页内存,无需独占CPU等资源,任何有Linux驱动的网卡都可以支持,无需引入第三方代码库。
- 兼容内核协议栈,可选择性复用内核已有的功能。
- 保持了内核的安全边界,提供与内核API一样稳定的接口。
- 无需对网络配置或管理工具做任何修改。
- 服务不中断的前提下动态重新编程,这意味着可以按需加入或移除功能,而不会引起任何流量中断,也能动态响应系统其他部分的的变化。
- 主流的发行版中,Linux内核已经内置并启用了XDP,并且支持主流的高速网络驱动,4.8+的内核已内置,5.4+能够完全使用。
缺点:
- XDP不提供缓存队列(qdisc),TX设备太慢时会直接丢包,因而不能在RX比TX快的设备上使用XDP。
- 由于不具备缓存队列,对与IP分片不太友好。
- XDP程序是专用的,不具备网络协议栈的通用性。
适用案例:
➢ 软件路由(XDP routing)
Linux内核实现了一个功能完全的路由表,生态系统功能丰富,结合XDP包处理框架实现了一个完美的路由功能。其性能与常规的Linux内核网络栈相比提升了2.5 - 3倍左右。
➢ ACL/DDoS防御
XDP可以直接在应用服务器上部署包过滤程序来防御此类攻击,无须修改应用代码。如果应用部署在虚拟机里,XDP程序还可以部署在宿主机上,保护机器上所有的虚拟机。其性能单核可以轻松处理10Gbps的最小包Dos流量。这种DDOS防御的部署更加灵活。
相比iptables相对较晚的hook点,XDP的丢包速率要比iptables高4倍左右。
➢ 负载均衡(load balancing)
其原理是通过对包头进行哈希,以此选择目标应用服务器,然后将数据包进行封装,发送给应用服务器,应用解封,处理请求,会包给客户端。在次过程中,XDP服务哈希,封包发送。通过bpf map进行配置,其性能比Linux内核IPVS高4倍左右。
Part 04、未来展望
ebpf/XDP作为Linux网络革新技术正在悄悄的改变着Linux网络发展模式,当前,XDP技术被OVS、Cilium、Polycube等用于网络快速路径的新选择,DPDK也相应的做了AF_XDP PMD。XDP程序在CPU可用来处理的最早时间点被执行,尤其适合DDoS防御、防火墙、负载均衡。基于XDP+eBPF的的ACL解决方案也有望改善目前的性能瓶颈,有望取代iptables解决方案。
XDP作为一个安全、快速、可编程、集成到操作系统内核的包处理框架。XDP性能虽然与基于kernel bypass的DPDK仍有差距,但优异的可扩展性,可编程性等提供了非常有竞争力的优势。相比于kernel bypass这种非此即彼、完全绕开内核的方式,我们相信XDP有更广阔的的应用前景。