Offload della segmentazione di pacchetti TCP di grandi dimensioni

I driver miniport NDIS possono eseguire l'offload della segmentazione di pacchetti TCP di grandi dimensioni maggiori dell'unità di trasmissione massima (MTU) del supporto di rete. Anche una scheda di interfaccia di rete che supporta la segmentazione di pacchetti TCP di grandi dimensioni deve essere in grado di:

  • Calcolare i checksum IP per i pacchetti di invio contenenti opzioni IP.

  • Calcolare i checksum TCP per i pacchetti di invio contenenti opzioni TCP.

Le versioni NDIS 6.0 e successive supportano l'offload di trasmissione di grandi dimensioni versione 1 (LSOv1), che è simile all'offload di invio di grandi dimensioni (LSO) in NDIS 5. x. Le versioni NDIS 6.0 e successive supportano anche l'offload di trasmissione di grandi dimensioni versione 2 (LSOv2), che offre servizi avanzati di segmentazione di pacchetti di grandi dimensioni, incluso il supporto per IPv6.

Un driver miniport che supporta LSOv2 e LSOv1 deve determinare il tipo di offload dalle informazioni OOB della struttura NET_BUFFER_LIST . Il driver può usare il membro Type della struttura NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO per determinare se lo stack di driver usa LSOv2 o LSOv1 ed eseguire i servizi di offload appropriati. Qualsiasi struttura NET_BUFFER_LIST che contiene i dati LSOv1 o LSOv2 OOB contiene anche una singola struttura NET_BUFFER . Per altre informazioni sulle NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, vedere Accesso alle informazioni sull'offload TCP/IP NET_BUFFER_LIST.

Tuttavia, in un caso in cui il miniport ha ricevuto OID_TCP_OFFLOAD_PARAMETERS per disattivare la funzionalità LSO sul miniport e dopo che il miniport ha completato correttamente l'OID, il miniport deve eliminare tutte le NET_BUFFER_LIST che contengono qualsiasi LSOv1 o LSOv2 OOB data(NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO).

Il trasporto TCP/IP esegue l'offload solo dei pacchetti TCP di grandi dimensioni che soddisfano i criteri seguenti:

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

  • Per LSOv1, scrive la lunghezza totale del pacchetto TCP di grandi dimensioni nel campo Lunghezza totale dell'intestazione IP del pacchetto. La lunghezza totale include la lunghezza dell'intestazione IP, la lunghezza delle opzioni IP, se presenti, la lunghezza dell'intestazione TCP, la lunghezza delle opzioni TCP, se presenti e la lunghezza del payload TCP. Per LSOv2, imposta il campo Lunghezza totale dell'intestazione IP del pacchetto su 0. I driver Miniport devono determinare la lunghezza del pacchetto dalla lunghezza della prima struttura NET_BUFFER nella struttura NET_BUFFER_LIST.

  • Calcola la somma di un complemento per lo pseudoheader TCP e scrive questa somma nel campo Checksum dell'intestazione TCP. Il trasporto TCP/IP calcola la somma del complemento dei campi seguenti nello pseudoheader: Indirizzo IP di origine, Indirizzo IP di destinazione e Protocollo. La somma del complemento per lo pseudoheader fornito dal trasporto TCP/IP fornisce alla scheda di interfaccia di rete un inizio iniziale nel calcolo del checksum TCP reale per ogni pacchetto che la scheda di interfaccia di rete deriva dal pacchetto TCP di grandi dimensioni senza dover esaminare l'intestazione IP. Si noti che RFC 793 stabilisce che il checksum pseudo-intestazione viene calcolato sull'indirizzo IP di origine, indirizzo IP di destinazione, protocollo e lunghezza TCP. La lunghezza TCP è la lunghezza dell'intestazione TCP più la lunghezza del payload TCP. La lunghezza TCP non include la lunghezza della pseudo-intestazione. Tuttavia, poiché il driver miniport sottostante e la scheda di interfaccia di rete generano segmenti TCP dal pacchetto di grandi dimensioni passato dal trasporto TCP/IP, il trasporto non conosce le dimensioni del payload TCP per ogni segmento TCP e pertanto non può includere la lunghezza TCP nella pseudo-intestazione. Come descritto di seguito, la scheda di interfaccia di rete estende invece il checksum di pseudo-intestazione fornito dal trasporto TCP/IP per coprire la lunghezza TCP di ogni segmento TCP generato.

  • Scrive il numero di sequenza corretto nel campo Numero di sequenza dell'intestazione TCP. Il numero di sequenza identifica il primo byte del payload TCP.

