主页 > imtoken苹果版下载官网怎样下载 > 基于ethtool的网络指标统计工具统计数据关系研究

基于ethtool的网络指标统计工具统计数据关系研究

问题背景

在处理丢包问题时,您需要了解以下问题:

ethtool统计值与netstat -s统计值的关系; ifconfig给出的drop和error与ethtool给出的rx_dropped和rx_errors有什么关系;

分析的思路是先用动态分析进行初步分析,再用静态分析读取代码,再从代码层面进行确认。

本文旨在记录分析过程和结论,同时深入挖掘内核数据结构中ethtool与网卡的实现和关系(本文以i40e为例,其他网卡实现有相似之处)的统计指标。

问题初探——动态分析不同工具数据netstat的来源

netstat -s 命令会看到协议栈的网络数据的一些统计信息。 我们用strace看看他是在哪里读取统计数据的:

...

...

...

可以看出主要是从/proc/net/snmp和/proc/net/netstat读取的数据。

这里简单介绍一下这两个文件的主要功能。

/proc/网络/snmp

以太坊源码分析_以太坊源码分析_sitehuoxing24.com 以太坊源码官网

这个文件是snmp协议对协议栈中各个协议(ip/icmp/tcp/udp)的相关信息的一些基本统计,比如in-out路径上的错误计数等。通过查看其中的一些统计异常值,可以分析系统潜在的性能问题。 (比如当udp中的InErrors不断增加时,可以猜测系统的socket接收队列已经达到瓶颈)

它打印如下:

/proc/网络/网络统计

与/proc/net/snmp 相比,netstat 给出了一些更详细的tcp 和ip 协议的统计信息(TcpExt/IpExt)。 比如可以通过Syncookies*分析出tcp半连接的一些相关状态信息。

netstat工具给出的信息是对信息进行归档,做更详细的文字说明。 这里我们可以在netstat源码中看到映射关系。 比如我们可以看到上面提到的syncookies*。 是下面的文字说明:

国家统计局

nstat和netstat有很多相似之处,同样用strace看看:

……

...

可以看出,它和netstat一样,主要是从/proc/net/snmp和/proc/net/netstat中读取数据。

值得一提的是,nstat的指标基本都是来自对应proc文件的原始字段名,而netstat是文本描述(查找映射关系的方法在netstat部分已经给出)。

配置文件

ifconfig给出的信息主要是接口信息,跟协议栈没有关系,所以我猜测跟netstat/nstat没有关系,跟ethtool也没有关系。 这里也strace来验证一下:

sitehuoxing24.com 以太坊源码官网_以太坊源码分析_以太坊源码分析

...

...

可以看到他读取了/proc/net/dev和/proc/net/if_inet6的值(这个文件是网卡的接口地址),/proc/net/的值在哪里dev从何而来,在后面的源码分析中会给出答案。

ethtool

也可以使用 strace 来跟踪:

...

...

可以看出这是直接通过ioctl与设备交互获取的,并不是从/proc/net/dev中读取的。

ioctl(输入/输出控制)是专用于设备输入输出操作的系统调用。 该调用传入与设备相关的请求代码。 系统调用的功能完全取决于请求代码。

这里猜测是ethtool试图获取buffer作为网卡设备具体硬件的统计信息,后面会从源码层面进行验证。

初步结论

从上面的观察结果来看,netstat和nstat其实是/proc/net/snmp和/proc/net/netstat的数据,但是ifconfig和ethtool显然与这两者无关。 问题1已经有了答案。

虽然ifconfig和ethtool给出的信息看起来像是网卡相关的统计,但是没办法通过动态跟踪直接锤击(ifconfig读取/proc/net/dev,而ethtool直接通过ioctl分发),结论是给出的后来通过对内核代码的分析。

以太坊源码分析_以太坊源码分析_sitehuoxing24.com 以太坊源码官网

深挖问题——ethtool如何获取stats的静态分析

以太网与一二层架构和ethtool的关系这里就不详细展开了,Linux内核和设备驱动都支持ethtool。

ethtool实现框架,原图来自网络:

这里MII寄存器定义在:include/uapi/linux/mii.h。

MII(Media Independent Interface),大多数以太网端口使用MII与网卡芯片协商一些相关信息。 不同的信号管脚有不同的用途,比如通知对方将有输入输出,通知是否拥塞等,这里不做详细展开,可以简单理解为由对方提供的接口驱动程序获取一些信息的硬件级别。

