Witam,
postanowiłem troszkę zwiększyć wydajność w/w skryptu przepisując jego pewne fragmenty i natrafiłem na troszkę głupi problem, o który wolę się zapytać was, gdyż brak mi odpowiedniego doświadczenia (jeszcze) na linii perl <-> SQL. Moją ideą jest zamiana "ciężkiego" -J MARK na coś ciut lepszego zwanego IPMARK, example:
iptables -t mangle -A POSTROUTING -o $if -j IPMARK --addr=dst --and-mask=0xffff --or-mask=0x10000
co powinno markować pakiety wg ostatnich dwóch oktetów, example:
192.168.88.99 to mark 5863 (hex), i do takiej kolejki 1:5863 wpada ruch z w/w marku (odpowiedni filtr to "tc_binary filter add dev $if parent 3:0 protocol ip fw"
w samym skrypcie zamieniłem kilka rzeczy: - funkcja u32todoquad zwraca wynik: "return sprintf "%x%x", ($p>>8)&0xff,$p&0xff;" czyli w odpowiedniej dla nas postaci hex.
- usunałem wpisy tworzące łańcuch LIMITS. - przerobiłem ciut pętelkę dodającą klasy i markująca pakiety, w moim "domowym" skrypcie wygląda to tak:
while (my $row = $dbq->fetchrow_hashref()) { if($nodetable{$row->{'customerid'}} && $row->{'downrate'}) { my %ifaces; $iptid ++; foreach my $ippair (split(' ',$nodetable{$row->{'customerid'}})) { my ($ipaddr, $if) = split(':',$ippair); print OUTFILE "$tc_binary class add dev eth1 parent 2:1 classid 2:".$ipaddr." htb rate ".$row->{'uprate'}."kbit ceil ".$row->{'upceil'}."kbit burst ".($row->{'uprate'} / 8)."kbit quantum 1500\n"; } } if($nodetable{$row->{'customerid'}} && $row->{'uprate'}) { $iptid ++; foreach my $ippair (split(' ',$nodetable{$row->{'customerid'}})) { my ($ipaddr, $if) = split(':',$ippair); print OUTFILE "$tc_binary class add dev $if parent 3:1 classid 3:".$ipaddr." htb rate ".$row->{'downceil'}."kbit ceil ".$row->{'downceil'}."kbit\n"; } } }
(tutaj ręcznie sobie zmodyfikowałem wan_interface na eth1, za to $if to moje LAN Interface (jest to ruter ktory rutuje z BGP do VLANów defacto)) I w czym rzecz. Zastanawiam się nad wzbogaceniem w/w kawałka kodu o stworzenie wyjątku, w którym klient ma więcej niż jeden komputer. W "oryginalnej" wersji skryptu (tj. lms-traffic-htbiplimits) w kodzie wynikowym jest taki wpis:
/usr/sbin/iptables -t mangle -A LIMITS -d xx.xx.89.93 -j MARK --set-mark 232 /usr/sbin/iptables -t mangle -A LIMITS -d xx.xx.89.8 -j MARK --set-mark 232 /sbin/tc class add dev eth0 parent 1:2 classid 1:1722 htb rate 8kbit ceil 600kbit burst 1kbit quantum 1500 /sbin/tc filter add dev eth0 protocol ip parent 1: handle 232 fw classid 1:1722
co jest jednoznaczne z tym, iż ruch od komputerów klienta, które mają adresy IP xx.xx.89.93 i xx.xx.89.8 wpadają do jednej klasy 1:1722 czyli w zasadzie to chcę uzyskać (klient w jednej taryfie (jednym paśmie) może mieć nawet i 10 komputerów...)
W moim znów kodzie podobny przykład ma takie rozwiazanie:
/sbin/tc class add dev eth0 parent 1:2 classid 1:595d htb rate 600kbit ceil 600kbit /sbin/tc class add dev eth0 parent 1:2 classid 1:598 htb rate 600kbit ceil 600kbit (595d == oktet 89.93, 598 == oktet 89.8)
i tworzy dwie oddzielne kolejki...
ma ktoś jakiś pomysł ? Miło było by rozwinąc wątek i stworzyć coś nowego/wydajniejszego. Cały skrypt wystawiam pod adresem: http://cyborg.d2.com.pl/~dzimi/lms-traffic-htbiptlimits.hex (jest on wysoce experymentalny i dostosowany do mojej sieci (tzn np. usunięte wpisy dotyczące iface wan czy lan (zadeklarowane statycznie w skrypcie, etc))