Dopo che il driver miniport ottiene la struttura NET_BUFFER_LIST nella relativa funzione MiniportSendNetBufferLists o MiniportCoSendNetBufferLists , può chiamare la macro NET_BUFFER_LIST_INFO con un _Id di TcpLargeSendNetBufferListInfo per ottenere il valore MSS scritto dal trasporto TCP/IP.

Il driver miniport ottiene la lunghezza totale del pacchetto di grandi dimensioni dall'intestazione IP del pacchetto e usa il valore MSS per dividere il pacchetto TCP di grandi dimensioni in pacchetti più piccoli. Ognuno dei pacchetti più piccoli contiene mss o meno byte di dati utente. Si noti che solo l'ultimo pacchetto creato dal pacchetto di grandi dimensioni segmentato 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 non si segue questa regola, la creazione e la trasmissione di pacchetti aggiuntivi non necessari potrebbero compromettere le prestazioni.

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

Nella figura seguente viene illustrata la segmentazione di un pacchetto di grandi dimensioni.

Diagramma che mostra la segmentazione di un pacchetto TCP di grandi dimensioni in pacchetti più piccoli con intestazioni MAC, IP e TCP.

La lunghezza dei dati utente TCP nel pacchetto TCP di grandi dimensioni deve essere uguale o minore del valore assegnato dal driver miniport al valore MaxOffLoadSize . Per altre informazioni sul valore MaxOffLoadSize , vedere Reporting a NIC's LSOv1 TCP-Packet-Segmentation Capabilities andReporting a NIC's LSOv2 TCP-Packet-Segmentation Capabilities.

Dopo che un driver emette un'indicazione di stato per indicare una modifica al valore MaxOffLoadSize , il driver non deve arrestarsi in modo anomalo se riceve una richiesta di invio LSO che usa il valore MaxOffLoadSize precedente. Al contrario, il driver può non riuscire a inviare la richiesta.

Un driver intermedio che emette in modo indipendente indicazioni sullo stato che segnalano una modifica nel valore MaxOffLoadSize deve garantire che l'adattatore miniport sottostante che non ha emesso un'indicazione di stato non ottiene pacchetti di dimensioni maggiori rispetto al valore MaxOffLoadSize segnalato dall'adattatore miniport.

Un driver miniport-intermedio che risponde a OID_TCP_OFFLOAD_PARAMETERS per disattivare i servizi LSO deve essere preparato per un piccolo intervallo di tempo in cui LSO invia richieste potrebbe comunque raggiungere il driver miniport.

La lunghezza dei dati utente TCP in un pacchetto di segmento deve essere minore o uguale a MSS. MSS è il valore ULONG che il trasporto TCP passa usando le informazioni NET_BUFFER_LIST LSO associate alla struttura NET_BUFFER_LIST . Si noti che solo l'ultimo pacchetto creato dal pacchetto di grandi dimensioni segmentato 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 non si segue questa regola, la creazione e la trasmissione di pacchetti aggiuntivi non necessari potrebbero compromettere le prestazioni.

Il numero di pacchetti di segmento derivati dal pacchetto TCP di grandi dimensioni deve essere uguale o maggiore del valore MinSegmentCount specificato dal driver miniport. Per altre informazioni sul valore MinSegmentCount , vedere Reporting a NIC's LSOv1 TCP-Packet-Segmentation Capabilities andReporting a NIC's LSOv2 TCP-Packet-Segmentation Capabilities.

I presupposti e le restrizioni seguenti si applicano all'elaborazione di intestazioni IP e TCP per qualsiasi driver miniport con supporto per LSO indipendentemente dalla versione:

  • Il bit MF nell'intestazione IP del pacchetto TCP di grandi dimensioni che il trasporto TCP/IP offloaded non verrà impostato e l'offset frammento nell'intestazione IP sarà zero.

  • I flag URG, RST e SYN nell'intestazione TCP del pacchetto TCP di grandi dimensioni non verranno impostati e l'offset urgente (puntatore) nell'intestazione TCP sarà zero.

  • Se il bit FIN nell'intestazione TCP del pacchetto di grandi dimensioni è impostato, il driver miniport deve impostare questo bit nell'intestazione TCP dell'ultimo pacchetto creato dal pacchetto TCP di grandi dimensioni.

  • Se il bit PSH nell'intestazione TCP del pacchetto TCP di grandi dimensioni è impostato, il driver miniport deve impostare questo bit nell'intestazione TCP dell'ultimo pacchetto creato dal pacchetto TCP di grandi dimensioni.

  • Se il bit CWR nell'intestazione TCP del pacchetto TCP di grandi dimensioni è impostato, il driver miniport deve impostare questo bit nell'intestazione TCP del primo pacchetto creato dal pacchetto TCP di grandi dimensioni. Il driver miniport può scegliere di impostare questo bit nell'intestazione TCP dell'ultimo pacchetto creato dal pacchetto TCP di grandi dimensioni, anche se questo è meno auspicabile.

  • Se il pacchetto TCP di grandi dimensioni contiene opzioni IP o opzioni TCP (o entrambe), il driver miniport copia queste opzioni, non modificate, in ogni pacchetto derivato dal pacchetto TCP di grandi dimensioni. In particolare, la scheda di interfaccia di rete non incrementerà l'opzione TimeStamp.

  • Tutte le intestazioni di pacchetto (Ethernet, IP, TCP) saranno incluse nel primo MDL del pacchetto. Le intestazioni non verranno suddivise tra più elenchi di dati mdls.

    Suggerimento

    Questo presupposto è valido quando LSO è abilitato. In caso contrario, quando LSO non è abilitato, i driver miniport non possono presupporre che le intestazioni IP si trovino nello stesso MDL delle intestazioni Ethernet.

