hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

tcpdumpのフックポイント、Netfilterのチェイン、Qdiscのカーネル内の場所



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関数で事前に登録したものです。

4.3 転送処理

レイヤ 関数名 概要
インターネット層 ip_forward パケットの転送処理をします。IPヘッダのTTL(Time To Live)が1以下のパケットは廃棄します。それ以外のパケットはTTLを1減算します。そして、FORWARDINGチェインを実行します。
ip_forward_finish dst_outputを実行します。dst_outputにはip_output関数へのポインタが設定されています。