Linux Altında QOS - 8- TC ile GRED queuing
Bir önceki yazımda RED ve kullanımını anlatmıştım. RED kullanımında birden çok servis veya bilgisayar için ayrı kurallar tanımlamak istediğimizi düşünelim. RED bu konuda yeterli değildir. Bu noktada devreye GRED giriyor. GRED temel olarak RED qdisc le aynı olmakla beraber bize hizmetler ve istemciler için ayrı sınıflar oluşturmamızı ve priority ( öncelik) tanımlamamızı sağlar. GRED de RED gibi özellikle backbone yapılarında faydalıdır. GRED yetenek olarak cisco sistemlerde WRED ve Distributed WRED’e karşılık gelir.

Yukardaki çizimde görülene benzer bir yapımız olduğunu, hatta Cisco üzerinden VOIP hizmetimizinde internetten geldiğini düşünelim. elbetteki voip,SQL,MAIL hepsinin red tarafından droplanma ihtimalinin aynı olmasını istemeyiz. hemen bunun için yapılmış olan örnek planlama tablosuna göz atalım.

tabloda görüleceği üzerine hizmetlerin önemine ve çalışma şekline göre farklı gecikme ve umulan bant genişliği ayırılmış . GRED de RED gibi bant genişliği kontrolü yapmaz. bu ayarlar kuyruk oluştuğunda hangi paketin düşürüleceği ile ilgilidir. Kısacası GRED ile fifo dan daha iyi bir önceliklendirme yapılandırmak istiyoruz. VOIP ve DNS de dikkat ederseniz düşürülme ihtimali N/a verilmiş. bunun sebebi bu hizmetlerin TCP değil UDP üzerinden verilmesi.
GRED in diğer önemli farkı ise oluşturduğumuz sanal qdisc ler içerisinde priority belirleyerek hiyerarşik bir yapı oluşturabilmemiz. sanırım fazla karışıklık yaratmadan örneklere geçmek iyi olacak.

evet resimdeki komutu açıklayalım. tc qdisc ekle dev eth0 üzerinde çalışsın. gred algoritması kullansın. 8 sanal qdisc oluştursun ve grio olsun, grio bize az sonraki örneklerde kullanılan priority leri tanımlamamızı sağlar. şimdi hesaplanmış olan tabloya göz atalım :

