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()以外にも手を入れているだろうか?