NetBSD-current ip_flowを通らない場合のNetBSD-currentのIPパケット受信処理
NetBSD-currentのip_flowに関して調査している。
まずは、ip_flowを通らない場合のNetBSD-currentのIPパケット受信処理を調べて
みた。
個々のイーサネットデバイスドライバは、デバイスからパケットデータを取り出
してmbufに詰め、最後に
(*ifp->if_input)(ifp, m);
を呼ぶ。
イーサネットではこのポインタはether_input()を指している。
ether_input()では、以下の作業を行っている:
・パケットサイズが有効なサイズかチェック
・マルチキャストパケットへの手当て
・ブリッジが有効ならbridge_input()へ処理を譲る
・CARPが有効ならcarp_input()へ処理を譲る
・PFIL_HOOKSが有効ならpfil_run_hooks()を実行
return値が0なら終了、0以外なら処理続行
(此処がパケットフィルタ&NATなはず)
・VLANが有効ならvlan_input()へ処理を譲る
・AGRが有効ならagr_input()へ処理を譲る
・特別なイーサネットフレームの処理
・VLANパケットはvlan_input()へ渡す
・PPPOEパケットはsoftint_schedule(pppoe_softintr)するかドロップする
・SLOWPROTOCOLSはieee8023ad_lacp_input()かieee8023ad_marker_input()へ渡す
・通常のイーサネットフレームの処理
・IPパケットならipflow_fastforward()を実行
return値が0以外なら終了、0ならschednetisr(NETISR_IP)を呼び出し
・ARPパケットならschednetisr(NETISR_ARP)を呼び出し
・REVARPパケットならrevarpinput()へ処理を譲る
・IPv6パケットならip6flow_fastforward()を実行
return値が0以外なら終了、0ならschednetisr(NETISR_IPV6)を呼び出し
・IPXパケットならschednetisr(NETISR_IPX)を呼び出し
・ATALKパケットならschednetisr(NETISR_ATALK)を呼び出し
・AARPパケットならaarpinput()へ処理を譲る
・認識出来なかったパケットは捨てる
・上述の2つとも違う種類のパケットの処理(省略)
・キューがフルならパケットを捨てる、開いてればキューを入れとく
(netisrが後で取りにくる?)
ここまでは割り込みコンテキスト内で行われる(トップハーフ)。
これ以降はnetisrで、次のコンテキスト切り替え時に行われる(ボトムハーフ)。
netisrは独自のAPIを持っているが、softintで実装されている。
最初からsoftintで書いていないのは歴史的事情?