题 如何找出网络接口丢弃数据包的原因?


有没有办法在Linux上获取有关丢弃数据包的各种原因的统计信息?

在多个服务器上的所有网络接口(openSUSE 12.3)上, ifconfig 和 netstat -i 在接待处报告丢弃的数据包。当我做的时候 tcpdump,丢弃的数据包数量停止增加,这意味着接口队列未满并丢弃数据。因此必须有其他原因发生这种情况(例如,接收到多播pkts,而接口不是该多播组的一部分)。

我在哪里可以找到这样的信息? (/ proc?/ sys?一些日志?)

统计信息示例(/ sys / class / net / <dev> / statistics和ethtool输出的合并):

alloc_rx_buff_failed: 0
collisions: 0
dropped_smbus: 0
multicast: 1644
rx_align_errors: 0
rx_broadcast: 23626
rx_bytes: 1897203
rx_compressed: 0
rx_crc_errors: 0
rx_csum_offload_errors: 0
rx_csum_offload_good: 0
rx_dropped: 4738
rx_errors: 0
rx_fifo_errors: 0
rx_flow_control_xoff: 0
rx_flow_control_xon: 0
rx_frame_errors: 0
rx_length_errors: 0
rx_long_byte_count: 1998731
rx_long_length_errors: 0
rx_missed_errors: 0
rx_multicast: 1644
rx_no_buffer_count: 0
rx_over_errors: 0
rx_packets: 25382
rx_short_length_errors: 0
rx_smbus: 0
tx_aborted_errors: 0
tx_abort_late_coll: 0
tx_broadcast: 7
tx_bytes: 11300
tx_carrier_errors: 0
tx_compressed: 0
tx_deferred_ok: 0
tx_dropped: 0
tx_errors: 0
tx_fifo_errors: 0
tx_flow_control_xoff: 0
tx_flow_control_xon: 0
tx_heartbeat_errors: 0
tx_multicast: 43
tx_multi_coll_ok: 0
tx_packets: 63
tx_restart_queue: 0
tx_single_coll_ok: 0
tx_smbus: 0
tx_tcp_seg_failed: 0
tx_tcp_seg_good: 0
tx_timeout_count: 0
tx_window_errors: 0

15
2017-12-13 08:46




也可以看看 ifconfig丢弃的RX数据包究竟是什么? 和 如何找到丢弃的数据包 - Martin Schröder


答案:


尝试 /sys/class/net/eth0/statistics/  (即 eth0),它并不完美,但它通过发送/接收以及载波,窗口,fifo,crc,帧,长度(以及更多)类型的错误来分解错误。

丢弃与“忽略”不同, netstat 显示接口级别统计信息,更高级别(第3层,IP堆栈)忽略的多播数据包将不会显示为丢弃(尽管它可能在某些NIC统计信息上显示为“已过滤”)。各种卸载功能可能会使统计数据有些复杂。

如果有,您可以获得更多统计数据 ethtool

# ethtool -S eth0
 rx_packets: 60666755
 tx_packets: 2206194
 rx_bytes: 6630349870
 tx_bytes: 815877983
 rx_broadcast: 58230114
 tx_broadcast: 9307
 rx_multicast: 8406
 tx_multicast: 17
 rx_errors: 0
 tx_errors: 0
 tx_dropped: 0
 multicast: 8406
 collisions: 0
 rx_length_errors: 0
 rx_over_errors: 0
 rx_crc_errors: 0
 rx_frame_errors: 0
 rx_no_buffer_count: 0
 rx_missed_errors: 0
 tx_aborted_errors: 0
 tx_carrier_errors: 0
 tx_fifo_errors: 0
 tx_heartbeat_errors: 0
 [...]

一些统计信息取决于NIC驱动程序,具体含义也是如此。以上内容来自英特尔 e1000。看过少数驱动程序之后,有些驱动程序会收集比其他驱动程序更多的统计信息(ethtool可用的统计信息往往保存在单独的源文件中,例如 drivers/net/ethernet/intel/e1000/e1000_ethtool.c,如果你需要翻找)。

ethtool -i eth0 将显示驱动程序的详细信息,输出 lspci -v 应该更详细,但也有点混乱。


更新  在 tg3.c 功能 tg3_rx() 只有一个地方可能有一个 tp->rx_dropped++ 代码乱七八糟 gotos,所以还有其他几个原因而不是明显的原因,即任何原因 goto drop_it  要么 goto drop_it_no_recycle。 (请注意,丢弃计数器是驱动程序维护的少数计数器之一,其余部分由设备本身维护。)

我必须提供的驱动源是3.123。我最好的猜测是这段代码:

           if (len > (tp->dev->mtu + ETH_HLEN) &&
                skb->protocol != htons(ETH_P_8021Q)) {
                    dev_kfree_skb(skb);
                    goto drop_it_no_recycle;
            }

检查MTU,可能的原因是巨型帧,或 略微超大的以太网帧 允许封装。我无法解释原因 tcpdump 可能会改变行为,不知道更改接口MTU。另请注意,您可以“看到”大于MTU的数据包 tcpdump 如果 TSO/LRO 已启用(说明)。


21
2017-12-13 11:21



谢谢你提出的答案。 sysfs statistics dir或by给出的信息 ethtool -S 是类似的(至少在我的系统上),我只得到有关丢弃数据包的信息。我将使用输出更新我的帖子。 - Huygens
我检查了驱动程序源代码(tg3.c),发现只引用了丢弃的VLAN错误和不正确的套接字缓冲区长度。我不知道该从中得出什么结论...... - Huygens
感谢您的更新,遗憾的是我不能再次+1 ;-)如果tcpdump报告巨型帧或大于我的MTU(1500)的帧,我会看看。 - Huygens
我确实有TSO和LRO''。 Tcpdump会报告大于我的MTU的帧,但是我需要看看这是否是由于LRO ...我将在周一看到。现在是时候在周末了。 - Huygens
如果 tg3 是一个模块和你 真 想要深究它你可以使用 printk()-喜欢 netdev_info() 要记录某些事件,代码中已有实例供您复制。看到 include/linux/skbuff.h 为了 sk_buff 结构(不适合胆小的人)。在相关的地方洒几个电话 tg3_rx(),重建并重新加载模块,等待...... - mr.spuratic