“cat / proc / net / dev”和“ip -s link”显示不同的统计信息。 哪一个在撒谎?

我注意到/proc/net/dev说eth3有1753个dropip -s link显示0 dropped 。 为什么有差异? 不同的数据来自哪里? 哪一个是正确的?

我已经剥离了额外的数据。

 # uname -a Linux example09 2.6.32-5-amd64 #1 SMP Thu Mar 22 17:26:33 UTC 2012 x86_64 GNU/Linux # lsb_release -a Distributor ID: Debian Description: Debian GNU/Linux 6.0.4 (squeeze) Release: 6.0.4 Codename: squeeze # cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed eth3:1258629839430 12545003042 0 1753 0 0 0 10594858 6666255952912 10026428444 0 0 0 0 0 0 # ip -s link 5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP qlen 1000 link/ether 00:15:17:96:0b:61 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 244248462 3955476484 0 0 0 10595400 TX: bytes packets errors dropped carrier collsns 683632524 1436809416 0 0 0 0 

在Squeeze机器上,信任/proc/net/dev 。 这是查看相同数据的更直接可靠的方法。

对于计数丢失的具体情况,我无法解释确切的问题,但我可以在其他挤压框中观察。 如果我关心,我会报告它作为Debian的错误(并build议有人做,并在这里报告)。

两者都从net_device_statstx_dropped字段中获取数字。 在/proc/net/dev ,该行由net/core/dev.c

像往常一样, ip通过netlink,更确切地说是networking设备统计,rtnetlink。 结构传递给用户空间rtnl_link_stats

本地结构使用unsigned longrtnetlink使用__u32 ,或多或less的隐式转换在copy_rtnl_link_stats完成。

捕获从结构开始使用的32位版本非常容易,rx_packets:while /proc/net/dev显示1258629839430, ip显示244248462,它大致对应于最后的32位(再加上几个字节在命令之间); 与数据包数量相同的东西。

这两个第一领域的数字嘎吱嘎吱:

 % echo '1258629839430 % (2^32)'|bc; echo 244248462 204421702 244248462 % echo '12545003042 % (2^32)'|bc; echo 3955476484 3955068450 3955476484 

在引入IFLA_STATS64情况变得更好了:

  • 在内核中(从提交10708f37ae729baba9b67bd134c3720709d4ae62,在2.6.35和更高版本上可用)
  • 在iproute2中(从提交8864ac9dc5bd5ce049280337deb21191673a02d0,在v2.6.33-36和更高版本中可用的上游)。

在大多数设备上,从硬件计数器读取/ proc / net / dev 。 其他统计信息从设备结构中的networking堆栈更新。

丢包更可能不匹配,因为它们可以通过硬件来实现:packet mac目的地既不是设备也不是多播,设备不是混杂的:硬件直接丢弃数据包,堆栈永远不会知道它存在。

最后,你可能想知道为什么不同步它们或者总是使用硬件统计信息? 当堆栈由于任何原因而丢弃数据包时,它不能更新硬件计数器,并且为了debugging,知道你可以find每一个来追踪数据包被丢弃的位置。

希望这可以帮助