Il driver miniport deve inviare i pacchetti in strutture NET_BUFFER_LIST nell'ordine in cui riceve le strutture NET_BUFFER_LIST dal trasporto TCP/IP.

Quando si elabora un pacchetto TCP di grandi dimensioni, l'adattatore miniport è responsabile solo della segmentazione del pacchetto e dell'affisso di intestazioni MAC, IP e TCP ai pacchetti derivati dal pacchetto TCP di grandi dimensioni. Il trasporto TCP/IP esegue tutte le altre attività, ad esempio modificando le dimensioni della finestra di invio in base alle dimensioni della finestra di ricezione dell'host remoto.

Prima di completare l'operazione di invio per il pacchetto di grandi dimensioni, ad esempio con NdisMSendNetBufferListsComplete o NdisMCoSendNetBufferListsComplete, il driver miniport scrive il valore NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO (NET_BUFFER_LIST informazioni per offload di invio di grandi dimensioni) con il numero totale di byte di dati utente TCP inviati correttamente in tutti i pacchetti creati dal pacchetto TCP di grandi dimensioni.

Oltre ai requisiti LSO precedenti, anche i driver miniport che supportano LSOv2 devono:

  • Supportare IPv4 o IPv6 o IPv4 e IPv6.

  • Supportare la replica delle opzioni IPv4, dal pacchetto di grandi dimensioni, in ogni pacchetto di segmento generato dalla scheda di interfaccia di rete.Support replication of the IPv4 options, from the large packet, in each segment packet that the network interface card (NIC) generate.

  • Supportare la replica dell'intestazione dell'estensione IPv6, dal pacchetto TCP di grandi dimensioni, in ogni pacchetto di segmento TCP.

  • Supportare la replica delle opzioni TCP in ogni pacchetto di segmento TCP generato dal driver miniport.

  • Usare l'intestazione IP e TCP nella struttura NET_BUFFER_LIST come modello per generare intestazioni TCP/IP per ogni pacchetto di segmento.

  • Usare i valori di identificazione IP (ID IP) nell'intervallo tra 0x0000 e 0x7FFF. L'intervallo tra 0x8000 e 0xFFFF è riservato per i dispositivi con supporto per l'offload del camino TCP. Ad esempio, se l'intestazione IP del modello inizia con un valore di campo Identificazione di 0x7FFE, il primo pacchetto del segmento TCP deve avere un valore ID IP di 0x7FFE, seguito da 0x7FFF, 0x0000, 0x0001 e così via.

  • Utilizzare l'offset di byte nel membro TcpHeaderOffset di NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO per determinare la posizione dell'intestazione TCP, a partire dal primo byte del pacchetto.

  • Limitare il numero di strutture NET_BUFFER associate a ogni struttura NET_BUFFER_LIST LSOv2 a una.

    Nota

    Si tratta di un nuovo requisito per i driver miniport che supportano LSOv2. Questa regola non viene applicata per i driver miniport LSOv1 in modo esplicito, anche se è consigliabile.

  • Determinare la lunghezza totale del pacchetto dalla lunghezza della prima struttura NET_BUFFER nella struttura NET_BUFFER_LIST. Questo è diverso dai driver del metodo usati per LSOv1.

  • Supportare le opzioni TCP, le opzioni IP e le intestazioni dell'estensione IP.

  • Al termine di un'operazione di invio, il driver miniport deve impostare il membro LsoV2TransmitComplete.Riservato della struttura NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO su zero e il membro LsoV2TransmitComplete.Type su NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE.