Condividi tramite


Spostare la segmentazione di pacchetti TCP di grandi dimensioni

I driver miniport NDIS (Network Driver Interface Specification) possono scaricare la segmentazione di pacchetti TCP di grandi dimensioni che superano la massima unità di trasmissione (MTU) del supporto di rete. Una scheda di interfaccia di rete che supporta la segmentazione di pacchetti TCP di grandi dimensioni deve anche essere in grado di:

  • Calcolare i checksum IP per i pacchetti da inviare che contengono 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 invio di grandi dimensioni versione 1 (LSOv1), 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 invio di grandi dimensioni versione 2 (LSOv2), che offre servizi avanzati di segmentazione dei pacchetti, incluso il supporto per IPv6.

Un driver miniport che supporta LSOv2 e LSOv1 deve determinare il tipo di offload dalle informazioni fuori banda (OOB) della struttura NET_BUFFER_LIST. Il driver può usare il tipo membro 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 ulteriori informazioni su NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, vedere Informazioni sull'offload TCP/IP NET_BUFFER_LIST.

Tuttavia, in un caso in cui il miniport abbia ricevuto gli OID_TCP_OFFLOAD_PARAMETERS per disattivare la funzionalità LSO sul miniport e dopo che il miniport ha completato correttamente l'OID, il miniport deve scartare tutte le NET_BUFFER_LIST che contengono qualsiasi dato LSOv1 o LSOv2 OOB diverso da zero (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:

  • Il pacchetto è un pacchetto TCP. Il trasporto TCP/IP non esegue l'offload di pacchetti UDP di grandi dimensioni per la segmentazione.

  • Il pacchetto deve essere divisibile per almeno il numero minimo di segmenti specificati dal driver miniport. Per ulteriori informazioni, vedere Segnalazione delle capacità TCP di LSOv1 di una NICPacket-Segmentation e Segnalazione delle capacità TCP di LSOv2 di una NICPacket-Segmentation.

  • Il pacchetto non è un pacchetto di loopback.

  • Il pacchetto non verrà inviato tramite un tunnel.

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 Total Length 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 Total Length dell'intestazione IP del pacchetto su 0. I driver Miniport devono determinare la lunghezza del pacchetto a partire dalla lunghezza della prima struttura NET_BUFFER nella struttura NET_BUFFER_LIST.

  • Calcola somma di complementi per lo pseudoheader TCP e scrive questa somma nel campo Checksum dell'intestazione TCP. Il trasporto TCP/IP calcola la somma del complemento di uno sui campi seguenti nello pseudoheader: Source IP Address, Destination IP Addresse Protocol. 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 di pseudo-intestazione viene calcolato su Source IP Address, Destination IP Address, Protocole TCP Length. 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 Sequence Number dell'intestazione TCP. Il numero di sequenza identifica il primo byte del payload TCP.

Dopo che il driver miniport ottiene la struttura di 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. Solo l'ultimo pacchetto creato dal pacchetto grande segmentato deve contenere meno byte di dati utente rispetto all'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 aggiunge 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 grande pacchetto TCP, la NIC calcola la parte variabile del checksum TCP (per l'intestazione TCP e il payload TCP), aggiunge questo checksum alla somma complemento a uno per lo pseudoheader calcolato dal trasporto TCP/IP, e quindi calcola il complemento a uno a 16 bit del checksum. Per altre informazioni sul calcolo di tali checksum, vedere RFC 793 e RFC 1122.

La figura seguente mostra 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 ulteriori informazioni sul valore MaxOffLoadSize, consultare Segnalazione delle capacità TCP LSOv1 di una NICPacket-Segmentation e Segnalazione delle capacità TCP LSOv2 di una NICPacket-Segmentation.

Dopo che un driver ha emesso un'indicazione di stato per segnalare una modifica al valore MaxOffLoadSize, non deve andare in crash se riceve una richiesta di invio LSO che utilizza 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 abbia emesso un'indicazione di stato non ottenga pacchetti di dimensioni maggiori rispetto al valore MaxOffLoadSize segnalato dall'adattatore miniport.

Un driver intermedio-miniport che risponde a OID_TCP_OFFLOAD_PARAMETERS per disabilitare i servizi LSO deve essere preparato per un breve periodo di tempo in cui le richieste di invio LSO potrebbero comunque raggiungere il driver miniport.

La lunghezza dei dati utente TCP in un pacchetto segmento deve essere minore o uguale all'MSS. MSS è il valore ULONG passato dal trasporto TCP utilizzando le informazioni di NET_BUFFER_LIST LSO associate alla struttura NET_BUFFER_LIST. 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 and Reporting 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 grande pacchetto TCP che il trasporto TCP/IP ha offloadato non verrà impostato e l'offset del frammento nell'intestazione IP sarà zero.

  • Il flag URG, i flag RSTe i flag SYN nell'intestazione TCP del pacchetto TCP di grandi dimensioni non verranno impostati, e l'offset d'urgenza (puntatore) nell'intestazione TCP sarà zero.

  • Se i bit FIN nell'intestazione TCP del pacchetto di grandi dimensioni sono impostati, il driver miniport deve impostare questi bit nell'intestazione TCP dell'ultimo pacchetto che crea dal grande pacchetto TCP.

  • Se la PSH bit nell'intestazione TCP del pacchetto TCP di grandi dimensioni è impostata, 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 grande pacchetto TCP è impostato, il driver miniport deve impostare questo bit nell'intestazione TCP del primo pacchetto che crea dal grande pacchetto TCP. Il driver miniport potrebbe scegliere di impostare questo bit nell'intestazione TCP dell'ultimo pacchetto che crea dal grande pacchetto TCP, anche se questo è meno preferibile.

  • 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 Time Stamp.

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

    Mancia

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

Il driver miniport deve inviare i pacchetti nelle 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 trasmissione 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 (informazioniNET_BUFFER_LIST per lo scaricamento dell'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 precedenti per LSO, anche i driver miniport con supporto per LSOv2 devono:

  • Supportare sia IPv4 che IPv6, o entrambi.

  • 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 compreso tra 0x0000 e 0x7FFF. L'intervallo compreso tra 0x8000 e 0xFFFF è riservato per i dispositivi compatibili con offload TCP. Ad esempio, se l'intestazione IP del modello inizia con un valore del campo Identificazione di 0x7FFE, il primo pacchetto di segmento TCP deve avere un valore ID IP di 0x7FFE, seguito da 0x7FFF, 0x0000, 0x0001 e così via.

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

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

    Nota

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

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

  • Sostenere le opzioni TCP, le opzioni IP e le intestazioni di estensione IP.

  • Al termine di un'operazione di invio, il driver miniport deve impostare il membro LsoV2TransmitComplete.Reserved 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.