FreeBSD 7.0 ip_fastforwardの仕組み
大雑把な流れは以下の通り:
デバイスドライバからether_input()が呼ばれる。
条件毎に必要な処理を行い、ether_demux()を呼ぶ。
ether_demux()でプロトコル毎の処理を行う。
IPの場合はip_fastforward()を呼び、返り値が0ならnetisr_dispatch()を実行する。
たのプロトコルではfastforwardしないのでnetisr_dispatch()を直接呼ぶ。
ip_fastforward()では、フォワーディングとファーストフォワードが有効になっているか確かめ、ヘッダがおかしくないか調べてから宛先を見る。
自分宛やローカルホストだったらreturn 0で抜けてnetisr_dispatch()に渡す事にする。
外部のホスト宛なら、pfil_run_hooks()でPFIL_INのフックを実行しパケットが捨てられたら処理を中止する。
アドレスが書き換わって自分宛になったらreturn 0で抜けnetisr_dispatch()に渡す。
依然外向けなら、ip_findroute()をぶ。
ip_findroute()では、宛先ルートを取得する。
宛先が無効ならICMP Host unreachableを送信元へ送る。
ルートが有効ならpfil_run_hooks()でPFIL_OUTのフックを実行、パケットが捨てられたら処理を中止する。
アドレスが書き換わって自分宛になったらreturn 0で抜けnetisr_dispatch()に渡す。
自分宛ではないなら、もう一度ip_findroute()を実行。
問題がなければ、(*ifp->if_output)()を実行してether_output()を呼び出してパケットを送出する。
- 分かった事
- ip_forwardの仕組みの中にNAT対応/フィルタ対応が含まれている。
この為殆どの場合においてファーストパスが有効になりそうだが、代償としてか、コードが大変複雑なものになっている。
-
- ip_flowにあったハッシュテーブルによる宛先キャッシュは無くなった。
ルーティングテーブルが有れば十分という事だろうか。
- まだ分からない事
- NetBSDとのソース互換性はどの程度ある?
- ip_forward対応の為、ether_input()以外にも手を入れているだろうか?