Dummynet

研究関連でDummynetを使う必要があったので,その設定をやっていました.
取りあえずPCにNIC2枚挿してFreeBSD 4.10をインストール.

カーネルの再構築

まず,カーネルの再構築を行います.
/usr/src/sys/i386/conf/GENERICの設定ファイルを適当なファイル名でコピーし,以下の行を追加します.IPFIREWALL_*というオプションはイマイチ意味が分かってないのですが,取りあえず設定してます.

options    IPFIREWALL
options    IPFIREWALL_VERBOSE
options    IPFIREWALL_FORWARD
options    IPFIREWALL_DEFAULT_TO_ACCEPT
options    DUMMYNET
options    BRIDGE
options    HZ=1000

そして,再構築してリブート.

# cd /usr/src/sys/i386/conf/
# config DUMMYNET
# cd ../../compile/DUMMYNET/
# make clean
# make depend
# make
# make install
# reboot

bridge及びipfwの適用

bridge及びipfwを有効にするにはsysctlを設定します.
今回は,インターフェースがfxp0, rl0という名前でした.

# sysctl -w net.link.ether.bridge=1
# sysctl -w net.link.ether.bridge_ipfw=1
# sysctl -w net.link.bridge_cfg="fxp0:1,rl0:1,"

起動する度に↑の設定を行うのは面倒なので,通常は/etc/sysctl.confに記述しておくようです.

net.link.ether.bridge_cfg=fxp0:1,rl0:1,
net.link.ether.bridge=1
net.link.ether.bridge_ipfw=1

ipfwの設定

これまでの設定で,bridgeとしての役割は果たすようになったと思います.
ipfwは,トラヒック制御を行う時などに用いられます.
今回は,2PC間である程度の通信遅延を発生させたかったので,遅延時間だけ設定します.

# ipfw add pipe 1 ip from any to any
# ipfw pipe 1 config delay 50ms

これも,通常は/etc/rc.firewallに設定するようです(今回は,記述しても反映されなかったので保留).
上記のように設定すると,このPCを経由する場合50msほど遅延が発生するようになります.
例えば,192.168.1.30→192.168.1.49へpingを送った場合

設定前:

# ping -s 1500 192.168.1.49
PING 192.168.1.49 (192.168.1.49): 1500 data bytes
1508 bytes from 192.168.1.49: icmp_seq=0 ttl=64 time=0.952 ms
1508 bytes from 192.168.1.49: icmp_seq=1 ttl=64 time=0.929 ms
1508 bytes from 192.168.1.49: icmp_seq=2 ttl=64 time=0.928 ms
1508 bytes from 192.168.1.49: icmp_seq=3 ttl=64 time=0.925 ms

設定後:

# ping -s 1500 192.168.1.49
PING 192.168.1.49 (192.168.1.49): 1500 data bytes
1508 bytes from 192.168.1.49: icmp_seq=0 ttl=64 time=99.711 ms
1508 bytes from 192.168.1.49: icmp_seq=1 ttl=64 time=100.171 ms
1508 bytes from 192.168.1.49: icmp_seq=2 ttl=64 time=99.653 ms
1508 bytes from 192.168.1.49: icmp_seq=3 ttl=64 time=100.126 ms

言うまでもないかもしれませんが,設定した時間の倍位かかっているのはRTT(行って帰って来るまでの時間)が表示されているためです.

参考URLと補足

ほぼ,↑のサイトのパクりです.


ちなみに,HZの値は1秒間にカーネルが割り込みを掛ける回数を表しています.
そして,パケットは一旦バッファリングされた後,一定時間遅延させて送出されるようですが,恐らくこの一定時間遅延させるという部分を割り込み処理を使って実現しているのだと思います.そうすると,パケットは最小1/HZ間隔で送出されることになります.そのため,HZの値を大きくすると精度が高くなります.
尚,現在の一般的なPC(Pentium 4 2.0G〜)では,HZが20,000辺りからかなりパフォーマンスが悪くなり,100,000より大きな値を設定した場合kernel panicが起こる可能性が高いようです.