Der Linux Netzwerk Stack
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Part Number | 59 | |
Number of Parts | 79 | |
Author | ||
License | CC Attribution 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/19574 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
LINUXStack (abstract data type)Local area networkDatabaseBefehlsprozessorIPSecTraffic shapingVolumetric flow rateComputer hardwareEthernetDesktopRouter (computing)Server (computing)Datei-ServerLINUXProzessorSmart cardCommunications protocolComputer hardwareDatabaseServer (computing)DesktopRouter (computing)XMLUMLLecture/ConferenceComputer animation
01:09
BefehlsprozessorLINUXTINA <Telekommunikation>Query languageTraffic shapingSpeciesAlgorithmVolumetric flow ratePower (physics)Lecture/Conference
02:02
RSS <Informatik>Queue (abstract data type)TransmitterMoment (mathematics)Programmer (hardware)Computer animation
02:46
RSS <Informatik>Interrupt <Informatik>Kernel (computing)Perturbation theoryAPPELL <Programm>Interrupt <Informatik>Lecture/ConferenceComputer animation
03:53
Kernel (computing)BefehlsprozessorStylus (computing)Device driverQueue (abstract data type)Interrupt <Informatik>Device driverProfessional network servicePhysical quantitySet (mathematics)SoftwareFunction (mathematics)Queue (abstract data type)Programmer (hardware)Scheduling (computing)FunktionalitätLecture/ConferenceComputer animation
07:18
Interrupt <Informatik>Mischung <Mathematik>Scheduling (computing)Device driverFunction (mathematics)Interrupt <Informatik>Application softwareComputer animation
08:44
Interrupt <Informatik>Mischung <Mathematik>INGA <Programm>Computer wormQuery languageInterrupt <Informatik>Lecture/Conference
09:57
Device driverComputer hardwareRSS <Informatik>Interrupt <Informatik>Queue (abstract data type)BefehlsprozessorEthernetComputer hardwareHauptspeicherDevice driverSmart cardComputer animation
10:52
Block (periodic table)Device driverEthernetBefehlsprozessorComputer hardwareInterrupt <Informatik>RSS <Informatik>Cellular automatonAPILink (knot theory)Smart cardComputer hardwareInternetDevice driverMechanism designLastteilungBit rateTCP/IPInterrupt <Informatik>Lecture/Conference
11:52
Device driverData structureComputer hardwareLengthComputer animation
12:41
Device driverComputer hardwareInterrupt <Informatik>Sound effectLecture/Conference
13:43
Computer hardwareAtomic nucleusStack (abstract data type)IP addressData conversionSound effectAgreeablenessComputer animation
15:16
Device driverNetwork socketComputer hardwareFeedbackPerimeterCommunications protocolHand fanInternetUDP <Protokoll>Queue (abstract data type)TCP/IPIP 6Lecture/Conference
17:44
Data structureKernel (computing)AllokationUDP <Protokoll>Local ringImplementationMetadataData structureNetwork socketContent (media)HexagonDevice driverComputer animation
18:50
AllokationLocal ringMetadataMenu (computing)Data structureProgrammer (hardware)LengthDevice driverPhysical quantityLecture/Conference
20:15
Network socketStack (abstract data type)EmpennageDevice driverUDP <Protokoll>Hausdorff spaceStack (abstract data type)Computer animation
21:03
Menu (computing)Network socketInformationQueue (abstract data type)IPSecSet (mathematics)DeciphermentAdditionFirewall (computing)Professional network serviceALT <Programm>Lecture/Conference
22:33
Computer scienceRamificationJames <Programm>Router (computing)Computer animationProgram flowchart
23:51
RoutingNetwork socketRouter (computing)InformationProgrammer (hardware)CASHELecture/Conference
25:18
Plane (geometry)Computer animation
26:03
Limit (category theory)Communications protocolSoftwareContent (media)UDP <Protokoll>RamificationSound effectQueue (abstract data type)Lecture/Conference
28:28
Computer hardwareDevice driverSet (mathematics)Computer animationProgram flowchart
29:23
Device driverDevice driverLimitierungsverfahrenComputer fileStack (abstract data type)Professional network serviceLecture/ConferenceComputer animation
30:55
InformationIP addressDurchschlagComputer hardwareStack (abstract data type)Lecture/Conference
31:40
Device driverGame theoryGeometryDevice driverComputer hardwareStack (abstract data type)Data structureInformationSoftwareInterface (computing)Function (mathematics)Programmer (hardware)Abstract machineComputer animationLecture/Conference
35:45
Computer hardwareDevice driverEngineering drawingDiagramLecture/Conference
36:42
Hash functionBefehlsprozessorRSS <Informatik>Interrupt <Informatik>Hash functionComputer hardwareApache <Programm>ProzessorDesktopTuningDigital filterProgrammer (hardware)Parallel programming modelComputer animation
38:21
BefehlsprozessorProzessorPlane (geometry)Structural loadLecture/Conference
39:10
BefehlsprozessorScalabilityVirtualizationGooglePatch (Unix)Direction (geometry)Computer hardwareNetwork socketFlagScalabilityComputer virusComputer animation
40:32
ScalabilityWorld of WarcraftOperating systemSwitch <Kommunikationstechnik>ScalabilityCodeInterface (computing)Professional network serviceVirtualizationOverhead (computing)Network socketComputer hardwareMachine codeDevice driverListe <Informatik>InformationEnergy levelCompilerSoftwareMilitary operationLINUXSoftware developerRouter (computing)Stack (abstract data type)Switching <Kommunikationstechnik>Mountain passMainframe computerSpoke-hub distribution paradigmLecture/Conference
47:16
Computer hardwareKernel (computing)NumberIntelBenchmarkPropositional formulaInterrupt <Informatik>LINUXDevice driverCodeOverhead (computing)IPSecCache (computing)Monster groupSpeciesImplementationALT <Programm>FunktionalitätLösung <Mathematik>Lecture/Conference
54:00
Lecture/ConferenceComputer animation
Transcript: German(auto-generated)
00:08
Vielen Dank. So, mal zur Einstimmung. So ein paar etliche Probleme, die Linux ganz generell hat, die gelten natürlich auch im Speziellen für den Netzwerkstack, also zum Beispiel halt die Hardware. Das soll ja gescheit funktionieren,
00:22
sowohl auf einem Mobiltelefon als auf irgendeinem Server mit 64 oder sogar noch mehr Prozessoren. Dann haben wir ganz verschiedene Übertragungstechniken, wir müssen uns rumschlagen mit 56 Gigabit Ethernetkarten und bald auch 100 Gigabit Ethernetkarten. Dann gibt es allerdings auch Wireless-Larn, es gibt langsame
00:41
Verbindungen, die wir noch unterstützen müssen und sogar ganz archaische Protokolle. Und dann gibt es auch der Einsatzzweck, immer eigentlich nicht vorhersehbar als Entwickler, weil wir wissen ja nicht, ob das dann irgendwann mal ein Desktop ist oder als Embedded-Gerät läuft oder ob das ein Router ist oder ein Paketfilter oder eine Bridge oder was auch immer und
01:02
selbst wenn es gesagt wird, dass das ein Server-Einsatz ist, dann ist Server nicht gleich Server, weil ein Datenbankenserver zum Beispiel, der kriegt immer sehr vielen Request-Response-Type-Traffic, das heißt, es wird eine Verbindung aufgebaut, dann wird eine Query geschickt und dann wird schnellstmöglich eine Antwort erwartet. Das ist natürlich ein völlig anderes
01:20
Anforderungsprofil als zum Beispiel ein NFS-Dateiserver, der halt hauptsächlich sehr schnell und dauerhaft Hochlast ausliefern soll. Das heißt, im Endeffekt will man eigentlich vom Netzwerksstack so die Eier legen, die wollen mich sau, man will eigentlich kriegen, Latenz, hoher Durchsatz, möglichst wenig CPU-Zyklen sollen dabei verbraucht werden und dann soll es
01:41
auch noch speicherbar sein, soll fair sein und ein großes Feature-Set brauchen wir auch, weil die Leute wollen IPsec, sie wollen NAT, dann wollen sie Traffic-Shaping machen können in allen verschiedenen Algorithmen und Arten und so weiter und so fort und das soll alles der Netzwerksstack leisten können und dann wollen wir uns mal anschauen, wie das denn so
02:02
funktioniert. Zuerst wollen wir uns mal damit beschäftigen, wie eigentlich ein Paket von der Netzwerkkarte bis zum Programm kommt, was Verarbeitungsschritte dabei durchlaufen werden und warum das so ist und dann schauen wir uns auch das inverse an, also wie findet eigentlich Übertragung statt von dem
02:23
Moment, wo ein Programm jetzt irgendwas sendet, bis es dann auf der Netzwerksschnittstelle rausplumpst. Dann schauen wir uns an, welche Tricks der Netzwerksstack so benutzt, um überhaupt moderne Netzwerkkarten auslasten zu können und dann ist es gar nicht mehr so einfach, ohne gewisse Kompromisse einzugehen.
02:47
Dann schauen wir uns an, welche Tricks der Netzwerksstack benutzen muss, um bestimmte Netzwerkprobleme wie zum Beispiel Bufferplot zu umgehen. Da erkläre ich noch, was das ist und zu guter Letzt runden wir das ab mit einem
03:02
Überblick über die aktuellen Hot Topics, wo gerade ganz besonders viel Entwicklungszeit darauf verwendet wird. So ein Paket kommt zum Körnern. Es gibt eigentlich nur drei Wege. Das erste ist Interrupt plus ein Backlog pro
03:21
CPU. Das ist so die traditionelle Methode, die allerdings heutzutage kaum noch benutzt wird. Wir schauen uns gleich im Detail an, wie das so theoretisch funktioniert, beziehungsweise wie die einfachen Treiber, die das benutzen, funktionieren. Dann der zweite Weg, das ist NAPI. Das ist eigentlich das, was alle machen und zu guter Letzt noch als neuere Exot dazu gekommen, eine
03:46
Methode, die extrem die Latenz reduzieren soll, allerdings auf Kosten von CPU-Zyklen. Da wird dann also aktiv immer nachgefragt, hast du ein Paket, hast du ein Paket, hast du ein Paket. Ein ganz einfacher Netzwerktreiber
04:03
nutzt eben diese erste Methode. Das heißt, das wird über Interrupt Handling gemacht. Solche Netzwerkkarten sind eigentlich heutzutage immer noch verbreitet, zumindest im SoC-Umfeld, wo man eben nicht viel Platz hat auf dem Die oder überhaupt wenig Raum
04:23
hat. Und dann hat man eben sehr einfache Bausteine, also auch aus Kostengründen. Und die können dann zum Beispiel immer nur ein oder zwei Pakete überhaupt annehmen, bevor sich der Treiber wegräumen muss. Und dann funktioniert das ganz einfach. Der Treiber, der registriert
04:41
einfach einen Interrupt-Händler und sobald dann ein Paket empfangen worden, das in der Karte quasi abholbereit bereit liegt, dann feuert dieser Interrupt. Und wenn der Colonel dann diesen Interrupt-Händler dann aufruft, dann muss der eine ganze Menge Arbeit machen, zum Beispiel das gesamte Paket erstmal aus dem Hardware-Speicher rauskopieren. Und da
05:05
man allerdings in einem Interrupt-Händler nicht so viel Arbeit machen sollte, weil sie halt eben immer die Arbeit unterbrechen, wird dann eben, nachdem das Paket rauskopiert worden ist, erst mal das Ganze auf eine Warteschlange geschoben und dann erst später weiterverarbeitet
05:25
außerhalb von diesem Hard-IHQ-Kontext. Und das passiert über sogenannte Soft-IHQs. Die muss man leider ein bisschen ausholen, weil Soft-IHQs sind etwas sehr archaisches. Das kommt aus den Uhrzeiten des Linus-Curnals. Manchmal hört man auch in der Literatur den Begriff
05:41
Bottom-Half. Und in vielen Funktionsnamen im Colonel gibt es immer noch diesen Unterstrich BH, so fix bei manchen Funktionen, die mit Soft-IHQs zu tun haben. Gewissermaßen ist das einfach eine Funktionalität des Kernels, die zu bestimmten Zeitpunkten ausgeführt wird und zwar am
06:03
Scheduler vorbei und auch wesentlich häufiger als das Scheduler. Es wird nicht nur vom Netzwerksubsystem benutzt, sondern es benutzen auch andere Sachen. Also das Blocklayer benutzt es zum Beispiel auch, Timer nutzen teilweise Soft-IHQs und so weiter. Die werden eigentlich immer dann ausgeführt, wenn ein Hardware-Interrupt fertig ist. Dann wird einfach
06:22
geschaut, hat irgendjemand Arbeit für mich reingekippt und wenn ja, dann läuft immer so ein Soft-IHQ los. Der Vorteil ist, dass während ein Soft-IHQ läuft Hardware-Interrupts freigegeben sind. Das heißt also, wenn dann zum Beispiel jemand das auf der Tastatur macht, dann kann der Tastatur-Interrupt verarbeitet werden, weil er eben höhergewichtiger ist
06:41
als so ein Soft-IHQ. Der Nachteil an Soft-IHQs ist, dass halt die CPU trotzdem immer noch, also aus Sicht vom Scheduler oder vom Benutzerprogramm, immer noch zu undefinierbaren Zeitpunkten geklaut wird. Also irgendein Prozess wird halt, wenn der Soft-IHQ halt gerade anläuft, erst mal präemptet. Und deswegen gibt es da auch
07:03
noch einen sogenannten Car-Soft-IHQ. Da komme ich noch später drauf, was das ist. Das haben vielleicht manche schon in Top gesehen, wenn irgendwie viel Netzwerklast ist, dass da dann dieser ominöse Car-Soft-IHQ-ID ganz viel CPU-Zeit klaut. Ein weiteres Problem von
07:21
Interrupts ist und warum wir die eigentlich fürs Netzwerksubsystem so gut wie gar nicht mehr benutzen, ist, wenn man halt plötzlich 100.000 oder gar auf 10 Millionen Pakete pro Sekunde verarbeiten will, dann will man nicht 10 Millionen Interrupts pro Sekunde verarbeiten, weil wenn man das macht, dann geht nichts mehr. Dann steht die Maschine, die abverarbeitet noch Interrupts und kein Benutzerprogramm
07:41
mehr, kriegt mehr die CPU und alles steht still. Also geht man dazu über, dass man ein Hybrid-Modell macht, bei dem quasi ein Interrupt immer nur ankündigt, dass demnächst Arbeit ansteht und dass irgendwelche Pakete zu verarbeiten sind, aber es wird nicht mehr pro Paket ausgelöst. Dafür gibt es eben dieses NAPI. Und ein neuerer
08:03
Treiber, der eben dieses NAPI benutzt, der hat auch einen sehr viel einfacheren Interrupt-Händler. Denn dieser Interrupt-Händler, der macht eigentlich nur zwei Sachen. Der tut erstens mal den Interrupt von der Netzwerkarte abschalten, dass die nicht mehr meckert. Und dann tut er eben so einen sogenannten NAPI-Cycle
08:22
vormerken. Und erst danach, wenn dann dieser Soft-Interrupt anläuft, erst dann wird eine dezidierte Funktion, die der Treiber registriert, aufgerufen und erst dies dann da überhaupt für zuständig, Pakete zu verarbeiten. Jetzt hat man immer noch das Problem, was mache ich jetzt, wenn
08:42
die Netzwerkarte unter Dauerlast steht, weil halt jemand irgendwie dauernd ein riesiger Dateiübertragung läuft. Das ist so gelöst, dass dieser Soft-Interrupt einfach eine Zeitbegrenzung hat. Das heißt also, wenn der einfach zu lange dauert, dann wird er abgebrochen mitten drin. Und dann wird es über diesen sogenannten Karsov-DQD gemacht.
09:02
Der Karsov-DQD, der ist eben aus Scheduler-Sicht ein ganz normales Programm. Das heißt, der steht auch unter Scheduler-Kontrolle und ich kann das mit Nice zum Beispiel als Benutzer auch in der Puertätliste nach oben und nach unten schieben. Deswegen, wer mal auf einem Netzwerkserver einen Top anschmeißt, der wird immer diesen nominösen Karsov-DQD
09:20
sehen, der da läuft. Und das ist eigentlich im Wesentlichen der Netzwerk-Stack, der da verarbeitet wird unter dem, unter diesem Prozess. Und wenn dann mal alle Pakete verarbeitet sind, dann werden Interrupts wieder angeschaltet, um dann eben den nächsten Abfragezyklus zu triggern. Was aber theoretisch auch gar nicht
09:42
passieren muss. Also wenn halt immer Pakete da sind, dann wird halt einfach immer nur der nächste Soft-Interrupt weiter geschedult und Interrupts haben dann gar nichts mehr zu sagen da. Neue Ethernet-Karten gibt es jetzt auch schon die
10:02
ersten angekündigt vor 100 Gigabit und die sind natürlich sehr viel komplexer als diese einfachen Karten, die es mal vor 15 Jahren gab und sind auch wesentlich komplexer vom Feature-Set her. Das gucken wir uns auch noch an. Und zwar sind
10:21
diese normalerweise so implementiert, dass sie so eine Art FIFO-Ringenpuffer haben und der Treiber dann pro Ringenbuffer-Element schon vorher einen Speicherblock allokiert und ist der Hardware mitteilt. Hier hast du einen Speicherblock und hier hast du noch einen Speicherblock und so weiter. Und die Hardware tut dann ohne die CPU direkt über das sogenanntes
10:41
DMA, also Direct Memory Access, direkt in den Hauptspeicher schreiben und das heißt die CPU ist da außen vor. Und viele Features sind heutzutage auch direkt in der Hardware abgebildet. Das heißt also zum Beispiel so Sachen wie TCP-IP oder Ethernet-Prüfung macht heutzutage eigentlich nie die CPU, sondern
11:01
das macht die Netzerkarte selber und in speziellen Register kann der Treiber dann zum Beispiel herausfinden, ob die Checksum ok waren oder eben nicht. Es geht sogar so weit, dass moderne Karten nicht nur eine Empfangs- und Sende-Q haben, sondern die haben 16, 32 oder so und haben dann pro
11:22
Q ein extra Interrupt. Und dann gibt es so ein Mechanismus, das heißt RSS, Receive Site Scaling, das kommt auch noch, um dann zum Beispiel zu sagen, diese CPU verarbeitet nur Pakete von dieser Q und diese andere CPU nur von Jena. Da geht es
11:40
halt um Skalierung und Lastverteilung. Und sie benutzen eben alle, ohne Ausnahmen NAPI, weil ohne das könnte man gar nicht solche Datenraten erreichen. Das ist mal so vereinfacht dargestellt, so ein RX-Ring auf der Netzerkarte. Im Wesentlichen ist das, wie ich schon gesagt habe, einfach ein Array aus, wenn
12:05
man so will, einer Datenstruktur, was aber im Endeffekt nur Register auf der Hardware sind. Dort stehen dann so Sachen drin, wie die Speicheradresse, wo das Paket abgelegt werden soll, die Länge von dem Paket, die die Hardware empfangen hat, die Checksumme, dann
12:22
gibt es Statusregister, in denen dann drin steht, ob zum Beispiel hier gerade ein Paket empfangen wurde auf dem Skriptor oder eben noch nicht. Es gibt Fehlerregister, in denen dann Sachen drin stehen, wie Checksumme ist ungültig oder kein gültiger Hader oder sonst irgendwelche Fehler. Und das ist auch, wie gesagt, das ist
12:41
komplett abhängig von der Hardware und das muss dem jeweiligen Treiber implementiert werden. Und das heißt, immer wenn so ein NAPI-Zyklus anläuft, dann guckt einfach der Treiber am nächsten Array-Eintrag nach, ob in diesem Status-Flag irgendwas gesetzt ist, von wegen ich habe ein Paket und wenn ja, dann geht es weiter und wenn
13:03
eben nicht, dann stelle ich wieder die Interrupts ein und dann ist der Zyklus beendet. Und diese Register, die sind auch alle magisch in dem Sinne, dass die Hardware die selber ausfüllt und der Treiber damit eigentlich gar nichts zu tun hat. Das einzige, was der Treiber im Endeffekt halt macht, ist, er muss halt Speicherblöcke allokieren und
13:21
der Hardware mitteilen, welche er reserviert hat und er muss der Hardware auch wieder mitteilen, wenn er zum Beispiel die Hardware signalisiert hat, dass da ein Paket ist, dann muss der Treiber, nachdem die Verarbeitung erfolgt ist, auch sagen, jetzt ist dieser Eintrag, den kannst du jetzt wieder benutzen, um das nächste Paket zu empfangen. Das ist eine
13:44
auch vereinfachte Darstellung vom Empfangstack und da sehen wir jetzt auch schon eigentlich so die ganzen Protokoll-Schichten, die wir so im Kern haben. Also man sieht so im Endeffekt dieses NAPI-Poll da oben, das ist so eigentlich der
14:01
Einsprungspunkt direkt vom Softwareco-Händler. Der ruft eine Treiberfunktion auf, die dann eben pro Hardware speziell ist, wo dann eben die exakte Hardware eben in die Hardware-Queues reinguckt und sich dort Pakete abholt und dann wird es
14:21
in diesem Kontext eben so nach und nach durch den Stack geschickt. Ganz vorne als allererstes gibt es die Marketsockets, das ist zum Beispiel TCP-Dump oder heutzutage benutzt man auch Wireshark, das nutzt das. Das ist auch ziemlich logisch, dass das am Anfang ist, weil man will ja, wenn man sowas benutzt, dann debugt man meistens irgendwelche Probleme und dann will man natürlich, dass es
14:41
möglichst früh, möglichst direkt nach der Netzwerkkarte sitzt, damit man auch möglichst an exakt die Daten rankommt, die tatsächlich empfangen wurden und nicht vielleicht irgendwas, was erst später schon verfälscht wurde durch Netzwerkadresse Umsetzung oder sonst was. Danach kommen dann verschiedene Module, um zum Beispiel Traffic Shaping oder Traffic Policing zu machen, also
15:01
Traffic Control, der sich schon mal benutzt hat, sitzt in dem Pfad drin. Dann jetzt künftig auch NF-Tables hat jetzt auch einen Hook bekommen, um eben auch Firewalling auf Device-Ebene zu machen. Danach kommt etwas, das nennt sich RX-Handler. Das wird benutzt, um logische Devices abzubilden, die es nicht in
15:21
Hardware gibt, also zum Beispiel Bridges oder wenn man mehrere Netzwerkkarten in den Bond konfiguriert hat, sodass sie halt als logisch ein Gerät funktionieren sollen. Dann werden Pakete dort umgeleitet in so einen speziellen Treiber, der dann zum Beispiel Bridging-Funktionalität implementiert und dort gibt es dann auch eine Rückkupplung. Das
15:40
ist auch ähnlich so wie bei dem Storage-Vortrag, den wir vorhin gehört haben, also wo manche Storage-Funktionalität dann auch wieder extra auf einen anderen Treiber umsetzen will. Das ist ähnlich, das heißt, wenn ein Paket empfangen wird und das Gerät, das es empfangen hat, steckt in der Bridge, dann wird das
16:00
Paket an den Bridging-Treiber geschickt, dann musst du ja nachgucken, ist das eine lokale Mega-Adresse, ist das vielleicht meine eigene und wenn es die eigene ist, dann muss ich das ja in den Host-Stack zustellen und das funktioniert dann so, dass das Paket einfach wieder zurückgeschleust wird in den Empfang-Stack, um dann eben das Paket weiter verarbeiten zu können und dann eben dann später bei zum
16:21
Beispiel TCP-IP vorbeizukommen. Und wenn es halt zum Beispiel eine normale Netzwerk- Karte ist, die jetzt nicht gerade halt irgendwie so ein virtuelles oder logisches Gerät konfiguriert hat, dann werden danach die speziellen Protokoll-Handler durchlaufen, also zum Beispiel steht da eine Misanet-Paket drin, was der nächste
16:40
Protokoll-Handler ist, also zum Beispiel IP oder IPv6 oder was ganz anderes und dann hat der Colonel da eben halt so eine Liste aus Protokollen, die er halt eben kennt und dann findet er eben das Richtige raus und falls keiner da ist, dann wird das Paket auch weggeschmissen. Also das fehlt ja eigentlich noch, also hier ist eigentlich noch der Drop-Fällig, wenn halt kein Treffer da ist. Und dann wird es halt eben
17:01
verzweigt, also zum Beispiel wenn ich jetzt ein IPv4-Paket empfange habe, dann geht es dann ins IPv4-Modul und wenn das muss, dann halt gucken, was ist das nächste Hörer-Protokoll und dann geht es halt irgendwann an TCP oder UDP oder was auch immer, was da registriert ist. Und was vielleicht auch ganz interessant ist aus Netzwerk-Stack-Sicht, es endet immer in einer Queue,
17:21
nämlich der Queue vom Socket, im Normalfall zumindest, also von dem Nutzerprogramm, was das empfangen will und es beginnt in einer Queue. Also das eigentliche, das zentrale Augenmerk eigentlich des Linux-Netzwerk-Stack ist, dass er mit dem Gedanken entworfen wurde, dass ein Paket immer irgendwo gequeued werden muss, irgendwann. So, wir haben jetzt
17:46
gesehen, wie das Paket durch den Netzwerk-Stack durchläuft, aber dafür brauche ich ja noch ein bisschen mehr Extra-Informationen, also zum Beispiel hat ein Paket der nicht nur das, was eigentlich über das Netzwerk übertragen wurde, sondern da gibt es ja ganz viel Kontext, den ich
18:00
brauche, um so eine Verarbeitung machen zu können. Ich muss wissen, über welches Interface kam das Paket rein. Ich muss wissen, zu welchem Socket gehört das. Dann gibt es irgendwelche Sondersachen, die ich beachten muss. Und dafür benutzt der Kernleiter das heißt SKB. Das ist so die zentrale Datenstruktur im ganzen Netzwerk-Stack, ohne die auch wirklich gar nichts
18:20
geht. Und die ist sogar so wichtig, dass die sogar direkt dem Netzwerk-Treiber allokiert wird. Also immer, wenn ein Paket empfangen wird, muss der Treiber so ein SKB, so ein SKB-Datenstruktur allokieren und assoziert dann halt sozusagen die empfangenden Daten mit dieser Datenstruktur.
18:41
Und sendeseitig ist es genau umgekehrt. Das heißt, dort tut dann quasi das erste Protokoll, was sich mit den Nutzerdaten auseinandersetzt, diese Datenstruktur allokieren. Was auch sehr wichtig ist, dieser SKB wird auch benutzt, um halt Fairness sicher zu stellen. Also wenn ich zum
19:01
Beispiel mehrere Programme habe auf meinem Computer, eins schickt viel Daten, eins schickt wenig Daten, dann will ich ja nicht, dass ein Programm, das sehr viel schickt, den ganzen Speicher klauen kann. Das heißt, ich muss Accounting machen. Und da ich auch nicht weiß, zum Beispiel im Treiber, im Vorfeld kann ich ja nicht wissen, ob jetzt das nächste Paket zehn Bytes enthält oder ein Kilobyte. Das heißt,
19:22
ich muss ja immer mit dem schlimmsten Fall rechnen, dass das Paket maximal groß ist und deswegen muss ich auch immer maximal große große Speicherblöcke allokieren. Das heißt also, wenn ein Paket nur 20 Bytes groß ist, kann es aber trotzdem sein, dass der Speicherbereich, in dem das Paket liegt, zwei Kilobyte groß ist in Wahrheit. Deswegen wird zum Beispiel auch in
19:40
dieser SKB-Datenstruktur nicht nur die Länge vom Paket vermerkt, sondern auch der True Size, also die echte Größe, also die gesamte tatsächliche Speicherressourcen, die momentan durch das Paket verbraucht werden. Also dazu gehört also auch die SKB-Datenstruktur selber, die ist nämlich auch ziemlich groß, also inzwischen auch über 200 Bytes und dazu
20:01
gehören dann eben auch der gesamte Backing-Speicherbereich, der benötigt ist. Wenn man sich das SKB-Dings mal anschaut, dann ist es auch so, dass während dieses Paket durch den Stack verarbeitet wird, in
20:22
diesem SKB sozusagen wie so eine Art Protokoll immer mehr Felder ausgefüllt werden durch den Stack. Also am Anfang ist das quasi alles leer und das Allererste, was eigentlich der Treiber noch macht, der tut hier dieses Data und dieses Het, das kann er noch assoziieren mit dem Beginn
20:40
von dem ganzen Paket. Aber der ganze Rest, also wo beginnt der Netzwerk-Heder, wo beginnt der TCP bzw. UDP-Heder und so weiter, das ist am Anfang alles leer und näherst dann werden die einzelnen Schichten quasi das Paket sehen und anfangen zu passen, füllen die dann quasi diese Offsets da aus in diesem SKB, sodass man dann halt irgendwann im UDP-Teil
21:04
ist, nicht mehr komplett neu passen muss, sondern man hat dann eben die passenden Offsets direkt verfügbar im Köln und kann dann halt sagen, ich brauche jetzt mal kurz den Netzwerk-Heder und dann kann ich direkt einfach schauen, wo beginnt denn das Ding? Das habe ich dann hier und dann kann ich einfach durch eine Addition
21:21
mit diesem Offset da rauskriegen, wo eigentlich der IP-Heder liegt, weil es eben schon gepasst wurde. Und außer den Offsets für Netzwerk-Heder sind da eben so ganz viele andere Sachen drin, also Routing- Informationen stecken da drin, wenn man IPSEC benutzt, stecken da die Informationen drin, wie Fähr- und Entschlüsselung passieren
21:41
soll. Der Socket wird drin gespeichert und so weiter und so fort, also es ist eine ganze Menge Zeug, auch Firewalling-Sachen werden drin gespeichert. Und auch, wie ich vorhin schon sagte, Hewing ist auch so ein zentraler Bauschwein. Sogar die ersten beiden Felder in diesem SK-Buff sind eigentlich speziell
22:01
für nächstes Element und vorheriges Element in der Liste vorgesehen. Das heißt also, diese SK-Buff-Datenschruktur, die ist auch so gemacht, dass sie quasi am Ende direkt in die Warteschlange vom Socket reingepackt werden kann, bis dann halt das Programm sich mal bequemt von dem Socket zu lesen.
22:24
So, das ist schematisch betrachtet ist das der IP-Stack. Ich hab das mal, vielleicht kennen ein paar IP-Tables, deswegen, die aus dem
22:41
IP-Tables-Programm bekannte Terminologie benutzt, also Pre-Routing, Forwarding und so weiter. Und das passt auch ganz gut, weil genau an diesen Stellen die gleichnamigen Chains aus dem IP-Tables-Tool sitzen. Das heißt also, im IP-Stack ist tatsächlich noch bevor geroutet wird, ist da eine Verzweigung drin und wenn
23:01
ein IP-Table aktiv ist, dann wird erst mal umgebogen und dann wird geschaut, gibt es denn irgendwelche Nat-Konfiguration, die da ist und so weiter. Dann ist es eines der ersten Sachen, die der IP-Stack machen muss, ist zu schauen, ist das Paket überhaupt für mich oder muss ich das vorwarten oder ist es ungültig oder sonst was?
23:23
Und dann wird eben ein Routing-Look abgemacht. Das heißt, der muss nachschauen. Hab ich überhaupt eine Route dafür? Und wenn ja, ist die lokal oder ist die für irgendwas anderes? Und dort gibt es dann eben die erste Verzweigung. Ist es für einen lokalen Prozess, dann wird es eben in die Input-Schleife umgeleitet oder wenn es gevorwartet werden soll,
23:41
dann geht es in die Vorwarting-Logik. Und für einen lokalen Prozess ist es ähnlich, auch wenn der Daten schicken will. Ist am Anfang immer erst mal ein Routing-Look ab, auch wenn es dadurch vereinfacht wird, dass dieses Routing-Look ab eigentlich immer nur einmal gemacht wird. Zum Beispiel bei TCP, wenn ich einen Connect,
24:01
also wenn ein User-Space-Programm einen Connect macht und sich verbinden will, sondern man host, dann wird eigentlich nur einmal dieser Routing-Look abgemacht und danach wird das Resultat, merkt sich der Colonel direkt im Socket und schaut dann danach immer nur nach, ob sich vielleicht Routing-Informationen seit dem letzten Mal geändert haben. Und wenn nicht, dann wird da nicht jedes Mal einen neuen Routing-Look abgemacht, sondern nutzt halt einfach
24:20
das letzte bekannte Resultat, um halt zu erfahren, über welchen Farb das Paket irgendwie versendet werden soll. Bis dahin Fragen. Ja, die Frage ist, ob man diese Informationen
24:40
irgendwie vom Socket abfragen kann. Geht es jetzt speziell um die gecashten Routen oder? Nein, also es geht meines Wissen nach kann man nicht direkt aus dem User-Space rausfinden, welche Routen dezidiert in dem Wo gecasht sind. Es gibt IP-Nail-Cache, den kann man sich über das IP-Tool raus ausgeben lassen,
25:01
aber für die im Socket gecashten Information ist mir nichts bekannt. So jetzt wollen wir uns mal anschauen, wie der Versand funktioniert. Es wird nämlich sogar etwas komplexer als für den Empfang,
25:22
weil es gibt tatsächlich sehr viele Methoden, wie ein Paket überhaupt zur Netzerkarte gelangen kann. Also das Einfachste ist, das Programm sendet einfach was. Aber außerdem gibt es halt eben noch sehr viele andere Sachen, wie ein Sendevorgang ausgelöst werden kann. Das Häufigste dürften eigentlich sogar die Timer sein.
25:40
Also gerade zum Beispiel TCP muss ich ja Pakete so lange merken, bis von der Gegenstelle eine Empfangsbestätigung vorliegt. Und daher ist es dann tatsächlich so, dass wenn ein Programm was sendet und beim TCP sorge, dass das TCP nicht direkt ein neues Paket generiert,
26:00
sondern es guckt nach, ob vielleicht sogar noch ein unverschicktes Paket in der lokalen Queue rumliegt. Und wenn ja, dann wird es immer versuchen, da noch die Daten irgendwie ran zu fummeln. Dann gibt es bei TCP zum Beispiel Window Probing, dass wenn zum Beispiel die Gegenstelle mal gesagt hat, ich kann jetzt gerade keine Daten mehr annehmen, dann muss man halt hin und wieder mal
26:21
nachschauen, wie es denn so aussieht. Also das wird auch über Timer gemacht. Dann kann es direkt über aus dem Receive Kontext passieren. Also wenn ich zum Beispiel den Fall habe, dass Pakete einfach weitergeleitet werden, weil es zum Beispiel eine Bridge ist oder eben IP-Vorwarte gemacht wird, dann nehme ich ja im Endeffekt, mache ich ja gar nichts anderes als auf dem einen Interface
26:41
Pakete anzunehmen und sie auf der anderen Seite wieder rauszuschicken. Und dann gibt es noch ein Transmitsoft-IRQ, was hauptsächlich dann benutzt wird, wenn eine Netzwerkschnittstelle komplett überlastet ist und keine weiteren Pakete annehmen kann für eine Zeit. Dann kommt etwas zum Tragen. Das nennt sich Queuing Disk
27:00
oder Queue Disziplin, wo dann Pakete eben noch mal für das Gerät speziell zwischengespeichert werden. Und dann wird so ähnlich wie das beim NAPI RX passiert, wird das dann halt eben auch für TX gemacht. Das heißt, man stopft da quasi seine SKB-Datenstrukturen in diese Queue Disk rein und dann sagt man zum TX-Soft-IRQ,
27:21
schau mal nach, ob wieder was geht, wenn du das nächste Mal läufst. Und schematisch würde das in etwa so aussehen. Ist auch wieder ein bisschen vereinfacht, aber es reicht für unsere Zwecke. Also da ganz unten ist quasi der Zeitpunkt, wo ein Programm sagt, ich will jetzt mal was schreiben
27:41
und dann guckt der Körner eben anhand von der Pfeilskriptornummer, dass er das einzige aus der Körner eigentlich hat, findet er dann halt zum Beispiel raus, das ist jetzt, gehört jetzt zur IP-Familie zum Beispiel. Und dann wiederum gibt es eine Verzweigung abhängig von dem Protokoll-Typ
28:01
in zum Beispiel UDP oder TCP. Und erst an dieser Stelle wird jetzt so eine SKB-Datenstruktur allokiert und mit den mit den Daten, die dann aus vom Userspace reinkopiert werden, assoziiert. Und dann beginnt quasi wieder dieses Ausfüllen von diesem von diesem SKB-Protokoll. Das heißt also,
28:22
hier wird dann der TCP-Hetter hinzugefügt. Dann im nächsten Schritt wird der IP-Hetter angefügt und so weiter. Und irgendwann landet es dann beim Netzwerk Core. Und der tut dann auch verschiedene Dinge, was dann wiederum unabhängig ist vom eigentlichen Protokoll. Also es spielt dann keine Rolle mehr, ob das ursprünglich
28:40
aus dem TCP-IP-Layer kam oder ob das TIP-C ist oder Stream-Control oder sonst was. Das ist an der Stelle dann wieder einheitlich. Da gibt es dann im Endeffekt die drei Möglichkeiten. Jemand debackt gerade und hat TCP dann laufen oder Wireshark, dann muss das halt da noch zugestellt werden. Oder aber
29:00
ich habe jetzt eine Netzwerkschnittstelle, die kann weiterhin Pakete annehmen. Dann geht es direkt über den Treiber und der Treiber schiebt es direkt zur Hardware. Oder aber die Hardware ist total überlastet. Oder aber der Nutzer sagt z.B. Hey, ich will aber, dass über diese Netzwerkschnittstelle nur maximal zwei MBit pro Sekunde rausgesendet werden darf.
29:21
Dann kann der Nutzer nämlich auf der Netzwerkschnittstelle mit dem Programm TC sogenannte Q-Discs konfigurieren um dann zum Beispiel so eine Ratenlimitierung umzusetzen. Und wenn so was aktiv ist oder die Netzwerkschnittstelle überlastet, dann geht es eben nicht direkt über den Treiber, sondern muss ich tatsächlich erst mal zur Q-Disc
29:41
und die Q-Disc speichert es dann erst mal zwischen. Und dann wird über spät zu einem späteren Zeitpunkt über so ein TX Software Q erneut versucht, irgendwas zu senden. Jetzt kommen wir zu so ein paar
30:00
Stack Features, die für Performance benutzt werden. Das bekannteste ist vielleicht GSO oder GHO, wer sich irgendwie professionell mit Administrationen von den NUC-Systemen auseinandersetzt, der hatte da vielleicht sogar schon unliebsame Begebungen mit dieser Technik. Das ist nämlich tatsächlich so, dass aus der Sicht des Netzwerksdecks
30:21
ein SKB nicht dasselbe ist wie ein Paket, sondern diese körnelseitige Repräsentierung von dem SKB kann tatsächlich in der Übertragung von sehr viel mehr Paketen resultieren, weil so ein SKB, der kann bis zu 64 Kilobyte groß werden. Das hat einfach folgenden Hintergrund.
30:40
Wir wollen ja nicht, wir wollen halt vermeiden, dass wenn wir jetzt zum Beispiel eine große Datei über eine Netzwerksschnittstelle rausschicken wollen, die zum Beispiel eine MTU von 1500 hat, dann wollen wir natürlich möglichst wenig diesen ganzen diesen ganzen Trip da durch den durch den durch den Stack da machen.
31:01
Also da wollen wir halt die Anzahl an Trips, die wir halt hier durch, die wir uns da durchhangeln müssen, die wollen wir natürlich reduzieren. Und eine einfache Möglichkeit, das zu machen, ist es halt, dass man halt nicht ein logisches, also ein echtes Paket hier durchreicht, sondern man tut so eine Art Superpaket durchreichen,
31:21
was zwar die richtigen Header-Informationen hat, also richtige IP-Adresse, richtigen diese Peapod-Informationen und so weiter, aber das Paket ist halt viel, viel größer als das, was die Netzwerkkarte eigentlich versenden kann. Und der Trick ist dann halt eben, dass die Hardware sogar möglichst viel
31:42
von dem Protokoll verstehen kann, um damit was anzufangen. Also im Idealfall, also aus Netzwerksdecksicht wäre der Idealfall, dass die Netzwerkkarte das sogenannte TSO unterstützt. Das steht für TCP Segmentation Offload und das bedeutet nichts anderes, als dass die Netzwerkkarte in der Lage sein muss, so ein großes Paket zu zerstückelen
32:01
in einzelne, einzelne Pakete, die sie versenden kann und gleichzeitig auch so viel von dem Protokoll verstehen muss, dass sie halt diese ganzen Header-Informationen auch korrekt duplizieren kann. Das heißt, die Netzwerkkarte muss in der Lage sein, zum Beispiel TCP Check-Zooming zu berechnen, muss in der Lage sein, die TCP-Header korrekt auszufüllen,
32:20
die ganzen Optionen zu duplizieren und so weiter und so fort. Dann gibt es eine etwas abgespeckte Variante von dem TSO. Das nennt sich GSO. Das ist dann, wenn die Hardware zwar nicht jetzt zum Beispiel TCP versteht, aber zum Beispiel in der Lage ist, dass sie aus verschiedenen
32:41
Eingabe-Buffern arbeiten kann, was halt eben so eine Art Kompromiss ist. Das heißt, wir können immer noch so große Superpakete runter unterreichen in die Netzwerkkarte. Und der Treiber kann auch damit was anfangen, aber es wird halt dann wieder mehr von Seiten der CPU gemacht, weil die CPU dann eben zum Beispiel
33:01
die TCP-Header duplizieren muss. Und für den Fall, dass man eine Hardware hat, die das gar nicht kann, muss alles komplett in Software gemacht werden. Das funktioniert so, dass der Colonel oder beziehungsweise der Treiber, der füllt quasi in so einer Art Datenstruktur hinterlegt, der quasi für den Colonel in einer Bitmaske die Features,
33:23
die die Hardware unterstützt. Und da stehen dann also Sachen drin, hey, ich kann TSO und ich kann GSO oder ich kann es halt eben nicht. Und der Colonel versucht auch diese Informationen bis ans Programm, also versteckt. Aber er versucht es bis ans Programm durchzureichen. Das heißt also, wenn wir dabei sind, gerade so ein Disziplibpaket zu bauen, dann versucht der Colonel
33:41
quasi schon zu erraten, dass das mit großer Wahrscheinlichkeit über eine Schnittstelle geht, die das zum Beispiel nicht kann. Und dann versuchen wir das zu vermeiden, dass wir so Superpakete runterreichen und wir wissen, dass das im Endeffekt der Treiber eh alles in Software machen müsste. Irgendwann kam dann jemand
34:00
auf die Idee, dass dieses Offload-Prinzip auch für die Empfangsseite gar nicht so schlecht wäre, weil wenn man halt ein Paket empfängt, dann ist es natürlich auch effizienter, wenn man nur noch ein Zehntel oder ein Fünfzehntel der Trips durch den Empfangsstack hat. Und dann hat man sich dieses GAO überlegt, was immer zu Missverständnissen führt. Weil GAO ist eigentlich
34:21
genau dasselbe wie GSO. Ist genau das Gleiche. Also ein GAO-Paket ist immer automatisch ein GSO-Paket. Was auch nötig ist, weil wenn man zum Beispiel Vorwarting macht, dann muss man ja auf der Sendeseite die Transformation wieder rückgängig machen können. Das heißt also, es ist eigentlich so eigentlich werden die Begriffe, es ist fast ein Synonym.
34:42
GAO sagt eigentlich nur, dass man halt diese Optimierungstechnik auf der Empfangsseite anwendet. Technisch gesehen sitzt es sogar noch vor dem TCP-DAM, also fast noch im Treiber. Das heißt, man guckt einfach nach, ich habe ein Paket empfangen. Jetzt kommt das nächste Paket, dann guckt der Treiber oder so eine Hilfsfunktion, die vom Treiber benutzt werden muss,
35:01
guckt dann quasi nach, gehört das nächste Paket logisch gesehen zum selben TCP-Flow zum Beispiel, passen die Sequenznummern, stimmen die Checksummen und wenn ja, dann werden die quasi miteinander verschmolzen. Das heißt, ich habe noch einen, ich habe einen so SKB-Hetter und dann wird jetzt das zweite Datenpaket wird quasi da gerade noch
35:21
hinein gequetscht und das geht dann halt eben so lange, bis irgendwann ein Paket kommt, das nicht aggregiert werden kann, zum Beispiel weil Pakete umsortiert wurden im Netzwerk und das ist jetzt halt nicht mehr in derselben Reihenfolge oder weil eine Checksumme ungültig ist oder sowas. Dann wird es halt eben irgendwann als ein großes Riesenpaket durch diese ganze Stack Verarbeitungsmaschinerie
35:41
durchgereicht. Und dafür gibt es dann eben diese sogenannten lichtliniearen SKBs. Das man hat also das da oben ist, das ist so diese SKWF-Meter-Datenstruktur, wo die Hetter drinstehen, die Aufsätze und so weiter. Das ist ein währenden Jahrespaket,
36:03
also da wäre jetzt der Ethernet-Hetter, der IP-Hetter und so weiter und dann die eigentlichen Daten. Und ganz am Ende von dem Ding, da tut der Colonel als Trick noch so eine versteckt von Treiber und von der Hardware so ein extra Informationspaket hinterlegen. Und dort kann man weitere Buffer
36:21
quasi auch verweisen. Das heißt also, wenn ich jetzt diese GEO-Mechanik zum Beispiel, die würde dann versuchen, wenn jetzt das hier logisch gesehen ein IP-Paket enthält, was eben zu dem dazu passt, dann wird es halt darüber referenziert.
36:43
So, jetzt kommt noch was zum Receive-Side-Scaling, wer mal ein bisschen mit rumspielen will. Dann gibt es eine Datei, die ist PROC INTERRUPTS. Da kann man sich anzeigen lassen, welche Interrupts von welcher CPU und wie häufig bearbeitet werden. Ich habe da hier mal als Beispiel mal aus meinem Frischgebot
37:00
den Desktop mal gepastet, dass der Interrupt 28, das ist in dem Fall jetzt die Netzwerk-Schnittstelle ETH0. Und da sieht man, das ist jetzt die Standard-Einstellung, da ist nichts getunt. Das heißt also, es ist im Wesentlichen zufällig. Jede CPU, die gerade lustig ist, die kann sich halt eben diesen Interrupt greifen und dann eine Verarbeitung durchführen. Man kann das aber durchaus auch umkonfigurieren,
37:22
indem man eben über so eine Datei, die heißt SMP Affinity, das umstellt. Das hat jetzt eigentlich gar nichts mit Netzwerk zu tun, sondern das funktioniert für alle Interrupts, weil es einfach nur festlegt, welche CPU dann die Verarbeitung durchführt. Aber gerade für den Netzwerksdeck ist es halt eben interessant. Wenn ich jetzt zum Beispiel eine Hardware habe,
37:41
die mehrere Interrupts bereitstellt, dann kann ich zum Beispiel feste Zuordnungen machen. Und wenn ich zum Beispiel 16 Hardware-Qs habe und 8 Prozessoren, dann kann ich halt zum Beispiel zwei Hardware-Qs pro Prozessor machen und dadurch halt eben automatisch mehr Parallelisierung erreichen. Die Verteilung auf diese Qs, die macht die Hardware im Allgemeinen komplett automatisch
38:00
oder sie macht es komplett automatisch, meistens über eine Hash-Funktion. Es gibt allerdings auch inzwischen neuer Nix mit programmierbaren Filtern. Da kann man dann tatsächlich sogar so Sachen machen, wie TCP-Syn-Pakete in diese Q machen oder TCP-Port 80 in jene und kann da ziemlich viel Tuning machen. Zum Beispiel, indem man dann auch Apache oder Bein oder welches Programm man halt gerade benutzen will
38:21
oder tun will, auf bestimmte CPUs zwingt und dann halt eben auch die Pakete hardware-seitig schon direkt auf die CPU leitet. Es gibt ja auch einen Analog, das ist halt das Transmit-Paket. Das ist halt ein spezieller Anfeld.
38:40
Ja, also das muss man im Prinzip machen, wenn man sehr High-Performance-Server haben will. Also wo halt man sehr viele Prozessoren hat und eine sehr hohe Last, also wirklich 100.000 von Connections pro Sekunde. Also wir reden hier nicht von so
39:01
Home-Servern oder sowas. Da ist es natürlich völlig egal. XPS ist so quasi die als analoge, aber halt eben nicht für Empfang, sondern für Sendung. Und auch dort gibt es halt eben eine Proc-Datei, mit der man eben festlegen kann, welche CPU dann den Versand
39:20
eigentlich machen soll. Noch kurz was zu vielleicht ein paar aktuellen Schwerpunkte, die so gerade in der Köln-Entwicklung gemacht werden. Also Google macht zum Beispiel gerade sehr, sehr viel in Richtung Skalierbarkeit, weil es denen barres Geld spart. Ist ja auch klar, wenn man so viel Hardware
39:42
ausgeben muss für die Last, dann spart das natürlich enormen Hardware-Ressourcen, wenn man plötzlich irgendwie die Effizienz um nur 3% draufschraubt. Dann kommt auch von Google gerade ein Patch für Zero Copy aus User Space. Und zwar ist ja das Problem, dass wenn man die Standard
40:00
Unix-Schnittstellen benutzt, also zum Beispiel SendMessage, um Daten auf den Socket zu schreiben, dann müssen die Daten immer erst vom User Space in den Körner rein kopiert werden. Und das kostet natürlich auch ganz gewaltig Zeit, zumindest relativ gesehen, wenn man solche schnellen Netzerkarten hat. Und was die jetzt gemacht haben ist, sie führen ein neues Flag ein für SendMessage.
40:21
Ich will Zero Copy. Und wenn das Gesetz ist, dann pinnt der Körner den Speicher vom User Space direkt und benutzt diese Daten. User Space darf die natürlich nicht überschreiben in der Zeit. Und über die Socket Error-Q kriegt man dann vom Körner gesagt, wenn TCP die Empfangsbestätigung
40:41
bekommen hat vom Gegenüber. Also das ist nicht so ganz trivial. Aber die ersten Patches sind schon, also wer sich angucken will, die Patches wurden vor ein paar Tagen auf der NetFMany-Liste gepostet. Dann auch Stichpunkt-Skalierung. Der Linus-Körner hat, wie eigentlich jedes andere Betriebssystem auch
41:01
Skalierbarkeitsprobleme mit dem TCP ListenLog. Also wer TCP kennt, der weiß die Anhörung, die bindet einen Socket, zum Beispiel eben TCP Port 80. Und wenn Verbindung aufgemacht wird vom Client, dann schickt er einen Synpar geht an diesen ListenSocket. Und das Problem ist jetzt, dass natürlich alle Verbindungsversuche
41:21
und alle Synpakete immer auf diesen selben ListenSocket kommen. Und damit teilen die sich natürlich auch alle dasselbe Log, was natürlich schlecht ist, wenn man plötzlich irgendwie 500.000 Synanfragen pro Sekunde hat und das auch noch die normale Arbeitsbelastung von dem System sein soll. Und dort wird gerade was gemacht, um das halt eben umgehen zu können.
41:40
Dann wird gerade daran gearbeitet, mehr Badging zu machen. Also zum Beispiel nicht, dass man sagt, ich will einen SKB allokieren, sondern man sagt halt, ich will 32 SKBs allokieren und der Allokator, der muss dann nur einmal bestimmte atomare Operationen durchführen und gibt einem halt gleich alles auf einmal und das analoge auch fürs Freigeben von Speicher.
42:01
Dann passiert viel in der Virtualisierungsecke. Es kamen ein paar Leute entdeckt, dass Network Namespaces zu viel Overhead haben und für ihre Fälle eigentlich viel zu viel Features haben. Sie hätten gerne was leichtgewichtigeres. Deswegen wird er gerade an diesem Virtual Router Funktion gearbeitet. Dann auch in der Virtualisierung wird gerade daran geschraubt, dass Netfilter Hubs
42:21
nicht mehr global sind, sondern pro Network Namespace, damit man eben nicht den Overhead in allen Network Namespaces Paketfilter Overhead hat, nur weil das halt im Host Betriebssystem an ist. Dann gibt es Bemühungen, gerade so
42:41
für Switching Anwendungsfälle. Also wir reden hier von wirklich Hardware Switches, auf denen dann Linux laufen soll. Da wird gerade eine API geschraubt, die halt eben eine einheitliche Schnittstelle bereitstellen soll, mit denen dann eben Hardware Chips programmierbar, die programmierbar sind,
43:00
eben dem Benutzer präsentiert werden, damit es halt einheitlich ist und nicht so wie heute, dass da jeder Hersteller so sein eigenes SDK hat, mit dem man sich rumschlagen muss. Da wird zum Beispiel gerade viel von Mellanox gemacht. Und dann zu guter Letzt gibt es noch eBPF. Das ist so eine Art Compiler, mit dem der Colonel dann
43:21
bestimmten Code direkt in die Maschinen Sprache übersetzt werden kann und dann eben native Ausführungsgeschwindigkeit hat. Da gibt es vielerlei Anwendungsfälle, also eine Möglichkeit, über die man zum Beispiel denkt, ist, dass man halt aus dem User Space raus direkt zum Beispiel
43:41
Switching Logik programmieren kann. Das heißt, das wird nicht einfach beschrieben, welches Paket an welche Schnittstelle soll, sondern es wird tatsächlich programmiert und das eBPF kombiniert ist dann in nativen Code. Und dann hat man natürlich nicht mehr jeden erdenklichen Code für alle Fälle, sondern es wird nur der Code ausgeführt, der tatsächlich benutzt wird.
44:00
Das ist ja klar. Und dann zu guter Letzt noch NF Tables als Nachfolger beziehungsweise IP6 Tables, was gerade auch ein bisschen mehr Entwicklerzeit bekommt, um halt eben endlich Feature-Äquivalent zu werden, so eBTables und Co. Gibt es Fragen?
44:22
Ja, ja. Nee, das wird direkt, muss direkt verglichen werden. Achso. Ich habe wieder die Sünde begangen, die Frage nicht zu wiederholen,
44:41
weil ich es doch dauernd vergessen. Also die Frage war bei GRO, wie das aus Treibersicht funktioniert und ob der da das Paket hasht. Sondern nein, es werden da Aufrufe gemacht bis hoch in den TCP-Stack. Also da gibt es dann Callbacks. GRORC heißen die. Die gehen bis rauf
45:01
in den TCP-Stack. Das heißt, der Treiber, der ruft erst mal, also erst mal wird nachgeguckt, ist es auf Ethernet-Ebene überhaupt? Irgendwie passen die MAC-Adressen und so weiter? Und wenn ja, dann wird nachgeguckt, was denn das nächste Protokoll? Und dann wird halt geguckt, IP. Dann schaue ich nach, sind die IP-Header gleich? Und so hangelt sich das halt durch.
45:26
Doch, das funktioniert auch für Forwarding, weil der lokale Stack immer noch genug versteht. Also der muss ja nicht nach herausfinden, ob es tatsächlich lokal einen Socket dafür gibt. Sondern es reicht da völlig zu gucken, ob die TCP-Portnummern
45:40
und die Sequenznummern und so weiter übereinstimmen. Und dafür reichen alle Informationen, die im Paket stehen, komplett aus. Ja, so ein Software. Aber es ist kein Re-Assembly. Also es ist auch nicht ein Muss. Also der guckt wirklich nur einfach nach. Passen die Pakete irgendwie zusammen? Und wenn da die Antwort lautet Nein,
46:02
dann versucht er da jetzt nicht irgendwie, ich speichere das jetzt mal für zehn Minuten Zwischenrunden, schaue mal, ob da noch irgendwas kommt. Sondern dann wird halt gesagt, nee, dann aggregiere ich jetzt nicht. Und ob es mit Forwarding was bringt, das kommt immer auf den Einzelfall an. Also wenn man rein das Forwarding macht, dann würde ich vermuten, dass es was bringt, wenn man das Geo abschaltet.
46:21
Wenn man dann allerdings vorwartet und gleichzeitig sehr viele Firewalling-Regelungen hat, dann könnte es aber schon wieder was bringen, weil ich dann halt wesentlich weniger Lookups in den Regelsatz habe.
47:36
Ja, nö, würde ich gar nicht sagen. Also, also die Frage lässt sich
47:45
lässt sich so zusammenfassen, dass es im Endeffekt nur darum geht, wie komplex ein Ethernet-Treiber ist. Und das hängt eigentlich zentral eigentlich nur von der Frage ab, wie komplex die Hardware ist. Also moderne Ethernet-Netzwerk-Karten sind Monster, Netzwerk-Treiber sind Monster, weil die Hardware inzwischen
48:01
so extrem komplex ist. Also teilweise können moderne Netzwerk-Karten IPsec offloading in Hardware zum Beispiel, was von Linux noch nicht unterstützt wird. Aber es gibt welche, die können das. Und wenn man aber ganz, ganz, ganz primitiv den Netzwerk-Treiber anguckt, also was weiß ich, so DM9000 oder sowas, das ist, das ist nicht viel.
48:22
Also das wird weder in Code noch in sonst was. Also da spricht eigentlich nichts dagegen. Wobei, ne, gibt's noch weitere Fragen?
49:07
Ich muss die Frage nicht wiederholen, weil ich die Antwort nicht weiß. Ihr müsst da nachschauen. Ihr müsst da nachschauen. Also es ging im Endeffekt um die Frage in der Darstellung von Top, ob die Anzeige SI, die Soft Interrupt Last anzeigt,
49:22
ob die noch korreliert mit dem KSOFT-IR-QD, falls alles umgeleitet wird auf KSOFT-IR-QD. Ich weiß es nicht. Ich müsste selber im Köln nachschauen oder beziehungsweise im Top.
50:00
Nein, also die Frage war, ob man irgendwie verhindern kann, dass eine Umleitung passiert auf dem KSOFT-IR-QD. Und das geht meistens noch nicht, weil das ist direkt im Köln verdrahtet. Da wird einfach nur nachgeschaut. Also in der Verarbeitung von den Soft Interrupts wird einfach nur nachgeschaut am Ende, wenn er fertig ist, ob schon neue scheduled wurden. Und wenn das halt so häufig passiert ist,
50:21
dann sagt er halt ne jetzt nicht mehr und dann wird eben auf KSOFT-IR-QD umgeschaltet. Ja, das ist nochmal ein ganz anderes Beast.
50:42
Also die Frage, das dreht sich um Busy-Poll, um die Busy-Poll-Funktionität. Ich weiß nicht, wie das unter Free-Bizte funktioniert und an Linux funktioniert das so, dass quasi der Prozess, der dieses Busy-Polling will und dann liest, dass in dessen Kontext direkt gepollt wird.
51:47
Die Frage ging um vorwartige Performance. Und wieso da manche Hersteller so viel bessere Zahlen haben als der Linux-Körner. Also zum ersten Mal ist, zum einen Mal sind in den letzten sechs Monaten
52:00
viele Sachen passiert, was vorwartige Performance angeht. Also gerade die Linux-Rooting, also die FIP-Implementierung ist extrem optimiert worden in den letzten sechs Monaten. Sodass da die Ergebnisse schon etwas besser aussehen sollten und zwar wesentlich. Also ich würde mal so schätzen, so 100 Prozent mehr dürfte durchaus drin sein. Ja, da ist einiges passiert.
52:22
Man kann auch noch ein paar Tricks machen im Kernel mit Caching. Ich habe das mal versucht, aber leider habe ich dann auch, also ich habe keine so Embedded-Hardware, sage ich mal, sondern ich habe halt nur etwas größere Hardware und dort sieht man dann halt häufig keine Unterschiede mehr. Und ich tue halt ungern Sachen in den Kernel rein machen,
52:41
wo ich denke, dass es vielleicht was hilft, aber ich habe keine quantifizierbaren Aussagen dazu. Das ist so ein bisschen das Problem. Also es gibt so ein paar dezidiertere Lösungen, so eine Intel hat zum Beispiel halt eben dieses DPDK,
53:01
was dann so viele tolle Benchmarking-Demos hat für Forwarding, aber man muss halt auch sagen, das DPDK hat halt im Endeffekt keinerlei Funktionalität, weil du musst ja alles selber programmieren im DPDK. Und das, was die ja machen Benchmark-Programm ist ja im Endeffekt, wenn es da reinkommt, dann soll es auf der anderen Seite rausplumpsen und mehr macht das Ding ja gar nicht. Und das ist natürlich nicht so vergleichbar mit dem, was der Linux Kernel machen muss.
53:22
Und dadurch, dass der Linux Kernel halt auch nicht für Forwarding entworfen wurde, sondern das Deck ist halt gedacht für lokales Queuing. Deswegen hat man ja auch diesen ganzen Overhead von wegen alter Treiber musste erst mal das Paket entnehmen und musste einen neuen Speicherblock allokieren und so weiter. Und das hat man ja im Forwarding-Fall. Könnte man das ja eigentlich komplett vermeiden. Man könnte einfach immer
53:41
den gleichen Speicher wieder benutzen. Man weiß, dass das gevorwartet wird und innerhalb von einer absehbaren Zeit auf jeden Fall wieder benutzbar ist. Könnte man das alles vermeiden. Ja, aber das kann man halt nicht in einem normalen Betriebsteam machen.