ovs-dpdk和ovs-kernel的checksum处理

  • Post author:
  • Post category:其他


转载请注明出处:

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。

    1. ovs-dpdk现不支持物理网卡的 checksum硬件计算功能,VM发出的数据包,默认由VM的协议栈计算L4 checksum。VM不能打开tx-checksumming on功能,这是因为vhost-backend和qemu协商时,不支持HOST的VIRTIO_NET_F_CSUM功能,ovs-dpdk也没有对mbuf特殊的处理。
    2. 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 版权协议,转载请附上原文出处链接和本声明。