Laborator 11. Controlul traficului

Cunoștințe și abilități ce vor fi dobândite

Pregătire infrastructură de laborator

În cadrul acestui laborator vom folosi următoarea topologie formată din trei mașini virtuale (gateway, client1 și client2). Acestea sunt conectate conform schemei de mai jos:

Pentru a pregăti configurația de laborator va trebui să descărcați pe mașina fizică (mjolnir), în directorul saisp/, arhiva laboratorului:

student@mjolnir:~/saisp$ wget --user=user-curs --ask-password http://repository.grid.pub.ro/cs/saisp/laboratoare/lab-11.zip
student@mjolnir:~/saisp$ unzip lab-11.zip

În urma dezarhivării rezultă trei fișiere imagine KVM (format qcow2, gateway.qcow2, client1.qcow2 și client2.qcow2) și un script de pornire a topologiei (lab11-start). Imaginea de bază base.qcow2 este deja în directorul saisp/ și este baza pentru celelalte trei fișiere: gateway.qcow2, client1.qcow2 și client2.qcow2.

Puteți urma pașii de mai sus pentru a descărca infrastructura KVM pentru laborator pentru lucru acasă.

Pentru pornirea topologiei de mai sus, rulați scriptul lab11-start:

student@mjolnir:~/saisp$ ./lab11-start

Pentru accesarea celor trei mașini (gateway, client1 și client2) folosiți SSH către adresele IP aferente fiecăreia. Pentru conectarea la mașina virtuală pentru gateway folosiți comanda

student@mjolnir:~/saisp$ ssh -l root 192.168.1.3

pentru conectarea la client1 folosiți comanda

student@mjolnir:~/saisp$ ssh -l root 192.168.1.1

iar pentru conectarea la client2 folosiți comanda

student@mjolnir:~/saisp$ ssh -l root 192.168.1.2

Parola pentru cele trei mașini virtuale este student atât pentru utilizatorul root cât și pentru utilizatorul student.

Pentru a avea acces la Internet din masina virtuala, rulati pe masina fizica comanda:

sudo iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE

Laboratorul 11

Exerciții

00. [10p] Completare formular de feedback

Vă invităm să evaluați activitatea echipei de SAISP și să precizați punctele tari și punctele slabe și sugestiile voastre de îmbunătățire a materiei. Feedback-ul vostru este foarte important pentru noi să creștem calitatea materiei în anii următori și să îmbunătățim materiile pe care le veți face în continuare.

Găsiți formularul de feedback în partea dreaptă a paginii principale de SAISP de pe cs.curs.pub.ro într-un frame numit “FEEDBACK”.

Vă mulțumim!

01. [10p] iperf (generator de trafic)

Pentru a fi capabili să evaluăm politicile de QoS setate în rețeaua administrată de noi, avem nevoie de un utilitar care să genereze diferite tipuri de pachete, de diferite dimensiuni (UDP, TCP) și să măsoare viteza cu care acestea au fost transmise. Cel mai folosit utilitar pentru acest lucru este iperf. Acesta creează pachete direct în memorie și le trimite pe rețea, eliminând overhead-ul altor dispozitive I/O (exemplu: dacă testam cu un transfer FTP se adăuga overhead-ul citirii/scrierii pe disc a fișierului transferat).

Utilitarul iperf poate rula în 2 moduri:

  • client: cel care generează traficul
  • server: cel care primește traficul

În cadrul acestui laborator dorim să limităm traficul de download, astfel clientul iperf va rula pe gateway, iar server-ul iperf, cel care primește traficul, va rula pe mașinile virtuale client1 și client2.

Instalați iperf pe toate cele 3 stații:

root@client1:~# apt-get update
root@client1:~# apt-get install iperf
 
root@client2:~# apt-get update
root@client2:~# apt-get install iperf
 
root@gateway:~# apt-get update
root@gateway:~# apt-get install iperf

Pe stația client1, porniți iperf în modul server:

iperf -s

Pe stația gateway, porniti iperf în modul client:

iperf -c 192.168.1.1

După 10 secunde, atât server-ul (client1) cât și clientul (gateway) vor afișa statistici legate de traficul schimbat:

root@gateway:~# iperf -c 192.168.1.1
------------------------------------------------------------
Client connecting to 192.168.1.1, TCP port 5001
TCP window size: 22.9 KByte (default)
------------------------------------------------------------
[  3] local 192.168.1.3 port 57685 connected with 192.168.1.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   190 MBytes   159 Mbits/sec
 
root@client1:~# iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.3 port 57685
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-10.0 sec   190 MBytes   159 Mbits/sec

Generați trafic de tip UDP între stația gateway și stația client2 în care lungimea pachetelor să fie de 256 de octeți (Hint: --len).

02. [10p] Generarea traficului pe baza unor caracteristici și constrângeri din lumea reală

În cadrul laboratorului, vom explora principalele strategii de QoS din Linux. Pentru a observa comportamentul strategiilor implementate, vom folosi un model de trafic, compus din:

  • trafic de voce (UDP, port 8000)
  • trafic video (UDP, port 6000)
  • trafic FTP (TCP, port 21)
  • trafic HTTP (TCP, port 80)

Traficul nu va fi real ci îl vom simula cu ajutorul lui iperf prezentat anterior.

Fiecare tip de trafic din cele considerate mai sus are anumite caracteristici și constrângeri. Pentru o funcționare optimă, trebuie să ținem seama de acestea:

  • trafic de voce
    • sensibil la: delay, jitter, packet loss
    • consum de banda: mic, constant
  • trafic video
    • sensibil la: delay, jitter, packet loss
    • consum de banda: mare, constant
  • trafic FTP si HTTP
    • sensibil la: nimic
    • consum de banda: mare, variabil, greedy (tinde sa “umple” intreaga latime de banda a legaturii)

Dupa cum ați observat la exercițiul anterior, o conexiune iperf client-server generează un singur tip de trafic (implicit, trafic TCP pe portul 5001). Noi dorim să generăm mai multe tipuri de trafic, concomitent, pentru a vedea cum se afectează între ele. Deci va trebui să instanțiem mai multe astfel de perechi, în background.

Vom crea un script cu numele iperf-client1.sh care va porni 4 servere iperf pe stația client1 (urmăriți comentariile):

iperf-client1.sh
#!/bin/bash
 
# Asculta trafic UDP, pe port-ul 8000 - fluxul de voce
iperf --server --udp --port 8000 &> out1.txt  &
 
# Asculta trafic UDP, pe port-ul 6000 - fluxul video
iperf --server --udp --port 6000 &> out2.txt &
 
# Asculta trafic TCP, pe port-ul 21 - fluxul FTP
# Daca nu se specifica --udp, implicit este TCP
iperf --server --port 21 &> out3.txt &
 
# Asculta trafic TCP, pe port-ul 80 - fluxul HTTP
# Daca nu se specifica --udp, implicit este TCP.
iperf --server --port 80 &> out4.txt &
 
echo "iperf servers started. Now run the script on the gateway."

Vom crea pe stația gateway un script cu numele iperf-gateway.sh care se va conecta la cele 4 servere pornite pe stația client1, generând cele 4 tipuri de trafic prezentate anterior. Simulăm tipurile de trafic prin generare de pachete ce au caracteristici asemănătoare cu cele din cazurile reale. Urmăriți comentariile din fișier:

iperf-gateway.sh
#!/bin/bash
 
IP_VM="192.168.1.1"
TIME=60 # Durata unui test
 
# Initiaza un flux UDP catre server, pe portul 8000
# Fiecare datagrama are dimensiunea de 128 octeti (tipic pentru pachetele de voce)
# Se trimite la o rata de 640Kbps (dorim sa simulam 10 conversatii VoIP, a cate 64Kbps)
iperf -x SC --client $IP_VM --port 8000 --udp --len 128 --bandwidth 640K --time $TIME > out3.txt 2> /dev/null &
 
# Initiaza un flux UDP catre server, pe portul 6000
# Fiecare datagrama are dimensiunea maxima (pentru ca nu o specificam explicit)
# Se trimite la o rata de 30Mbps
iperf -x SC --client $IP_VM --port 6000 --udp --bandwidth 30M --time $TIME > out4.txt 2> /dev/null &
 
# Initiaza un flux TCP catre server, pe portul 80 (HTTP)
# Limitam dimensiunea unui segment la 512 octeti
iperf -x SC --client $IP_VM --port 80 --mss 512 --time $TIME > out1.txt 2> /dev/null &
 
# Initiaza un flux TCP catre server, pe portul 21 (FTP)
# Dimensiunea unui segment va fi de 1400 octeti (dorim ca fluxul FTP sa fie mai agresiv)
# Dimensiunea ferestrei TCP va fi de 256K (dorim ca fluxul FTP sa fie mai agresiv)
iperf -x SC --client $IP_VM --port 21 --window 256K --mss 1400 --time $TIME > out2.txt 2> /dev/null &
 
