HTB Script

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everybody!

I wrote nice script, but I need some help....
Script is working almost well.

My question is:
Can I minimalize PING time more than this script can? (nowadays is 70-150ms with large load of link)
My first problem is - unreal big PING on router, and almost excellent (nowadays is 70-150ms) PING on computers in network.


My users don't complain, but I noticed that the pages is becoming load quickly and when it's almost done.. the transfer is going down!!
And second symptom is: when I open pages PING grows to 800ms, and quickly go down. It's almost imperceptible, but it happens.
What's wrong? All packets is going to correct pipes. What should I do more?
I suspect, that time of change of speed (HTB's reaction time) many queues is long. How can I improve this?
Script is very nice, but I need some professional help and advices.


Everything You can check when script is working:
./htb0.5.3en stat <IP> (example: ./htb0.5.3en stat 192.168.0.2)
./htb0.5.3en stat lan
./htb0.5.3en stats

My network's statistics:
http://stats.opat.hopto.org/
http://stats.zabierzow.net/

I attached my script. IMQ with imq_nat.diff patch is required (or AB option in kernels 2.6), patched iptables(IMQ patch) is required, iproute is required and bc is required. I tested this script on 2.6.9 kernel and iproute from .deb package.

And second less important problem... How Can I mark squid's MISS packets? Is Debian's Squid Package patched to change TOS?
http://stats.zabierzow.net/squid.php :d


Someone will help?
#!/bin/bash
#
# rc.htb 0.5.3, (C)Lenthir 2oo4, GNU GPL
# 2004-11-01 9:30
VER="0.5.3"
DAT="2004-11-01 9:30"

MAX=3330
#######################
#Configuration:
ext_dwl=2000                                           #speed of link(s)(kbit/s) - download
ext_upl=220                                            #speed of link(s)(kbit/s) - upload

int="192.168.0.2 192.168.0.3 192.168.0.4 192.168.1.2"  #internal addresses IP
ext="80.53.64.3"                                       #external addresses IP with or without external router IP

srv_ext="80.53.64.3"                                   #external router IP(machine where you exec this script)
lan_int="192.168.0.0/24 192.168.1.0/24 192.168.2.0/24" #subnetworks(pool of addresses)

int_dwl[0]=85; int_upl[0]=85                           #subnetworks speed(download; upload) in order such how it is above
int_dwl[1]=2;  int_upl[1]=2
int_dwl[2]=80; int_upl[2]=80

TC=`which iptables`                                    #path to tc
MODPROBE=`which modprobe`                              #path to modprobe
IP=`which ip`                                          #path to ip
IPTABLES=`which iptables`                              #path to iptables
firewall="/etc/init.d/rc.iptables restart"             #how is firewall(iptables) restart?

#u_r2q=10                                              #r2q (optional)
u_quantum=1500                                         #quantum (optional todo, at present required)

porty_tcp="20 21 22 23 25 53 80 110 143 220 443 993 995 27015" #tcp preference ports
porty_udp="53"                                         #udp preference ports
pping=1                                                # 0 - ping throw in preference queue 1 - ping throw in not preference queue

#End
#######################

stop()
{
$TC qdisc del root dev imq0 2> /dev/null
$TC qdisc del root dev imq1 2> /dev/null
$IP link set imq0 down
$IP link set imq1 down
}

start()
{ stop

#It checks is router adress in ext.
ipki="$ext $int"
for srvip in $srv_ext
do
if [[ `echo $ipki | grep $srvip` != $ipki ]]; then
ext="$ext $srvip"
fi
done

ile_int=`echo ${int}|awk '{print NF}'`
ile_ext=`echo ${ext}|awk '{print NF}'`
ile=$(echo "$ile_int + $ile_ext" | bc)

if [[ $ile -ge $MAX ]]
        then
        echo "Too many computers!"
        exit 1
        fi

# download
tmp=$(echo "$ext_dwl%$ile" | bc)
min=$(echo "$ext_dwl/$ile" | bc)
pri_min=$(echo "$min/2+$min%2" | bc)
sec_min=$(echo "$min/2" | bc)
max=$ext_dwl

echo " Quantity of computers: $ile"
echo "%===================================================================%"
echo " Setting download queue."
echo " Minimum download: $min kbit/s"
echo " Maximum download: $max kbit/s"
echo " Queue: -preference: $pri_min kbit/s  -not preference: $sec_min kbit/s"
echo " Free: $tmp kbit/s"
echo " "

if [[ u_r2q=="" ]]; then
$TC qdisc add dev imq0 root handle 1:0 htb
else
$TC qdisc add dev imq0 root handle 1:0 htb r2q $u_r2q
fi

$TC class add dev imq0 parent 1:0 classid 1:1 htb rate ${ext_dwl}kbit ceil ${ext_dwl}kbit

j=2
for usr in $ext
        do
        $TC class add dev imq0 parent 1:1 classid 1:$j htb rate ${min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq0 parent 1:$j classid 1:$(($j+1)) htb rate ${pri_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq0 parent 1:$j classid 1:$(($j+2)) htb rate ${sec_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC qdisc add dev imq0 parent 1:$(($j+1)) sfq
        $TC qdisc add dev imq0 parent 1:$(($j+2)) sfq
        $TC filter add dev imq0 protocol ip parent 1:0 pref 2 u32 match ip dst $usr flowid 1:$j
        for prt in $porty_tcp
                 do
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 6 0xff match ip sport $prt 0xffff flowid 1:$(($j+1))
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 6 0xff match ip dport $prt 0xffff flowid 1:$(($j+1))
                 done
        for prt in $porty_udp
                 do
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 17 0xff match ip sport $prt 0xffff flowid 1:$(($j+1))
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 17 0xff match ip dport $prt 0xffff flowid 1:$(($j+1))
                 done
        if [[ $pping -eq 1 ]]; then
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 1 0xff flowid 1:$(($j+1))
                 fi
        $TC filter add dev imq0 protocol ip parent 1:$j pref 4 u32 match ip dst $usr flowid 1:$((j+2))
        let "j=j+3"
        done

for usr in $int
        do
        $TC class add dev imq0 parent 1:1 classid 1:$j htb rate ${min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq0 parent 1:$j classid 1:$(($j+1)) htb rate ${pri_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq0 parent 1:$j classid 1:$(($j+2)) htb rate ${sec_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC qdisc add dev imq0 parent 1:$(($j+1)) sfq
        $TC qdisc add dev imq0 parent 1:$(($j+2)) sfq
        $TC filter add dev imq0 protocol ip parent 1:0 pref 2 u32 match ip dst $usr flowid 1:$j
        for prt in $porty_tcp
                 do
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 6 0xff match ip sport $prt 0xffff flowid 1:$(($j+1))
                 done
        for prt in $porty_udp
                 do
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 17 0xff match ip sport $prt 0xffff flowid 1:$(($j+1))
                 done
        if [[ $pping -eq 1 ]]; then
                 $TC filter add dev imq0 protocol ip parent 1:$j pref 3 u32 match ip protocol 1 0xff flowid 1:$(($j+1))
                 fi
        $TC filter add dev imq0 protocol ip parent 1:$j pref 4 u32 match ip dst $usr flowid 1:$((j+2))
        let "j=j+3"
        done

i=0
for ntr in $lan_int
        do
        $TC class add dev imq0 parent 1:0 classid 1:$j htb rate ${int_dwl[$i]}Mbit ceil ${int_dwl[$i]}Mbit quantum $u_quantum
        $TC qdisc add dev imq0 parent 1:$j sfq
        for ipek in $ext ${lan_int}
        do
               $TC filter add dev imq0 protocol ip parent 1:0 pref 1 u32 match ip src $ntr match ip dst $ipek flowid 1:$j
        done
        let "j=j+1"
        let "i=i+1"
        done

$IPTABLES -t mangle -A PREROUTING -j IMQ --todev 0
$IP link set imq0 up

# upload
tmp=$(echo "$ext_upl%$ile" | bc)
min=$(echo "$ext_upl/$ile" | bc)
pri_min=$(echo "$min/2+$min%2" | bc)
sec_min=$(echo "$min/2" | bc)
max=$ext_upl

echo " Setting upload queue."
echo " Minimum upload: $min kbit/s"
echo " Maximum upload: $max kbit/s"
echo " Queue: -preference: $pri_min kbit/s  -not preference: $sec_min kbit/s"
echo " Free: $tmp kbit/s"
echo "%===================================================================%"

if [[ u_r2q=="" ]]; then
$TC qdisc add dev imq1 root handle 2:0 htb
else
$TC qdisc add dev imq1 root handle 2:0 htb r2q $u_r2q
fi

$TC class add dev imq1 parent 2:0 classid 2:1 htb rate ${ext_upl}kbit ceil ${ext_upl}kbit

j=2
for usr in $ext
        do
        $TC class add dev imq1 parent 2:1 classid 2:$j htb rate ${min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq1 parent 2:$j classid 2:$(($j+1)) htb rate ${pri_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq1 parent 2:$j classid 2:$(($j+2)) htb rate ${sec_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC qdisc add dev imq1 parent 2:$(($j+1)) sfq
        $TC qdisc add dev imq1 parent 2:$(($j+2)) sfq
        $TC filter add dev imq1 protocol ip parent 2:0 pref 2 u32 match ip src $usr flowid 2:$j
	for prt in $porty_tcp
                 do
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 6 0xff match ip dport $prt 0xffff flowid 2:$(($j+1))
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 6 0xff match ip sport $prt 0xffff flowid 2:$(($j+1))
                 done
        for prt in $porty_udp
                 do
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 17 0xff match ip dport $prt 0xffff flowid 2:$(($j+1))
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 17 0xff match ip sport $prt 0xffff flowid 2:$(($j+1))
                 done
        if [[ $pping -eq 1 ]]; then
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 1 0xff flowid 2:$(($j+1))
                 fi
	$TC filter add dev imq1 protocol ip parent 2:$j pref 4 u32 match ip src $usr flowid 2:$((j+2))
        let "j=j+3"
        done

for usr in $int
        do
        $TC class add dev imq1 parent 2:1 classid 2:$j htb rate ${min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq1 parent 2:$j classid 2:$(($j+1)) htb rate ${pri_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC class add dev imq1 parent 2:$j classid 2:$(($j+2)) htb rate ${sec_min}kbit ceil ${max}kbit quantum $u_quantum
        $TC qdisc add dev imq1 parent 2:$(($j+1)) sfq
        $TC qdisc add dev imq1 parent 2:$(($j+2)) sfq
        $TC filter add dev imq1 protocol ip parent 2:0 pref 2 u32 match ip src $usr flowid 2:$j
	for prt in $porty_tcp
                 do
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 6 0xff match ip dport $prt 0xffff flowid 2:$(($j+1))
                 done
        for prt in $porty_udp
                 do
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 17 0xff match ip dport $prt 0xffff flowid 2:$(($j+1))
                 done
        if [[ $pping -eq 1 ]]; then
                 $TC filter add dev imq1 protocol ip parent 2:$j pref 3 u32 match ip protocol 1 0xff flowid 2:$(($j+1))
                 fi
        $TC filter add dev imq1 protocol ip parent 2:$j pref 4 u32 match ip src $usr flowid 2:$((j+2))
	let "j=j+3"
        done

i=0
for ntr in $lan_int
        do
        $TC class add dev imq1 parent 2:0 classid 2:$j htb rate ${int_upl[$i]}Mbit ceil ${int_upl[$i]}Mbit quantum $u_quantum
        $TC qdisc add dev imq1 parent 2:$j sfq
        for ipek in $ext ${lan_int}
        do
                $TC filter add dev imq1 protocol ip parent 2:0 pref 1 u32 match ip dst $ntr match ip src $ipek flowid 2:$j
        done
        let "j=j+1"
        let "i=i+1"
        done

$IPTABLES -t mangle -A POSTROUTING -j IMQ --todev 1
$IP link set imq1 up
}
echo "rc.htb $VER, (C)Lenthir 2oo4, GNU GPL"
echo "$DAT"
case "$1" in
    'start')
      echo "Uruchamianie kolejkowania..."
      start
      echo "Gotowe."
      exit 0
      ;;
    'stop')
      echo -n "Zatrzymywanie kolejkowania..."
      stop
      echo " wykonano."
      ;;
    'restart')
      echo "Restartowanie kolejkowania..."
      $firewall
      start
      echo "Gotowe."
      ;;
    'status')
      echo "Klasy na interfejsie imq0!"
      echo "%====================================%"
      $TC class show dev imq0 | grep root
      $TC class show dev imq0 | grep -v root | sort | nl
      echo "Klasy na interfejsie imq1!"
      echo "%====================================%"
      $TC class show dev imq1 | grep root
      $TC class show dev imq1 | grep -v root | sort | nl
      ;;
    'stat')
      if [[ "$2" == "" ]]; then
        echo "Script need second argument - adress IP"
        exit 1
      elif [[ "$2" == "lan" ]]; then
      j=2
        for usr in $ext
                do
                let "j=j+3"
                done
        for usr in $int
                do
                let "j=j+3"
                done
      i=0;trs="echo \"Transfer w LAN\""
        for uvs in $lan_int
                do
                trs="$trs && echo \"Lan[$i]:\" && tc -s class show dev imq0 | grep -A 3 \"htb 1:$j \" && tc -s class show dev imq1 | grep -A 3 \"htb 2:$j \""
                let "j=j+1"
                let "i=i+1"
                done
        watch -d -n 1 "$trs"
      else
      j=2
        for usr in $ext
                do
                if [[ "$2" == "$usr" ]]; then
                        watch -d -n 1 "echo \"Download: \" && tc -s class show dev imq0 | grep -A 3 \"htb 1:$j \" && tc -s class show dev imq0 | grep -A 3 \"1:$(($j+1)) \" && tc -s class show dev imq0 | grep -A 3 \"1:$(($j+2)) \" && echo && echo \"Upload: \" && tc -s class show dev imq1 | grep -A 3 \"htb 2:$j \" && tc -s class show dev imq1 | grep -A 3 \"2:$(($j+1)) \" && tc -s class show dev imq1 | grep -A 3 \"2:$(($j+2)) \""
                        echo "Zakoñczono."
                        exit 0
                fi
                let "j=j+3"
                done
        for usr in $int
                do
                if [[ "$2" == "$usr" ]]; then
                        watch -d -n 1 "echo \"Download: \" && tc -s class show dev imq0 | grep -A 3 \"htb 1:$j \" && tc -s class show dev imq0 | grep -A 3 \"1:$(($j+1)) \" && tc -s class show dev imq0 | grep -A 3 \"1:$(($j+2)) \" && echo && echo \"Upload: \" && tc -s class show dev imq1 | grep -A 3 \"htb 2:$j \" && tc -s class show dev imq1 | grep -A 3 \"2:$(($j+1)) \" && tc -s class show dev imq1 | grep -A 3 \"2:$(($j+2)) \""
                        echo "Zakoñczono."
                        exit 0
                fi
                let "j=j+3"
                done
      fi
      ;;
    *)
      echo
      echo "U¿ycie: rc.htb start|stop|restart|status"
      echo "rc.htb stat <lan|adress IP>"
      exit 1
      ;;
esac

[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux