/ Linux Reviews / Networking / Kształtowanie Ruchu i Zaawansowany Routing HOWTO - en - pl
14.3. DSMARKDokumenty źródłowe:
Ten rozdział jest autorstwa Esteve Camps <esteve%hades.udg.es>. 14.3.1. WprowadzeniePo pierwsze, dobrze byłoby przeczytać RFC poświęcone temu tematowi (RFC2474, RFC2475, RFC2597 i RFC2598) ze strony IETF DiffServ working Group oraz strony autorstwa Wernera Almesbergera (napisał kod odpowiedzialny za różnicowanie usług w Linuksie). 14.3.2. Z czym jest związany Dsmark?Dsmark jest kolejką z dyscypliną, która oferuje możliwości potrzebne w `Usługach Zróżnicowanych' (ang. "Differentiated Services") (nazywanych również DiffServ lub po prostu DS). DiffServ jest jedną z dwóch architektur QoS (druga nazywa się Usługami Zintegrowanymi) bazujących na wartościach przenoszonych przez pakiet w polu DS nagłówka IP. Jednym z pierwszych rozwiązań zaprojektowanych dla IP z myślą o QoS było pole Typ Usługi (bajt ToS) umieszczone w nagłówku IP. Zmieniając tą wartość, możemy wybrać wysoki/niski poziom przepustowości, zwłokę czy też niezawodność. Nie zapewnia to wymaganej elastyczności jeśli chodzi o nowe usługi (takie jak aplikacje czasu rzeczywistego, interaktywne i inne). Po tym pomyśle pojawiły się nowe architektury. Jedną z nich jest DiffServ, która zachowała bity ToS i przemianowane pole DS. 14.3.3. Wskazówki dotyczące Usług ZróżnicowanychUsługi Zróżnicowane są zorientowane na grupy. Oznacza to, że nie wiemy nic o potokach (którymi zajmą się Usługi Zróżnicowane); wiemy o agragacjach potoków i zastosujemy w stosunku do nich różne zasady, w zależności od tego, do której agregacji należy pakiet. Kiedy pakiet dociera do węzła brzegowego (węzła wejściowego do domeny DiffServ) można w stosunku do niego zastosować zdefiniowane zasady, poddać go kształtowaniu ruchu i/lub zaznaczyć go (oznaczanie dotyczy przydzielania wartości polu DS. Całkiem jak z krowami :-) ). Jest to znacznik na podstawie którego węzły domeny DiffServ będą decydowały, który poziom QoS zastosować. Jak pewnie wydedukujesz, Usługi Zróżnicowane zawierają domenę, w której reguły DS będą stosowane. Tak naprawdę możesz o niej myśleć w ten sposób: `Pakiety docierające do mojej domeny będą poddane działaniu reguł, które dyktują zasady klasyfikujące a każdy przemierzany węzeł zastosuje w stosunku do takiego pakietu poziom QoS'. Tak naprawdę, możesz stosować własne zasady w swoich lokalnych domenach, ale pewne `Ustalenia Poziomu Usług' (ang. "Service Level Agreements") powinny zostać rozważone przy podłączaniu do innych domen DS. Możesz mieć w tym momencie masę pytań. DiffServ to więcej niż do tej pory powiedziałem. Proszę zrozumieć, że nie potrafię streścić 3 RFC w 50 liniach :-). 14.3.4. Praca z DsmarkJak podaje bibliografia DiffServ, rozróżniamy węzły brzegowe i wewnętrzne. Są to dwa ważne punkty w ścieżce obsługiwanego ruchu. Oba typy wykonują klasyfikację gdy otrzymują pakiety. Rezultaty tej klasyfikacji mogą zostać wykorzystane w różnych miejscach procesu DS zanim pakiet zostanie wypuszczony do sieci. Dlatego architektura DiffServ udostępnia strukturę `sk_buff', zawierającą nowe pole nazwane `skb->tc_index', w którym przechowywana jest wartość początkowej klasyfikacji dla późniejszego wykorzystania w trakcie procesu DS. Wartość `skb->tc_index' zostaje początkowo ustawiona przez qdisc DSMARK, przez pobranie pola DS z nagłówka pakietu IP. Poza tym, klasyfikator `cls_tcindex' przeczyta całość lub część pola `skb->tc_index' i użyje tej wartości by wybrać klasy. Przyjrzyjmy się najpierw komendzie qdisc DSMARK i jej parametrom: ... dsmark indices INDICES [ default_index DEFAULT_INDEX ] [ set_tc_index ]Co oznaczają?
14.3.5. Jak działa SCH_DSMARK.Kolejka wykonuje następujące kroki:
skb->ihp->tos
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
| | ^
| -- If you declare set_tc_index, we set DS | | <-----May change
| value into skb->tc_index variable | |O DS field
| A| |R
+-|-+ +------+ +---+-+ Internal +-+ +---N|-----|----+
| | | | tc |--->| | |--> . . . -->| | | D| | |
| | |----->|index |--->| | | Qdisc | |---->| v | |
| | | |filter|--->| | | +---------------+ | ---->(mask,value) |
-->| O | +------+ +-|-+--------------^----+ / | (. , .) |
| | | ^ | | | | (. , .) |
| | +----------|---------|----------------|-------|--+ (. , .) |
| | sch_dsmark | | | | |
+-|------------|---------|----------------|-------|------------------+
| | | <- tc_index -> | |
| |(read) | may change | | <--------------Index to the
| | | | | (mask,value)
v | v v | pairs table
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->
skb->tc_index
Jak wykonać oznaczanie pakietu? Zmień maskę i wartość klasy, którą chciałbyś komentować. Spójrz na następującą linijkę: tc class change dev eth0 classid 1:1 dsmark mask 0x3 value 0xb8Zmienia to parę (maska,wartość) w tablicy mieszającej powodując oznaczenie pakietów należących do klasy 1:1. Musisz `zmienić' te wartości z uwagi na domyślne wartości, które para (maska,wartość) otrzymuje przy inicjalizacji (zobacz tabelę poniżej). Teraz wytłumaczymy jak działa filtr TC_INDEX i jak wpasowuje się w to wszystko. Oprócz pracy z usługami DS, TC_INDEX może być używany w innych konfiguracjach. 14.3.6. Filtr TC_INDEXPoniżej podstawowa komenda deklarująca filtr TC_INDEX: ... tcindex [ hash ROZMIAR ] [ mask MASKA ] [ shift PRZESUNIĘCIE ]
[ pass_on | fall_through ]
[ classid CLASSID ] [ police OKREŚLENIE_POLITYKI ]
Pokażemy teraz przykład by wyjaśnić tryb pracy TC_INDEX. Zwróć uwagę na
wyróżnione słowa:
tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 \ set_tc_index tc filter add dev eth0 parent 1:0 protocol ip prio 1 \ tcindex mask 0xfc shift 2 tc qdisc add dev eth0 parent 1:0 handle 2:0 cbq bandwidth 10Mbit \ cell 8 avpkt 1000 mpu 64 # EF traffic class tc class add dev eth0 parent 2:0 classid 2:1 cbq bandwidth 10Mbit \ rate 1500Kbit avpkt 1000 prio 1 bounded isolated allot 1514 weight 1 maxburst 10 # Packet fifo qdisc for EF traffic tc qdisc add dev eth0 parent 2:1 pfifo limit 5 tc filter add dev eth0 parent 2:0 protocol ip prio 1 \ handle 0x2e tcindex classid 2:1 pass_on(Powyższy kod nie jest kompletny. Pochodzi z przykładu dla EFCBQ dostarczanego z dystrybucją iproute2). Po pierwsze, załóżmy że otrzymaliśmy pakiet oznaczony `EF'. Jeśli zapoznasz się z RFC2598 dowiesz się, że rekomendowaną przez DSCP wartością dla ruchu `EF' jest 101110. Oznacza to, że pole DS będzie miało wartość 10111000 (pamiętaj, że mniej znaczące bity w bajcie ToS nie są używane przez DS), lub w zapisie heksdecymalnym 0xB8.
TC INDEX
FILTER
+---+ +-------+ +---+-+ +------+ +-+ +-------+
| | | | | | | |FILTER| +-+ +-+ | | | |
| |----->| MASK | -> | | | -> |HANDLE|->| | | | -> | | -> | |
| | . | =0xfc | | | | |0x2E | | +----+ | | | | |
| | . | | | | | +------+ +--------+ | | | |
| | . | | | | | | | | |
-->| | . | SHIFT | | | | | | | |-->
| | . | =2 | | | +----------------------------+ | | |
| | | | | | CBQ 2:0 | | |
| | +-------+ +---+--------------------------------+ | |
| | | |
| +-------------------------------------------------------------+ |
| DSMARK 1:0 |
+-------------------------------------------------------------------------+
A więc dociera pakiet, z polem DS ustawionym na wartość 0xB8. Tak jak wytłumaczyliśmy wcześniej, kolejka DSMARK identyfikowana w tym przykładzie przez wartość 1:0, pobiera wartość z pola DS i zapisuje je w zmiennej `skb->tc_index'. Następny krok w przykładzie będzie dotyczył filtra skojarzonego z tą qdisc (druga linijka w przykładzie). Wykona to następujące operacje: Wartość1 = skb->tc_index & MASKA Klucz = Value1 >> PRZESUNIĘCIE W tym przykładzie, MASKA=0xFC a PRZESUNIĘCIE=2. Wartość1 = 10111000 & 11111100 = 10111000 Klucz = 10111000 >> 2 = 00101110 -> 0x2E heksdecymalnie Zwrócona wartość odpowiadać będzie uchwytowi wewnętrznego filtra w qdisc (w tym przykładzie, identyfikatorowi 2:0). Jeśli istnieje filtr z taką wartością id, sprawdzone zostaną odpowiednie instrukcje dotyczące polityki oraz ograniczeń przepustowości/częstotliwości (w tym przypadku filtr je zawiera) i zwrócona zostanie wartość identyfikatora klasy (w naszym przypadku, 2:1), która z kolei zostanie zapisana do zmiennej `skb->tc_index'. Jednak gdy znaleziony zostanie filtr z danym identyfikatorem, rezultat zależeć będzie od deklaracji flagi `fall_through'. Jeśli jest ona ustawiona, jako identyfikator klasy zwracany jest identyfikator klasy. Jeśli nie, zwracany jest błąd i proces kontynuowany jest na reszcie filtrów. Użycie flagi `fall_through' wymaga jednak ostrożności; powinno odbywać się tylko gdy istnieje prosta relacja między wartościami `skb->tc_index' a identyfikatorem klasy. Ostatnie parametry, które skomentujemy to wartość mieszająca i `pass_on'. Pierwszy odnosi się do rozmiaru tabeli mieszającej. `pass_on' jest z kolei używany do wskazania, że jeśli nie znaleziony zostanie identyfikator klasy równy zwróconemu wynikowi, należy kontynuować sprawdzanie na następnym filtrze. Domyślną akcją jest `fall_through' (spójrz na następną tabelę). Spójrzmy na koniec na wartości możliwe do ustawienia w parametrach TC_INDEX: Nazwa TC Wartość Domyślnie ----------------------------------------------------------------- Hash 1...0x10000 Zależne od implementacji Maska 0...0xffff 0xffff Przesunięcie 0...15 0 Fall through / Pass_on Flaga Fall_through Identyfikator klasy Major:minor żadna Polityka ..... żadna Ten rodzaj filtra jest bardzo potężny i niezbędne jest zapoznanie się z wszystkimi jego możliwościami. Poza tym, nie jest to jedyny filtr, którego można użyć w konfiguracjach DiffServ - można go używać tak jak każdego innego rodzaju filtru. Polecam zapoznanie się z przykładami DiffServ zawartymi w dystrybucji iproute2. Obiecuję, że uzupełnie ten tekst tak szybko jak będę mógł, poza tym wszystko co wytłumaczyłem jest rezultatem całej masy testów. Chciałbym podziękować wszystkim, którzy wytkną mi ewentualne błędy.
/ Linux Reviews / Networking / Kształtowanie Ruchu i Zaawansowany Routing HOWTO | |||||||||||||