wait
for i in out*; do echo; cat $i; done
rm out*.txt

Rulați script-urile create anterior (iperf-client1.sh pe stația client1 și iperf-gateway.sh pe stația gateway). Așteptați 60 de secunde și inspectați output-ul de pe stația gateway. Ce observați?

Observăm că fluxurile UDP au suferit packet loss, ele neavând nici un mecanism pentru retransmitere sau reglare a vitezei în funcție e starea legăturii. Pentru fluxul video, o pierdere de pachete de câteva procente este inacceptabilă. În continuare vom studia mecanismele implicite de QoS din Linux și cum putem preveni aceste pierderi de pachete.

03. [10p] Clasificarea folosind ToS

În Linux, strategiile de QoS se inspectează și configurează folosind comanda tc. Termenul folosit pentru strategiile de QoS este qdisc (de la queueing discipline).

Afisați detalii despre qdisc-ul implicit, asociat interfeței eth0 de pe stația gateway:

# tc qdisc show dev eth0
qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

Observați că qdisc-ul implicit este pfifo_fast (strategia implicită de QoS):

  • Numele vine de la priority FIFO.
  • Este un qdisc classless (nu putem clasifica traficul și limita traficul, îl putem doar prioritiza)
  • Nu este o simpla coada FIFO, ci conține 3 (sub)cozi, numite 0, 1 si 2 (fiecare din ele fiind FIFO). Cât timp coada coada 0 conține pachete, cozile 1 si 2 NU vor fi servite.

Ce reprezintă priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1? În Linux, kernel-ul asociază fiecărui pachet o prioritate, în functie de campul TOS (Type of Service) din header-ul IP. Prioritatea ne selectează una din cele 3 (sub)cozi din pfifo_fast: coada 0, 1 sau 2. Asocierile se fac după următorul tabel:

TOS     Means                    Linux Priority    Band
-------------------------------------------------------
0x0     Normal-Service           0 Best Effort     1
0x2     Minimize-Monetary Cost   1 Filler          2
0x4     Maximize-Reliability     0 Best Effort     1
0x6     mmc+mr                   0 Best Effort     1
0x8     Maximize-Throughput      2 Bulk            2
0xa     mmc+mt                   2 Bulk            2
0xc     mr+mt                    2 Bulk            2
0xe     mmc+mr+mt                2 Bulk            2
0x10    Minimize-Delay           6 Interactive     0
0x12    mmc+md                   6 Interactive     0
0x14    mr+md                    6 Interactive     0
0x16    mmc+mr+md                6 Interactive     0
0x18    mt+md                    4 Int. Bulk       1
0x1a    mmc+mt+md                4 Int. Bulk       1
0x1c    mr+mt+md                 4 Int. Bulk       1
0x1e    mmc+mr+mt+md             4 Int. Bulk       1

Observăm că pachetele normale (cu TOS 0x00) sunt introduse în (sub)coada 1. La punctul anterior, fluxul UDP avea o pierdere semnificativă de pachete. O primă soluție ar fi marcarea pachetelor de voce și video cu un ToS favorabil (de exemplu, 0x10), pentru a avea prioritate mai mare față de pachetele. Marcarea se realizează folosind lanțul mangle al comenzii iptables:

root@gateway:~#  iptables -t mangle -A OUTPUT -p udp --dport 6000:8000 -j TOS --set-tos Minimize-Delay

Comanda anterioară marchează toate pachetele UDP cu porturile în intervalul 6000 și 8000 cu tag-ul Minimize-Delay. Se observă că se poate folosi numele tag-ului în loc de valoare (0x10).

Rulați din nou scriptul iperf-gateway.sh pe stația gateway și observați că procentele pierdute s-au diminuat foarte puțin. Nu e suficientă doar o prioritizare a pachetelor.

04. [5p] Traffic shaping în Linux

Am observat faptul că policing-ul pe baza ToS-ului nu este suficient pentru a asigura echitatea între servicii. Soluția ce se apoate aplica este dată de limitarea serviciilor FTP și HTTP.

tbf este cea mai simplă metodă de a face traffic shaping în Linux. Este, de asemenea, un qdisc classless (ca și pfifo_fast).

