Linux TC Class / Filter Nummerierung

12

Derzeit arbeite ich an einer Traffic-Shaping-Lösung für ISP-Unternehmen und bin auf ein interessantes (philosophisches) Problem gestoßen.

Als ich mir die Anzahl der Endpunkte ansah, mit denen das System umgehen sollte (ca. 20.000), war ich ein wenig besorgt, was passieren würde, wenn ich den Datenverkehr von mehr Benutzern regeln / formen müsste. Da ich derzeit HFSC-Shaping-Tree (siehe tc-hfsc, meistens das Gleiche, aber das Coolere wie besser bekanntes HTB) für das gesamte Netzwerk verwende, müsste ich mehr ClassIDs verwenden (natürlich mindestens eine für jeden Benutzer im Netzwerk). Das Problem, das ich fand, war, dass TC ClassIDs ein bisschen begrenzt sind - es sind 16-Bit-Zahlen, was mir ein mögliches Maximum von 64.000 Benutzern gibt, die von dieser Lösung geprägt sind.

Ebenso muss ich in der Lage sein, einzelne Filtereinträge zu löschen oder zu ändern, wenn ich TC-Filter effizient verwalten möchte (z. B. nicht mit der Methode "Alle leeren"). (Ich verwende etwas Ähnliches wie eine Hash-Tabelle von LARTC [1]). Auch hier scheint die einzige Methode, die damit zu funktionieren scheint, darin zu bestehen, alle Filter mit individuellen Prioritäten zu nummerieren (tc filter add dev ... prio 1). Es gibt keinen anderen Parameter, der für diesen Zweck verwendet werden könnte, und bedauerlicherweise ist prio auch nur 16-Bit.

Meine Frage lautet wie folgt: Gibt es eine gute Methode zum Vergrößern des verfügbaren "Bezeichnerbereichs", z. B. den 32-Bit-Befehl "clsid's for tc class" und 32-Bit-Prioritäten (oder andere Änderungshandles) für "tc filter"? Befehl?

Vielen Dank,

-mk

(Übrigens hoffe ich, dass dies nicht für das Szenario "64.000 Benutzer sollten für alle reichen" gilt ...)

exa
quelle
Alle diese Werte werden im Kernel-Space gespeichert. Um sie zu vergrößern, müssen Sie Ihre Kernel- und Userspace-Dienstprogramme neu kompilieren. Haben Sie versucht, einen 64-Bit-Kernel zu verwenden? Sie können dort als 32bit definiert werden.
Hubert Kario
64-Bit-Kernel verwendet die gleichen Größen. Zum Beispiel ist die Filternummer eine U32-Ganzzahl, die aus dem oberen (Protokoll) und unteren Teil (Prio) besteht, beide offensichtlich 16 Bit. Klassen-IDs sind als u16 fest codiert. Ich werde wahrscheinlich versuchen, jemanden über LKML zu befragen.
Exa
1
Selbst wenn Sie Hash für Ihre Filter verwenden, werden Sie viele IO-Probleme haben, wenn Sie so viele Filter verwenden (ich denke für Upstream und Downstream). Ich habe viel Zeit aufgewendet und musste die Implementierung der Warteschlangen im Kernel patchen, damit die Dinge mit ksoftirqd funktionieren. Ich habe einen Patch von Simon Lodal benutzt, den ich vor 4 Jahren auf LARTC getroffen habe. Schauen Sie sich seinen Patch an: mail-archive.com/[email protected]/msg16279.html . Sie können versuchen, ihm eine E-Mail zu senden, da er immer eine sehr aktualisierte Version (gegen den letzten Kernel) bei sich hat.
Pabluez
@Pabluez Vielen Dank, ich werde versuchen, das Beste daraus zu machen.
exa
1
Ich denke, Ihre Anforderung ist gültig, aber wie Pabluez schrieb, beinhaltet dies sicherlich eine Menge Kerneländerungen. Ich möchte nicht sagen, dass Sie es falsch machen, aber ich möchte Sie dazu ermutigen, openflow zu überprüfen, bei dem die unteren Teile der Paketverarbeitung auf der Switch-Ebene erfolgen und die Überwachung vermutlich in einer benutzerdefinierten Software erfolgt Laufen im User-Space. Ich weiß nicht, ob es Ihren Anforderungen entspricht, aber es lohnt sich auf jeden Fall, nachzuforschen.
AndreasM

Antworten:

2

Ich denke, dass Sie nicht 64k Benutzer mit vor- und nachgelagerten Klassen und Filtern für jeden von ihnen auf der gleichen Schnittstelle setzen sollten. Sie können die Handler für jede vorhandene Schnittstelle wiederholen. Fügen Sie also weitere Schnittstellen hinzu. Sie benötigen eine unglaubliche Arbeit / Server / Netzwerkkarte, um diese Dinge zu haben. Wenn der Server abstürzt, sind 64.000 Benutzer offline (und es kommt leicht zu einem Absturz bei diesem Datenverkehr). Vergessen Sie nicht, dass JEDES Paket, das Ihre Netzwerkkarte durchläuft, von einem Filter geprüft und klassifiziert und an eine Klasse gesendet wird, um in die Warteschlange eingereiht zu werden. Dies ist eine Menge Arbeit für eine Netzwerkkarte eines ISP-Gateways mit 64.000 Kunden. Hauptsächlich mit all dem Videostream, den wir heutzutage haben (was schwierig ist, richtig in eine Warteschlange zu stellen).

Pabluez
quelle
Ich stelle die Verfügbarkeit des Dienstes auf einer anderen Ebene sicher, aber danke für Ihre Besorgnis. Tatsächlich ist es mit guten Netzwerkkarten nicht so schwer, einen Linux-Router zu haben, der 10 Gbit weiterleiten kann.
EXA
Für die ursprüngliche Frage interessierte ich mich mehr für Dinge wie das Hinzufügen von 5 verschiedenen Klassen für jeden Benutzer, die es mir ermöglichen würden, eine wirklich gute QOS-Arbeit (wie das separate Behandeln von Streams und Echtzeitverkehr) zu erledigen aktueller Anwendungsfall von ~ 20k Endpunkten (ich würde bereits hinter dem Limit sein).
exa
1
okay, 10 Gbit weiterzuleiten ist kein Problem, das Problem ist, dass es viele 64k * 2 (Ups Downs) Filter und Klassen gibt. Viel Glück aber: D
Pabluez
0

Sie können die Verkehrsabwicklung in zwei Maschinen aufteilen (mit einer dritten), anstatt den gesamten Verkehr auf einer Maschine abzuwickeln. Der Datenverkehr kann einfach basierend auf der Quell-IP-Adresse weitergeleitet werden. Sie haben also optimalerweise 10.000 Benutzer, wenn Sie die IP-Bereiche gleichmäßig aufteilen können.

Natürlich können Sie bei Bedarf mehr als zwei Maschinen verwenden. Ich denke, das ist vielleicht besser, als den Linux-Kernel zu patchen und ein paar andere Hacks zu machen. Kurz gesagt, die Verkehrssteuerung wird auf mehrere Maschinen verteilt. Der zentrale Knoten leitet den Verkehr nur an den richtigen Verarbeitungsknoten weiter.

Khaled
quelle