前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于以ethtool为主的网络指标统计工具之间统计数据关系的研究

关于以ethtool为主的网络指标统计工具之间统计数据关系的研究

原创
作者头像
johnazhang
发布2022-07-18 12:24:18
2.3K0
发布2022-07-18 12:24:18
举报
文章被收录于专栏:Linux问题笔记

问题背景

在一次丢包问题排查中,需要了解如下问题:

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

分析思路是,先可以用动态分析去初步分析,然后通过静态分析走读代码再从代码层面确认。

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

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

netstat

netstat -s命令会看到一些协议栈网络数据的统计,我们通过strace来看看他是读取的哪里的统计:

……

……

……

可以看到,其主要是从/proc/net/snmp和/proc/net/netstat中读取的数据。

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

/proc/net/snmp

该文件是snmp协议对协议栈中各协议(ip/icmp/tcp/udp)相关信息的一些基本统计,比如出入路径上的错误计数等,通过查看其中一些统计的异常值,可以对系统潜在的性能问题进行排查。(比如当udp中的InErrors不断增长的时候,可以猜测系统的socket接受队列达到瓶颈)

打印如下:

/proc/net/netstat

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

而netstat工具给出的信息,也正是将这些信息归档,并做出了更详细的文字描述,这里我们可以在netstat源码中看到映射关系, 比如可以看到上面提到的syncookies*对应的是如下这些文字描述:

nstat

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

......

……

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

值得一提的是,nstat的指标基本都是从对应的proc文件的原始字段名,而netstat则是一段文字说明(找映射关系的办法在netstat部分已经给出)。

ifconfig

ifconfig给出的主要是interface的信息,跟协议栈无关,因此猜测和netstat/nstat那套无关,和ethtool是一套,这里同样strace来验证一下:

……

……

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

ethtool

同样是用strace去跟一下:

……

……

可以看到,这里是直接用ioctl和设备交互获取的,并不是从/proc/net/dev中读出来的。

ioctl(input/output control)是一个专用于设备输入输出操作的系统调用,该调用传入一个跟设备有关的请求码,系统调用的功能完全取决于请求码。

在这里猜测是ethtool尝试获取网卡设备特定硬件上的作为统计信息的buffer,后面会从源码层面验证。

初步结论

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

而ifconfig和ethtool给出的信息虽然看着统计的是相似网卡相关数据,但通过动态追踪还没有办法直接实锤(ifconfig是读的/proc/net/dev,而ethtool是直接通过ioctl下放),后面通过对内核代码的分析来给出结论。

问题深挖——静态分析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其实是对应port相关的数据,此处先不展开,原理和vsi是一样的,重点是了解数据是如何更新的即可,继续跟i40e_update_vsi_stats:

……

这里我们终于见到了想看到的东西,把vsi相关联的net_device里的stats更新成vsi里记录的eth相关的stats,i40e_update_eth_stats是从网卡寄存器里(前面提到的MII)一一读取对应值的接口,通过这种方式实现了eth相关的stats的更新,这里细节就不展开了。

总之到这里我们就知道了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就是注册一套网络命名空间子系统,里头会注册ops指针,这里也不详细展开,看一下具体注册的dev_proc_ops:

看下dev_proc_net_init:

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

这里我们就可以看一下show对应的函数到底是怎么打印信息的了:

看到上面那个seq_puts打出来的是个error header,看一下下面的dev_seq_printf_stats:

这里终于看到我们熟悉的老朋友了,从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 errors就是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。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题背景
  • 问题初探——动态分析不同工具数据的由来
    • netstat
      • /proc/net/snmp
    • ifconfig
      • ethtool
        • 初步结论
        • 问题深挖——静态分析ethtool如何获取stats
        • 问题深挖——静态分析/proc/net/dev从哪里来
        • 结论
        相关产品与服务
        云服务器
        云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档