• virtio_net设备的校验和问题


    我们来看一个virtio_net设备的校验和配置:

    [root@10 ~]# ethtool -K eth0 tx-checksumming on   //caq:大写的K用来调整feature
    [root@10 ~]# ethtool -k eth0                      //caq:小写的k用来查看feature
    Features for eth0:
    rx-checksumming: off [fixed]
    tx-checksumming: on
            tx-checksum-ipv4: off [fixed]
            tx-checksum-ip-generic: on
            tx-checksum-ipv6: off [fixed]
            tx-checksum-fcoe-crc: off [fixed]
            tx-checksum-sctp: off [fixed]
    

    问题是:
    1、tx-checksum-ip-generic对应的feature是什么?
    2、为什么 tx-checksum-ip-generic 为on ,而 tx-checksum-ipv4 是off 并且是[fixed]呢?
    3、ethtool打印的[fixed]代表啥?
    4、tx-checksum-ip-generic 与 tx-checksum-ipv4 以及 tx-checksum-ipv6 的关系是?

    先来看第一个问题,查看内核代码:
    从如下的代码中,我们知道, NETIF_F_HW_CSUM_BIT 其实就对应着 tx-checksum-ip-generic 。第一个问题解答完毕。

    static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
    	[NETIF_F_SG_BIT] =               "tx-scatter-gather",
    	[NETIF_F_IP_CSUM_BIT] =          "tx-checksum-ipv4",
    	[NETIF_F_HW_CSUM_BIT] =          "tx-checksum-ip-generic",//caq:对user展示为 tx-checksum-ip-generic,其实就是 NETIF_F_HW_CSUM_BIT
    	[NETIF_F_IPV6_CSUM_BIT] =        "tx-checksum-ipv6",
    
    
    #define __NETIF_F_BIT(bit)	((netdev_features_t)1 << (bit))
    #define __NETIF_F(name)		__NETIF_F_BIT(NETIF_F_##name##_BIT)
    **#define NETIF_F_HW_CSUM		__NETIF_F(HW_CSUM)**
    #define NETIF_F_HW_VLAN_CTAG_FILTER __NETIF_F(HW_VLAN_CTAG_FILTER)
    #define NETIF_F_HW_VLAN_CTAG_RX	__NETIF_F(HW_VLAN_CTAG_RX)
    #define NETIF_F_HW_VLAN_CTAG_TX	__NETIF_F(HW_VLAN_CTAG_TX)
    **#define NETIF_F_IP_CSUM		__NETIF_F(IP_CSUM)**  //caq: NETIF_F_IP_CSUM 就是 1<< NETIF_F_IP_CSUM_BIT
    **#define NETIF_F_IPV6_CSUM	__NETIF_F(IPV6_CSUM)**
    

    从上面的宏可以看出,NETIF_F_HW_CSUM 其实就是 1<<NETIF_F_HW_CSUM_BIT
    具体的值由下面的枚举决定,也就是:

    enum {
    	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
    	NETIF_F_IP_CSUM_BIT,		/* Can checksum TCP/UDP over IPv4. */
    	__UNUSED_NETIF_F_1,
    	NETIF_F_HW_CSUM_BIT,		/* Can checksum all the packets. */
    	NETIF_F_IPV6_CSUM_BIT,		/* Can checksum TCP/UDP over IPV6 */
    

    再来关注第二个问题,也是查看内核代码,

    static int virtnet_probe(struct virtio_device *vdev)
    {
    .....
    /* Do we support "hardware" checksums? */
    	if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {//caq:设备进行校验和计算
    		/* This opens up the world of extra features. */
    		dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_SG;
    		if (csum)
    			dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
    .....
    }
    

    说明virtio_net设备,如果 VIRTIO_NET_F_CSUM 设置的话,只是具备了 NETIF_F_HW_CSUM 的feature,所以它展示为on,而
    NETIF_F_IP_CSUM并没有设置,所以为off,第二个问题解答完毕。

    第三个问题,为啥看到的是fixed打印,
    参考https://stackoverflow.com/questions/27478810/what-does-the-meaning-of-fixed-string-in-output-of-ethtool-command,
    Those are the parameters that cant be changed, they are "fixed",也就是固定的意思,不可更改,而不可更改的原因一般是,硬件或者驱动没有提供这个feature,所以用户
    去更改的时候会 报Could not change any device features。
    有兴趣的同学或者可以参考ethtool的源码。

    查看相关的合入记录,以及参考 kernel的资料,一般认为:
    NETIF_F_HW_CSUM is a superset of NETIF_F_IP_CSUM + NETIF_F_IPV6_CSUM. It means that device can fill TCP/UDP-like checksum anywhere in the packets whatever headers there might be.
    也就是说,NETIF_F_HW_CSUM 是 NETIF_F_IP_CSUM 和 NETIF_F_IPV6_CSUM 的一个超集。
    那是不是说 NETIF_F_HW_CSUM 设置了on,则 NETIF_F_IP_CSUM 一定是on呢?显然不是,这个超级就像 你用推土机挖山,也可以用锄头或者铁锹,推土机从
    功能上看覆盖了锄头和铁锹,但是你要用推土机挖一锄头,还得使能它具备锄头的能力才行。也就是特性上,目前还维护了三个。
    但是既然是硬件计算校验和,NETIF_F_HW_CSUM从功能上显然是能覆盖,所以
    NETIF_F_HW_CSUM 的出现,显得 NETIF_F_IP_CSUM 和 NETIF_F_IPV6_CSUM 就过时了。这个也和
    https://lwn.net/Articles/666178/ 这篇文章说的类似。第四个问题解答完毕。

    Many drivers advertise NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM and it
    probably isn't feasible to convert them all in a given time frame
    (although if we could this would be a great simplification to the
    stack). A reasonable direction may be to declare that new drivers must
    use NETIF_F_HW_CSUM as NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are
    considered deprecated.
    

    参考资料:
    https://www.kernel.org/doc/html/v5.14/networking/netdev-features.html

  • 相关阅读:
    如何屏蔽LOGDLOGI等打印输出
    struct hw_module_t HAL_MODULE_INFO_SYM
    Android的底层库libutils介绍
    在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(老罗学习笔记2)
    在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序(老罗学习笔记3)
    Linux kmalloc/kfree 源码解读
    IS_ERR、PTR_ERR、ERR_PTR
    PHP去除unicode续:json_encode之后,仅仅有文字,数字不见了的解决方法
    让JavaScript在Visual Studio 2015中编辑得更easy
    玩转阿里云server——安装WebserverTomcat7
  • 原文地址:https://www.cnblogs.com/10087622blog/p/15886345.html
Copyright © 2020-2023  润新知