Udostępnij za pośrednictwem


Odciążanie segmentacji UDP (USO)

Odciążanie segmentacji UDP (USO), obsługiwane w systemie Windows 10 w wersji 2004 lub nowszej, to funkcja umożliwiająca kartom sieciowym odciążanie segmentacji datagramów UDP, które są większe niż maksymalna jednostka transmisji (MTU) nośnika sieciowego. Dzięki temu system Windows zmniejsza wykorzystanie procesora związane z przetwarzaniem TCP/IP na pakiet. Wymagania dotyczące uso są podobne do duże odciążanie wysyłania w wersji 2 (LSOv2), który jest przeznaczony dla protokołu transportu TCP.

Wymagania dotyczące uso

Ta sekcja dotyczy głównie sterowników protokołu NDIS i miniportu. Uproszczone sterowniki filtrów NDIS (LWFs) muszą spełniać wymagania sterownika protokołu podczas modyfikowania lub wysyłania pakietów, a także mogą przyjmować, że wszystkie przekazane pakiety do obsługi pakietów FilterSendNetBufferLists spełniają wymagania sterownika protokołu.

Sterowniki miniportu mogą ułatwiać segmentację dużych pakietów UDP, które są większe niż MTU dla medium sieciowego. Karta sieciowa obsługująca segmentację dużych pakietów UDP musi być również w stanie wykonać następujące czynności:

  • Oblicz sumy kontrolne IP dla wysłanych pakietów zawierających opcje IPv4
  • Obliczanie sum kontrolnych UDP dla wysłanych pakietów

Sterownik miniportu obsługujący USO musi określić typ odciążania z informacji pozapasmowych (OOB) ze struktury NET_BUFFER_LIST. Jeśli wartość struktury NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO jest niezerowa, sterownik miniportu musi wykonać USO. Każda NET_BUFFER_LIST, która zawiera dane USO OOB, zawiera także jedną strukturę NET_BUFFER. Jeśli sterownik miniportu otrzymał OID_TCP_OFFLOAD_PARAMETERS aby wyłączyć USO i pomyślnie zakończył jego przetwarzanie, powinien odrzucić i zwrócić wszystkie NET_BUFFER_LIST, które mają ustawione pole OOB USO.

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

  • Pakiet jest pakietem UDP.
  • Długość pakietu musi być większa niż maksymalny rozmiar segmentu (MSS) * (MinSegmentCount - 1).
  • Jeśli sterownik miniportu nie ustawi możliwości SubMssFinalSegmentSupported, każdy duży pakiet UDP odciążony przez transport musi mieć Length % MSS == 0. Oznacza to, że duży pakiet jest podzielny na N pakiety, z każdym segmentem pakietu zawierającym dokładnie bajtów użytkownika MSS. Jeśli sterownik miniportu ustawia zdolność SubMssFinalSegmentSupported, to warunek podzielności długości pakietu w transporcie nie ma zastosowania. Innymi słowy, końcowy segment może być krótszy niż MSS.
  • Pakiet nie jest pakietem pętli zwrotnej.
  • Bit MF w nagłówku IP dużego pakietu UDP, którego transport TCP/IP został odciążony, nie będzie ustawiony, a przesunięcie fragmentu w nagłówku IP będzie równe zero.
  • Aplikacja określiła UDP_SEND_MSG_SIZE/WSASetUdpSendMessageSize.

Przed odciążeniem dużego pakietu UDP na potrzeby segmentacji transport TCP/IP wykonuje następujące czynności:

  • Aktualizuje informacje o segmentacji dużych pakietów skojarzone ze strukturą NET_BUFFER_LIST. Ta informacja jest strukturą NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO, która jest częścią informacji OOB struktury NET_BUFFER_LIST. Transport TCP/IP ustawia wartość MSS na żądaną wartość MSS.
  • Oblicza sumę uzupełniającą pseudonagłówka UDP i zapisuje tę sumę w polu Checksum nagłówka UDP. Transport TCP/IP oblicza sumę dopełnień jedynek z następujących pól w pseudo-nagłówku: Źródłowy adres IP, docelowy adres IP i protokół.

Jedynkowe uzupełnienie sumy dla pseudoheadera dostarczonego przez transport TCP/IP umożliwia karcie sieciowej wcześniejsze rozpoczęcie obliczania rzeczywistej sumy kontrolnej UDP dla każdego pakietu, który karta sieciowa rozdziela z dużego pakietu UDP, bez konieczności badania nagłówka IP.

Należy pamiętać, że RFC 768 i RFC 2460 określają, że pseudoheader jest obliczany na podstawie źródłowego adresu IP, docelowego adresu IP, protokołu i długości UDP (długość nagłówka UDP oraz długość ładunku UDP, a nie w tym długość pseudoheadera). Jednak, ze względu na to, że podstawowy sterownik miniportu i karta sieciowa generują datagramy UDP z dużych pakietów przekazywanych przez transport TCP/IP, transport nie zna rozmiaru ładunku UDP dla każdego datagramu UDP i w związku z tym nie może uwzględniać długości UDP w obliczeniach pseudoheaderowych. Zamiast tego, jak opisano w poniższej sekcji, karta sieciowa rozszerza sumę kontrolną pseudoheadera dostarczoną przez transport TCP/IP, aby uwzględnić długość UDP każdego wygenerowanego datagramu UDP.

Ważny

Jeśli pole sumy kontrolnej nagłówka UDP zapewnione przez transport TCP/IP wynosi zero, karta sieciowa nie powinna wykonywać obliczeń sumy kontrolnej UDP.

Wysyłanie pakietów z użyciem USO

Gdy sterownik miniportu uzyska NET_BUFFER_LIST w funkcji wywołania zwrotnego MiniportSendNetBufferLists, może wywołać makro NET_BUFFER_LIST_INFO z _IdUdpSegmentationOffloadInfo, aby uzyskać wartość MSS oraz protokół IP.

Sterownik miniportu uzyskuje łączną długość dużego pakietu od długości pierwszej struktury NET_BUFFER i używa wartości MSS, aby podzielić duży pakiet UDP na mniejsze pakiety UDP. Każdy z mniejszych pakietów zawiera mss lub mniej bajtów danych użytkownika. Tylko ostatni pakiet utworzony na podstawie segmentowanego dużego pakietu powinien zawierać mniej niż msS bajtów danych użytkownika. Wszystkie inne pakiety utworzone na podstawie segmentowanego pakietu muszą zawierać bajtów danych użytkownika usługi MSS. Jeśli sterownik miniportu nie jest zgodny z tą regułą, datagramy UDP są niepoprawnie dostarczane. Jeśli sterownik miniportu nie ustawi funkcji SubMssFinalSegmentSupported, długość pakietu dzieli się przez MSS, a każdy z segmentowanych pakietów zawiera MSS bajtów użytkownika.

Sterownik miniportu umieszcza na każdym segmencie nagłówki MAC, IP i UDP wywodzące się z dużego pakietu. Sterownik miniportu musi obliczyć sumy kontrolne IP i UDP dla tych pakietów pochodnych. Aby obliczyć sumę kontrolną UDP dla każdego pakietu, który został wygenerowany z dużego pakietu UDP, karta sieciowa oblicza zmienną część sumy kontrolnej UDP (dla nagłówka UDP i ładunku UDP). Następnie dodaje tę sumę kontrolną do sumy jedynek uzupełniających dla pseudoheadera, którą obliczono podczas transportu TCP/IP, a potem oblicza 16-bitowe uzupełnienie sumy kontrolnej. Aby uzyskać więcej informacji na temat obliczania takich sum kontrolnych, zobacz RFC 768 i RFC 2460.

Długość danych użytkownika UDP w dużym pakiecie UDP musi być mniejsza lub równa wartości przypisanej przez sterownik miniportu do MaxOffLoadSize.

Po wysłaniu sterownika wskazania stanu wskazującego zmianę MaxOffLoadSizesterownik nie może spowodować sprawdzenia usterek, czy odbiera żądanie wysyłania LSO używające poprzedniej wartości MaxOffLoadSize. Zamiast tego sterownik musi zakończyć żądanie wysyłania niepowodzeniem. Sterowniki muszą odrzucić każde żądanie wysyłki, którego nie mogą wykonać, z jakiegokolwiek powodu (w tym rozmiaru, minimalnej liczby segmentów, opcji IP itp.). Kierowcy muszą jak najszybciej wysłać informację o stanie, jeśli ich możliwości się zmienią.

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

Sterownik miniportu pośredniego, który reaguje na OID_TCP_OFFLOAD_PARAMETERS, aby wyłączyć usługi USO, musi być przygotowany na krótki okres, w którym żądania USO mogą wciąż docierać do sterownika miniportu.

Liczba pakietów segmentacji pochodzących z dużego pakietu UDP musi być równa lub większa niż wartość MinSegmentCount określona przez sterownik miniportu.

