パケットロスを意図的に発生させた実験をすることになったので、if_bridge + ipfw + dummynet をちょっとやってみた。OS は、FreeBSD 8.0 で、em0 と em1 を if_bridge で結ぶ感じ。fxp0 が、このマシンそのものが生きていくためのネットワークインタフェイスで、こっちは既に up & running.
まず、em0 と em1 を up にして、bridge でつなぐ。
ifconfig em0 up ifconfig em1 up ifconfig bridge0 create up addm em0 addm em1
NIS とか NFS 使ってないマシンなのを幸いに、ipfw と dummynet は kldload で入れる。NIS/NFS 使ってても、気をつければいけると思う。
kldload ipfw kldload dummynet ipfw add 100 allow ip from any to any via lo0 ipfw add 110 allow ip from any to any via fxp0
bridge まわりの sysctl はこんな感じでいいのかな。pfil_bridge は 0 にするのがいいみたい?
sysctl net.link.bridge.ipfw=1 sysctl net.link.bridge.pfil_member=0 sysctl net.link.bridge.pfil_bridge=0
それで、pipe へのルールと、pipe の定義。
ipfw add 200 pipe 1 all from any to any recv em0 xmit em1 ipfw add 210 pipe 2 all from any to any recv em1 xmit em0 ipfw pipe 1 config delay 10ms ipfw pipe 2 config delay 50ms
これで、60ms で ping が帰ってくるようになる。pfil_bridge を 1 にして、pipe X all from any to any via bridge0 とかだと、delay を 0 でなくした場合に ping が帰ってこなくなったりしたので、recv em0 xmit em1 とかで、双方向についてそれぞれのパイプを作ってやるのがよいのではないか、と思う。
もうちょっと進めて、em1→em0 が、1/3 ずつの確率で違う遅延になるようにしてみた。
ipfw delete 210 ipfw add 210 prob 0.33 pipe 2 all from any to any recv em1 xmit em0 ipfw add 210 prob 0.5 pipe 3 all from any to any recv em1 xmit em1 ipfw add 210 pipe 4 all from any to any recv em1 xmit em0 ipfw pipe 2 config delay 500ms ipfw pipe 3 config delay 1000ms ipfw pipe 4 config delay 1500ms
これで、ping -i 0.3 x.x.x.x とかすると、順番がばらばらになるのがわかって、面白い。到達時間のジッタとかを模擬するのにいいですね。prob を使って、確率でパケットを落としたり、pipe の bandwidth (bw), packet loss rate (plr) みたいなパラメータを使うと、かなりいろんな性能検証ができる。