Delen via


Het uitbesteden van de segmentatie van grote TCP-pakketten

NDIS-minipoortstuurprogramma's (Network Driver Interface Specification) kunnen de segmentatie van grote TCP-pakketten die groter zijn dan de maximale transmissie-eenheid (MTU) van het netwerkmedium offloaden. Een NIC die ondersteuning biedt voor de segmentatie van grote TCP-pakketten, moet ook het volgende kunnen doen:

  • Bereken IP-controlesommen voor verzendpakketten die IP-opties bevatten.

  • Bereken TCP-controlesommen voor het verzenden van pakketten die TCP-opties bevatten.

NDIS-versies 6.0 en hoger ondersteunen Large Send Offload versie 1 (LSOv1), dat vergelijkbaar is met Large Send Offload (LSO) in NDIS 5.x. NDIS-versies 6.0 en hoger bieden ook ondersteuning voor grote send offload versie 2 (LSOv2), die uitgebreide grote pakketsegmentatieservices biedt, waaronder ondersteuning voor IPv6.

Een minipoortstuurprogramma dat LSOv2 en LSOv1 ondersteunt, moet het offloadtype bepalen van de out-of-band (OOB) informatie over de structuur NET_BUFFER_LIST. Het stuurprogramma kan het type lid van de NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO structuur gebruiken om te bepalen of de stuurprogrammastack gebruikmaakt van LSOv2 of LSOv1 en de juiste offloadservices uitvoert. Elke NET_BUFFER_LIST structuur die de LSOv1- of LSOv2 OOB-gegevens bevat, bevat ook één NET_BUFFER structuur. Voor meer informatie over NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, zie Toegang tot TCP/IP Offload NET_BUFFER_LIST-informatie.

Als de minipoort echter OID_TCP_OFFLOAD_PARAMETERS heeft ontvangen om de LSO-functie uit te schakelen en de OID succesvol heeft voltooid, moet de minipoort alle NET_BUFFER_LIST laten vallen die enige niet-nul LSOv1- of LSOv2-OOB-gegevens bevat (NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO).

Het TCP/IP-transport laadt alleen die grote TCP-pakketten af die voldoen aan de volgende criteria:

Voordat een groot TCP-pakket voor segmentatie wordt uitbesteed, voert het TCP/IP-transport de volgende taken uit:

  • Voor LSOv1 schrijft u de totale lengte van het grote TCP-pakket naar het Total Length veld van de IP-header van het pakket. De totale lengte omvat de lengte van de IP-header, de lengte van de IP-opties als deze aanwezig zijn, de lengte van de TCP-header, de lengte van de TCP-opties als deze aanwezig zijn en de lengte van de TCP-nettolading. Voor LSOv2 stelt u het Total Length veld van de IP-header van het pakket in op 0. Miniportstuurprogramma's moeten de lengte van het pakket bepalen op basis van de lengte van de eerste NET_BUFFER structuur in de NET_BUFFER_LIST structuur.

  • Berekent aanvullingssom voor de TCP-pseudoheader en schrijft deze som naar het Checksum veld van de TCP-header. Het TCP/IP-transport berekent de één-aanvullingssom over de volgende velden in de pseudoheader: Source IP Address, Destination IP Addressen Protocol. De complement-som van de pseudoheader die wordt geleverd door de TCP/IP-transportlaag geeft de NIC een voorsprong bij het berekenen van de echte TCP-controlesom voor elk pakket dat de NIC afleidt van het grote TCP-pakket, zonder de IP-header te hoeven onderzoeken. Houd er rekening mee dat RFC 793 bepaalt dat de pseudo-header controlesom wordt berekend over de Source IP Address, Destination IP Address, Protocolen TCP Length. (De TCP-lengte is de lengte van de TCP-header plus de lengte van de TCP-nettolading. De TCP-lengte bevat niet de lengte van de pseudo-header.) Omdat het onderliggende minipoortstuurprogramma en de NIC ECHTER TCP-segmenten genereren van het grote pakket dat wordt doorgegeven door het TCP/IP-transport, weet het transport niet de grootte van de TCP-nettolading voor elk TCP-segment en kan daarom de TCP-lengte niet opnemen in de pseudo-header. In plaats daarvan, zoals hieronder beschreven, breidt de NIC de pseudo-header checksum uit die is geleverd door het TCP/IP-transport om de TCP-lengte van elk gegenereerd TCP-segment te dekken.

  • Hiermee schrijft u het juiste volgnummer naar het Sequence Number veld van de TCP-header. Het volgnummer identificeert de eerste byte van de TCP-nettolading.

Nadat het minipoortstuurprogramma de NET_BUFFER_LIST structuur in de MiniportSendNetBufferLists of MiniportCoSendNetBufferLists functie heeft verkregen, kan deze de NET_BUFFER_LIST_INFO macro aanroepen met een _Id van TcpLargeSendNetBufferListInfo om de MSS-waarde te verkrijgen die is geschreven door het TCP/IP-transport.

Het minipoortstuurprogramma verkrijgt de totale lengte van het grote pakket uit de IP-header van het pakket en gebruikt de MSS-waarde om het grote TCP-pakket te verdelen in kleinere pakketten. Elk van de kleinere pakketten bevat MSS of minder bytes gebruikersgegevens. Alleen het laatste pakket dat is gemaakt op basis van het gesegmenteerde grote pakket moet minder dan MSS-gebruikersgegevensbytes bevatten. Alle andere pakketten die zijn gemaakt op basis van het gesegmenteerde pakket, moeten MSS-gebruikersgegevensbytes bevatten. Als u deze regel niet volgt, kan het maken en verzenden van onnodige extra pakketten de prestaties verminderen.

Het minipoortstuurprogramma brengt MAC-, IP- en TCP-headers toe aan elk segment dat is afgeleid van het grote pakket. Het minipoortstuurprogramma moet de IP- en TCP-controlesommen voor deze afgeleide pakketten berekenen. Om de TCP-controlesom te berekenen voor elk pakket dat is afgeleid van het grote TCP-pakket, berekent de NIC het variabele gedeelte van de TCP-controlesom (voor de TCP-header en TCP-payload), voegt deze controlesom toe aan de aanvullingssom van de pseudoheader die door het TCP/IP-transport wordt berekend en berekent vervolgens de 16-bits aanvulling op de controlesom. Zie RFC 793 en RFC 1122 voor meer informatie over het berekenen van dergelijke controlesommen.

In de volgende afbeelding ziet u de segmentatie van een groot pakket.

diagram met de segmentatie van een groot TCP-pakket in kleinere pakketten met MAC-, IP- en TCP-headers.

De lengte van de TCP-gebruikersgegevens in het grote TCP-pakket moet gelijk zijn aan of kleiner zijn dan de waarde die het minipoortstuurprogramma toewijst aan de MaxOffLoadSize-waarde. Zie voor meer informatie over de MaxOffLoadSize waarde Rapportage van de LSOv1 TCP-Packet-Segmentation mogelijkheden en Rapportage van de LSOv2 TCP-Packet-Segmentation mogelijkheden.

Nadat een stuurprogramma een statusindicatie heeft opgegeven om een wijziging in de MaxOffLoadSize waarde aan te geven, mag het stuurprogramma niet crashen als er een LSO-verzendaanvraag wordt ontvangen die gebruikmaakt van de vorige MaxOffLoadSize waarde. In plaats daarvan kan het stuurprogramma de verzendaanvraag laten mislukken.

Een tussenliggend stuurprogramma dat onafhankelijk statusindicaties uitgeeft die een wijziging in de MaxOffLoadSize waarde melden, moet ervoor zorgen dat de onderliggende minipoortadapter die geen statusindicatie heeft uitgegeven, geen pakketten krijgt die groter zijn dan de MaxOffLoadSize waarde die de minipoortadapter heeft gerapporteerd.

Een minipoort-tussenstuurprogramma dat reageert op OID_TCP_OFFLOAD_PARAMETERS om LSO-services uit te schakelen, moet worden voorbereid voor een klein tijdsbestek waarin LSO-verzendaanvragen nog steeds het minipoortstuurprogramma kunnen bereiken.

De lengte van de TCP-gebruikersgegevens in een segmentpakket moet kleiner zijn dan of gelijk zijn aan de MSS. De MSS is de ULONG-waarde die het TCP-transport doorgeeft met behulp van de LSO NET_BUFFER_LIST-informatie die is gekoppeld aan de NET_BUFFER_LIST-structuur. Alleen het laatste pakket dat is gemaakt op basis van het gesegmenteerde grote pakket moet minder dan MSS-gebruikersgegevensbytes bevatten. Alle andere pakketten die zijn gemaakt op basis van het gesegmenteerde pakket, moeten MSS-gebruikersgegevensbytes bevatten. Als u deze regel niet volgt, kan het maken en verzenden van onnodige extra pakketten de prestaties verminderen.

Het aantal segmentpakketten dat is afgeleid van het grote TCP-pakket, moet gelijk zijn aan of groter zijn dan de MinSegmentCount-waarde die is opgegeven door het minipoortstuurprogramma. Voor meer informatie over de MinSegmentCount-waarde, zie Rapportage van een NIC's LSOv1 TCP-Packet-Segmentation mogelijkheden en Rapportage van een NIC's LSOv2 TCP-Packet-Segmentation mogelijkheden.

De volgende veronderstellingen en beperkingen zijn van toepassing op het verwerken van IP- en TCP-headers voor elk minipoortstuurprogramma dat geschikt is voor LSO, ongeacht de versie:

  • De MF-bit in de IP-header van het grote TCP-pakket dat het TCP/IP-transport heeft afgewikkeld, zal niet worden ingesteld, en de fragmentoffset in de IP-header zal nul zijn.

  • De URG-, RST-en SYN- vlaggen in de TCP-header van het grote TCP-pakket worden niet ingesteld en de urgente verschuiving (aanwijzer) in de TCP-header is nul.

  • Als de FIN- bit in de TCP-header van het grote pakket is ingesteld, moet het minipoortstuurprogramma deze bit instellen in de TCP-header van het laatste pakket dat wordt gemaakt op basis van het grote TCP-pakket.

  • Als de PSH bit in de TCP-header van het grote TCP-pakket is ingesteld, moet het minipoortstuurprogramma deze bit instellen in de TCP-header van het laatste pakket dat wordt gemaakt op basis van het grote TCP-pakket.

  • Als de CWR bit in de TCP-header van het grote TCP-pakket is ingesteld, moet het minipoortstuurprogramma deze bit instellen in de TCP-header van het eerste pakket dat wordt gemaakt op basis van het grote TCP-pakket. Het minipoortstuurprogramma kan ervoor kiezen om deze bit in te stellen in de TCP-header van het laatste pakket dat het maakt op basis van het grote TCP-pakket, hoewel dit minder wenselijk is.

  • Als het grote TCP-pakket IP-opties of TCP-opties (of beide) bevat, kopieert het minipoortstuurprogramma deze opties, ongewijzigd, naar elk pakket dat is afgeleid van het grote TCP-pakket. Specifiek zal de NIC de optie Tijdstempel niet verhogen.

  • Alle pakketheaders (ethernet, IP, TCP) komen voor in de eerste MDL van het pakket. De headers worden niet verdeeld over meerdere MDL's.

    Fooi

    Deze aanname is geldig wanneer LSO is ingeschakeld. Als LSO niet is ingeschakeld, kunnen minipoortstuurprogramma's er anders niet van uitgaan dat IP-headers zich in dezelfde MDL bevinden als ethernetheaders.

Het minipoortstuurprogramma moet de pakketten in NET_BUFFER_LIST structuren verzenden in de volgorde waarin het de NET_BUFFER_LIST structuren van het TCP/IP-transport ontvangt.

Bij het verwerken van een groot TCP-pakket is de minipoortadapter alleen verantwoordelijk voor het segmenteren van het pakket en het aanbrengen van MAC-, IP- en TCP-headers op de pakketten die zijn afgeleid van het grote TCP-pakket. Het TCP/IP-transport voert alle andere taken uit (zoals het aanpassen van de grootte van het verzendvenster op basis van de ontvangstvenstergrootte van de externe host).

Voordat u de verzendbewerking voor het grote pakket voltooit (zoals met NdisMSendNetBufferListsComplete of NdisMCoSendNetBufferListsComplete), schrijft het minipoortstuurprogramma de NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO waarde (NET_BUFFER_LIST informatie voor offloading van grote verzendingen) met het totale aantal TCP-gebruikersgegevensbytes die succesvol zijn verzonden in alle pakketten die zijn gemaakt uit het grote TCP-pakket.

Naast de vorige LSO-vereisten moeten LSOv2-compatibele minipoortstuurprogramma's ook:

  • Ondersteuning voor IPv4 of IPv6, of zowel IPv4 als IPv6.

  • Ondersteuning voor replicatie van de IPv4-opties, van het grote pakket, in elk segmentpakket dat door de netwerkinterfacekaart (NIC) wordt gegenereerd.

  • Ondersteuning voor replicatie van de IPv6-extensieheader, van het grote TCP-pakket, in elk TCP-segmentpakket.

  • Ondersteuning voor replicatie van TCP-opties in elk TCP-segmentpakket dat door het minipoortstuurprogramma wordt gegenereerd.

  • Gebruik de IP- en TCP-header in de NET_BUFFER_LIST-structuur als sjabloon om TCP/IP-headers te genereren voor elk segmentpakket.

  • Gebruik IP-id-waarden (IP-id) in het bereik van 0x0000 tot 0x7FFF. (Het bereik van 0x8000 tot 0xFFFF is gereserveerd voor apparaten die geschikt zijn voor TCP chimney offload.) Als de sjabloon-IP-header bijvoorbeeld begint met een id-veldwaarde van 0x7FFE, moet het eerste TCP-segmentpakket een IP-id-waarde hebben van 0x7FFE, gevolgd door 0x7FFF, 0x0000, 0x0001, etcetera.

  • Gebruik de byte-offset in het TcpHeaderOffset member van NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO om de locatie van de TCP-header te bepalen, beginnend vanaf de eerste byte van het pakket.

  • Beperk het aantal NET_BUFFER structuren dat is gekoppeld aan elke LSOv2-NET_BUFFER_LIST structuur tot één.

    Notitie

    Dit is een nieuwe vereiste voor miniportstuurprogramma's die geschikt zijn voor LSOv2. Deze regel wordt niet expliciet afgedwongen voor LSOv1-minipoortstuurprogramma's, hoewel dit wordt aanbevolen.

  • Bepaal de totale lengte van het pakket door de lengte van de eerste NET_BUFFER-structuur in de NET_BUFFER_LIST-structuur te gebruiken. Dit verschilt van de methodestuurprogramma's voor LSOv1.

  • Ondersteuning voor TCP-opties, IP-opties en IP-extensieheaders.

  • Wanneer een verzendbewerking is voltooid, moet het minipoortstuurprogramma het LsoV2TransmitComplete.Reserved lid van de NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO structuur instellen op nul en het LsoV2TransmitComplete.Type lid op NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE.