近期,Netfilter 和 Mellanox 联合开发了flowtable hardware offload 功能,使flowtable成为一种标准的conntrack卸载方案,并实现了Linux标准的Netfilter 硬件offload接口。作为一个新功能,还存在一些缺陷和不完善的地方。
对此,我们做了大量的硬件卸载开发工作,进行问题修复、功能优化,帮助完善kernel功能并提升性能,后续也计划将该功能合并至UCloud外网网关,进一步提升系统性能和管理能力。
优化后的性能飞跃
首先,来看一组简单粗暴的数据。
在所有硬件卸载开发工作完成后,我们基于flowtable的conntrack offload,从bps、pps、cpu使用率等维度分别进行了系列性能对比测试,测试结果如下:
- 非硬件卸载模式:
①单条流带宽测试为12GBps,耗费2个host CPU;
②多条流小包包量测试为1Mpps,耗费8个host CPU;
- 硬件卸载模式:
①单条流带宽测试为23GBps,耗费 0 host CPU;
②多条流小包包量测试为8Mpps,耗费 0 host CPU;
可以看到在硬件卸载模式下bps、pps性能提升显著,不仅做到了CPU无损耗,性能还分别提升1倍、8倍之多。不过对于新建连接率cps并没有太显著的提升,分析原因为该性能由conntrack在软件协议栈中完成,与硬件无关。在已有层面,一旦该特性应用于产品上,预估将带来极大的性能飞跃。
当然,性能提升的背后离不开每一个细微技术的打磨:我们对conntrack offload与NAT功能分别进行了问题修复与优化,并在此基础上,还与Netfilter、Mellanox合作开发了tunnel offload的新特性。 接下来,就来详细聊聊我们所做的工作。
Flowtable offload背景简介
Linux内核在版本4.16引入了flow offload功能,它为IP forward提供了基于流的卸载功能。当一条新建连接完成首回合原方向和反方向的报文时,完成路由,Firewall和NAT工作后,在处理反方向首报文的forward hook,根据报文路由、NAT等信息创建可卸载flow到接收网卡ingress hook上。后续的报文可以在接收ingress hook上直接转发,不需要再进入IP stack处理。 这种模式实现了完成建立连接的conntrack软件offload,不过目前flowtable offload只支持TCP和UDP协议的卸载。
图:Flowtable offload图示
当前内核中硬件支持offload的标准只有Network TC subsystem的tc flower接口。
Pablo Neira Ayuso首先将tc flower相应的offload接口进行公共化为network子系统flow offload,然后在flowtable offload中支持HW的flow offload接口。这样便可在驱动层面上完全统一使用flow offload接口。
Paul Blakey将flowtable offload指定到TC_SETUP_FT域,实现在驱动层来区分不同的subsystem。
在所有基本功能完善后,我们在review commit的代码后发现flowtable HW offload的建立并没有指定到正确的TC_SETUP_FT类型。对此,我们进行了简单的修复,并将patch提交至社区:
① Netfilter:nf_flow_table_offload:Fix block setup as TC_SETUP_FT cmd(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ee1bcfe01251e8958b53de45d2b0c85e09dd2719)
②Netfilter:nf_flow_table_offload:Fix block_cb tc_setup_type as TC_SETUP_CLSFLOWER(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e052901991ae21e15851bfc89c682bfcb39a4dcf)