Linux Switchdev Mellanox-Stil

Dies ist eine Transkription einer Rede, die bei Yandex NextHop 2020 gehalten wurde - Video am Ende der Seite






Schöne Grüße. Mein Name ist Alexander Zubkov, ich möchte Ihnen etwas über Linux Switchdev erzählen - was es ist und wie wir mit ihm in Qrator Labs leben.







Wir verwenden Switchdev seit ca. 2-3 Jahren für Mellanox-Switches. Mellanox Spectrum-basierte Switches werden als „White-Box“ klassifiziert. Dies bedeutet, dass Sie diesen Switches unterschiedliche Betriebssysteme hinzufügen können. Normalerweise stellt der Hersteller ein SDK dafür bereit, und Betriebssysteme verwenden dieses SDK, um mit dem Switch zu interagieren. Und im Fall von Mellanox-Switches gibt es ein Betriebssystem von Mellanox selbst, es gibt Cumulus. SAI (Switch Abstraction Interface) wird ebenfalls unterstützt - dies ist ein Versuch, ein Standard-SDK für verschiedene Switches zu erstellen, das wiederum bereits vom SONiC-Betriebssystem verwendet wird. Und natürlich wird Switchdev von Mellanox-Switches unterstützt.







Switchdev ist eine solche Infrastruktur im Linux-Kernel, mit der Sie eine Zuordnung der üblichen Netzwerkeinstellungen des Kernels selbst zum Datenbereich und zur Hardware Ihres Switches erstellen können. Dies wird als Offload bezeichnet. Das Bild zeigt, dass Pink der Switch-Treiber und Blue die API und die Dienstprogramme zum Konfigurieren des Benutzerbereichs ist. Switchdev fungiert hier als Vermittler: Für den Benutzerbereich stellt es das Switch-Modell dar, für den Treiber stellt es die Infrastruktur für die Organisation dieser Anzeige bereit.







Wir verwenden einen ziemlich standardmäßigen Satz von Funktionen für Mellanox-Switches: Routing, ECMP, im Allgemeinen nichts Ungewöhnliches. All dies wird durch die Möglichkeit des Ausladens in die Datenlinie unterstützt. Das einzige, was fehlt, ist richtlinienbasiertes Routing - der Mellanox-Treiber wird nicht unterstützt.







Der Mellanox-Treiber befindet sich in einem Vanilla Linux-Kernel mit Switchdev-Unterstützung - es werden keine Patches oder zusätzlichen Binärtreiber benötigt. Sie können den Kernel praktisch aus Ihrer Lieblingsdistribution nehmen oder den Vanillekern selbst kompilieren und verwenden. Die Firmware im Switch wird vom Treiber selbst aktualisiert - Sie müssen nur die entsprechende Datei einfügen, die normalerweise im Linux-Firmware-Paket oder ähnlichem enthalten ist.







Um den Switch selbst zu konfigurieren, werden natürlich Standard-Linux-Dienstprogramme in großen Mengen verwendet. Ein Satz von iproute2, ethtool, LLDP-Daemon für QoS wird ebenfalls verwendet. Und sysctl für einige Optionen.







Für vrf unter Linux gibt es beide Netzwerk-Namespaces. Es gibt aber auch ein sogenanntes vrf-Subsystem - es unterscheidet sich von Netzwerk-Namespaces. In diesem Fall befinden sich alle Ihre Schnittstellen im selben Namespace - wenn Sie mit vrf arbeiten. Und um das Routing zu steuern, gibt es in der IP-Regel eine spezielle Regel, die bestimmt, zu welcher VRF das Paket gehört, und diese entsprechend an eine bestimmte Routing-Tabelle weiterleitet. Um dies zu konfigurieren - vrf unter Linux - wird eine spezielle Schnittstelle vom Typ vrf erstellt, an die diese Tabelle während der Erstellung gebunden wird. Wenn Sie Ihrem vrf eine Schnittstelle hinzufügen möchten, legen Sie mit dem Befehl ip link dieses spezielle Gerät als Hauptschnittstelle für Ihre Schnittstelle fest.Und da sich alle diese Schnittstellen im selben Namespace befinden, können Sie explizit eine Schnittstelle von einem anderen vrf zur Route angeben und so Routen zwischen den Schnittstellen erstellen.







