FreeBSD traffic shaper - DUMMYNET
Obsah
Úvod
Možnost jednoduchého omezení provozu nabízí akce probability ( =pravděpodobnost) příkazu ipfw.
Př.:
# zahazovat 20% ICMP echo požadavků
ipfw add prob 0.8 allow icmp from any to any in icmptypes 8
Komplexnější možnosti nabízí dummynet, jemuž se budu v tomto dokumentu věnovat.
DUMMYNET
Dummynet byl původně navžen pro testování síťových protokolů. Implementuje
variantu Weighted Fair Queueingu tzv. WF2Q+ ( =Worst-case Fair Weighted Fair Queueing).
K omezování provozu slouží dvě struktury:
- pipe ( =roura) emuluje linku s určitou šířkou pásma, zpomalením, velikostí fronty,
po jejímž přeplnění se pakety začnou zahazovat a dále pak ztrátovostí.
- queue ( =fronta) implementuje WF2Q+ (Worst-case Fair Weighted Fair Queueing).
Jednotlivé fronty jsou napojeny na rouru. Každá fronta má svou váhu, tedy pakety jdoucí
frontou s vyšší váhou mají v rouře přednost před pakety jdoucí přes frontu s nižší váhou.
Dále každá fronta má svou velikost a ztrátovost. Fronty se také mohou vytvářet dynamicky
podle zdrojové/cílové IP adresy, zdrojového/cílového portu nebo protokolu.
Přesun paketů z front struktur queue do fronty struktury pipe probíhá až když je ve
frontě struktury pipe místo. Fronta struktury pipe se vyprazdňuje rychlostí
danou její konfigurací.
Zprovoznění DUMMYNETu
Máme dvě možnosti:
1) Zavést modul dummynet.ko do jádra
$ kldload dummynet
Pozor: s modulem dummynet.ko se natáhne i modul ipfw.ko, takže jestliže pracujete vzdáleně,
je potřeba to udělat nějak takto:
$ kldload dummynet && ipfw add allow all from any to any
jinak si pod sebou podřežete větev...
2) Kompilací jádra s podporou DUMMYNET
$ cd /usr/src/sys/i386/conf && vim JADRO
# podpora pro samotný IPFW
options IPFIREWALL
# podpora pro DUMMYNET
options DUMMYNET
$ /usr/sbin/config JADRO
$ cd ../../config/JADRO
$ make depend
$ make
$ make install
$ reboot
Výpis a mazání rour a front
výpis rour a front
$ ipfw pipe show
$ ipfw queue show
smazání rour/front
$ ipfw pipe delete císlo_routy
$ ipfw queue delete císlo_fronty
smazání všech rour/front
$ ipfw pipe flush
$ ipfw queue flush
Konfigurace roury
$ ipfw pipe number config pipe-configuration
Možné nastavení roury:
bw bandwidth
Šířka pásma v [K|M]{bit/s|Byte/s}. Implicitní hodnota 0
( =nula) značí neomezenou šířku pásma. Jednotka musí bezprostředně následovat číslo.
delay ms-delay
Zpoždění v milisekundách. Implicitní hodnota 0 znamená žádné zpoždění.
plr packet-loss-rate
Ztrátovost paketů udávající číslo v rozmezí 0 ( = bez ztráty) a 1 ( = 100% ztráta).
queue {slots | sizeKbytes}
Velikost fronty roury v slotech nebo KBytech. Implicitní hodnota je 50 slotů,
což je běžná velikost fronty u ethernetových zařízení. Čím je menši kapacita linky
tím menší by měla být fronta v konfiguraci roury (je-li fronta příliš velká, dochází
k retransmisím, i když nebyl paket firewalem zahozen).
mask mask-specifier
Vytvoří se dynamická roura, která má stejné parametry jako roura originální. Možná
kritéria jsou:
dst-ip mask, src-ip mask, dst-port mask,
src-port mask, proto mask nebo all.
Poznámka: pro simulaci full duplex provozu je potřeba vydefinovat pipe i queue 2krát
- pro oba směry samostatně, bude-li pipe jen jedna pro oba směry, potom simuluje half duplex provoz.
Dále je dobré nastavit $ sysctl -w net.inet.ip.fw.one_pass=1
aby paket
opouštějící rouru neprocházel firewallem znovu, ale pokračoval na dalším pravidle.
Konfigurace fronty
$ ipfw queue number config queue-configuration
Možné nastavení fronty:
pipe pipe_number
Napojí frontu na rouru s číslem pipe_number. Na jednu rouru může být napojeno
několik front.
weight weight
Určuje váhu, která bude použita pro pakety jdoucí přes tuto frontu. weight je
číslo v rozsahu 1-100, implicitní hodnota je 1.
plr packet-loss-rate
Ztrátovost paketů udávající číslo v rozmezí 0 ( = bez ztráty) a 1 ( = 100% ztráta).
queue {slots | sizeKbytes}
Velikost fronty roury v slotech nebo KBytech. Implicitní hodnota je 50 slotů,
což je běžná velikost fronty u ethernetových zařízení. Čím je menši kapacita linky
tím menší by měla být fronta v konfiguraci roury (je-li fronta příliš velká, dochází
k retransmisím, i když nebyl paket firewalem zahozen).
mask mask-specifier
Vytvoří se dynamická fronta, která má stejné parametry jako fronta originální. Šířka
pásma se sdílí pro danou rouru. Možná kritéria jsou:
dst-ip mask, src-ip mask, dst-port mask,
src-port mask, proto mask nebo all.
Příklady
Omezení linky na 128Kbit/s full-duplex a její rovnoměrné rozdělení
# roury o šířce pásma 128Kbit/s s délkou fronty 16KBytů pro oba směry
ipfw pipe 1 config bw 128Kbps queue 16Kbytes
ipfw pipe 2 config bw 128Kbps queue 16Kbytes
# rovnoměrné rozdělení pásma rour podle zdrojové a cílové IP adresy
ipfw queue 1 config pipe 1 mask src-ip 0xffffffff queue 16Kbytes
ipfw queue 2 config pipe 2 mask dst-ip 0xffffffff queue 16Kbytes
ipfw add queue 1 ip from ... to ....
ipfw add queue 2 ip from ... to ....
Omezení linky na 256Kbit/s half-duplex a její dělení v poměru 2/3
# roura o šířce pásma 256Kbit/s s délkou fronty 32KBytů
ipfw pipe 1 config bw 256Kbit/s queue 32Kbytes
# fronty s váhami 40 a 60 = dělení v poměru 2/3
ipfw queue 1 config pipe 1 weight 40 queue 32Kbytes
ipfw queue 2 config pipe 1 weight 60 queue 32Kbytes
ipfw add queue 1 ip from ... to ....
ipfw add queue 2 ip from ... to ....
Odkazy
dummynet manuál
slidy z BSDConEurope 2001
ipfw - manuálové stránky
dummynet - manuálové stránky