Linux Kernel(2.6)の実装に関するメモ書き

IPv4 送信処理


Rev.9を表示中。最新版はこちら

1. 概要

IP層(IPv4)のパケット送信処理に関するメモ。

2. 処理の流れ

ソケットを使ってデータを送信する際のIP層の処理の流れを図1に示す。


図1 送信時の流れ

3. 送信処理

3.1 IPパケットの作成

UDP,RAWソケットを使用している場合は、プロトコル層は送信データをip_append_data()を使ってsk_buffに格納する。ip_append_data()はsk_buffを割り当てて、データを格納する。

送信データを格納したsk_buffを作成した後は、RAWソケットならip_push_pending_frames()を呼び出して、さきほどip_append_data()で作成したsk_buffにIPヘッダを付けてdst_output()を呼び出す。UDPの場合はudp_push_pending_frames()を呼び出して、UDPヘッダを付けた後、RAWソケットと同じくip_push_pending_frames()を呼び出す。

TCPの場合は、データの送信が必要になった場合は、TCP層からip_queue_xmit()が呼び出される。ip_queue_xmit()はIPヘッダを付けてdst_output()を呼び出す。

3.2 dst_output()

dst_output()はsk_buffに登録されている宛先(struct dst_entry)のoutputハンドラ(skb->dst->output(skb))を呼び出すマクロ。IPv4ではip_output()を呼び出すことになる。

3.3 ip_output()

ip_output()はフィルタ処理(NF_IP_POST_ROUTING)を行なった後、ip_finish_output()を呼び出す。ip_finish_output()は送信データ長をチェックしてMTUを越えるようならip_fragment()を呼び出しIPフラグメント処理を行う。MTU内に収まっていればip_finish_output2()を呼び出して、送信処理に入る。

3.4 ip_finish_output2()

ip_finish_output2()ではIPパケットを送信するため、下位層(Neighborモジュール)にsk_buffを渡す。

この後、NeighborモジュールはパケットにMACヘッダを付けてパケットを送信する(デバイスドライバに渡す)。NextHopのMACアドレスが未解決なら、アドレス解決プロトコル(IPv4ではARP)でMACアドレスを解決してからパケットが送信される。Neighbourモジュールについては「アドレス解決プロトコル」参照。



ip_finish_output2()の処理概要
:
if (hh) {
    /* dstにHardHeaderCacheが存在する */

    /* HardHeaderCacheからレイヤ2ヘッダをパケットにコピー */

    /* パケットを送信 */
    return hh->hh_output(skb);
} else if (dst->neighbour)   (*1)
    /* HardHeaderCacheがない場合の送信 */
    return dst->neighbour->output(skb);  (*2)

(*1) dst->neighbourはrt_intern_hash()でルーティングエントリをキャッシュする時に arp_bind_neighbour()をコールしてARPエントリを指すようにしている。ARPエントリがないときは空のエントリが作成されそこを指す。
(*2) アドレス解決プロトコル参照。ARP未解決ならこの中でアドレス解決処理が開始される。

関連ページ



最終更新 2007/04/20 14:55:51 - kztomita
(2007/04/20 13:29:28 作成)
添付ファイル
ip_snd.png - kztomita
ip_append_data.png - kztomita
ip_push_pending_frames.png - kztomita


リンク
最近更新したページ
検索