Dorim să limităm viteza pentru fluxurile FTP și HTTP (însumate) la aproximativ 9Mbps. Deoarece fluxul de voce are 640kbps, iar cel video are 30Mbps, rezulta ca o valoare acceptabila pentru viteza totală ar fi 40Mbps. Pe stația gateway ne dorim următoarele setări:

  • Viteza maximă de transfer să fie 50Mbps (40Mbps pentru datele propriu zise și o marjă de 20% pentru încapsulare - headere IP, TCP/UDP, Ethernet)
  • În caz de congestie, acceptăm un surplus de 128Kbps, pentru 50ms.

Vom seta qdisc-ul tbf, pe interfața eth0 astfel:

root@gateway:~# tc qdisc add dev eth0 root tbf rate 50mbit burst 128kbit latency 50ms

Rulați din nou script-ul iperf-gateway.sh de pe stația gateway. Asteptați 60 de secunde și inspectați output-ul afișat. Ce observați? Pierderile de pachete pentru conexiunea UDP au dispărut, qdisc-ul tbf asigurând echitate între conexiuni.

Cu toate că suma vitezelor fluxurilor este de aproximativ 50Mbps, ea nu este distribuită așa cum ne-am fi asteptat. Fluxurile FTP și HTTP ocupa mai mult decât 9Mbps. Motivul este că limitarea a fost facută printr-o metoda classless, ce limitează întreg traficul de pe o interfață, fără a avea posibilitatea de a selecta și clasifica diferite tipuri de trafic. Soluția este dată de aplicarea unui qdisc classful, ce trateaza in mod separat diferitele clase de trafic.

05. [10p] Traffic shaping classful

htb este un qdisc classful (tratează traficul în mod diferențiat, în funcție de clasa din care face parte). Este varianta classful a tbf (împarte traficul pe clase, apoi aplica tbf pe fiecare în parte).

Clasele sunt organizate într-o structura de arbore. Cu cât o clasa este mai jos în ierarhie, cu atât este mai specifică. Fiecare clasă are asociată o strategie de QoS (qdisc). În mod implicit, qdisc-ul este pfifo_fast, iar acesta poate fi modificat.

Exemplu de ierarhie:

               1:           root qdisc (always present)
               |
              1:1           child class (with default qdisc)
             /   \
            /     \
          1:3     1:4       leaf classes (with user-defined qdiscs)
           |       |
          30:     40:       qdiscs
         (sfq)   (sfq)

Observații:

  • Fiecare clasa este identificată printr-un major și un minor, sub forma “major:minor”. Toate clasele dintr-o ierarhie trebuie să aiba același major.
  • Fiecare qdisc este identificat doar printr-un major. Minorul este întotdeauna zero. O scriere de forma major: este echivalentă cu major:0.
  • Deși nu este reprezentat, clasa 1:1 are un qdisc asociat (cel implicit).
  • Claselor 1:3 și 1:4 le-a fost schimbat qdisc-ul implicit (în loc de pfifo_fast, avem sfq, un qdisc ce funcționează după modelul Round Robin)

Tratarea pachetelor:

  • Dacă un pachet se potrivește cu clasa 1:1, dar NU se potrivește cu clasa 1:3 sau 1:4, va fi tratat conform qdisc-ului implicit al clasei 1:1, adica pfifo_fast.
  • Dacă un pachet se potrivește cu clasa 1:1 ȘI cu clasa 1:3, va fi tratat conform qdisc-ului clasei 1:3, adica sfq.
  • Analog pentru clasa 1:4.

Clasificarea pachetelor:

  • Pentru a decide din ce clasă face parte un pachet, trebuie definite filtre.
  • Un filtru specifică condițiile de match și clasa în care trebuie inclus pachetul.
  • De obicei, filtrele se atașează rădăcinii.

Ne propunem sa alocam cate o clasa fiecarui tip de trafic din cele definite în scenariu. Fiecare clasă de trafic va fi limitată la o lățime de bandă bine definită, astfel:

  • voce: 1Mbps
  • video: 40Mbps
  • FTP: 5Mbps
  • HTTP: 3Mbps

Toate configurațiile vor fi făcute pe interfața eth0 a stației gateway (politifice de traffic shaping pot fi aplicate doar pentru traficul care iese pe o interfață). Mai întâi, trebuie să ștergem orice alt qdisc de pe interfața eth0:

root@gateway:~# tc qdisc del dev eth0 root

Adăugam qdisc-ul htb, cu majorul 1: (sau 1:0):

root@gateway:~# tc qdisc add dev eth0 root handle 1: htb

