eBPF学习摘要3-XDP学习和理解
概述
Linux网络数据包接收数据包的链路为Nic——>rx_ring——>skbuff——>网络协议处理(如ip_recv)这样做的问题在于会产生大量内核态到用户态的切换过程,这会造成大量性能消耗,所以为了提升网络性能才诞生出Kernel bypass的技术如DPDK、SolarFlare技术,像DPDK就是直接饶过内核态,用户态应用直接访问网络硬件提高数据包处理效率,降低因为切换带来的损耗,但这种方式本身也存在一些缺点:1、绕开了内核态,很难与Linux操作系统中内核态本身存在的一些工具集成,一些功能需要重新开发。2、需要单独cpu核参与处理。
XDP(eXpress Data Path)是一个eBPF hook,可以在内核中执行eBPF程序实现对网络数据包处理,在Linux内核 4.8 版中引入。实现方式与Kernel bypass完全相反在sk_buffer之前数据包从driver出来以后就可以直接被XDP程序捕获执行,极大提升了网络数据包的处理效率。
实现方式
如下图所示
1、数据包通过网卡,触发XDP执行
2、xdp程序执行读取BPF mps配置的规则对数据包执行相应的操作,通常为
(1)XDP_DROP:直接丢弃,不占用CPU资源,有效防止DDOS
(2)XDP_Allow:正常转发到内核网络栈
(3)XDP_REDIRECT:重定向到其他网卡,或通过AF_XDP直接发送到用户空间。
(4)XDP_TX:将处理后的包发给相同的网卡。
三种处理模式:
XDP在网络栈中有三个处理点:
offloaded模式的XDP:对于支持可编程的网卡,直接在网卡上运行XDP程序。
Native模式的XDP:默认模式、对于支持的网卡驱动,可以在包到达内核后立刻进行处理。(目前大部分网卡已经支持)
Offloaded和Native模式
Generic模式的XDP:网卡和驱动不支持上述两种情况的XDP时,可以在receive_skb函数此点进行处理。这个处理的位置相对靠后,在tc处理点之前,这种性能最差,一般用于测试调试模式。
应用场景
- 负载均衡器:通过XDP_TX和XDP_TX实现数据包的快速转发,目前很多k8s网络插件取代kube-proxy实现Service负载均衡器就是如此。Facebook的全部流量都是经过基于XDP的四层负载均衡器(katran)处理转发(https://lpc.events/event/11/contributions/950/attachments/889/1704/lpc_from_xdp_to_socket_fb.pdf)
- 防火墙:Cloudflare在他们的DDoS防御L4Drop中使用用了XDP无需高CPU占用就可提供高性能丢包率(https://blog.cloudflare.com/how-to-drop-10-million-packets/)
- 流量监控和采样:位于内核网络栈前端,通过自定义的eBPF程序即可实现对网络流量的采样,目前很多基于eBPF的APM就是这样实现的。
性能测试
https://people.netfilter.org/hawk/presentations/KernelRecipes2018/XDP_Kernel_Recipes_2018.pdf
http://vger.kernel.org/lpc_net2018_talks/lpc18-xdp-future.pdf
https://blog.cloudflare.com/how-to-drop-10-million-packets/
https://blog.csdn.net/hbhgyu/article/details/109354273
这里面包含了对丢包性能、转发性能、DDos防御能力的测试。
总结:
随着eBPF技术的持续发展,XDP能够实现DPDK相近的性能,但又更具有兼容性和灵活性,未来会得到越来越好的发展,围绕eBPF和XDP的生态软件也会越来越丰富。
参考链接:
https://zhuanlan.zhihu.com/p/453005342
https://zhuanlan.zhihu.com/p/438158551
https://mp.weixin.qq.com/s/H9imUbdJnfj1NKdK9jtxEw
https://zhuanlan.zhihu.com/p/321387418
https://mp.weixin.qq.com/s/lUvxUkFg4w1X0ioktxGiHA
https://www.seekret.io/blog/a-gentle-introduction-to-xdp/