Numeracja klas / filtrów w systemie Linux

12

Obecnie pracuję nad rozwiązaniem do kształtowania ruchu dla firm na poziomie ISP i napotkałem interesujący (nieco filozoficzny) problem.

Patrząc na liczbę punktów końcowych, które powinien obsłużyć system (czyli około ~ 20 tys.), Trochę się martwiłem, co by się stało, gdybym musiał regulować / kształtować ruch większej liczby użytkowników. Ponieważ obecnie używam drzewa kształtującego HFSC (patrz tc-hfsc, głównie ta sama, ale fajniejsza rzecz jak lepiej znany HTB) dla całej sieci, musiałbym użyć większej liczby identyfikatorów ClassID (oczywiście co najmniej jeden dla każdego użytkownika w sieć). Problem, który znalazłem, polegał na tym, że identyfikatory TC ClassID są nieco ograniczone - są to liczby 16-bitowe, co daje mi maksymalnie 64 000 użytkowników ukształtowanych przez to rozwiązanie.

Podobnie, jeśli chcę efektywnie zarządzać filtrami TC (np. Nie stosując techniki „opróżnij wszystko”), muszę mieć możliwość usuwania lub modyfikowania poszczególnych pozycji filtrów. (Używam czegoś podobnego do tabeli skrótów z LARTC [1]). Ponownie, jedyną metodą, która wydaje się działać z tym jest numerowanie wszystkich filtrów przy użyciu indywidualnych priorytetów (filtr tc dodaj dev ... prio 1). Nie ma innego parametru, który mógłby zostać użyty w tym celu, a niestety prio jest również tylko 16-bitowe.

Moje pytanie brzmi: czy istnieje jakaś dobra metoda powiększenia dostępnej „przestrzeni identyfikatora”, taka jak 32-bitowy clsid dla polecenia „klasa tc” i 32-bitowe priorytety (lub inne uchwyty modyfikacji) dla „filtra tc” Komenda?

Dziękuję bardzo,

-mk

(przy okazji mam nadzieję, że nie przejdzie to do scenariusza „64 tys. użytkowników powinno wystarczyć dla wszystkich”).

exa
źródło
Wszystkie te wartości są przechowywane w przestrzeni jądra, aby je powiększyć, trzeba będzie ponownie skompilować narzędzia jądra i przestrzeni użytkownika. Próbowałeś używać 64-bitowego jądra? Można je zdefiniować jako 32-bitowe.
Hubert Kario
Jądro 64-bitowe używa tych samych rozmiarów. Na przykład, numer filtra to u32-liczba całkowita, która składa się z górnej (protokołu) i dolnej części (prio), oczywiście 16-bitowych. Identyfikatory klas są zakodowane na stałe jako u16. Prawdopodobnie spróbuję zapytać kogoś na LKML.
exa
1
nawet używając skrótu do filtrów, będziesz miał wiele problemów z IO, jeśli używasz tylu filtrów (chyba dla upstream i downstream). Spędziłem dużo czasu i musiałem załatać implementację kolejek w jądrze, żeby wszystko działało bez ksoftirqd. Użyłem łatki od faceta o nazwisku Simon Lodal, którego poznałem na LARTC 4 lata temu. Spójrz na jego łatkę mail-archive.com/[email protected]/msg16279.html . Możesz spróbować wysłać mu wiadomość e-mail, ponieważ zawsze ma przy sobie bardzo zaktualizowaną wersję (w stosunku do ostatniego jądra).
Pabluez
@Pabluez Dzięki bardzo, postaram się jak najlepiej z tego skorzystać.
ex
1
Myślę, że twoje wymagania są prawidłowe, ale jak napisał Pabluez, z pewnością wymaga to wielu zmian w jądrze. Nie chcę powiedzieć „robisz to źle”, ale zachęcam do sprawdzenia otwartego przepływu, w którym dolne części obsługi pakietów są wykonywane na poziomie przełącznika, a policyjne są wykonywane w niestandardowym oprogramowaniu, prawdopodobnie działa w przestrzeni użytkownika. Nie wiem, czy pasuje to do twoich wymagań, ale z pewnością warto to zbadać.
AndreasM

Odpowiedzi:

2

myślę, że nie powinieneś umieszczać 64k użytkowników z klasami i filtrami upstream i downstream dla każdego z nich na tym samym interfejsie. Możesz powtarzać procedury obsługi dla każdego posiadanego interfejsu, więc dodaj więcej interfejsów. Będziesz potrzebował niesamowitej pracy / serwera / karty sieciowej, aby mieć te rzeczy. Jeśli serwer ulegnie awarii, będziesz mieć 64 tys. Użytkowników offline (i łatwo ulegnie awarii przy takiej ilości ruchu). Nie zapominaj, że KAŻDY pakiet, który przechodzi przez twoją kartę sieciową, zostanie sprawdzony i sklasyfikowany przez filtr i wysłany do klasy w kolejce. To dużo pracy dla karty sieciowej bramy ISP z 64 tysiącami klientów. Głównie z całym strumieniem wideo, który mamy obecnie (co jest trudne do prawidłowego umieszczenia w kolejce).

Pabluez
źródło
Zapewniam dostępność usług na innym poziomie, ale dziękuję za troskę. W rzeczywistości przy dobrych kartach sieciowych nie jest tak trudno mieć router linux, który mógłby przesyłać 10 Gbitów.
ex
W przypadku pierwotnego pytania bardziej interesowały mnie rzeczy takie jak dodanie 5 różnych klas dla każdego użytkownika, co pozwoliłoby mi wykonać naprawdę dobrą pracę QOS (np. Osobna obsługa strumieni i ruchu w czasie rzeczywistym), ale w obecnych warunkach jest to w większości nie do pomyślenia (z moim aktualny przypadek użycia ~ 20 000 punktów końcowych, już byłbym za granicą).
ex
1
okej, przesłanie 10 Gbitów nie stanowi żadnego problemu, problemem jest wiele filtrów i klas 64k * 2 (wzrosty i spadki). Powodzenia: D
Pabluez
0

Możesz podzielić obsługę ruchu na dwa komputery (używając trzeciego) zamiast obsługiwać cały ruch na jednym komputerze. Ruch może być kierowany po prostu na podstawie źródłowego adresu IP. Tak więc będziesz mieć optymalnie 10 000 użytkowników, jeśli możesz równomiernie podzielić zakresy adresów IP.

Oczywiście w razie potrzeby można użyć więcej niż dwóch maszyn. Myślę, że może to być lepsze niż łatanie jądra Linuksa i robienie innych hacków. Krótko mówiąc, kształtowanie ruchu będzie dystrybuowane na kilku maszynach. Węzeł centralny po prostu przekieruje ruch do odpowiedniego węzła przetwarzania.

Khaled
źródło