Offload della segmentazione UDP (USO)

UDP Segmentation Offload (USO), supportato in Windows 10, versione 2004 e successive, è una funzionalità che consente alle schede di interfaccia di rete (NIC) di scaricare la segmentazione dei datagrammi UDP maggiori dell'unità massima di trasmissione (MTU) del supporto di rete. In questo modo, Windows l'utilizzo della CPU associato all'elaborazione TCP/IP per pacchetto. I requisiti per USO sono simili a LSOv2, che è per il protocollo di trasporto TCP.

Requisiti per USO

Questa sezione fa riferimento principalmente al protocollo NDIS e ai driver miniport. I driver filtro leggero NDIS (LWF) devono soddisfare i requisiti dei driver di protocollo quando si modificano o inviano pacchetti e possono anche presupporre che tutti i pacchetti forniti al gestore FilterSendNetBufferLists soddisfino i requisiti del driver di protocollo.

I driver miniport possono eseguire l'offload della segmentazione di pacchetti UDP di grandi dimensioni maggiori rispetto all'MTU del supporto di rete. Anche una scheda di interfaccia di rete che supporta la segmentazione di pacchetti UDP di grandi dimensioni deve essere in grado di eseguire le operazioni seguenti:

  • Calcolare i checksum IP per i pacchetti inviati che contengono opzioni IPv4
  • Calcolare i checksum UDP per i pacchetti inviati

Un driver miniport che supporta USO deve determinare il tipo di offload dalle NET_BUFFER_LIST fuori banda (OOB) della struttura. Se il valore della struttura NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO è diverso da zero, il driver miniport deve eseguire USO. Qualsiasi NET_BUFFER_LIST che contiene dati OOB uso contiene anche una singola NET_BUFFER struttura. Tuttavia, nel caso in cui il driver miniport abbia ricevuto OID_TCP_OFFLOAD_PARAMETERS per disattivare USO, dopo che il driver miniport ha completato correttamente l'OID, deve rifiutare e restituire qualsiasi NET_BUFFER_LIST con il campo USO OOB impostato.

Il trasporto TCP/IP scarica solo i pacchetti UDP che soddisfano i criteri seguenti:

  • Il pacchetto è un pacchetto UDP.
  • La lunghezza del pacchetto deve essere maggiore della dimensione massima del segmento (MSS) * (MinSegmentCount - 1).
  • Se il driver miniport non imposta la funzionalità SubMssFinalSegmentSupported , ogni pacchetto UDP di grandi dimensioni scaricato dal trasporto deve avere Lunghezza % MSS == 0. Ciò significa che il pacchetto di grandi dimensioni è divisibile in N pacchetti con ogni segmento di pacchetto contenente esattamente byte utente MSS . Se il driver miniport imposta la funzionalità SubMssFinalSegmentSupported , questa condizione di divisione della lunghezza del pacchetto nel trasporto non viene applicata. In altre parole, il segmento finale può essere minore di MSS.
  • Il pacchetto non è un pacchetto di loopback.
  • Il bit MF nell'intestazione IP del pacchetto UDP di grandi dimensioni che il trasporto TCP/IP scaricato non verrà impostato e l'offset di frammento nell'intestazione IP sarà zero.
  • L'applicazione ha specificato UDP_SEND_MSG_SIZE/WSASetUdpSendMessageSize.

Prima di eseguire l'offload di un pacchetto UDP di grandi dimensioni per la segmentazione, il trasporto TCP/IP esegue le operazioni seguenti:

  • Aggiorna le informazioni di segmentazione di pacchetti di grandi dimensioni associate alla NET_BUFFER_LIST struttura. Queste informazioni sono una NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO struttura che fa parte delle NET_BUFFER_LIST OOB della struttura. Il trasporto TCP/IP imposta il valore MSS sul servizio MSS desiderato.
  • Calcola la somma del complemento di uno per lo pseudo-intestazione UDP e scrive la somma nel campo Checksum dell'intestazione UDP. Il trasporto TCP/IP calcola la somma dei complementi di uno sui campi seguenti nello pseudo-intestazione: Indirizzo IP di origine, Indirizzo IP di destinazione e Protocollo.

La somma del complemento per la pseudo-intestazione fornita dal trasporto TCP/IP offre alla scheda di interfaccia di rete un inizio anticipato nel calcolo del checksum UDP reale per ogni pacchetto derivato dalla scheda di interfaccia di rete dal pacchetto UDP di grandi dimensioni, senza dover esaminare l'intestazione IP.

Si noti che RFC 768 e RFC 2460 prevedono che lo pseudoheader sia calcolato sull'indirizzo IP di origine, sull'indirizzo IP di destinazione, sul protocollo e sulla lunghezza UDP (lunghezza dell'intestazione UDP più la lunghezza del payload UDP, senza includere la lunghezza dello pseudoheader). Tuttavia, poiché il driver miniport sottostante e la scheda di interfaccia di rete generano datagrammi UDP dal pacchetto di grandi dimensioni passato dal trasporto TCP/IP, il trasporto non conosce le dimensioni del payload UDP per ogni datagramma UDP e pertanto non può includere la lunghezza UDP nel calcolo pseudo-intestazione. Come descritto nella sezione seguente, la scheda di interfaccia di rete estende invece il checksum pseudo-intestazione fornito dal trasporto TCP/IP per coprire la lunghezza UDP di ogni datagramma UDP generato.

Importante

Se il campo checksum dell'intestazione UDP fornito dal trasporto TCP/IP è zero, la scheda di interfaccia di rete non deve eseguire il calcolo del checksum UDP.

Invio di pacchetti con USO

Dopo che il driver miniport ottiene il NET_BUFFER_LIST nella funzione di callback MiniportSendNetBufferLists , può chiamare la macro NET_BUFFER_LIST_INFO con un _Id di UdpSegmentationOffloadInfo per ottenere il valore MSS e il protocollo IP.

Il driver miniport ottiene la lunghezza totale del pacchetto di grandi dimensioni dalla lunghezza della prima struttura NET_BUFFER e usa il valore MSS per dividere il pacchetto UDP di grandi dimensioni in pacchetti UDP più piccoli. Ognuno dei pacchetti più piccoli contiene mss o un numero minore di byte di dati utente. Si noti che solo l'ultimo pacchetto creato dal pacchetto segmentato di grandi dimensioni deve contenere meno di byte di dati utente MSS . Tutti gli altri pacchetti creati dal pacchetto segmentato devono contenere byte di dati utente MSS . Se un driver miniport non rispetta questa regola, i datagrammi UDP verranno recapitati in modo non corretto. Se il driver miniport non imposta la funzionalità SubMssFinalSegmentSupported , la lunghezza del pacchetto viene diviso per MSS e ognuno dei pacchetti segmentati contiene byte utente MSS .

Il driver miniport apposta intestazioni MAC, IP e UDP a ogni segmento derivato dal pacchetto di grandi dimensioni. Il driver miniport deve calcolare i checksum IP e UDP per questi pacchetti derivati. Per calcolare il checksum UDP per ogni pacchetto derivato dal pacchetto UDP di grandi dimensioni, la scheda di interfaccia di rete calcola la parte variabile del checksum UDP (per l'intestazione UDP e il payload UDP), aggiunge questo checksum alla somma del complemento per lo pseudo-intestazione calcolata dal trasporto TCP/IP, quindi calcola il complemento a 16 bit per il checksum. Per altre informazioni sul calcolo di tali checksum, vedere RFC 768 e RFC 2460.

La lunghezza dei dati utente UDP nel pacchetto UDP di grandi dimensioni deve essere minore o uguale al valore assegnato dal driver miniport al valore MaxOffLoadSize .

Dopo che un driver ha inviato un'indicazione di stato per indicare una modifica al valore MaxOffLoadSize , il driver non deve causare un controllo di bug se riceve una richiesta di invio LSO che usa il valore MaxOffLoadSize precedente . Al contrario, il driver deve non inviare la richiesta. I driver devono avere esito negativo per qualsiasi richiesta di invio che non possono eseguire, per qualsiasi motivo (tra cui dimensioni, numero minimo di segmenti, opzioni IP e così via). I driver devono inviare un'indicazione di stato il prima possibile se le funzionalità cambiano.

Un driver intermedio che emesso in modo indipendente indica che segnala una modifica nel valore MaxOffLoadSize deve garantire che l'adattatore miniport sottostante che non ha emesso un'indicazione di stato non otterrà pacchetti maggiori del valore MaxOffLoadSize segnalato dall'adapter miniport.

Un driver intermedio miniport che risponde OID_TCP_OFFLOAD_PARAMETERS per disattivare i servizi USO deve essere preparato per un intervallo di tempo ridotto in cui le richieste USO potrebbero ancora raggiungere il driver miniport.

Il numero di pacchetti di segmentazione che sono stati dervisati dal pacchetto UDP di grandi dimensioni deve essere uguale o maggiore del valore MinSegmentCount specificato dal driver miniport.

Quando si elabora un pacchetto UDP di grandi dimensioni, il driver miniport è responsabile solo della segmentazione del pacchetto e dell'assegnazione delle intestazioni MAC, IP e UDP ai pacchetti derivati dal pacchetto UDP di grandi dimensioni. Se il miniport non riesce a inviare almeno un pacchetto segmentato, l'NBL deve essere completato con uno stato di errore. Il miniport può continuare a inviare pacchetti successivi, ma non è necessario. L'NBL non può essere completato in NDIS fino a quando tutti i pacchetti segmentati non sono stati trasmessi o non hanno avuto esito negativo.

Anche i driver miniport con funzionalità USO devono eseguire le operazioni seguenti:

  • Supporta sia IPv4 che IPv6.
  • Supportare la replica delle opzioni IPv4 dal pacchetto di grandi dimensioni in ogni pacchetto segmentato generato dalla scheda di interfaccia di rete.
  • Usare l'intestazione IP e UDP nella struttura NET_BUFFER_LIST come modello per generare intestazioni UDP e IP per ogni pacchetto segmentato.
  • Usare i valori di identificazione IP (ID IP) nell'intervallo 0x0000 a 0xFFFF. Ad esempio, se l'intestazione IP del modello inizia con un valore del campo Identification pari a 0xFFFE, il primo pacchetto di datagrammi UDP deve avere un valore 0xFFFE, seguito da 0xFFFF, 0x0000, 0x0001 e così via.
  • Se il pacchetto UDP di grandi dimensioni contiene opzioni IP, il driver miniport copia queste opzioni, senza modifiche, in ogni pacchetto derivato dal pacchetto UDP di grandi dimensioni.
  • Usare l'offset di byte nel membro UdpHeaderOffsetdi NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO per determinare la posizione dell'intestazione UDP, a partire dal primo byte del pacchetto.
  • Incrementare le statistiche di trasmissione in base ai pacchetti segmentati. Includere ad esempio il numero di byte di intestazione Ethernet, IP e UDP per ogni segmento di pacchetto e il numero di pacchetti è il numero di segmenti di dimensioni MSS, non 1.
  • Impostare i campi Lunghezza totale UDP e Lunghezza IP in base alle dimensioni di ogni datagramma segmentato.

Modifiche all'interfaccia NDIS

Questa sezione descrive le modifiche in NDIS 6.83 che consentono lo stack di driver TCP/IP host di sfruttare le funzionalità dell'uso esposte dai driver miniport.

NDIS e il driver miniport eseguono le operazioni seguenti:

  • Annunciare che la scheda di interfaccia di rete supporta la funzionalità USO
  • Abilitare o disabilitare USO
  • Ottenere lo stato della funzionalità USO corrente

Funzionalità uso pubblicitario

I driver miniport annunciano la funzionalità USO compilando il campo UdpSegmentation della struttura NDIS_OFFLOAD , che viene passato nei parametri di NdisMSetMiniportAttributes. Il campo Header.Revision nella struttura NDIS_OFFLOAD deve essere impostato su NDIS_OFFLOAD_REVISION_6 e il campo Header.Size deve essere impostato su NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_6.

Esecuzione di query sullo stato uso

È possibile eseguire query sullo stato uso corrente con OID_TCP_OFFLOAD_CURRENT_CONFIG. NDIS gestisce questo OID e non lo passa al driver miniport.

Modifica dello stato di USO

USO può essere abilitato o disabilitato usando OID_TCP_OFFLOAD_PARAMETERS. Dopo che il driver miniport elabora l'OID, deve inviare un'indicazione NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG stato con lo stato di offload aggiornato.

Parole chiave di USO

Le parole chiave dell'enumerazione USO sono le seguenti:

  • *UsoIPv4
  • *UsoIPv6

Questi valori descrivono se USO è abilitato o disabilitato per quel particolare protocollo IP. Le impostazioni di USO non dipendono dalla configurazione NDIS_TCP_IP_CHECKSUM_OFFLOAD configurazione. Ad esempio, la disabilitazione di *UDPChecksumOffloadIPv4 non disabilita in modo implicito *UsoIPv4.

Nome della sottochiave Descrizione dei parametri Valore Descrizione dell'enumerazione
*UsoIPv4 Offload della segmentazione UDP (IPv4) 0 Disabled
1 Attivato
*UsoIPv6 Offload della segmentazione UDP (IPV6) 0 Disabled
1 Attivato