Zum Beispiel haben wir eine Aufgabe, bei der richtlinienbasiertes Routing helfen würde - wir empfangen Datenverkehr vom Uplink und möchten ihn vollständig und bedingungslos an einige Filterknoten weiterleiten. In Cisco oder Arista würden wir Richtlinienroutenzuordnungen oder eine Servicerichtlinie erstellen. In Linux- und IP-Regeln können Sie dies tun - aber in Linux wird all dies leider nicht ausgelagert.







Und wir müssen uns umdrehen. Zum Beispiel haben wir ein solches Feature erstellt - wir haben vrf in zwei Teile geteilt, dh in einem Teil - im äußeren Teil gibt es eine Schnittstelle zu unserem Uplink und im inneren Teil gibt es Schnittstellen zu unseren Filterknoten.







Und so sieht Routing aus. In der internen vrf haben wir einen mehr oder weniger standardmäßigen Satz von Routen - das heißt, wir haben dort interne Routen und eine Standardroute über unseren Uplink. Und bereits in der externen Schnittstelle haben wir nur eine Standardroute, die jedoch durch unsere Filterknoten verläuft. Somit haben wir ein pseudorichtlinienbasiertes Routing für Schnittstellen erhalten. Der gesamte Datenverkehr, der über die Uplink-Schnittstelle eingeht, wird auf einer anderen Route geleitet.







Wenn Sie einen Switch auf Switchdev konfigurieren, müssen Sie im Allgemeinen zuerst die Ports, dann die Verbindung konfigurieren, dann eine Verbindung zur Bridge herstellen, dann vlans, vrfs und am Ende der Adresse und der Routen. Dies wird hauptsächlich durch die Struktur der Schnittstellen unter Linux bestimmt - wie Sie alles konfigurieren sollten, gibt es einige andere Einschränkungen, die es Ihnen nicht erlauben, die Einstellungen willkürlich zu ändern. Das heißt, dies ist eine ziemlich trostlose Arbeit, die in unserem Unternehmen ursprünglich von einem großen Init-Skript ausgeführt wurde, das all dies konfiguriert hat. Aber natürlich müssen wir manchmal zur Laufzeit in der Produktion Änderungen vornehmen.







Es ist manchmal schmerzhaft, weil Sie diese Struktur fast von Hand sortieren müssen - um einige Schnittstellen zu zerlegen, wieder zusammenzusetzen, und das ist natürlich alles mit Fehlern behaftet. Wenn Sie bei Cisco arbeiten, ändern Sie die Einstellungen, und die Shell kümmert sich um alles, und dann wird eine Art Arbeit auf niedriger Ebene ausgeführt.







Nun, danke für die Tatsache, dass wir Perl haben - wir haben ein Skript mlxrtr geschrieben, das eine solche Konfiguration verwendet und Befehlssätze für die Konfiguration des Netzwerks und alles andere generiert. Außerdem werden Änderungen unterstützt. Wenn Sie Änderungen vornehmen, wird Ihre aktuelle Konfiguration unter Linux gelesen und es wird angezeigt, was getan werden muss, um den gewünschten Status zu erreichen.







Wenn Sie diese Konfiguration ausführen, werden zunächst solche Befehle für Sie generiert, und ich habe auch dieselben Befehle ausgegeben.











Es gibt einige Befehle, aber im Allgemeinen kann es mehr oder weniger unterstützt werden, wenn Sie es in Ihrem Init-Skript haben.







Wenn Sie beispielsweise einen Port auf eine andere Verbindung umschalten müssen, müssen Sie diesen Port von der alten Verbindung trennen, die neue Verbindung von der Brücke trennen, dann den Port mit dieser Verbindung verbinden, die Verbindung zur Brücke zurückgeben und die darauf befindlichen vlans neu konfigurieren im Allgemeinen eine ziemlich trostlose Arbeit und es ist natürlich unangenehm, sie mit den Händen zu machen. Das Skript erledigt dies alles von selbst.







Des Weiteren. ACL ist konfigurierbar ... Sie können iptables verwenden, es wird jedoch nicht entladen - Sie können es nur zum Filtern des Verkehrs auf Steuerebenen verwenden. Und wenn Sie in der Datenzeile filtern möchten, müssen Sie im Fall von Switchdev den TC-Filter verwenden. Und hier ist zu beachten, dass der TC-Filter bereits nicht nur den gerouteten, sondern auch den geschalteten Verkehr filtert. Außerdem kann der TC-Filter nur an physischen Ports aufgehängt werden. Wenn Sie also mit VLANs arbeiten, müssen Sie hier komplexere Konstruktionen ausführen. Aber es gibt dort interessante Funktionen, zum Beispiel können Sie einen solchen Block an mehrere Schnittstellen hängen und sie fummeln (im Sinne einer gemeinsamen Nutzung) an einem gemeinsamen Filter herum. Es gibt auch einen goto-Operator in den tc-Regeln, der auch ziemlich cool ist und es Ihnen ermöglicht, im Gegensatz zu Cisco oder Arista nichtlineare acls zu erstellen.







Hier haben wir auch ein Dienstprogramm zum Konfigurieren von acl - mlxacl. Wir arbeiten hauptsächlich mit vlans auf der dritten Ebene und das Dienstprogramm arbeitet so, dass es für jedes vlan eine separate Kette erstellt und in der Hauptkette einfach mit vlans übereinstimmt und zur entsprechenden Kette für dieses vlan wechselt.







Auch hier gibt es ein Beispiel für eine solche Konfiguration - solche Befehle sind das Ergebnis. Es gibt weniger davon als bei der Konfiguration des Switches selbst, da eine Regel ungefähr einem Befehl zugeordnet ist - nicht so schwierig.







Wenn Sie jedoch Änderungen vornehmen müssen - in diesem Fall habe ich eine Regel gelöscht, und das Dienstprogramm führt alles so aus, dass alle geänderten Ketten neu geschrieben werden. Anschließend wird es in der Null-Hauptkette neu nummeriert, sodass sie auf neue Ketten verweisen. Und es ist klar, dass es in diesem Fall mit manueller Arbeit möglich wäre, es in einem Befehl zu lösen.







Aber dafür müssen wir zuerst den aktuellen Status betrachten und so sieht die tc-Filterausgabe aus - es ist ziemlich schwierig, damit zu arbeiten.







Wenn Sie mit all dem arbeiten, sehen Sie die Passanten so an. Deshalb haben wir dieses Dienstprogramm - mlxacl - zuerst geschrieben, weil es viel schmerzhafter war, damit zu arbeiten, und dann Wort für Wort und für die restlichen Einstellungen haben wir auch das Dienstprogramm geschrieben.







Diese Dienstprogramme, von denen ich Ihnen erzählt habe, haben wir auf Gitlab veröffentlicht - Sie können sie verwenden. Sie sind unter MIT lizenziert und entsprechend frei verfügbar.







Natürlich ohne Garantie. Dies sind ein paar Perl-Skripte (die Ihre Fragen vorwegnehmen - weil ich Perl kenne und es funktioniert einfach), relativ klein, fast ohne Abhängigkeiten - es werden natürlich ein paar Perl-Module verwendet, die in der Standard-Perl-Distribution und den Linux-Dienstprogrammen enthalten sind.







Wenn Sie ein wenig mit einer seriellen Konsole mit COM-Anschlüssen gearbeitet haben, möchte ich Ihnen einige Ratschläge geben. Wenn zum Beispiel jemand dachte, es wäre eine Möglichkeit, Vim zu verlassen, hätten Sie es fast erraten.







Für einige BIOS entspricht dies Strg + Alt + Entf, da sie es über die serielle Schnittstelle wahrnehmen. Das heißt, wenn Ihr Bootloader zum Beispiel hängt und Sie den Switch irgendwie neu starten müssen, können Sie ihn verwenden.



Wenn es um den Kernel geht, fängt er natürlich die Arbeit mit der Tastatur ab. Hier sollten Sie also besser die Befehle Ihres SysRq-Kernels akzeptieren lassen - andernfalls ist es schwierig, den Switch neu zu starten. Und im Fall von SysRq wird dort PrintScreen verwendet, wenn Sie mit einer Tastatur und einem normalen Terminal arbeiten, und im Fall einer seriellen Konsole mit COM-Anschluss müssen Sie ein spezielles Unterbrechungssignal senden - im Minicom ist es Strg + F, im Bildschirm ' e Strg + A, Strg + B, und erstellen Sie dann einen speziellen SysRq-Schlüssel.



Und um beim Booten in das BIOS zu gelangen - natürlich in das BIOS des Switches, denn wie bei einem normalen Computer gibt es ein BIOS, über das es normalerweise bootet - können Sie Strg + B drücken.



Das ist alles, was ich dir kurz sagen wollte. Bei Fragen stehe ich Ihnen gerne zur Verfügung.







Englische Version der Publikation.



All Articles