1 はじめに
tcpdumpのフックポイント、Netfilterのチェイン、Qdiscの場所についてまとめました。これらの位置を理解しておくと、ネットワークのトラブルシューティング等に役立ちます。
2 検証環境
AlmaLinuxの版数は以下のとおりです。
[root@server ~]# cat /etc/redhat-release AlmaLinux release 8.6 (Sky Tiger)
カーネル版数は以下のとおりです。
[root@server ~]# uname -r 4.18.0-372.9.1.el8.x86_64
3 鳥瞰図
ドライバとトランスポート層の間の関数の呼び出し関係を以下に図示します。この図は、systemtapを使ってサーバ/クライアントの2台構成の環境でncコマンドを実行した際の関数呼び出しを確認したもので、図の左側が受信処理、右側が送信処理を表しています。楕円の内側には関数名が表示されていますが、すべての関数が図示されているわけではありません。また、ドライバとトランスポート層の間の適切な用語が見当たらないため、便宜上デバイス層と呼ぶことにします。
図中の網掛け部分について以下に説明します。
網掛けの色 | 概要 |
---|---|
黄色 | iptablesコマンドでパケット廃棄等のルールを設定する場所です。チェインと呼ばれています。デフォルトで5つのチェインが定義されています。 |
緑色 | ルーティング処理を実行する場所です。宛先IPアドレスをキーにルーティングテーブルを検索して宛先を決定します。 |
オレンジ色 | ルーティング処理を実行すると、その結果に応じて dst_input および dst_output に関数へのポインタが設定されます。たとえば、受信パケットに対してルーティング処理を実行すると、宛先IPアドレスが自分宛のパケットの場合には dst_input に ip_local_deliver 関数へのポインタ、他のサーバ宛ての場合にはdst_input に ip_forward 関数へのポインタが設定されます。 |
赤色 | tcpdumpのフックポイントです。tcpdump/tsharkコマンドを実行すると、フックポイントの関数が呼び出され、送受信のパケットがキャプチャされます。 |
青色 | Qdiscと呼ばれる場所です。Traffic Control(交通整理)を実行する場所です。tcコマンドは、Qdiscに対してパケットの遅延、廃棄、並び替えを実行します。 |
灰色 | ドライバ関数へのポインタが設定されています。ops->ndo_start_xmitを呼び出すと、NICに対応したドライバ関数が実行されます。ここでは、e1000_xmit_frame関数(Intelのe1000eドライバ)を図示しています。 |
4 関数の概要
4.1 受信処理
レイヤ | 関数名 | 概要 |
---|---|---|
トランスポート層 | tcp_v4_rcv | TCPの受信処理入り口関数です。 |
udp_rcv | UDPの受信処理入り口関数です。 | |
インターネット層 | ip_protocol_deliver_rcu | IPヘッダに設定されているプロトコル番号(TCP=6,UDP=17)にしたがって、TCPまたはUDPの受信処理入り口関数を呼び出します。 |
ip_local_deliver | ルーティング処理の結果、受信パケットが自分宛のパケットを処理します。フラグメントされたIPパケットを元の1つのIPパケットに再構築します。そして、INPUTチェインを実行します。 | |
ip_rcv_finish | ルーティング処理を呼び出します。 | |
ip_rcv | IPの受信処理入り口の関数です。IPヘッダのサイズやIPのバージョンをチェックします。そして、PREROUTINGチェインを実行します。 | |
デバイス層 | net_rx_action | ソフト割り込みの入り口関数です。ソフト割り込みの延長でプロトコルの受信処理が行われます。 |
ドライバ | e1000_intr_msix_rx | NICの受信バッファからドライバのリングバッファ(受信バッファ)に受信パケットのDMA転送が完了すると、受信完了割り込みが発生します。この受信完了割り込みで呼び出す関数です。この関数はrequest_irq関数で事前に登録したものです。 |
4.2 送信処理
レイヤ | 関数名 | 概要 |
---|---|---|
トランスポート層 | tcp_transmit_skb | TCPヘッダを組み立てて、送信パケットをIP層に引き渡します。 |
udp_send_skb | UDPヘッダを組み立てて、送信パケットをIP層に引き渡します。 | |
インターネット層 | ip_local_out | IPの送信処理入り口の関数です。IPヘッダにIPパケット長、チェックサム値を設定したあと、OUTPUTチェインを実行します。 |
ip_output | 送信パケットの管理情報(sk_buff構造体)を更新します。そして、POSTROUTINGチェインを実行します。 | |
デバイス層 | qdisc_run | Qdiscを呼び出して、Traffic Controlを実行します。 |
ドライバ | e1000_xmit_frame | 送信パケットをドライバのリングバッファ(送信バッファ)にマッピングしたあと、NICに対してDMA転送を要求します。 |
e1000_intr_msix_tx | リングバッファからNICの送信バッファに送信パケットのDMA転送が完了すると、送信完了割り込みが発生します。この送信完了割り込みで呼び出す関数です。この関数はrequest_irq関数で事前に登録したものです。 |
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