隙あらば寝る

うぇぶのかいしゃではたらくえんじにあがかいています

tcpdump で dropped by kernel をなくしたい

結論

tcpdump に適切なオプションを渡す。

  • -B で大きい数字を指定することでカーネルバッファのサイズを増やす
  • -n で余計な名前解決を減らすことでカーネルバッファの読み込みスピードを上げる
  • -w で tmpfs を指定すると IO のスピードをかなり減らせるので検討してもよい

詳細

tcpdump していたがどうも集めたデータがおかしいという事があった。 こういうときは tcpdump の実行終了時に

X packets dropped by kernel

と出ていることがある。

tcpdump - Why would the kernel drop packets? - Unix & Linux Stack Exchange

が参考になるが、どうも tcpdump にはバッファがあって、それを使い果たすと drop したということになるらしい。

具体的には tcpdump が内部で使っている libpcap において、raw socket から recv(3) する際に、ENOBUFS が出るとカウンタを増加させていた。参考

tcpdump の -B オプションでバッファを指定すると libpcap の内部で raw socket の SO_RCVBUF サイズを変更するという処理が行われる。参考

この値が増えるとカーネルの中でバッファできる量が増えるので drop 率が減る。

しかし、そもそもの話としてバッファのデータを読み出すのが遅れるのが根本的な問題点であり、

読み込みのスピードを上げるのが根本的な解決になる。

そのためにも余計な処理をしないようにするのが良く、-n を付けて名前解決を減らす。

あと標準出力も遅い部類になると思うので、ちゃんと調べるつもりならなにはともあれ -w で保存したほうがよい。

かつ tmpfs とかに書くと I/O のオーバーヘッドがかなり減るので最後の手段として使える。

おまけ

アカウント持ってないので見れないんだが、ぐぐってたら以下のページを見つけた。

Why does tcpdump display some packets as "packets dropped by kernel" ? - Red Hat Customer Portal

なんてかいてあるのか気になる...