FreeBSDにおけるFIB
FreeBSDでは、FIB(Forwarding Informations Base)を複数持つことができる。
FIBとは
以下、経路表(以下RI)とFIBの違いを不正確を承知で簡単にまとめておく
- 特に動的経路制御(RIP/OSPF/BGP/IS-ISなど)を行っているような場合、同一destinationへのnexthopが複数個RIに登録されることがある。
- しかし、Kernelは、パケットを送出するときに「どこに投げれば良いか」を、毎回Riを参照して、いちいち再計算して送り出すのは効率が悪い
- RIが書き換わったときに、再計算して、destination単位でnexthopを決め、再計算不要な表を事前に作っておけば便利
- この送出時の再計算を不要にするための表がFIB
このFIBが複数あるということで、例えばJail環境におけるPrisoner毎に利用するFIBを変えたり、pfなどを利用してPolicy Routingを行ったりすることが容易になる(と思われる)。
net.fibs
FreeBSDにおいて、sysctl net.fibs
を実行すると、現在のFreeBSD kernel内のFIB数がわかる。
FIBには0から順番に番号が付与されている。また、 FIBはプロセス単位で割り当てることが可能である。 FreeBSD 7.1-RELEASE以降、特に設定しなければ、FIBは1個で、FIB 0が利用される。
setfib(1)を利用することでプロセスにFIBを割り当てることができる。
# setfib -1 ping www.example.com
この場合、ping には FIB 1が割り当てられる。
コマンドによってはFIBを指定するオプションが用意されている。たとえばrouteコマンドは次のようにして、経路情報の変更をどのFIBに反映させるかを指定できる。
route add -net -inet 192.168.2.0/24 10.0.0.1 -fib 2
netstat -rの場合は、次のように指定する。
netstat -r -F 2
FIBを複数用意して、"netstat -nrF 1" のように実行してみると、感じがつかめる筈。
FIBが複数ある場合の利用FIBの決定アルゴリズムは以下の通り。
- FIBが設定されているパケットは、設定されているFIBが使われる。設定されていなければ、FIB 0が使われる
- 外部から到着して、IP forwardingの対象となるパケットには、FIB 0が使われる
- あるプロセスがlistenしているTCPソケットがあり、 そのプロセスにFIBが割り当てられている場合、acceptしたソケット側にも同じFIBに割り当てられる
- TCP以外でFIBが割り当てられているパケットの場合、 そのパケットに対する応答パケットは、同じFIBが割り当てられる
- gif(4)やtun(4)などのトンネルインタフェースで生成されるカプセル化されたパケットは、そのインタフェースを作ったプロセスのFIBが割り当てられる
ifconfig gif0 create tunnelfib 1
とした場合、gif0でカプセル化されたパケットはFIB 1で処理されるifconfig gif0 create fib 1
とした場合、受信してgif0でカプセル化解除されたパケットがFIB 1で処理される
- ルーティングメッセージは、 そのメッセージを生成したプロセスのFIBが割り当てられる
上記決定ロジックによってFIBが決定されるので、FIB 1に適当に経路を追加・削除しても、FIB 0を修正しない限り影響はない(筈)。
FIB数は、カーネルオプションの他、loader tunableでも変更可能。(/etc/sysctl.confでは変更不能)。以下主要なtunables.
- net.fibs: FIB数。16個まで指定可能。
- net.my_fibnum: デフォルト FIB の番号
- 何も指定しなければ0になる。
- net.add_addr_allfibs: デフォルトFIB以外の全FIBに、インタフェースの経路を自動的に追加するかどうか。
- defaultは1
- 0にすると、 明示的に経路を追加しない限り0番以外には経路が追加されない
なお、FIBはIPFWでも設定可能。allowの代わりにsetfibというアクションルールを指定すれば良い。
# ipfw add 1000 setfib 番号 from any to any
この条件にマッチするパケットが指定された番号の FIB に割り当てられます。そしてルールの処理は、マッチしようがしまいが、 そのまま直後のルールに続く。