IPv4 送信処理
Rev.7を表示中。最新版はこちら。
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()を呼び出す。
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パケットを送信するため、下位層にsk_buffを渡す。
: 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未解決ならこの中でアドレス解決処理が開始される。