przejście do zawartości
Jan Kończak
Narzędzia użytkownika
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Ostatnie zmiany
Menadżer multimediów
Indeks
Jesteś tutaj:
start
»
sk2
»
tc
sk2:tc
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
====== Kształtowanie ruchu ====== ===== Wstęp ===== Kiedy pakiet jest gotowy do **wysłania**, trafia do "kolejki" ("queue"). [[https://pl.wikipedia.org/wiki/Plik:Netfilter-packet-flow-pl.svg|[1]]] \\ Kiedy system operacyjny jest gotowy do wysłania pakietu, pobiera go z "kolejki". "Kolejka" domyślnie jest kolejką – system wyciąga pakiety z kolejki w kolejności w jakiej zostały dodane. Można jednak zastąpić to zachowanie (dyscyplinę kolejkowania – Queueing DISCipline, qdisc) innym. Pozwala to kształtować ruch – ograniczać prędkość i priorytetyzować wybrane pakiety ([[https://en.wikipedia.org/wiki/Traffic_shaping|Traffic shaping]]). Nie da się (w bezpośredni sposób) kształtować ruchu wchodzącego – karta sieciowa nie ma kontroli nad tym co i w jakiej kolejności ktoś do niej wysyła. ===== Materiały ===== * **[[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html]]** * Rozdział 9 z: [[http://lartc.org/howto/index.html]] * <html><small></html>[[http://linux-tc-notes.sourceforge.net/tc/doc/]]<html></small></html> * <html><small></html>[[http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm]]<html></small></html> ===== Man / help ===== Pomoc do poleceń ''tc'' można uzyskać dodając (też w środek komendy) słowo kluczowe ''help'', np: tc qdisc help tc qdisc add dev eth0 handle 1 root codel help tc class add dev eth0 parent 2:2 classid 2:22 htb help tc filter add dev eth0 parent 5:0 u32 match ip sport 80 0xffff help Komenda ''tc'' opisana jest na wielu stronach podręcznika: * Główna strona: ''man tc'' * Przykłady stron: ''man tc-prio tc-htb tc-u32 tc-fw tc-tbf tc-fq_codel'' * Lista wszystkich dostępnych: ''whatis -r '^tc-.*' '' ===== Schemat polecenia ===== dodaje nową dyscyplinę typ dyscypliny | | | nazwa (numer) nowej dyscypliny | ^ ___L__ ^ / \ / \ / \ tc qdisc add dev eth0 handle 1 root htb default 2 tc qdisc add dev eth0 handle 2 parent 1:2 sfq divisor 4096 \______/ \______/ \________/ \__________/ | | | | | na urządzeniu eth0 | opcje konkretnej dyscypliny | | zajmuje się dyscyplinami kolejkowania określa do czego dołączona jest dyscyplina: • root – główna dla urządzenia • parent 1:2 – przyczepiona do klasy 1:2 ===== Proste przykłady ===== Wyświetlanie dyscyplin: * ''tc qdisc'' – dyscypliny dla wszystkich urządzeń * ''tc qdisc show dev eth0'' – podstawowy widok * ''tc -d qdisc show dev eth0'' – widok szczegółowy * ''tc -s qdisc show dev eth0'' – pokazuje statystyki //Zadanie 1. // Wyświetl jakie dyscypliny kolejkowe są używane. Sprawdź ile bajtów wysłał twój komputer przez kartę ''em1''. Usunięcie bieżącej dyscypliny kolejkowania: \\ ''tc qdisc del root dev eth0'' Dodanie przykładowych dyscyplin: * ''tc qdisc add dev eth0 handle 1 root pfifo'' * ''tc qdisc add dev eth0 handle 1 root sfq'' * ''tc qdisc add dev eth0 handle 1 root tbf rate 10mbit burst 64k latency 50ms'' Zawsze interfejs musi mieć jedną główną (root) dyscyplinę. Testowanie prędkości (netperf): * ''netserver'' – włącza działający w tle serwer oczekujący na klientów \\ * ''netperf -H //host-docelowy//'' – nawiązuje połączenie z netserverem, uruchamia domyślny test (TCP_STREAM) \\ * ''netperf -t UDP_STREAM -H //host-docelowy//'' – nawiązuje połączenie z netserverem, uruchamia test UDP_STREAM <html><!-- server: socat tcp-l:9,fork /dev/null client: dd if=/dev/zero | nc 10.0.0.10 9 & dd if=/dev/zero | nc 10.0.1.1 9 & sleep 10 ; pkill -INT -f 'dd if' --></html> Testowanie prędkości - netcat i [[http://www.ivarch.com/programs/pv.shtml|pv]]: * instalacja pv w opensuse: ''zypper install pv'' * odbiorca: ''nc -l 3000 | pv > /dev/null'' * nadawca: ''pv /dev/zero | nc lab-net-1 3000'' //Zadanie 2a. // Zmień kolejkę na urządzeniu ''em1'' na podany wyżej przykładu z ''sfq''. Sprawdź maksymalną prędkość przesyłania danych. //Zadanie 2b. // Zmień kolejkę na urządzeniu ''em1'' na podany wyżej przykładu z ''tbf''. Sprawdź maksymalną prędkość przesyłania danych. Przepełnienie kolejki. ===== Bezklasowe i klasowe dyscypliny ===== Złożone dyscypliny kolejkowania pozwalają przyłączać do siebie **klasy** (class). \\ Administrator może wybrać jaki ruch trafia do konkretnej klasy tworząc **filtry** (filter). Proste dyscypliny kolejkowania nie pozwalają na to – stąd podział na klasowe i bezklasowe qdisc. === Bezklasowe === Przykładowe: * ''pfifo'' i ''bfifo'' – proste kolejki; zbierają statystyki ile (p)akietów / (b)ajtów wysłały. * ''pfifo_fast'' – kolejki priorytetowe dające pierwszeństwo na podstawie pola ToS protokołu IP [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#pfifo-fast]] * ''sfq'' – zapewnia fairness [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#stochastic-fair-queueing-sfq]] * ''tbf'' – ogranicza prędkość [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#token-bucket-filter]] * ''fq_codel'', <html><small></html>''codel''<html></small></html>, ''cake'' – dobiera rozmiar kolejki tak żeby nie ograniczać prędkości i utrzymywać małe opóźnienie [[http://www.bufferbloat.net/projects/codel/wiki]] === Klasowe === Przykładowe: * ''prio'' [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#prio]] * ''htb'' [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#hierarchical-token-bucket]] ===== qdisc vs class ===== Klasowy qdisc moze mieć wiele klas. \\ qdisc zawsze ma numer ''//x//:0'' – minor ''0'' i dowolny major. \\ class ma numer ''//x//://y//'', gdzie major oznacza qdisc w którym został stworzony, a minor – niezerowy identyfikator klasy wewnątrz qdisc Zapis ''1:0'' mozna zastąpić czasami przez ''1:'' (a czasami też samym ''1''). ===== prio + filtry ===== **[[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#prio]]** ''tc qdisc add dev eth0 handle 1 root prio'' – ustawienie klasowego qdisc, kolejki priorytetowej ''tc class show dev eth0'' – wyświetlenie klas (prio automatycznie tworzy 3 klasy) \\ ''tc -s class show dev eth0'' – wyświetlenie statystyk klas //Zadanie 3. // Zmień dyscyplinę kolejkową na ''em1'' na ''prio''. Wyświetl listę klas i ich statystyki. Zbadaj gdzie domyślnie trafia ruch. Filtry: * Podstawa działania: pakiet który trafia do "kolejki" pakietów czekających na wysłanie trafia wpierw do root qdisc. Ten decyduje co z nim zrobić: przegląda filtry i jeśli któryś pasuje – stosuje go. Jeśli żaden nie pasuje – wykonuje domyślną akcję. Dla ''prio'' domyślna akcja to wybór jednej z 3 kolejek bazując na polu TOS w nagłówku IP (''man tc-prio'') * ''tc filter show dev eth0'' – listuje filtry * Filtr ** ''u32'' ** * Przykładowy filtr: \\ ''tc filter add dev eth0 parent 1:0 protocol ip u32 match ip dst 150.254.32.130/32 flowid 1:3'' <code> dodaj na klasie/dycyplinie /-\ /-------\ tc filter add dev eth0 parent 1:0 protocol ip u32 match ip dst 150.254.32.130/32 flowid 1:3 \_____/ \____/ \_______/ \______________________________________________/ filtry na urządzeniu filtr ma dotyczyć IP filtr 'u32' dopasowujący się do IP wymuszający przydzielenie do klasy 1:3</code> * Przetestuj działanie filtra komendą \\ ''netperf -H 150.254.32.130 & netperf -H 150.254.32.131 ; wait'' * Przetestuj działanie filtra komendą \\ ''netperf -t UDP_STREAM -H 150.254.32.130 & netperf -t UDP_STREAM -H 150.254.32.131 ; wait'' * Wypisz statystyki dla klas, wygeneruj ruch, wypisz ponownie statystyki i porównaj \\ ''tc -s class show dev eth0'' * Filtr ''u32'' w ''tc'' pozwalają filtrować: * adresy IP, źródłowe i docelowe * protokoły warstwy transportowej (icmp, tcp, udp) ++ przykład|: \\ ''tc filter add dev eth0 parent 1:0 u32 match ip protocol 1 0xff flowid 1:1''++ * pole TOS w nagłówku IP (https://en.wikipedia.org/wiki/Differentiated_services) * <html><small></html>porty protokołów warstwy transportowej (ssh, dns, http, openvpn, xmpp) ++ przykład | (nie do końca poprawny): \\ ''tc filter add dev eth0 parent 1:0 u32 match ip sport 443 0xffff match ip protocol 6 0xff flowid 1:1''++<html></small></html> * Filtr ** ''fw'' ** * Do bardziej złożonego filtrowania można użyć filtru ''fw'', który pozwala odpowiednio oznaczony ruch (np. przez iptables) wrzucać do wybranej klasy * Dodawanie filtrów z wykorzystaniem iptables: \\ ''iptables -A OUTPUT -d 150.254.32.130 -j MARK --set-mark 130'' – nakazuje iptables zaznaczać pakiety \\ ''tc filter add dev eth0 parent 1:0 handle 130 fw flowid 1:3'' – nakazuje pakiety zaznaczone jako 130 wrzucać do klasy 1:3 * http://www.lartc.org/howto/lartc.qdisc.filters.html //Zadanie 4. // Dodaj filtr typu ''u32'' który pakiety do wybranego komputera będzie umieszczał w klasie o niższym priorytecie. Korzystając ze statystyk klas sprawdź czy filtr działa. Sprawdź (np. netperfem) jakie są prędkości wysyłania danych jeśli jednocześnie dane są wysyłane tego komputera i do dowolnego innego. //Zadanie 5. // Dodaj filtr typu ''fw'' i regułę iptables które pakiety protokołu icmp będą umieszczały w kolejce o najwyższym priorytecie. Korzystając ze statystyk klas sprawdź czy filtr działa. ===== htb ===== **[[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#hierarchical-token-bucket]]** Dodanie dyscypliny kolejkowej htb realizuje się przykładowo komendą: tc qdisc add dev eth0 root handle 1 htb default 2 gdzie ''//default 2//'' oznacza, że domyślnie pakiety będą trafiać do klasy 1:2 HTB nie tworzy domyślnie żadnych klas. Tworzenie trzech klas: tc class add dev eth0 parent 1:0 classid 1:1 htb rate 100mbit tc class add dev eth0 parent 1:1 classid 1:2 htb rate 50mbit tc class add dev eth0 parent 1:1 classid 1:3 htb rate 40mbit ceil 100mbit Usunięcie klasy: ''tc class del dev eth0 classid 1:3'' W HTB zwykle tworzy się klasy tak, by bezpośrednio do qdisc była podpięta jedna klasa, definiująca tylko rate (maksymalny dla łącza), a pod nią były podpięte kolejne, definiujące rate i ceil (których sumaryczny rate ani pojedynczy ceil jest nie większy niż możliwości łącza). Dodaj regułę wrzucającą wybrany ruch do klasy 1:3, sprawdź pożyczanie Klasy w HTB mogą tworzyć dowolną hierarchię (drzewo) – można wpinać klasy do klas, np: tc class add dev eth0 parent 1:1 classid 1:4 htb rate 10mbit ceil 100mbit tc class add dev eth0 parent 1:4 classid 1:41 htb rate 5mbit ceil 50mbit tc class add dev eth0 parent 1:4 classid 1:42 htb rate 5mbit ceil 100mbit <html><object id="svg-object" data="/jkonczak/_media/sk2:htb.svg" type="image/svg+xml"></object></html> [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#przyklad]] //Zadanie 6a. // Zmień dyscyplinę kolejową na ''htb''. Następnie narysuj i stwórz odpowiednimi poleceniami drzewo klas potrzebne do podzielenia ruchu tak, by: * na pakiety idące do jednego wybranego komputera było zagwarantowane 10mbit bez możliwości pożyczania ruchu * na pakiety idące do drugiego wybranego komputera było zagwarantowane 20mbit ruchu z możliwością pożyczania do 100mbit * na pozostałe pakiety było zagwarantowane 70mbit ruchu z możliwością pożyczania do 100mbit //Zadanie 6b. // Dodaj odpowiednie filtry i przetestuj czy działają korzystając ze statystyk klas. //Zadanie 6c. // Sprawdź przestrzeganie limitów i działanie pożyczania używając programu netperf. ===== Dodawanie qdisc do klas ===== Każda klasa która nie ma żadnej klasy pod sobą ma swój domyślny qdisc. \\ Można go zmienić na dowolny wybrany, np: \\ ''tc qdisc add dev eth0 handle 2 parent 1:2 fq_codel'' \\ ''tc qdisc add dev eth0 handle 3 parent 1:42 sfq'' Usunięcie qdisc: \\ ''tc qdisc del dev eth0 handle 2:0 parent 1:2'' [[http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/ts.html#koleki-klasowe-zlozone]] Można w ten sposób dowolnie zagnieżdżać w sobie klasowe dyscypliny kolejkowania. //Zadanie 7. // Dodaj pod wybraną klasę z utworzonej wcześniej dyscypliny kolejkowej kolejną dyscyplinę kolejkową dowolnego typu. <html><small></html> ===== [Ekstra] IFB + ingress tc ===== Karta sieciowa nie ma kontroli nad tym co i w jakiej kolejności ktoś do niej wysyła, ale używając TC można próbować kształtować ruch wejściowy opóźniając lub odrzucając to co już przyszło. Ma to sens, bo protokół TCP dostosowuje prędkość nawiązanego już połączenia do możliwości sieci, więc opóźnienie lub odrzucenie segmentów TCP które przyszły do systemu spowodują zmianę prędkości wsyłania przez nadawcę. TC pozwala na bezpośrednie kształtowanie ruchu wchodzącego, ale jest ono zdecydowanie mniej rozbudowane niż kształtowanie ruchu wychodzącego. Dlatego zwykle używa się urządzenia pośredniego, które pozwala traktować ruch wchodzący jako wychodzący. ++++ Przykład kształtowania na wejściu: | <code> # dodanie urządzenia 'pośredniego' (Intermediate Functional Block), które: # * działa jako kolejka na wejściu # * pozwala kształtować wysyłanie pakietów z kolejki do systemu # (https://wiki.linuxfoundation.org/networking/ifb) ip link add name ifb0 type ifb ip link set ifb0 up # # alternatywnie można użyć komend: #modprobe ifb numifbs=1 #ifconfig ifb0 up # dodanie dyscypliny kolejkowej typu ingress - pakiety wchodzące # (handle ffff jest domyślne dla qdisc ingress) tc qdisc add dev enp0s3 handle ffff ingress # dyscyplina ingress nie pozwala na rozbudowaną konfigurację, ale: # można przekazać ruch do pośredniego urządzenia, które pozwoli ruchu wchodzący przetwarzać tak jak wychodzący # dodanie flitra, który cały ruch wchodzący przekaże do urządzenia ifb: # # na urządzeniu enp0s3 sprawdza czy 0==0 jako ruch wychodzący na ifb0 # ___/\___ ___/\__________ _/\_ __/\__ # / \ / \ / \ / \ tc filter add dev enp0s3 parent ffff: u32 match u32 0 0 action mirred egress redirect dev ifb0 # \____ ____/ \____ _____/ \_ ___/ # \/ \/ \/ # na qdisc ffff: (ingres) przekierowuje ruch (man tc-mirred) # efekt powyższej komendy widać po wpisaniu tc filter show dev enp0s3 ingress # lub: #tc filter show dev enp0s3 parent ffff: # dalsza konfiguracja odbywa się jak dla zwykłego ruchu wychodzącego dla urządzenia ifb # przykład z HTB: tc qdisc add dev ifb0 root handle 1 htb default 2 tc class add dev ifb0 parent 1:0 classid 1:1 htb rate 1Gbit tc class add dev ifb0 parent 1:1 classid 1:2 htb rate 100Mbit ceil 1Gbit tc class add dev ifb0 parent 1:1 classid 1:3 htb rate 100Mbit tc filter add dev ifb0 parent 1:0 protocol ip u32 match ip src 10.0.1.3 flowid 1:3 </code> ++++ ===== [Ekstra] netem ===== Netem to dyscyplina kolejkowa pozwalająca symulować opóźnienia, błędy, stratę i duplikację pakietów. Dzięki netem można w łatwy sposób sprawdzać jak zachowałby się dany program w zadanych warunkach, np. przy dużych opóźnieniach (łącza satelitarne), czasowo pojawiającym się opóźnieniu kilku pakietów (internet po sieciach radiowych), zmianie kolejności pakietów (multipath routing w infrastrukturze ISP). \\ Dla przykładu: podczas zajęć z programowania netem [[sk2:sockets_caveats#kolejnosc_danych_i_nie_zawodnosc|był użyty]] do sprawdzenia jakie gwarancje daje TCP, a nie daje ich UDP. Pomoc do netem można znaleźć: * ''man tc-netem'' * [[https://wiki.linuxfoundation.org/networking/netem]] <html></small></html>
sk2/tc.1607421514.txt.gz
· ostatnio zmienione: 2020/12/08 10:58 (edycja zewnętrzna)
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Złóż / rozłóż wszystko
Do góry