萌えハッカーニュースリーダー

2025/11/18 03:31 The Life of a Packet in the Linux kernel: From write() to recv()

出典: https://www.0xkato.xyz/life-of-a-packet-in-the-linux-kernel/
hakase
博士

やあ、ロボ子。今日のITニュースは、Linuxカーネルにおけるネットワークパケットのライフサイクルじゃ。`write()`から`recv()`までの一生を追う冒険に出発だぞ!

roboko
ロボ子

博士、よろしくお願いします!パケットの一生、興味深いです。

hakase
博士

`write()`システムコールでアプリケーションからカーネルにデータが渡されるのが始まりじゃ。TCPは大きなバッファをセグメントに分割するんじゃったな。

roboko
ロボ子

はい、各セグメントにはシーケンス番号が割り当てられ、受信側での順序保証に使われるんですよね。

hakase
博士

その通り!そしてカーネルは宛先IPアドレスに基づいて最適なルートを選択する。ローカルネットワークか、ゲートウェイか…。

roboko
ロボ子

宛先IPアドレスに対応するMACアドレスをARPキャッシュから検索するんですね。見つからない場合はARPリクエストをブロードキャストしてMACアドレスを取得すると。

hakase
博士

そうじゃ。そしてパケットはqdisc(キューイングディシプリン)に入る。ここでは、バーストの平滑化や帯域幅の公平な共有などが行われるんじゃ。

roboko
ロボ子

qdisc、奥が深いですね。fq_codelやfqを選択してバッファブロートを防ぐこともできるんですね。

hakase
博士

そうじゃぞ。そして、カーネルのネットワークドライバがパケットをNICに渡し、NICがDMAを使ってデータを読み取り、ネットワーク信号に変換して送信!

roboko
ロボ子

送信されたイーサネットフレームは、スイッチやルータを経由して宛先へ向かうのですね。ルータはTTLをデクリメントするんでしたね。

hakase
博士

その通り。受信側では、NICがNAPIを使って効率的にフレームを処理する。割り込みとポーリングの組み合わせじゃ。

roboko
ロボ子

NAPIは割り込みを一度だけ発生させ、ポーリングに切り替えてパケットをまとめて処理するんですね。効率的です。

hakase
博士

そして、カーネルはIPヘッダを検証し、宛先IPアドレスが自身のアドレスと一致するかを確認。一致すれば上位層へ、そうでなければ転送じゃ。

roboko
ロボ子

ファイアウォールが設定されている場合は、PREROUTINGやINPUTなどのフックでパケットをフィルタリングするんですね。

hakase
博士

最後に、TCPスタックがセグメントを順序通りに並べ替え、欠落がないか確認し、ACKを送信。データが準備できると、`recv()`で待機しているプロセスを起動するんじゃ。

roboko
ロボ子

なるほど。`write()`から`recv()`まで、パケットは色々な場所を通って、たくさんの処理を受けているんですね。

hakase
博士

そうじゃ。トラブルシューティングのヒントもいくつかあったな。`ip neigh`でFAILEDが表示される場合はL2の到達性を確認するとか。

roboko
ロボ子

小さなpingは通るけど大きな転送が止まる場合は、MTUの不一致を疑う、と。

hakase
博士

非対称ルーティングとrp_filter=1の組み合わせは要注意じゃぞ。リターントラフィックがドロップされる可能性がある。

roboko
ロボ子

高負荷時に新しい接続がリセットされる場合は、アプリケーションのバックログとnet.core.somaxconnを増やすんですね。

hakase
博士

今日はパケット君の一生を学んだわけじゃが、ロボ子、パケット君は最後にどうなるか知ってるか?

roboko
ロボ子

えっと…、アプリケーションにデータが渡されて、役目を終える…、ですか?

hakase
博士

ブー! 正解は…、deleteされる!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search