Bu değerler nasıl hesaplanıyor ?
. 0.01 * Bandwidth Share * Desired Latency * Network Bandwidth
Maximum Threshold = —————————————————————————————————————
. 8 bits/byte* 1000 ms/sec
Minimum Threshold = 1/2 * Maximum Threshold
Avpkt = Average Packet Length
Burst = ( 2 * MinThreshold + MaxThreshold) / ( 3 * Avpkt )
Limit = 4 * MaxThreshold
Network Bandwidth (10Mbps) = 10 * 1024 * 1024 bits/sec = 10.485.760 bits/sec
SQL için örnek hesaplama :
. 0.01 * 25 * 100 * 10.485.760
Maximum Threshold = ———————————————— = 32768 bytes
. 8 * 1000
Minimum Threshold = 1/2 * 32768 = 16384
Avpkt = 1024
Burst = ( 2 * 32768 + 16384 ) / ( 3 * 1024 ) = 27
Limit = 4 * 32768 = 131072
dikkat edilecek nokta UDP hizmetlerde MAX ve MIn değerleri arasında fark olmaması, UDP paketler kendilerini TCP’deki bir mantıkla ayarlayamazlar. UDP akışının TCP bağlantılara zarar vermemesi için minumum ve maximum aynı verilmiş. tc filter min ve max değerlerinin aynı olmasına izin vermediği için örneklerde hesaplanan değerin bir fazlası kullanılmıştır.
şimdi tablonun uygulamasını yapalım :
bash-3.2# tc qdisc add dev eth0 root gred setup DPs 8 default 8 grio
RTNETLINK answers: Invalid argument
diyerek grio yani priority destekli 8 sanal qdisc içeren root qdisc oluşturup default sanal qdisc’i 8 inci olarak eklemeye çalışıyor ve hata veriyor neden ? çünkü herzamanki gibi linux saymaya 0 dan başlıyor ve herzamanki gibi referans sitelerimizdeki dökümanlar yanlış!
bash-3.2# tc qdisc add dev eth0 root gred setup DPs 8 default 7 grio
bash-3.2#
şimdi oldu.
voip servisi için tablomuzdaki değerleri girelim :
bash-3.2# tc qdisc change dev eth0 root gred limit 3146 min 393 max 394 burst 5 avpkt 128 bandwidth 10Mbit DP 1 probability 1 prio 1
bash-3.2#
Referans da bu şekilde verilmiş. ama DP 0 dan saymaya başladığı için DP 0 yerine 1 den başlamak bir kaç defa denedim TC’yi tamamen kullanılmaz duruma soktu. girdiğim kuralları dahi silemedim. o yüzden bu şekilde düzelterek tablodaki tüm verileri en baştan başlayarak girelim.
bash-3.2# tc qdisc add dev eth0 root gred setup DPs 8 default 7 grio
bash-3.2# tc qdisc change dev eth0 root gred limit 3146 min 393 max 394 burst 5 avpkt 128 bandwidth 10Mbit DP 0 probability 1 prio 1
bash-3.2# tc qdisc change dev eth0 root gred limit 5243 min 655 max 656 burst 4 avpkt 256 bandwidth 10Mbit DP 1 probability 1 prio 2
bash-3.2# tc qdisc change dev eth0 root gred limit 131072 min 16384 max 32768 burst 27 avpkt 1024 bandwidth 10Mbit DP 2 probability 0.01 prio 3
bash-3.2# tc qdisc change dev eth0 root gred limit 41943 min 5243 max 10486 burst 17 avpkt 512 bandwidth 10Mbit DP 3 probability 0.01 prio 4
bash-3.2# tc qdisc change dev eth0 root gred limit 104858 min 13107 max 26214 burst 21 avpkt 1024 bandwidth 10Mbit DP 4 probability 0.04 prio 5
bash-3.2# tc qdisc change dev eth0 root gred limit 52429 min 6554 max 13107 burst 11 avpkt 1024 bandwidth 10Mbit DP 5 probability 0.04 prio 6
bash-3.2# tc qdisc change dev eth0 root gred limit 31457 min 3932 max 3933 burst 6 avpkt 1024 bandwidth 10Mbit DP 6 probability 1 prio 7
bash-3.2# tc qdisc change dev eth0 root gred limit 104858 min 13107 max 26214 burst 21 avpkt 1024 bandwidth 10Mbit DP 7 probability 0.04 prio 8
Şİmdi girmiş olduğumuz değerleri görelim :
bash-3.2# tc -s -d qdisc show dev eth0
qdisc gred 8001: root
DP:0 (prio 1) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 3146b min 393b max 394b ewma 2 Plog 1 Scell_log 5
DP:1 (prio 2) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 5243b min 655b max 656b ewma 2 Plog 1 Scell_log 6
DP:2 (prio 3) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 128Kb min 16Kb max 32Kb ewma 4 Plog 21 Scell_log 10
DP:3 (prio 4) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 41943b min 5243b max 10486b ewma 4 Plog 20 Scell_log 9
DP:4 (prio 5) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 104858b min 13107b max 26214b ewma 4 Plog 19 Scell_log 10
DP:5 (prio 6) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 52429b min 6554b max 13107b ewma 3 Plog 18 Scell_log 9
DP:6 (prio 7) Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 31457b min 3932b max 3933b ewma 2 Plog 1 Scell_log 8
DP:7 (prio
Average Queue 0b Measured Queue 0b
Packet drops: 0 (forced 0 early 0)
Packet totals: 0 (bytes 0)
limit 104858b min 13107b max 26214b ewma 4 Plog 19 Scell_log 10
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
bash-3.2#
Bu yukarıdaki ilk şekilde görmüş olduğumuz işin henüz yarısı. öncelikle yazmış olduğumuz GRED kurallarında dikkat ederseniz hiçbir tc filter girmedik. yani hangi paketin hangi VQ’ya atanacağını belirtmedik. bunu yapmak için iki yöntem kullanabiliyoruz.
1. eth1 için ingress qdisc oluşturup filter ile paketleri işaretlemek ( package tagging, marking )
2. paketleri işaretlemek için iptables ( netfilter ) yardımı almak.
hemen örneklerimizi verelim :
bash-3.2# iptables -t mangle -A PREROUTING -i wlan0 -p udp –dport 5001: –sport 5001: -j MARK –set-mark 0
bash-3.2#
voip trafiği için 5001 den gelip 5001 e gidenleri 0 için markladik. ( pek uygun bir yöntem değil basitçe örneklemiş olduk. kendime ait donanımda eth1 olmadığı için örneği wlan0 için yaptım )
filter ile işaretlemek :
ingress qdisc ekleyelim :
bash-3.2# tc qdisc add dev wlan0 ingress
bash-3.2#
ilk önce iptables ile işaretlediğimiz paketimiz için filter ekleyelim :
bash-3.2# tc filter add dev wlan0 parent ffff: protocol ip prio 1 handle 1 fw flowid :0
bash-3.2#
açıklayalım : tc ile filter ekliyoruz dev wlan0 için parent ffff: yani ingress qdisc , prio 1 diğe rule lar arasında önce prio 1 işlem görecek, sonra prio 2 bu sıralama sayesinde gecikmenin önemli olduğu voip paketlerini bir an önce process ettik. filter’ımıza handle verdik ve flowid:0 diyerek gred VQ0 e gönderdik.
tc -d -s filter show dev wlan0 parent ffff: diyerek eklediğimiz filter’ı görebiliriz.
şimdi 5 nolu VQ yani mail içi girdiğimiz kural için filter ekleyelim :
bash-3.2# tc filter add dev wlan0 parent ffff: protocol ip prio 6 u32 match ip src 192.168.1.50/32 flowid :5
yine aynı şeklde ekledik. u32 filter kullanarak sadece 192.168.1.50 ipsinden gelen paketleri ( mail server varsayılan ip adresi ) VQ5 e gönderdik. tc filter show ip adreslerini hex olarak gösterir.
filter protocol ip pref 6 u32 fh 800: ht divisor 1
filter protocol ip pref 6 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :5
match c0a80132/ffffffff at 12
Sanırım bukadarı diğer kuralları yazmak için yeterli olur.