帯域制御

現在、作成中

NICの3枚差しによる帯域制御の実験を行なった。 作業環境は下記の通り。

M/B: Iwill BD100
CPU: Celeron300A
MEM: 128MB
NIC: DEC21143(tulip)
OS: FreeBSD-3.2R

各種の帯域制御方法

dummynetは、FreeBSD-3.0Release(?)にて正式に組み込まれている。 また、PicoBSDというOne Floppy Router/Bridgeバージョンもある。 dummynetは、柔軟な帯域制御とプロトコルテストのためのツールである。 プロトコルスタックを通るパケットをインターセプトしたり、帯域制御や伝送遅延、 固定サイズキュー、パケット損失などの効果をシミュレートしたパイプに通すこと によって実現している。

DUMMYNETのインストール

# cd /usr/src/sys/i386/conf
# cp GENERIC dummynet
# vi dummynet

下記を変更(カーネルオプション)

ident   dummynet

下記を追加(どこでもよい。ここでは末尾に追加した)。

options "MAXMEM=(128*1024)"
options IPFIREWALL
options IPFIREWALL_VERBOSE
options DUMMYNET
options HZ

# config dummynet
Kernel build directory is ../../compile/dummynet
# cd ../../compile/dummynet
# make depend
# make
# make install
これまでに使っていたカーネル/kernelは、/kernel.oldとなる。
dummynet(4)によれば、下記のカーネルオプションが関係している。
IPFIREWALL               - enable ipfirewall (required for dummynet).
IPFIREWALL_VERBOSE       - enable firewall output.
IPFIREWALL_VERBOSE_LIMIT - limit firewall output.
DUMMYNET                 - enable dummynet operation.
NMBCLUSTER               - set the amount of network packet buffers
HZ                       - sets the timer granularity
通常、次のオプションが必要である。
options IPFIREWALL
options DUMMYNET

SYSCTL変数

dummynetには、次のSYSCTL変数が含まれている。
net.inet.ip.fw.one_pass
1に設定するとパケットが一度だけipfwコードを通る。
net.link.ether.bridge_ipfw
1に設定すると、ブリッジングされたパケットがipfwコードを通る。

dummynetの設定

/etc/rc.conf, /etc/rc.firewallファイルを編集すればよい。
/etc/rc.confファイルの設定

gateway_enable="YES"
firewall_enable="YES"
firewall_type="open"
firewall_method="dummynet"
ifconfig_de0="inet XXX.XXX.XXX.XXX netmask 255.255.255.0 media 100BaseTX mediaopt full-duplex"
ifconfig_de1="inet XXX.XXX.XXX.XXX netmask 255.255.255.0 media 100BaseTX mediaopt full-duplex"
ifconfig_de2="inet XXX.XXX.XXX.XXX netmask 255.255.255.0 media 100BaseTX mediaopt full-duplex"
network_interfaces="de0 de1 de2 lo0"
de0, de1, de2を100Mbps, Full-Duplexに設定している。Swithing HUBの自動認識 モードでは、10Base-T, Half-Duplexとして認識したためである。
/etc/rc.firewallの設定

# Prototype setups.
if [ "${firewall_type}" = "open" -o "${firewall_type}" = "OPEN" ]; then

    if [ "${firewall_method}" = "dummynet" ]; then

        $fwcmd add pipe 1 ip from any to any via lo0
        $fwcmd add pipe 2 ip from any to any via de0
        $fwcmd add pipe 3 ip from any to any via de1
        $fwcmd add pipe 4 ip from any to any via de2
        $fwcmd pipe 1 config bw 9600bit/s delay 300ms queue 10 plr 0.001
        $fwcmd pipe 2 config bw 9600bit/s delay 300ms queue 10 plr 0.001
        $fwcmd pipe 3 config bw 9600bit/s delay 300ms queue 10 plr 0.001
        $fwcmd pipe 4 config bw 9600bit/s delay 300ms queue 10 plr 0.001

    else

        $fwcmd add 65000 pass all from any to any

    fi

elif [ "${firewall_type}" = "client" ]; then
この例では、lo0, de0, de1, de2について、帯域幅 9600bps, 遅延 300msec, パケット損失(plr) 0.01%のトラフィックをシミュレートする。 注意しなければならないことは、全二重(Full-Duplex)の場合、方向それぞれ についてのトラフィックが各パイプを通るので、この例の場合、pingコマンド による測定結果では、2倍の遅延、パケット損失となることである。
非対称トラフィックのシミュレーションを行ないたい場合は、各方向ごとに 異なったパイプを通すようにすればよい。 下記にその例を示す。
ipfw add pipe 1 ip from A to B out
ipfw add pipe 2 ip from B to A in
ipfw pipe 1 config bw 512Kbit/s delay 80ms
ipfw pipe 2 config bw 64Kbit/s delay 300ms

ipltd 2.01のインストール

% cd src
% tar xofz ipltd_v2.01.tgz
% cd ipltd_v2.01
% make
% su
# cp ipltd /usr/local/sbin

カーネルの再構築

# cd /usr/src/sys/i386/conf
# cp GENERIC ipltd
# vi ipltd

下記を変更

ident   ipltd

下記を追加(どこでもよい。ここでは末尾に追加した)。

options "MAXMEM=(128*1024)"
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_FORWARD
options IPDIVERT

# config ipltd
Kernel build directory is ../../compile/ipltd
# cd ../../compile/ipltd
# make depend
# make
# make install
これまでに使っていたカーネル/kernelは、/kernel.oldとなる。

ipltd 2.01の設定

/etc/rc.conf, /etc/rc.firewallファイルを編集すればよい。
/etc/rc.confファイルの設定

下記を変更した。

firewall_method="ipltd"
/etc/rc.firewallの設定

# Prototype setups.
if [ "${firewall_type}" = "open" -o "${firewall_type}" = "OPEN" ]; then

    if [ "${firewall_method}" = "dummynet" ]; then

        $fwcmd add pipe 1 ip from any to any via lo0
        $fwcmd add pipe 2 ip from any to any via de0
        $fwcmd add pipe 3 ip from any to any via de1
        $fwcmd add pipe 4 ip from any to any via de2
        $fwcmd pipe 1 config bw 9600bit/s delay 300ms queue 10 plr 0.001
        $fwcmd pipe 2 config bw 9600bit/s delay 300ms queue 10 plr 0.001
        $fwcmd pipe 3 config bw 9600bit/s delay 300ms queue 10 plr 0.001
        $fwcmd pipe 4 config bw 9600bit/s delay 300ms queue 10 plr 0.001

    elif [ "${firewall_method}" = "ipltd" ]; then

        $fwcmd add divert 10000 ip from any to any out xmit de0
        $fwcmd add divert 10001 ip from any to any out xmit de1
        $fwcmd add divert 10002 ip from any to any out xmit de2
        $fwcmd add pass all from any to any
        /usr/local/sbin/ipltd -c 2000 -b 2400 -B 10000 -d 10000
        /usr/local/sbin/ipltd -c 2000 -b 2400 -B 10000 -d 10001
        /usr/local/sbin/ipltd -c 2000 -b 2400 -B 10000 -d 10002

    else

        $fwcmd add 65000 pass all from any to any

    fi

elif [ "${firewall_type}" = "client" ]; then

この例では、de0, de1, de2について、2000msec間で2400byte、つまり9600bpsの
トラフィックに制限している。

ET/BWMGRのほうは有料($495)である。 FreeBSD用以外にLinux 2.2.xバージョンがある。

Bridgeとして設定

Dummynetをブリッジとして動作させたい場合は、カーネルオプションに下記を追加 して再構築する。
options BRIDGE
再起動後、下記のようにsysctl変数を設定する。
# sysctl net.link.ether.bridge=1
# sysctl net.link.ether.bridge_ipfw=1
詳細は、man bridgeを参照のこと。 (続く) 戻る