Offloading der Segmentierung von großen TCP-Paketen
Network Driver Interface Specification (NDIS) Miniport-Treiber können die Segmentierung großer TCP-Pakete, die größer als die maximale Übertragungseinheit (MTU) des Netzwerkmediums sind, auslagern. Eine NIC, die die Segmentierung großer TCP-Pakete unterstützt, muss auch in der Lage sein:
IP-Prüfsummen für Sendepakete berechnen, die IP-Optionen enthalten.
Berechnen von TCP-Prüfsummen für Sendepakete, die TCP-Optionen enthalten.
NDIS-Versionen 6.0 und höher unterstützen Large Send Offload Version 1 (LSOv1), das Large Send Offload (LSO) in NDIS 5.x ähnelt. NDIS-Versionen 6.0 und höher unterstützen auch Large Send Offload Version 2 (LSOv2), die erweiterte Dienste für die Segmentierung großer Pakete bietet, einschließlich Unterstützung für IPv6.
Ein Miniport-Treiber, der LSOv2 und LSOv1 unterstützt, muss den Typ des Offloads aus den Out-of-Band (OOB)-Informationen der NET_BUFFER_LIST-Struktur bestimmen. Der Treiber kann das Type-Mitglied der NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO-Struktur verwenden, um festzustellen, ob der Treiber-Stack LSOv2 oder LSOv1 verwendet und die entsprechenden Offloading-Dienste ausführen. Jede NET_BUFFER_LIST-Struktur, die die LSOv1 oder LSOv2 OOB-Daten enthält, enthält auch eine einzelne NET_BUFFER-Struktur. Weitere Informationen über NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO finden Sie unter Zugriff auf TCP/IP Offload NET_BUFFER_LIST Informationen.
In einem Fall, in dem der Miniport OID_TCP_OFFLOAD_PARAMETERS empfangen hat, um die LSO-Funktion auf dem Miniport auszuschalten und nachdem der Miniport die OID erfolgreich abgeschlossen hat, muss der Miniport jedoch alle NET_BUFFER_LIST, die LSOv1 oder LSOv2 OOB Daten ungleich Null enthalten, verwerfen (NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO).
Der TCP/IP-Transport lagert nur diejenigen großen TCP-Pakete aus, die die folgenden Kriterien erfüllen:
Das Paket ist ein TCP-Paket. Der TCP/IP-Transport entlädt keine großen UDP-Pakete für die Segmentierung.
Das Paket muss zumindest durch die Mindestanzahl der vom Miniporttreiber angegebenen Segmente teilbar sein. Weitere Informationen finden Sie unter Melden der TCP-Paketsegmentierungsfunktionen einer NIC LSOV1 und Melden der TCP-Paketsegmentierungsfunktionen einer NIC LSOV2.
Das Paket ist kein Loopbackpaket.
Das Paket wird nicht über einen Tunnel gesendet.
Bevor der TCP/IP-Transport ein großes TCP-Paket für die Segmentierung auslagert:
- Aktualisiert die Segmentierungsinformationen für große Pakete, die der NET_BUFFER_LIST-Struktur zugeordnet sind. Bei diesen Informationen handelt es sich um eine NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO-Struktur, die ein Element der NET_BUFFER_LIST-Informationen ist, die der NET_BUFFER_LIST-Struktur zugeordnet sind. Weitere Informationen zu den NET_BUFFER_LIST-Informationen finden Sie unter Zugreifen auf TCP/IP-Auslagerungsinformationen von NET_BUFFER_LIST. Der TCP/IP-Transport legt den Wert MSS für die maximale Segmentgröße fest.
Bei LSOv1 wird die Gesamtlänge des großen TCP-Pakets in das Feld
Total Length
des IP-Headers des Pakets geschrieben. Die Gesamtlänge enthält die Länge des IP-Headers, die Länge der IP-Optionen, wenn sie vorhanden sind, die Länge des TCP-Headers, die Länge der TCP-Optionen, wenn sie vorhanden sind, und die Länge der TCP-Nutzlast. Legt für LSOv2 dasTotal Length
Feld des IP-Headers des Pakets auf 0 fest. Miniport-Treiber sollten die Länge des Pakets anhand der Länge der ersten NET_BUFFER-Struktur in der NET_BUFFER_LIST-Struktur ermitteln.Berechnet die One's-Complement-Summe für den TCP-Pseudo-Header und schreibt diese Summe in das
Checksum
-Feld des TCP-Headers. Der TCP/IP-Transport berechnet die One's-Complement-Summe über die folgenden Felder im Pseudoheader:Source IP Address
,Destination IP Address
undProtocol
. Die Einerkomplementsumme für den vom TCP/IP-Transport bereitgestellten Pseudoheader ermöglicht der NIC eine frühzeitige Berechnung der tatsächlichen TCP-Prüfsumme für jedes Paket, das die NIC vom großen TCP-Paket ableitet, ohne dass der IP-Header untersucht werden muss. Beachten Sie, dass RFC 793 vorschreibt, dass die Pseudo-Header-Prüfsumme über die FelderSource IP Address
,Destination IP Address
,Protocol
undTCP Length
berechnet wird. (Die TCP-Länge ist die Länge des TCP-Headers plus die Länge der TCP-Nutzlast. Die TCP-Länge enthält nicht die Länge des Pseudoheaders.) Da jedoch der zugrunde liegende Miniporttreiber und die NIC TCP-Segmente aus dem großen Paket generieren, das vom TCP/IP-Transport übergeben wird, weiß der Transport nicht die Größe der TCP-Nutzlast für jedes TCP-Segment und kann daher die TCP-Länge nicht in den Pseudoheader aufnehmen. Wie unten beschrieben, erweitert die NIC stattdessen die Pseudoheaderprüfsumme, die vom TCP/IP-Transport bereitgestellt wurde, um die TCP-Länge jedes generierten TCP-Segments zu berücksichtigen.Schreibt die richtige Sequenznummer in das
Sequence Number
-Feld des TCP-Headers. Die Sequenznummer identifiziert das erste Byte der TCP-Nutzlast.
Nachdem der Miniport-Treiber die NET_BUFFER_LIST-Struktur in seiner MiniportSendNetBufferLists- oder MiniportCoSendNetBufferLists-Funktion abgerufen hat, kann er das NET_BUFFER_LIST_INFO-Makro mit einem _Id
von TcpLargeSendNetBufferListInfo
aufrufen, um den vom TCP/IP-Transport geschriebenen MSS-Wert abzurufen.
Der Miniporttreiber ruft die Gesamtlänge des großen Pakets aus dem IP-Header des Pakets ab und verwendet den MSS-Wert, um das große TCP-Paket in kleinere Pakete aufzuteilen. Jedes der kleineren Pakete enthält Benutzerdatenbytes der MSS oder weniger. Nur das letzte Paket, das aus dem segmentierten großen Paket erstellt wurde, sollte weniger als MSS-Benutzerdatenbytes enthalten. In allen anderen Pakete, die aus dem segmentierten Paket erstellt wurden, sollten die Benutzerdatenbytes der MSS entsprechen. Wenn Sie dieser Regel nicht folgen, kann die Erstellung und Übertragung unnötiger zusätzlicher Pakete die Leistung beeinträchtigen.
Der Miniporttreiber bringt MAC-, IP- und TCP-Header für jedes Segment an, das vom großen Paket abgeleitet wird. Der Miniporttreiber muss die IP- und TCP-Prüfsummen für diese abgeleiteten Pakete berechnen. Um die TCP-Prüfsumme für jedes Paket zu berechnen, das vom großen TCP-Paket abgeleitet wurde, berechnet die NIC den variablen Teil der TCP-Prüfsumme (für den TCP-Header und die TCP-Nutzlast), fügt diese Prüfsumme der Einerkomplementsumme für den vom TCP/IP-Transport berechneten Pseudoheader hinzu und berechnet dann das 16-Bit-Einerkomplement für die Prüfsumme. Weitere Informationen zum Berechnen solcher Prüfsummen finden Sie unter RFC 793 und RFC 1122.
Die folgende Abbildung zeigt die Segmentierung eines großen Pakets.
Die Länge der TCP-Benutzerdaten im großen TCP-Paket sollte dem Wert entsprechen, den der Miniporttreiber dem Wert MaxOffLoadSize
zuweist, oder kleiner sein. Weitere Informationen über den MaxOffLoadSize
-Wert finden Sie unter Reporten der LSOv1 TCP-Paket-Segmentierungs-Funktionen einer NIC und Reporten der LSOv2 TCP-Paket-Segmentierungs-Funktionen einer NIC.
Nachdem ein Treiber eine Statusanzeige ausgegeben hat, um eine Änderung des MaxOffLoadSize
Werts anzugeben, darf der Treiber nicht abstürzen, wenn er eine LSO-Sendeanforderung empfängt, die den vorherigen MaxOffLoadSize
Wert verwendet. Stattdessen kann der Treiber die Sendeanforderung fehlschlagen.
Ein Zwischentreiber, der unabhängig Statusanzeigen ausgibt, die eine Änderung des MaxOffLoadSize
-Werts melden, muss sicherstellen, dass der zugrunde liegende Miniportadapter, der keine Statusanzeige ausgegeben hat, keine Pakete erhält, die größer sind als der MaxOffLoadSize
Wert, den der Miniportadapter gemeldet hat.
Ein Miniport-Zwischentreiber, der auf OID_TCP_OFFLOAD_PARAMETERS reagiert, um LSO-Dienste zu deaktivieren, muss für ein kleines Zeitfenster vorbereitet sein, in dem LSO-Sendeanforderungen weiterhin den Miniporttreiber erreichen können.
Die Länge der TCP-Benutzerdaten in einem Segmentpaket muss kleiner oder gleich dem MSS sein. Der MSS-Wert ist der ULONG-Wert, den der TCP-Transport unter Verwendung der LSO NET_BUFFER_LIST-Informationen weitergibt, die der NET_BUFFER_LIST-Struktur zugeordnet sind. Nur das letzte Paket, das aus dem segmentierten großen Paket erstellt wurde, sollte weniger als MSS-Benutzerdatenbytes enthalten. Alle anderen Pakete, die aus dem segmentierten Paket erstellt wurden, sollten MSS-Nutzdaten-Bytes enthalten. Wenn Sie dieser Regel nicht folgen, kann die Erstellung und Übertragung unnötiger zusätzlicher Pakete die Leistung beeinträchtigen.
Die Anzahl der Segmentpakete, die vom großen TCP-Paket abgeleitet wurden, muss gleich oder größer als der vom Miniporttreiber angegebene MinSegmentCount
Wert sein. Weitere Informationen über den MinSegmentCount
-Wert finden Sie unter Reporten der LSOv1 TCP-Paket-Segmentierungs-Funktionen einer NIC und Reporten der LSOv2 TCP-Paket-Segmentierungs-Funktionen einer NIC.
Die folgenden Annahmen und Einschränkungen gelten für die Verarbeitung von IP- und TCP-Headern für jeden LSO-fähigen Miniporttreiber unabhängig von der Version:
Das MF-Bit im IP-Header des großen TCP-Pakets, das der TCP/IP-Transport ausgelagert hat, wird nicht festgelegt, und der Fragment-Offset im IP-Header wird auf Null gesetzt.
Die Flags URG, RST und SYN im TCP-Header des großen TCP-Pakets werden nicht festgelegt und der Dringlichkeitsoffset (Pointer) im TCP-Header ist Null.
Wenn das Bit FIN im TCP-Header des großen Pakets gesetzt ist, muss der Miniport-Treiber dieses Bit im TCP-Header des letzten Pakets festlegen, das er aus dem großen TCP-Paket erstellt.
Wenn das PSH Bit im TCP-Header des großen TCP-Pakets festgelegt ist, muss der Miniporttreiber dieses Bit im TCP-Header des letzten Pakets festlegen, das es aus dem großen TCP-Paket erstellt.
Wenn das Bit CWR im TCP-Header des großen TCP-Pakets gesetzt ist, muss der Miniport-Treiber dieses Bit im TCP-Header des ersten Pakets festlegen, das er aus dem großen TCP-Paket erstellt. Der Miniporttreiber kann dieses Bit im TCP-Header des letzten Pakets festlegen, das er aus dem großen TCP-Paket erstellt, obwohl dies weniger wünschenswert ist.
Wenn das große TCP-Paket IP-Optionen oder TCP-Optionen (oder beides) enthält, kopiert der Miniporttreiber diese Optionen unverändert in jedes Paket, das er vom großen TCP-Paket abgeleitet hat. Insbesondere wird die NIC die Option Time Stamp nicht inkrementieren.
Alle Paketheader (Ethernet, IP, TCP) befinden sich in der ersten MDL des Pakets. Die Header werden nicht auf mehrere MDLs aufgeteilt.
Tipp
Diese Annahme ist gültig, wenn LSO aktiviert ist. Andernfalls können Miniporttreiber, wenn LSO nicht aktiviert ist, nicht davon ausgehen, dass SICH IP-Header in derselben MDL wie Ethernet-Header befinden.
Der Miniport-Treiber muss die Pakete in NET_BUFFER_LIST-Strukturen in der Reihenfolge senden, in der er die NET_BUFFER_LIST-Strukturen vom TCP/IP-Transport erhält.
Bei der Verarbeitung eines großen TCP-Pakets ist der Miniportadapter nur für das Segmentieren des Pakets und das Anbringen von MAC-, IP- und TCP-Headern an die Pakete verantwortlich, die vom großen TCP-Paket abgeleitet werden. Der TCP/IP-Transport führt alle anderen Aufgaben aus (z. B. Anpassen der Größe des Sendefensters basierend auf der Empfangsfenstergröße des Remotehosts).
Bevor er den Sendevorgang für das große Paket abschließt (wie z. B. mit NdisMSendNetBufferListsComplete oder NdisMCoSendNetBufferListsComplete), schreibt der Miniport-Treiber den Wert NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO (NET_BUFFER_LIST-Informationen für Large-Send-Offloads) mit der Gesamtzahl der erfolgreich gesendeten TCP-Benutzerdatenbytes in alle Pakete, die aus dem großen TCP-Paket erstellt wurden.
Zusätzlich zu den genannten LSO-Anforderungen gilt für LSOv2-fähige Miniporttreiber:
Unterstützt IPv4 oder IPv6 oder sowohl IPv4 als auch IPv6.
Die Replikation der IPv4-Optionen aus dem großen Paket in jedem Segmentpaket, das die Netzwerkschnittstelle Karte (NIC) generiert, wird unterstützt.
Die Replikation des IPv6-Erweiterungsheaders aus dem großen TCP-Paket in jedem TCP-Segmentpaket wird unterstützt.
Unterstützt die Replikation von TCP-Optionen in jedem TCP-Segmentpaket, das der Miniporttreiber generiert.
Verwenden Sie den IP- und TCP-Header in der NET_BUFFER_LIST Struktur als Vorlage, um TCP/IP-Header für jedes Segmentpaket zu generieren.
Verwenden Sie IP-Identifikationswerte (IP-ID) im Bereich von 0x0000 bis 0x7FFF. (Der Bereich von 0x8000 bis 0xFFFF ist für Geräte reserviert, die sich für die TCP-Chimney-Auslagerung eignen.) Wenn der IP-Header der Vorlage z. B. mit einem Identifikationsfeldwert 0x7FFE beginnt, muss das erste TCP-Segmentpaket über einen IP-ID-Wert 0x7FFE verfügen, gefolgt von 0x7FFF, 0x0000, 0x0001 usw.
Verwenden Sie den Byte-Offset im TcpHeaderOffset-Mitglied von NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, um den Speicherort des TCP-Headers zu bestimmen, beginnend mit dem ersten Byte des Pakets.
Begrenzen Sie die Anzahl der NET_BUFFER-Strukturen, die jeder LSOv2 NET_BUFFER_LIST-Struktur zugeordnet sind, auf eine.
Anmerkung
Dies ist eine neue Anforderung für LSOv2-fähige Miniporttreiber. Diese Regel wird für LSOv1 Miniport-Treiber nicht explizit erzwungen, obwohl sie empfohlen wird.
Ermitteln Sie die Gesamtlänge des Pakets anhand der Länge der ersten
NET_BUFFER
-Struktur in derNET_BUFFER_LIST
-Struktur. Dies ist anders als bei den Methoden-Treibern für LSOv1.TCP-Optionen, IP-Optionen und IP-Erweiterungsheader werden unterstützt.
Wenn ein Sendevorgang abgeschlossen ist, muss der Miniport-Treiber das
LsoV2TransmitComplete.Reserved
-Mitglied der NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO-Struktur auf Null und dasLsoV2TransmitComplete.Type
-Mitglied aufNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE
festlegen.