重点关注ethtool函数在驱动中是如何实现的。 这里我们可以看到ethtool在内核态提供了一组ethtool_ops函数接口,可以被驱动注册:

找到statistics对应的注册函数get_ethtool_stats:

它是net_device中的一个成员变量,所以作为任何版本的驱动,只需要在对应的结构体中注册自己的函数即可。

这里我们以i40e为例,看看ethtool是如何获取数据的,首先找到i40e注册的ethtool_ops,这里是i40e_ethtool_ops,对应的get_ethtool_stats是i40e_get_ethtool_stats:

... 下面还有很多这里就不展开了

可以看出这里会调用i40e_update_stats(vsi)来更新数据,而从上面的代码片段来看,vsi与入参netdev有关,先看vsi:

查看 i40e_update_stats:

这里注意,这个pf其实就是端口相关的数据。 这里就不展开了。 原理和vsi一样。 关键是要了解数据是如何更新的。 继续关注i40e_update_vsi_stats:

以太坊源码分析_以太坊源码分析_sitehuoxing24.com 以太坊源码官网

...

在这里,我们终于看到了我们想看到的。 将与 vsi 关联的 net_device 中的统计信息更新为 vsi 中记录的与 eth 相关的统计信息。 i40e_update_eth_stats从网卡寄存器(上面提到的MII)中一个一个读取对应的值 。 这样就实现了eth相关统计信息的更新,这里不再赘述。

总之,这里我们知道net_device中的stats是在这条路径上更新的。

这里还需要提一下rtnl_link_stats64这个结构体,它是net_device中主要统计数据的结构体,也就是说ethtool读取的还是这个东西:

其实问题2的一些答案也可以在评论中找到(rx_dropped、rx_errors相关评论)。

最后一张流程图展示了ethtool是如何获取i40e网卡相关统计信息的:

深挖问题——静态分析/proc/net/dev从何而来

对于proc文件系统,这里不做详细介绍以太坊源码分析,直接从创建/proc/net/dev的入口dev_proc_init开始:

这里register_pernet_subsys是注册一组network namespace子系统,会注册ops指针,这里不详细展开。 看一下具体注册的dev_proc_ops:

查看 dev_proc_net_init:

proc_create_net 注意到在创建“dev”时注册了 dev_seq_ops:

这里我们可以看到show对应的函数是如何打印信息的:

看到上面的seq_puts是error header,再看下面的dev_seq_printf_stats:

以太坊源码分析_sitehuoxing24.com 以太坊源码官网_以太坊源码分析

在这里,我们终于见到了我们熟悉的老朋友。 从net_device中取出的rtnl_link_stats64可以看到下面都是熟悉的指标。

打印/proc/net/dev的关系图:

至此可以断定以太坊源码分析,在/proc/net/dev下看到的数据和ethtool看到的数据都是net_device中的rtnl_link_stats64,可以认为两者是一回事。 哪个字段代表哪些指标可以从这里看出(比如drop就是rx_dropped+rx_missed_errors),也可以对应具体的驱动分析源码(比如上面的i40e,可以看一下i40e_update_stats函数)。

回头看问题本身,我们之前验证过ifconfig来自/proc/net/dev,看一下/proc/net/dev:

可以看到每个网卡的信息都已经归档了,ifconfig只是美化了这些信息的格式。 到这里,只要知道errs和drop分别对应哪些指标,一开始提出的问题2就迎刃而解了。 而这个直接查看刚才/proc/net/dev对应的打印界面就可以解决。

先看errs,对应第四列:

这样我就知道了RX错误是rx_errors

而drop对应的是第五列:

这样就知道RX dropped是rx_dropped + rx_missed_errors

综上所述

netstat、nstat是/proc/net/netstat和/proc/net/snmp中的数据;

ifconfig读取/proc/net/dev下的数据,后面的数据是从内核数据结构net_device中的结构体rtnl_link_stats64中获取的;

ethtool直接通过ioctl从同一个结构体(net_device中的rtnl_link_stats64)获取数据;

因此可以认为ifconfig和ethtool看到的网卡相关数据是同一个来源,但是/proc/net/dev已经进行了一定程度的归档,所以ifconfig中RX dropped = rx_dropped + rx_missed_errors,RX errors = rx_errors .