なぜパケットドロップが発生するのか?
(レイヤー 3 レベルで) パケットがドロップ (破棄) されるのは、以下のような場合があります。
- ルーティングテーブルにルートが無い場合
- ルーティングテーブル上に存在する Null ルート合致した場合
- IP ヘッダの df ビットが立っているのに、MTU 値を超えるパケットサイズの場合
- TTL が 0 になった場合
- NW機器の転送能力のキャパシティを超えた場合
1. ルーティングテーブルにルートが無い場合
ルーティングテーブルに宛先 IP のルートが無い場合、どこに送ればよいか分からなくなるため、その NW 機器でパケットが破棄されます。
破棄されるタイミングで NW 機器から ICMP の Destination Unreachable (Network Unreachable) が送信元 IP アドレス宛に通知されます。
ただし、大抵ルーティングテーブルにはデフォルトルートが入っているため、このケースは稀です。
2. ルーティングテーブル上に存在するNullルートに合致した場合
ある NW 機器上で『この宛先の通信は破棄したい』というとき、ACL で書くこともできますが、Null ルートを設定することでパケットを破棄できます。
例えば 192.168.1.0/24 宛の通信を破棄したい場合は、『192.168.1.0/24 宛のパケットのネクストホップは Null インタフェース』という Null ルートを設定すれば良いのです。
(config)# ip route 192.168.1.0 255.255.255.0 interface null
この Null ルートは、OSPF や EIGRP で集約ルートを設定する際に生成されます。ルーティング・ループを回避するためです。
この理由の詳細については以下をご参照下さい。
3. IPヘッダのdfビットが立っているのに、MTU値を超えるパケットサイズの場合
MTU 値を超えるパケットサイズを転送しようとしたとき、ルータはフラグメンテーションを試みます。
ただし、df ビットが立っている場合は、フラグメンテーション禁止のため、その NW 機器でパケットが破棄されます。
破棄されるタイミングで NW 機器から ICMP の Destination Unreachable (Need Fragmentation but Can't Fragment) が送信元 IP アドレス宛に通知されます。その際、送信元に適切な MTU 値を知らせることができます。
しかし、もしこの ICMP がアクセスリスト等で拒否されている場合、適切な MTU 値を知ることができず、また、宛先に届いたかどうかすら分からないため、タイムアウトまで待ち続けることになります。
4. TTLが0になった場合
ルーティングをする際には IP ヘッダの TTL フィールドの値を 1 つ減らします。
ルータに TTL = 1 のパケットが入ってきたとき、さらにルーティングが必要になる場合 (宛先 IP アドレスがその NW 機器に Connected の NW アドレスではない場合)、 TTL = 0となり、その NW 機器でパケットが破棄されます。
破棄されるタイミングで NW 機器からICMP の Time Exceededが 送信元 IP アドレス宛に通知されます。
コマンドプロンプトで ping を打ち、"転送中にTTLが期限切れになりました"、もしくは、"TTL expired in transit"と出てくるのは、この ICMP を受け取ったためです。
この場合の原因はたいてい、どこかでルーティングループが起こっています。『経由する NW 機器が多過ぎる』という可能性もありますが、現在では、あり得ないと考えても良いレベルです。
きちんと確認したい場合は、tracert を使って調査します。
5. NW機器の転送能力のキャパシティを超えた場合
これは当たり前ですが、機器の性能以上のパケットが入ってきたときは、一部のパケットは破棄されます。
関係する性能指標としては、bps や pps、CPU 使用率やメモリ使用率などがあります。
bps や pps はいわゆるパケットの流量です。詳細は以下をご参照下さい。
CPU 使用率は、ハードウェア処理のルーティング、スイッチングには関係ないだろと思う方もいるかもしれませんが、パケットを受信 NIC から取り出すときや、ヘッダ書き換え処理をしたパケットを送信 NIC へセットする際には、僅かながら CPU を利用します。
なので、CPU が 100% 稼働していると影響はあります。
また、メモリ使用率についてですが、受信パケットを保存するメモリ領域としては、具体的には ring-buffer と呼ばれるメモリの heap 領域を使います。
受信バッファを rx-ring、送信バッファを tx-ring と呼びます。
これらの値を変更したい場合は以下コマンドを使います。大きくすれば、パケットロスの可能性は低くなります。
(config-if)# rx-ring-limit 128
(config-if)# tx-ring-limit 128
ただし、これらの設定は大きくし過ぎるとパケットロスは減るものの、遅延が大きくなりますのでチューニングの際には注意が必要です。
パケットロス(ドロップ)発生時は再送されるのか?
TCP 通信であれば再送制御により再送されます。これはドロップの原因が L1 ~ L4 のどのレベルであろうと再送されます。
UDP の場合はどうかというと、上位アプリケーションプロトコル次第 (プログラマーのプログラミング実装次第) です。
例えば syslog を UDP で送信しているのであれば、ドロップしたらそのログは欠けてしまいます。音声パケットは再送されてもリアルタイムでないと音声の再生には使えないので、一般的には再送しません。ですが tftp は再送します。
もう1つ、SNMP の例でいうと、SNMP trap は欠けたら再送しませんが、SNMP inform を使うと、相手から応答が無いと再送します。なのでアラームの取りこぼしが無くなります。
パケットドロップの確認方法
パケットキャプチャを見る
「パケットドロップが発生したか否か?」を見るには Wireshark でパケットキャプチャを取得するのが一番簡単です。
TCP であれば背景が黒色になっているところは要注意です。Bad TCP と呼ばれます。意味は下記を参照してください。
また、ICMP のエラーが返ってきていたら、その内容からドロップの理由がわかるでしょう。(前述の理由 2 ~ 4 等は ICMP で判断することができます。)
NW 機器やサーバのインタフェースのカウンタを見る
「どこで発生したか?」が分かるのであれば、その NW 機器やサーバでインタフェースのカウンタを見ればある程度の状況を把握できます。
例えば Linux では以下のように確認できます。
パケットロスとパケットドロップの違い
どちらも同じことを指しています。
強いて言えば、ニュアンスが異なるでしょう。
パケットロスは「どこかでパケットが無くなった!」、パケットドロップは「ここでパケットを機器の仕様通りに破棄する」といったニュアンスです。
コメント