我注意到/proc/net/dev
显示 eth3 有 1753 drop
s。ip -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
答案1
在挤压机上,信任/proc/net/dev
。这是查看相同数据的更直接、更可靠的方法。
对于计数丢失的特殊情况,我无法解释确切的问题,但我可以在其他 Squeeze 盒子上观察到它。如果我关心,我会将其作为错误报告给 Debian(并建议有人这样做并在此处报告)。
tx_dropped
二者均从的字段中获取数字net_device_stats
。在 中,该行由/proc/net/dev
生成。dev_seq_printf_stats
net/core/dev.c
ip
像往常一样,通过 netlink 进行,更准确地说,对于网络设备统计,通过 rtnetlink 进行。传递给用户空间的结构rtnl_link_stats
。
本机结构使用unsigned long
s,rtnetlink
使用__u32
,在 中完成或多或少隐式的转换copy_rtnl_link_stats
。
从结构 rx_packets 的开头很容易就能发现使用的是 32 位版本:虽然/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,可在上游 v2.6.35 及更高版本中使用)
- 在 iproute2 中(来自提交 8864ac9dc5bd5ce049280337deb21191673a02d0,可在 v2.6.33-36 及更高版本中上游使用)。
答案2
在大多数设备上,/proc/net/dev是从硬件计数器读取的。其他统计数据是从设备结构中的网络堆栈更新的。
丢弃更可能不匹配,因为它们可以由硬件制成:数据包 mac 目的地既不是设备也不是多播,并且设备不是混杂的:硬件直接丢弃数据包,堆栈永远不会知道它存在。
最后,您可能想知道为什么不同步它们或始终使用硬件统计数据?当堆栈因任何原因丢弃数据包时,它无法更新硬件计数器,并且对于调试来说,知道您可以找到每个计数器以追踪数据包被丢弃的位置很有用。
希望这可以帮助