web-dev-qa-db-ja.com

ネットワークインターフェイスがパケットをドロップしている理由を見つける方法は?

Linuxで、パケットがドロップされたさまざまな理由に関する統計を取得する方法はありますか?

複数のサーバー上のすべてのネットワークインターフェイス(openSUSE 12.3)では、ifconfigおよびnetstat -iは、受信時にドロップされたパケットを報告しています。 tcpdumpを実行すると、ドロップされるパケットの数が増加しなくなります。これは、インターフェイスキューがいっぱいではなく、データをドロップすることを意味します。したがって、これが発生している理由は他にもあるはずです(たとえば、インターフェースがこのマルチキャストグループの一部ではないのに、マルチキャストパケットが受信されました)。

そのような情報はどこにありますか? (/ 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
20
Huygens

/sys/class/net/eth0/statistics/を試してください(つまり、eth0の場合)。これは完璧ではありませんが、送信/受信、およびキャリア、ウィンドウ、fifo、crc、フレーム、長さ(およびその他いくつか)のタイプのエラーによってエラーを分析します。

ドロップは「無視」と同じではありません。netstatはインターフェイスレベルの統計を表示します。上位レベル(レイヤー3、IPスタック)によって無視されたマルチキャストパケットはドロップとして表示されません(表示される場合があります)一部のNIC stats)で「フィルタリング」されているため、さまざまなオフロード機能によって統計が多少複雑になる場合があります。

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ドライバに依存します。正確な意味はこれと同じです。上記はIntel e1000によるものです。少数のドライバを検討した結果、一部のドライバは他のドライバよりもはるかに多くの統計を収集します(利用可能な統計ethtoolは、別のソースファイル(たとえばdrivers/net/ethernet/intel/e1000/e1000_ethtool.cなど)に保持される傾向があります。

ethtool -i eth0はドライバーの詳細を表示しますが、lspci -vの出力はより詳細である必要がありますが、多少雑然としています。


Updatetg3.c関数tg3_rx()には、tp->rx_dropped++と思われる場所が1つだけありますbutコードgotosが散らばっているので、明らかなもの以外にもいくつかの原因があります。つまり、goto drop_itまたはgoto drop_it_no_recycleを持つものです。 (ドロップカウンターはドライバーによって維持される数少ないものの1つであり、残りはデバイス自体によって維持されることに注意してください。)

私が手にしなければならないドライバソースは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を変更することはわかっていません。 [〜#〜] tso [〜#〜] / [〜#〜] lroの場合、tcpdumpを使用してMTUより大きなパケットを「見る」ことができることにも注意してください[〜#〜] が有効です( 説明 )。

25
mr.spuratic