Delen via


UDP-segmentatie-offload (USO)

UDP segmentation offload (USO), ondersteund in Windows 10, versie 2004 en hoger, is een functie waarmee netwerkinterfacekaarten (NIC's) de segmentatie van UDP-datagrammen kunnen offloaden die groter zijn dan de maximale transmissie-eenheid (MTU) van het netwerkmedium. Hierdoor vermindert Windows het CPU-gebruik dat is gekoppeld aan TCP/IP-verwerking per pakket. Vereisten voor USO zijn vergelijkbaar met grote send offload versie 2 (LSOv2), wat voor het TCP-transportprotocol is.

Vereisten voor USO

Deze sectie verwijst voornamelijk naar NDIS-protocol en minipoortstuurprogramma's. NDIS Lightweight-filterstuurprogramma's (LWF's) moeten voldoen aan de vereisten voor protocolstuurprogramma's bij het wijzigen of verzenden van pakketten en kunnen er ook van uitgaan dat alle pakketten die zijn geleverd aan de FilterSendNetBufferLists handler voldoen aan de vereisten voor protocolstuurprogramma's.

Miniportstuurprogramma's kunnen de segmentatie van grote UDP-pakketten die groter zijn dan de MTU van het netwerkmedium offloaden. Een NIC die ondersteuning biedt voor de segmentatie van grote UDP-pakketten, moet ook het volgende kunnen doen:

  • IP-controlesommen berekenen voor verzonden pakketten die IPv4-opties bevatten
  • UDP-controlesommen berekenen voor verzonden pakketten

Een minipoortstuurprogramma dat USO ondersteunt, moet het afvoertype bepalen uit de out of band-informatie (OOB) van de NET_BUFFER_LIST-structuur. Als de waarde van de NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO structuur niet-nul is, moet de miniport driver USO uitvoeren. Elke NET_BUFFER_LIST die USO-OOB-gegevens bevat, bevat ook één NET_BUFFER structuur. In het geval dat het minipoortstuurprogramma OID_TCP_OFFLOAD_PARAMETERS heeft ontvangen om USO uit te schakelen, nadat het minipoortstuurprogramma de OID succesvol heeft uitgevoerd, moet het alle NET_BUFFER_LIST weigeren en retourneren die het USO OOB-veld ingesteld hebben.

Het TCP/IP-transport offloadt alleen die UDP-pakketten die voldoen aan deze criteria.

  • Het pakket is een UDP-pakket.
  • De pakketlengte moet groter zijn dan de maximale segmentgrootte (MSS) * (MinSegmentCount - 1).
  • Als het miniport-stuurprogramma de SubMssFinalSegmentSupported-mogelijkheden niet instelt, moet elk groot UDP-pakket dat door het transport wordt uitbesteed, Length % MSS == 0hebben. Dat wil zeggen dat het grote pakket deelbaar is in N pakketten met elk pakketsegment dat exact MSS gebruikersbytes bevat. Als het miniportstuurprogramma de SubMssFinalSegmentSupported capaciteit instelt, is de voorwaarde voor de deelbaarheid van pakketlengtes voor het transport niet van toepassing. Met andere woorden, het laatste segment kan kleiner zijn dan MSS-.
  • Het pakket is geen loopbackpakket.
  • De MF--bit in de IP-header van het grote UDP-pakket dat door de TCP/IP-transportlaag is afgehandeld, wordt niet ingesteld, en de Fragment Offset in de IP-header is nul.
  • De toepassing heeft UDP_SEND_MSG_SIZE/WSASetUdpSendMessageSizeopgegeven.

Voordat u een groot UDP-pakket voor segmentatie offloadt, doet het TCP/IP-transport het volgende:

  • Hiermee werkt u de grote pakketsegmentatiegegevens bij die zijn gekoppeld aan de NET_BUFFER_LIST-structuur. Deze informatie is een NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO structuur die deel uitmaakt van de OOB-informatie van de NET_BUFFER_LIST structuur. Het TCP/IP-transport stelt de MSS-waarde in op de gewenste MSS.
  • Berekent een aanvullingssom voor de UDP pseudoheader en schrijft deze som naar het Checksum veld van de UDP-header. Het TCP/IP-transport berekent de som van de aanvullingen op de volgende velden in de pseudoheader: bron-IP-adres, doel-IP-adres en protocol.

De aanvullingssom van de pseudoheader die wordt geleverd door het TCP/IP-transport geeft de NIC een vroege start bij het berekenen van de echte UDP-controlesom voor elk pakket dat de NIC afleidt van het grote UDP-pakket, zonder de IP-header te hoeven onderzoeken.

Houd er rekening mee dat RFC 768 en RFC 2460- bepaalt dat de pseudoheader wordt berekend via het bron-IP-adres, het doel-IP-adres, het protocol en de UDP-lengte (de lengte van de UDP-header plus de lengte van de UDP-nettolading, niet inclusief de lengte van de pseudoheader). Omdat het onderliggende minipoortstuurprogramma en de NIC UDP-gegevensgrammen genereren uit het grote pakket dat door het TCP/IP-vervoersprotocol wordt doorgegeven, weet het vervoersprotocol echter de grootte van de UDP-payload voor elk UDP-datagram niet en kan het de UDP-lengte dus niet opnemen in de pseudoheaderberekening. In plaats daarvan, zoals beschreven in de volgende sectie, breidt de NIC de pseudoheadercontrolesom uit die is geleverd door het TCP/IP-transport om de UDP-lengte van elk gegenereerd UDP-datagram te dekken.

Belangrijk

Als het UDP-headercontrolesomveld dat door het TCP/IP-transport wordt geleverd nul is, moet de NIC geen UDP-controlesomberekening uitvoeren.

Pakketten verzenden met USO

Nadat het minipoortstuurprogramma de NET_BUFFER_LIST in de MiniportSendNetBufferLists callback-functie heeft verkregen, kan deze de NET_BUFFER_LIST_INFO macro aanroepen met een _Id van UdpSegmentationOffloadInfo om de MSS-waarde en het IP-protocol te verkrijgen.

Het minipoortstuurprogramma verkrijgt de totale lengte van het grote pakket van de lengte van de eerste NET_BUFFER structuur en gebruikt de MSS--waarde om het grote UDP-pakket te verdelen in kleinere UDP-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 bytes gebruikersgegevens bevatten. Alle andere pakketten die zijn gemaakt op basis van het gesegmenteerde pakket, moeten MSS- bytes gebruikersgegevens bevatten. Als een minipoortstuurprogramma niet aan deze regel voldoet, worden de UDP-gegevensgrammen onjuist geleverd. Als het minipoortstuurprogramma de SubMssFinalSegmentSupported mogelijkheid niet instelt, wordt de pakketlengte gedeeld door MSS- en bevat elk van de gesegmenteerde pakketten MSS gebruikersbytes.

Het miniport driver voegt MAC-, IP- en UDP-headers toe aan elk segment dat is afgeleid van het grote pakket. Het minipoortstuurprogramma moet de IP- en UDP-controlesommen voor deze afgeleide pakketten berekenen. Om de UDP-controlesom te berekenen voor elk pakket dat is afgeleid van het grote UDP-pakket, berekent de NIC het variabele deel van de UDP-controlesom (voor de UDP-header en UDP-lading), voegt deze controlesom toe aan de eentegenuitsom van de pseudoheader die is berekend door het TCP/IP-transport, en berekent vervolgens de 16-bits eentegenuitsom voor de controlesom. Zie RFC 768 en RFC 2460voor meer informatie over het berekenen van dergelijke controlesommen.

De lengte van de UDP-gebruikersgegevens in het grote UDP-pakket moet kleiner zijn dan of gelijk zijn aan de waarde die het minipoortstuurprogramma toewijst aan MaxOffLoadSize.

Nadat een stuurprogramma een statusindicatie heeft opgegeven om een wijziging in MaxOffLoadSizeaan te geven, mag het stuurprogramma geen bugcontrole veroorzaken als er een LSO-verzendaanvraag wordt ontvangen die gebruikmaakt van de vorige MaxOffLoadSize waarde. In plaats daarvan moet het stuurprogramma de verzendaanvraag niet uitvoeren. Stuurprogramma's moeten elke verzendaanvraag laten mislukken die ze om welke reden dan ook niet kunnen uitvoeren (inclusief grootte, minimum aantal segmenten, IP-opties, enzovoort). Bestuurders moeten zo snel mogelijk een statusindicatie verzenden als hun capaciteiten veranderen.

Een tussenliggend stuurprogramma dat onafhankelijk statusindicaties uitgeeft die een wijziging in de MaxOffLoadSize waarde rapporteren, 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 miniport-tussenstuurprogramma dat reageert op OID_TCP_OFFLOAD_PARAMETERS om USO-services uit te schakelen, moet voorbereid zijn op een klein tijdsbestek waarin USO-aanvragen nog steeds het miniport-stuurprogramma kunnen bereiken.

Het aantal segmentatiepakketten dat is afgeleid van het grote UDP-pakket moet gelijk zijn aan of groter zijn dan de MinSegmentCount waarde die is opgegeven door het minipoortstuurprogramma.

Bij het verwerken van een groot UDP-pakket is het minipoortstuurprogramma alleen verantwoordelijk voor het segmenteren van het pakket en het aanbrengen van MAC-, IP- en UDP-headers op de pakketten die zijn afgeleid van het grote UDP-pakket. Als de minipoort niet in staat is om ten minste één gesegmenteerd pakket te verzenden, moet de NBL uiteindelijk worden voltooid met foutstatus. De minipoort kan volgende pakketten blijven verzenden, maar is hiervoor niet vereist. De NBL kan niet worden afgerond naar NDIS totdat alle gesegmenteerde pakketten zijn verzonden of mislukt.

Voor USO geschikte minipoortstuurprogramma's moeten ook het volgende doen:

  • Ondersteuning voor zowel IPv4 als IPv6.
  • Ondersteuning voor replicatie van IPv4-opties van het grote pakket in elk gesegmenteerd pakket dat door de NIC wordt gegenereerd.
  • Gebruik de IP- en UDP-header in de NET_BUFFER_LIST-structuur als sjabloon om UDP- en IP-headers te genereren voor elk gesegmenteerd pakket.
  • Gebruik IP ID-waarden (IP ID) in het bereik van 0x0000 tot 0xFFFF. Als de sjabloon-IP-header bijvoorbeeld begint met een id-veldwaarde van 0xFFFE, moet het eerste UDP-gegevensgrampakket een waarde hebben van 0xFFFE, gevolgd door 0xFFFF, 0x0000, 0x0001enzovoort.
  • Als het grote UDP-pakket IP-opties bevat, kopieert het minipoortstuurprogramma deze opties, ongewijzigd, naar elk pakket dat is afgeleid van het grote UDP-pakket.
  • Gebruik de byte-offset in het UdpHeaderOffset lid van NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO om de locatie van de UDP-header te bepalen, beginnend vanaf de eerste byte van het pakket.
  • Incrementele overdrachtsstatistieken op basis van de gesegmenteerde pakketten. Neem bijvoorbeeld het aantal bytes van de Ethernet-, IP- en UDP-headers op voor elk pakketsegment. Het aantal pakketten komt overeen met het aantal segmenten ter grootte van MSS, en niet 1.
  • Stel de velden totale lengte en IP-lengte van de UDP in op basis van elke gesegmenteerde datagramgrootte.

NDIS-interfacewijzigingen

In deze sectie worden de wijzigingen in NDIS 6.83 beschreven waarmee de host-TCP/IP-stuurprogrammastack de USO-mogelijkheden kan benutten die worden weergegeven door minipoortstuurprogramma's.

NDIS en het minipoortstuurprogramma voeren het volgende uit:

  • Adverteren dat de NIC ONDERSTEUNING biedt voor USO-functionaliteit
  • USO in- of uitschakelen
  • De huidige USO-functionaliteitsstatus ophalen

Adverteren van USO-functionaliteit

Miniportstuurprogramma's geven USO-capaciteit aan door het UdpSegmentation-veld van de NDIS_OFFLOAD-structuur in te vullen, die wordt doorgegeven in de parameters van NdisMSetMiniportAttributes. Het Header.Revision veld in de NDIS_OFFLOAD structuur moet worden ingesteld op NDIS_OFFLOAD_REVISION_6 en het Header.Size veld moet worden ingesteld op NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_6.

USO-status opvragen

De huidige USO-status kan worden opgevraagd met OID_TCP_OFFLOAD_CURRENT_CONFIG. NDIS verwerkt deze OID en geeft deze niet door aan het minipoortstuurprogramma.

USO-status wijzigen

USO kan worden ingeschakeld of uitgeschakeld met OID_TCP_OFFLOAD_PARAMETERS. Nadat het minipoortstuurprogramma de OID heeft verwerkt, moet deze een NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG statusindicatie met de bijgewerkte offloadstatus verzenden.

USO-trefwoorden

De USO-opsommingstrefwoorden zijn als volgt:

  • *UsoIPv4
  • *UsoIPv6

Deze waarden beschrijven of USO is ingeschakeld of uitgeschakeld voor dat specifieke IP-protocol. De USO-instellingen zijn niet afhankelijk van de NDIS_TCP_IP_CHECKSUM_OFFLOAD-configuratie. Als u bijvoorbeeld *UDPChecksumOffloadIPv4 uitschakelt, wordt *UsoIPv4niet impliciet uitgeschakeld.

Naam van subsleutel Parameterbeschrijving Waarde Opsommingsbeschrijving
*UsoIPv4 USO (IPv4) 0 Uitgeschakeld
1 Ingeschakeld
*UsoIPv6 USO (IPV6) 0 Uitgeschakeld
1 Ingeschakeld