Podczas przetwarzania dużego pakietu UDP sterownik miniportu jest odpowiedzialny tylko za segmentowanie pakietu i umieszczanie nagłówków MAC, IP i UDP do pakietów pochodzących z dużego pakietu UDP. Jeśli miniport nie może wysłać co najmniej jednego pakietu segmentowanego, NBL musi być ostatecznie zakończona ze statusem niepowodzenia. Miniport może kontynuować wysyłanie kolejnych pakietów, ale nie jest to wymagane. Nie można zakończyć przekazywania NBL do NDIS, dopóki wszystkie segmentowane pakiety nie zostaną przesłane lub nie powiodą się.

Sterowniki miniportów z obsługą USO muszą również wykonywać następujące czynności:

  • Obsługa protokołów IPv4 i IPv6.
  • Wspieranie replikacji opcji IPv4 z dużego pakietu w każdym segmentowanym pakiecie, który generuje karta sieciowa.
  • Użyj nagłówka IP i UDP w strukturze NET_BUFFER_LIST jako szablonu, aby wygenerować nagłówki UDP i IP dla każdego pakietu segmentowanego.
  • Użyj wartości identyfikacji adresów IP (IP ID) w zakresie od 0x0000 do 0xFFFF. Na przykład, jeśli nagłówek IP szablonu rozpoczyna się od wartości pola Identyfikacja 0xFFFE, to pierwszy pakiet datagramu UDP musi mieć wartość 0xFFFE, a następnie 0xFFFF, 0x0000, 0x0001i tak dalej.
  • Jeśli duży pakiet UDP zawiera opcje IP, sterownik miniportu kopiuje te opcje, niezmienione, do każdego pakietu pochodzącego z dużego pakietu UDP.
  • Użyj przesunięcia bajtów w UdpHeaderOffset członka NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO, aby określić lokalizację nagłówka UDP, począwszy od pierwszego bajtu pakietu.
  • Zwiększaj statystyki przesyłania na podstawie segmentowanych pakietów. Na przykład, uwzględnij liczbę bajtów nagłówków Ethernet, IP i UDP dla każdego segmentu pakietu, a liczba pakietów to liczba segmentów o rozmiarze MSS, a nie 1.
  • Ustaw pola Łączna długość protokołu UDP i długość adresu IP na podstawie każdego segmentowanego rozmiaru datagramu.

Zmiany interfejsu NDIS

W tej sekcji opisano zmiany w usłudze NDIS 6.83, które umożliwiają stosowi sterowników TCP/IP hosta wykorzystanie funkcji USO uwidocznionych przez sterowniki miniportu.

NDIS i sterownik miniportu wykonują następujące czynności:

  • Anonsuj, że karta sieciowa obsługuje funkcje USO
  • Włączanie lub wyłączanie USO
  • Uzyskaj bieżący stan funkcjonalności USO

Reklamowanie możliwości USO

Sterowniki miniportu ogłaszają możliwości USO, wypełniając pole UdpSegmentation w strukturze NDIS_OFFLOAD, która jest przekazywana w parametrach funkcji NdisMSetMiniportAttributes. Pole Header.Revision w strukturze NDIS_OFFLOAD musi być ustawione na wartość NDIS_OFFLOAD_REVISION_6, a pole Header.Size musi być ustawione na wartość NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_6.

Wykonywanie zapytań dotyczących stanu USO

Bieżący stan USO można sprawdzić za pomocą OID_TCP_OFFLOAD_CURRENT_CONFIG. NDIS obsługuje ten identyfikator OID i nie przekazuje go do sterownika miniportu.

Zmienianie stanu USO

USO można włączyć lub wyłączyć przy użyciu OID_TCP_OFFLOAD_PARAMETERS. Gdy sterownik miniportu przetwarza identyfikator OID, musi wysłać NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG indykację stanu z zaktualizowanym stanem zadania odciążenia.

Słowa kluczowe USO

Słowa kluczowe wyliczenia USO są następujące:

  • *UsoIPv4
  • *UsoIPv6

Te wartości opisują, czy uso jest włączone, czy wyłączone dla tego konkretnego protokołu IP. Ustawienia USO nie są zależne od konfiguracji NDIS_TCP_IP_CHECKSUM_OFFLOAD. Na przykład wyłączenie *UDPChecksumOffloadIPv4 nie powoduje niejawnego wyłączenia *UsoIPv4.

Nazwa podklucza Opis parametru Wartość Opis wyliczenia
*UsoIPv4 USO (IPv4) 0 Niepełnosprawny
1 Włączone
*UsoIPv6 USO (IPV6) 0 Niepełnosprawny
1 Włączone