Udostępnij za pośrednictwem


Odciąż segmentację dużych pakietów TCP

Sterowniki miniportu specyfikacji NDIS (Network Driver Interface Specification) mogą odciążać segmentację dużych pakietów TCP, które są większe niż maksymalna jednostka transmisji (MTU) nośnika sieciowego. Karta sieciowa obsługująca segmentację dużych pakietów TCP musi również mieć następujące możliwości:

  • Oblicz sumy kontrolne IP dla pakietów do wysłania zawierających opcje IP.

  • Oblicz sumy kontrolne TCP dla pakietów wysyłających zawierających opcje protokołu TCP.

Wersje NDIS od 6.0 wzwyż obsługują duże odciążanie wysyłania w wersji 1 (LSOv1), które jest podobne do dużego odciążania wysyłania (LSO) w NDIS 5.x. Wersje NDIS 6.0 i nowsze wspierają również odciążanie wysyłania dużych pakietów w wersji 2 (LSOv2), które zapewnia rozszerzone usługi segmentacji pakietów, w tym wsparcie dla IPv6.

Sterownik miniportu obsługujący LSOv2 i LSOv1 musi określić typ odciążania z informacji o strukturze poza pasmem (OOB) NET_BUFFER_LIST. Sterownik może używać składowej typu struktury NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, aby określić, czy stos sterowników używa LSOv2 lub LSOv1, i wykonywać odpowiednie usługi odciążania sieciowego. Każda struktura NET_BUFFER_LIST zawierająca dane OOB LSOv1 lub LSOv2 zawiera również jedną strukturę NET_BUFFER. Aby uzyskać więcej informacji na temat NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, zobacz Dostęp do informacji o przechodzeniu TCP/IP w tryb offload dla NET_BUFFER_LIST.

Jednak w przypadku, gdy miniport otrzymał OID_TCP_OFFLOAD_PARAMETERS, aby wyłączyć funkcję LSO na miniportie, i po pomyślnym zakończeniu polecenia OID, miniport powinien upuścić wszystkie NET_BUFFER_LIST, które zawierają jakiekolwiek niezerowe dane LSOv1 lub LSOv2 OOB (NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO).

Transport TCP/IP odciąża tylko te duże pakiety TCP spełniające następujące kryteria:

Przed rozładowaniem dużego pakietu TCP w celu segmentacji, transport TCP/IP:

  • W przypadku LSOv1 zapisuje całkowitą długość dużego pakietu TCP w polu Total Length nagłówka IP pakietu. Łączna długość obejmuje długość nagłówka IP, długość opcji adresu IP, jeśli są obecne, długość nagłówka TCP, długość opcji TCP, jeśli są obecne, oraz długość ładunku TCP. W przypadku LSOv2 ustawia pole Total Length nagłówka IP pakietu na 0. Sterowniki miniportu powinny określać długość pakietu na podstawie długości pierwszej struktury NET_BUFFER w strukturze NET_BUFFER_LIST.

  • Oblicza sumę sumę uzupełniania dla pseudoheadera TCP i zapisuje tę sumę w polu Checksum nagłówka TCP. Transport TCP/IP oblicza sumę uzupełnienia jednego z następujących pól w pseudoheader: Source IP Address, Destination IP Addressi Protocol. Suma uzupełniająca do pseudo-nagłówka dostarczonego przez transport TCP/IP daje karcie sieciowej przewagę we wczesnym obliczaniu rzeczywistej sumy kontrolnej TCP dla każdego pakietu, który karta sieciowa uzyskuje z dużego pakietu TCP, bez konieczności badania nagłówka IP. Należy pamiętać, że RFC 793 przewiduje, że suma kontrolna pseudonagłówka jest obliczana na Source IP Address, Destination IP Address, Protocoli TCP Length. (Długość TCP to długość nagłówka TCP oraz długość ładunku TCP. Długość TCP nie zawiera długości pseudo-nagłówka.) Jednak ze względu na to, że podstawowy sterownik miniportu i karta sieciowa generują segmenty TCP z dużego pakietu przekazywanego przez transport TCP/IP, transport nie zna rozmiaru ładunku TCP dla każdego segmentu TCP i dlatego nie może zawierać długości TCP w pseudo-nagłówku. Zamiast tego, jak opisano poniżej, karta sieciowa rozszerza sumę kontrolną pseudo-nagłówka dostarczoną przez TCP/IP, aby pokrywała długość każdego wygenerowanego segmentu TCP.

  • Zapisuje prawidłowy numer sekwencji w polu Sequence Number nagłówka TCP. Numer sekwencji identyfikuje pierwszy bajt ładunku TCP.

Gdy sterownik miniportu uzyska strukturę NET_BUFFER_LIST w funkcji MiniportSendNetBufferLists lub MiniportCoSendNetBufferLists, może wywołać makro NET_BUFFER_LIST_INFO z parametrem _IdTcpLargeSendNetBufferListInfo, aby uzyskać wartość MSS zapisaną przez transport TCP/IP.

Sterownik miniportu uzyskuje łączną długość dużego pakietu z nagłówka IP pakietu i używa wartości MSS, aby podzielić duży pakiet TCP na mniejsze pakiety. Każdy z mniejszych pakietów zawiera pliki MSS lub mniej bajtów danych użytkownika. Tylko ostatni pakiet utworzony na podstawie segmentowanego dużego pakietu powinien zawierać mniej niż bajty danych użytkownika usługi MSS. Wszystkie inne pakiety utworzone na podstawie segmentowanego pakietu powinny zawierać bajty danych użytkownika usługi MSS. Jeśli nie zastosujesz się do tej reguły, tworzenie i przesyłanie niepotrzebnych dodatkowych pakietów może obniżyć wydajność.

Sterownik miniportu dołącza nagłówki MAC, IP i TCP do każdego segmentu wyodrębnianego z dużego pakietu. Sterownik miniportu musi obliczyć sumy kontrolne IP i TCP dla tych pakietów pochodnych. Aby obliczyć sumę kontrolną TCP dla każdego pakietu pochodzącego z dużego pakietu TCP, karta sieciowa oblicza zmienną część sumy kontrolnej TCP (dla nagłówka TCP i ładunku TCP), dodaje tę sumę kontrolną do sumy uzupełnienia jedynkowego dla pseudonagłówka obliczonego przez transport TCP/IP, a następnie oblicza uzupełnienie jedynkowe 16-bitowe dla sumy kontrolnej. Aby uzyskać więcej informacji na temat obliczania takich sum kontrolnych, zobacz RFC 793 i RFC 1122.

Na poniższej ilustracji przedstawiono segmentację dużego pakietu.

Diagram przedstawiający segmentację dużego pakietu TCP w mniejsze pakiety z nagłówkami MAC, IP i TCP.

Długość danych użytkownika TCP w dużym pakiecie TCP powinna być równa lub mniejsza niż wartość przypisana przez sterownik miniportu do wartości MaxOffLoadSize. Aby uzyskać więcej informacji na temat wartości MaxOffLoadSize, zobacz Zgłaszanie możliwości LSOv1 TCP karty sieciowejPacket-Segmentation oraz Zgłaszanie możliwości LSOv2 TCP karty sieciowejPacket-Segmentation.

Po tym jak sterownik wyda wskazanie stanu sygnalizujące zmianę wartości MaxOffLoadSize, nie powinien się zawiesić, jeśli otrzyma żądanie wysłania LSO z użyciem poprzedniej wartości MaxOffLoadSize. Zamiast tego sterownik może nie zrealizować żądania wysłania.

Sterownik pośredni, który niezależnie wystawia wskazania stanu zgłaszające zmianę wartości MaxOffLoadSize, musi upewnić się, że podstawowy adapter miniport, który nie wystawił wskazania stanu, nie otrzymuje żadnych pakietów większych niż wartość MaxOffLoadSize, którą zgłosił adapter miniport.

Sterownik miniport-pośredni, który reaguje na OID_TCP_OFFLOAD_PARAMETERS, aby wyłączyć usługi LSO, musi być przygotowany na krótki okres czasu, w którym żądania wysyłania LSO mogą wciąż docierać do sterownika miniportu.

Długość danych użytkownika TCP w pakiecie segmentu musi być mniejsza lub równa MSS. MsS to wartość ULONG przekazywana przez transport TCP przy użyciu informacji LSO NET_BUFFER_LIST skojarzonych ze strukturą NET_BUFFER_LIST. Tylko ostatni pakiet utworzony na podstawie segmentowanego dużego pakietu powinien zawierać mniej niż bajty danych użytkownika usługi MSS. Wszystkie inne pakiety utworzone na podstawie segmentowanego pakietu powinny zawierać bajty danych użytkownika usługi MSS. Jeśli nie zastosujesz się do tej reguły, tworzenie i przesyłanie niepotrzebnych dodatkowych pakietów może obniżyć wydajność.

Liczba pakietów segmentów, które zostały uzyskane z dużego pakietu TCP, musi być równa lub większa niż wartość MinSegmentCount określona przez sterownik miniportu. Aby uzyskać więcej informacji na temat wartości MinSegmentCount, zobacz Zgłaszanie możliwości LSOv1 TCP karty sieciowejPacket-Segmentation oraz Zgłaszanie możliwości LSOv2 TCP karty sieciowejPacket-Segmentation.

Następujące założenia i ograniczenia dotyczą przetwarzania nagłówków IP i TCP dla dowolnego sterownika miniportu z obsługą LSO niezależnie od wersji:

  • Bit MF w nagłówku IP dużego pakietu TCP, który został przeniesiony przez transport TCP/IP, nie zostanie ustawiony, a przesunięcie fragmentu w nagłówku IP będzie wynosić zero.

  • Flagi URG, RSTi SYN w nagłówku TCP dużego pakietu TCP nie zostaną ustawione, a pilne przesunięcie (wskaźnik) w nagłówku TCP będzie zerowe.

  • Jeśli parametr FIN bit w nagłówku TCP dużego pakietu jest ustawiony, sterownik miniportu musi ustawić ten bit w nagłówku TCP ostatniego pakietu tworzonego na podstawie dużego pakietu TCP.

  • Jeśli ustawiono bit PSH w nagłówku TCP dużego pakietu TCP, sterownik miniportu musi ustawić ten bit w nagłówku TCP ostatniego pakietu tworzonego na podstawie dużego pakietu TCP.

  • Jeśli ustawiono CWR bit w nagłówku TCP dużego pakietu TCP, sterownik miniportu musi ustawić ten bit w nagłówku TCP pierwszego pakietu tworzonego na podstawie dużego pakietu TCP. Sterownik miniportu może wybrać ustawienie tego bitu w nagłówku TCP ostatniego pakietu tworzonego na podstawie dużego pakietu TCP, chociaż jest to mniej pożądane.

  • Jeśli duży pakiet TCP zawiera opcje IP lub opcje TCP (lub oba), sterownik miniportu kopiuje te opcje, niezmienione, do każdego pakietu utworzonego z dużego pakietu TCP. W szczególności karta sieciowa nie zwiększy opcji znacznika czasu .

  • Wszystkie nagłówki pakietów (ethernet, IP, TCP) będą znajdować się w pierwszym MDL pakietu. Nagłówki nie zostaną rozdzielone pomiędzy różne MDL-e.

    Napiwek

    To założenie jest prawidłowe, gdy jest włączona funkcja LSO. W przeciwnym razie, gdy LSO nie jest włączone, sterowniki miniportu nie mogą zakładać, że nagłówki IP znajdują się w tym samym języku MDL co nagłówki ethernet.

Sterownik miniportu musi wysyłać pakiety w strukturach NET_BUFFER_LIST w kolejności, w której odbiera struktury NET_BUFFER_LIST z transportu TCP/IP.

Podczas przetwarzania dużego pakietu TCP karta miniportu jest odpowiedzialna tylko za segmentowanie pakietu i umieszczanie nagłówków MAC, IP i TCP na pakiety pochodzące z dużego pakietu TCP. Transport TCP/IP wykonuje wszystkie inne zadania (takie jak dostosowywanie rozmiaru okna wysyłania na podstawie rozmiaru okna odbierania hosta zdalnego).

Przed ukończeniem operacji wysyłania dla dużego pakietu (na przykład z NdisMSendNetBufferListsComplete lub NdisMCoSendNetBufferListsComplete), sterownik miniportu zapisuje wartość NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO (NET_BUFFER_LIST informacje dotyczące dużych odciążeń) z całkowitą liczbą bajtów danych użytkownika TCP, które zostały pomyślnie wysłane we wszystkich pakietach utworzonych z dużego pakietu TCP.

Oprócz poprzednich wymagań LSO, sterowniki miniport zgodne z LSOv2 muszą również:

  • Obsługa protokołów IPv4 lub IPv6 albo protokołów IPv4 i IPv6.

  • Umożliwienie replikacji opcji IPv4 z dużego pakietu w każdym pakiecie segmentowym generowanym przez kartę sieciową (NIC).

  • Obsługa replikacji nagłówka rozszerzenia IPv6 z dużego pakietu TCP w każdym pakiecie segmentu TCP.

  • Obsługa replikacji opcji TCP w każdym pakiecie segmentu TCP generowanym przez sterownik miniportu.

  • Użyj nagłówka IP i TCP w strukturze NET_BUFFER_LIST jako szablonu, aby wygenerować nagłówki TCP/IP dla każdego pakietu segmentu.

  • Użyj wartości identyfikacji adresów IP (IP ID) w zakresie od 0x0000 do 0x7FFF. (Zakres od 0x8000 do 0xFFFF jest zarezerwowany dla urządzeń obsługujących odciążanie TCP). Jeśli, na przykład, nagłówek adresu IP szablonu rozpoczyna się od wartości pola Identyfikacja 0x7FFE, pierwszy pakiet segmentu TCP musi mieć wartość identyfikatora IP 0x7FFE, a następnie 0x7FFF, 0x0000, 0x0001, itd.

  • Użyj przesunięcia bajtów w TcpHeaderOffset elementu członkowskiego NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, aby określić lokalizację nagłówka TCP, począwszy od pierwszego bajtu pakietu.

  • Ogranicz liczbę struktur NET_BUFFER skojarzonych z każdą strukturą LSOv2 NET_BUFFER_LIST do jednej.

    Notatka

    Jest to nowe wymaganie dla sterowników miniportów obsługujących LSOv2. Ta reguła nie jest wymuszana dla sterowników miniportowych LSOv1, aczkolwiek jest zalecana.

  • Określ łączną długość pakietu od długości pierwszej struktury NET_BUFFER w strukturze NET_BUFFER_LIST. Różni się to od sterowników metod dla LSOv1.

  • Obsługa opcji protokołu TCP, opcji adresów IP i nagłówków rozszerzenia IP.

  • Po zakończeniu operacji wysyłania sterownik miniportu musi ustawić element członkowski LsoV2TransmitComplete.Reserved struktury NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO na zero, a element członkowski LsoV2TransmitComplete.Type na NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE.