转载请注明出处:
http://blog.csdn.net/hliyuxin/article/details/52710749
- 现在遇到问题,部分docker的机器,迁移到ovs-dpdk上之后有tcp checksum错误, ethtool关闭docker 网卡tx checksum之后,服务正常。
-
查看原ovs-kernel的配置,docker 网卡tx-checksumming: on, 而物理网卡tx-checksumming: off。服务正常,没有tcp checksum error。
- ovs-dpdk现不支持物理网卡的 checksum硬件计算功能,VM发出的数据包,默认由VM的协议栈计算L4 checksum。VM不能打开tx-checksumming on功能,这是因为vhost-backend和qemu协商时,不支持HOST的VIRTIO_NET_F_CSUM功能,ovs-dpdk也没有对mbuf特殊的处理。
- kernel 版本ovs 的packet checksum处理是,skb的处理是在内核态,最终从物理port发出是通过netdev_send函数,调用了内核dev_queue_xmit函数, dev_queue_xmit是内核自带的函数。继续查看kernel源码,dev_queue_xmit调用了validate_xmit_skb函数,会对skb的checksum的有效性进行检查。如果packet的接收port打开了tx checksum功能,使checksum没有完整计算,但是packet需要send的port又不支持硬件checksum功能时,会对tx checksum进行补充计算。validate_xmit_skb:
/* If packet is not checksummed and device does not
* support checksumming for this protocol, complete
* checksumming here.
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (skb->encapsulation)
skb_set_inner_transport_header(skb,
skb_checksum_start_offset(skb));
else
skb_set_transport_header(skb,
skb_checksum_start_offset(skb));
if (!(features & NETIF_F_ALL_CSUM) &&
skb_checksum_help(skb))
goto out_kfree_skb;
}
- 如果ovs-dpdk需要支持物理网卡CSUM,需要修改dpdk vhost 部分代码,使VM和ovs之间协商HOST CSUM支持,然后OVS也对mbuf做特殊处理。前文分析,原kernelovs,可以针对不同vm port的网卡tx-checksumming的功能是否打开,和物理网卡硬件CSUM功能是否打开,动态对packet进行补充操作,但是ovs-dpdk不能识别TAP网卡的feature, 因为ovs-dpdk是用户态程序,收到的buf只具有基本的数据,不像skb保存了ip_summed和dev feature等信息,来判断mbuf是否有完整的checksum.
-
解决方法:(1)统一关闭虚拟port的tx checksumming功能,统一让虚拟机或namespace协议栈去计算L4 checksum
(2) 修改ovs-dpdk代码支持硬件CSUM功能,统一设置让出物理网卡的包由硬件CSUM
版权声明:本文为hliyuxin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。