Definim prima clasa, cea pentru traficul de voce. Trebuie să specificăm:

  • părintele, care este 1:
  • id-ul, fie acesta 1:1 (majorul trebuie sa fie același cu al părintelui, minorul poate fi orice)
  • parametrii htb: viteza și depășirea (burst-ul) acceptată
root@gateway:~# tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit burst 128k

Procedăm analog și pentru restul claselor:

tc class add dev eth0 parent 1: classid 1:2 htb rate 40mbit burst 128k
tc class add dev eth0 parent 1: classid 1:3 htb rate 5mbit burst 128k
tc class add dev eth0 parent 1: classid 1:4 htb rate 3mbit burst 128k

Verificăm qdisc-ul asociat interfeței eth0 și ierarhia de clase adăugată:

root@gateway:~# tc qdisc show dev eth0
qdisc htb 1: root refcnt 2 r2q 10 default 0 direct_packets_stat 82 direct_qlen 1000
 
root@gateway:~# tc class show dev eth0
class htb 1:1 root prio 0 rate 1000Kbit ceil 1000Kbit burst 128Kb cburst 1600b
class htb 1:2 root prio 0 rate 40000Kbit ceil 40000Kbit burst 128Kb cburst 1600b
class htb 1:3 root prio 0 rate 5000Kbit ceil 5000Kbit burst 128Kb cburst 1600b
class htb 1:4 root prio 0 rate 3000Kbit ceil 3000Kbit burst 128Kb cburst 1599b

Cu toate că am definit ierarhia de clase, nu am definit cum selectăm traficul pentru aceste clase. Vom folosi noțiunea de filtre oferită de utilitarul tc. Definim primul filtru, ce selectează trafic cu portul destinație 8000. Trebuie să specificam:

  • protocolul de nivel 3: IP
  • parintele: 1: - vom atasa toate filtrele în nodul rădăcina
  • prioritatea: 1 - toate filtrele vor avea aceeași prioritate
  • tipul de filtru: u32, ce poate face match pe header-ul IP
  • condiția de match: portul destinație (8000), și masca (0xffff - dorim să facem match pe toți cei 16 biți asociați câmpului destinație)
  • clasa în care va fi încadrat traficul (flowid): 1:1:
    root@gateway:~# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 8000 0xffff flowid 1:1

Procedăm analog și cu celelalte filtre:

root@gateway:~# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 6000 0xffff flowid 1:2
root@gateway:~# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 21 0xffff flowid 1:3
root@gateway:~# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 80 0xffff flowid 1:4

Verificăm filtrele create:

root@gateway:~# tc filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
  match 00001f40/0000ffff at 20
filter parent 1: protocol ip pref 1 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:2
  match 00001770/0000ffff at 20
filter parent 1: protocol ip pref 1 u32 fh 800::802 order 2050 key ht 800 bkt 0 flowid 1:3
  match 00000015/0000ffff at 20
filter parent 1: protocol ip pref 1 u32 fh 800::803 order 2051 key ht 800 bkt 0 flowid 1:4
  match 00000050/0000ffff at 20

Pe stația gateway, rulați din nou script-ul iperf-gateway.sh. Asteptați 60 de secunde și inspectați output-ul afișat. Ce observați?

  • Fiecare flux de trafic nu a depasit banda alocata.
  • Packet-loss-ul este în continuare apropiat de 0% (ca la tbf) pentru flow-urile UDP.

06. [15p] Politici de limitare per client

Ștergeți qdisc-ul root adăugat anterior.

Realizați configurațiile necesare astfel încât să limitați stația client1 la 5 mbps, iar stația client2 la 3mbps. În plus dorim ca cei 3mbps ai stației client2 să fie împărțiți după cum urmează:

  • 1mbps pentru traficul ce ajunge pe portul 1111 (Hint: folosiți 2 reguli de match ale clasificatorului u32)
  • 2mbps pentru traficul de pe restul porturilor

Testați folosind iperf.

07. [10p] HTB - observarea consumului de resurse

Ștergeți qdisc-ul root adăugat anterior.

Creați un script ce adaugă o limită de 1mbps pentru toate adresele IP din clasa 10.0.0.0/21 (trebuie să creați câte o clasă și câte un filtru pentru fiecare adresă IP). La finalul scriptului adăugați limita de 1mbps și pentru adresele IP asociate stațiilor client1 și client2.

Realizați un transfer între stația client2 și stația gateway folosind iperf. Utilizați 5 thread-uri pe partea de client a iperf (Hint: -P). În timpul transferului observați încărcarea stației gateway (în mod special thread-urile kernel ksoftirq). Acest lucru se datorează faptului că fiecare pachet trebuie să parcurgă toate filtrele adăugate secvențial. Clasificatoul u32 a venit cu o soluție pentru acest lucru: folosirea unor tabele de hash, stocând filtrele sub forma unui arbore. Cheia hash-ului este dată de un octet al adresei IP destinație (mai multe detalii în curs și la exercițiul de la BONUS).

08. [20p] HTB - u32 hashing tables

Generarea de mână a filtrelor folosind hash tables este anevoioasă și NU se recomandă. Vom folosi un program C, disponibil |aici.

Descărcați și compilați programul prefixtree:

root@gateway:~# wget http://vcalinus.gemenii.ro/prefixtree.c
root@gateway:~# make prefixtree
cc     prefixtree.c   -o prefixtree
root@gateway:~# ./prefixtree
IPv4 u32 hash filter generator - (C) 2006 Calin Velea
 
Syntax: prefixtree {prefix.in} {u32filters.out} {interface} {src/dst} [batch]

Vom scrie fișierul prefix.in care trebuie să conțină pe câte o linie adresa IP pentru care vrem să ne genereze filtrele și classid-ul asociat.

Modificați scriptul de la exercițiul 07. [10p] HTB - observarea consumului de resurse astfel încât să introducă perechea adresaIP classid în fișierul prefix.in în loc să adauge filtrul asociat. Adăugați și masca adresei IP (/32).

Rulăm comanda prefixtree pe fișierul generat:

root@gateway:~# ./prefixtree prefix.in filters.out eth0 dst
lines parsed: 4066
total hashtables: 4

Observați conținutul fișierului filters.out. Aplicăm filtrele generate:

root@gateway:~# chmod +x filters.out
root@gateway:~# ./filters.out

Testați din nou folosind iperf. Obervați faptul că stația gateway, cea care face limitările, nu mai intră în load (thread-urile kernel ksoftirqd au CPU usage foarte mic).

09. [BONUS - 10p] tcng (traffic control next generation)

Utilitarul tc oferă un control foarte bun asupra parametrilor QoS. Dar, din păcate, sintaxa este foarte complexă, greu de reținut și puțin lizibilă. tcng este un utilitar cu o sintaxă mult mai expresivă, asemănătoare limbajului C. Folosind aceasta sintaxă, el poate genera comenzile tc echivalente.

Pe stația gateway descărcați și instalați utilitarul tcng:

root@gateway:~# wget http://archive.debian.org/debian/pool/main/t/tcng/tcng_10b-3_amd64.deb
root@gateway:~# dpkg -i tcng_10b-3_amd64.deb

Un fișier tcng are următoarea sintaxă simplificată:

dev INTERFATA
{
     QDISC ()
     {
          class ( ACTIUNE ) FILTRU ;
          class ( ACTIUNE ) FILTRU ;
          ...
          class ( ACTIUNE ) FILTRU ;
      }
}

Ne propunem să creăm un fișier tcng, echivalent configurațiilor HTB de la 05. [10p] Traffic shaping classful:

  • Creati un fisier numit eth0_htb.tc.
  • Specificați interfața eth0 în câmpul dev.
  • Specificați QDISC-ul htb.
  • Pentru fiecare clasă, specificați acțiunea rate xMbps, unde x este lățimea de bandă corespunzătoare.
  • Pentru fiecare clasă, specificați filtrul în formatul udp_port == ABCD, respectiv tcp_port == ABCD, unde ABCD este portul corespunzător.
dev eth0
{
	htb ()
	{
		class ( rate 1Mbps ) if udp_dport == 8000 ; 
		class ( rate 40Mbps ) if udp_dport == 6000 ;
		class ( rate 5Mbps ) if tcp_dport == 21 ;
		class ( rate 3Mbps ) if tcp_dport == 80 ; 
	}
}

Rulați tcng pentru a obține comenzile echivalente tc:

tcng eth0_htb.tc

Inspectați comenzile tc generate și observați asemănările cu comenzile introduse manual.

10. [BONUS - 10p] Colectare statistici folosind tc

Pe lângă controlul traficului, utilitarul tc ne furnizează și statistici despre traficul transferat de fiecare clasă:

root@gateway:~# tc -s class show dev eth0

Scrieți un script care extrage numărul de octeți trimiși pentru una din clase. Utilizați acest script să generați un grafic folosind informațiile prezentate în 05. [20p] Baze de date Round Robin (RRD).