Udostępnij przez


Deskryptory pakietów i rozszerzenia

W netAdapterCx deskryptory pakietów są małymi, kompaktowymi, rozszerzalnymi strukturami środowiska uruchomieniowego, które opisują pakiet sieciowy. Każdy pakiet wymaga następujących elementów:

  • Jeden deskryptor rdzenia
  • Co najmniej jeden deskryptor fragmentów
  • Zero lub więcej rozszerzeń pakietów

Podstawowym deskryptorem pakietu jest struktura NET_PACKET. Zawiera on tylko najbardziej podstawowe metadane dotyczące wszystkich pakietów, takich jak układ ramek danego pakietu i indeks do pierwszego deskryptora fragmentu pakietu.

Każdy pakiet musi również zawierać co najmniej jeden deskryptor fragmentu lub NET_FRAGMENT struktury opisujące lokalizację w pamięci systemowej, w której znajdują się dane pakietu.

Rozszerzenia są opcjonalne i zawierają metadane poszczególnych pakietów lub poszczególnych fragmentów dla funkcji specyficznych dla scenariusza. Na przykład rozszerzenia pakietów mogą przechowywać informacje o odciążeniu sumy kontrolnej, dużym odciążaniu wysyłania (LSO) i konsolidacji segmentów odbieranych (RSC) lub mogą przechowywać szczegóły specyficzne dla aplikacji. Rozszerzenia fragmentów mogą przechowywać informacje o adresie wirtualnym, informacje o adresie logicznym DMA lub inne informacje dotyczące fragmentu.

Razem te deskryptory i rozszerzenia przechowują wszystkie metadane dotyczące pakietu sieciowego. Poniżej przedstawiono dwa przykłady sposobu opisywania pakietu. Pierwsza ilustracja przedstawia scenariusz, w którym cały pakiet jest przechowywany wewnątrz pojedynczego fragmentu pamięci, a odciążanie sumy kontrolnej zostało włączone.

Diagram przedstawiający układ pakietów z 1 fragmentem i 1 rozszerzeniem.

Druga ilustracja przedstawia pakiet przechowywany w dwóch fragmentach pamięci, z włączonym odciążaniem RSC i sumą kontrolną.

Diagram przedstawiający układ pakietów z 2 fragmentami i 2 rozszerzeniami.

Przechowywanie i dostęp do deskryptorów pakietów

Deskryptory pakietów i deskryptory fragmentów są przechowywane w strukturach NET_RING . Sterownik klienta karty sieciowej uzyskuje dostęp do pierścieni sieciowych i wykonuje na nich operacje przez wywołanie interfejsu Iteratora Pierścienia Sieci, co umożliwia sterownikowi pracę z NetAdapterCx w celu opublikowania danych sieciowych do sprzętu i drenażu ukończonych danych z powrotem do systemu operacyjnego.

Aby uzyskać więcej informacji na temat pierścieni sieciowych i interfejsu Iteratora pierścieni sieciowych, zobacz Wprowadzenie do pierścieni sieciowych.

Rozszerzalność deskryptora pakietów

Rozszerzalność to podstawowa funkcja deskryptora pakietów NetAdapterCx, tworząca podstawę możliwości i wydajności deskryptora. W czasie wykonywania system operacyjny przydziela wszystkie deskryptory pakietów dla każdej kolejki pakietów w ciągłym bloku wraz z wszystkimi dostępnymi rozszerzeniami. Każdy blok rozszerzenia znajduje się bezpośrednio za deskryptorem rdzenia, jak pokazano na poniższej ilustracji:

Diagram przedstawiający układ deskryptora pakietów NetAdapterCx z 3 blokami rozszerzeń.

Sterowniki klienta karty sieciowej nie mogą zakodować przesunięcia na dowolny blok rozszerzenia. Zamiast tego muszą wykonywać zapytania w czasie wykonywania przesunięcia do dowolnego określonego rozszerzenia. Na przykład sterownik może zapytać o przesunięcie względem rozszerzenia B i otrzymać 70 bajtów, jak na poniższej ilustracji:

Diagram przedstawiający wykonywanie zapytań o przesunięcie do rozszerzenia deskryptora pakietów podstawowych.

Po utworzeniu kolejki pakietów i jej deskryptorów, system gwarantuje, że ich przesunięcia rozszerzeń pozostają stałe, więc sterowniki nie muszą ich często ponownie sprawdzać. Ponadto, ponieważ wszystkie rozszerzenia są wstępnie przydzielane przez system w bloku w momencie inicjowania kolejki pakietów, nie ma potrzeby przydzielania bloków w czasie wykonywania, wyszukiwania listy dla określonego deskryptora lub konieczności przechowywania wskaźników do każdego rozszerzenia pakietu.

Wersjonowanie deskryptora pakietu

Podstawowy deskryptor pakietów NetAdapterCx można łatwo rozszerzyć w przyszłych wersjach, dodając nowe pola na końcu, na przykład na poniższej ilustracji:

Diagram przedstawiający wersjonowanie deskryptorów pakietów rdzeniowych NetAdapterCx.

Nowsze sterowniki klienta, które obsługują pola wersji 2, mogą uzyskiwać do nich dostęp, podczas gdy starsze sterowniki, które obsługują tylko wersję 1, będą używać przesunięć rozszerzeń, aby pominąć pola wersji 2 i w ten sposób uzyskiwać dostęp do pól, które są dla nich zrozumiałe. Ponadto każde rozszerzenie może być wersjonowane w taki sam sposób, jak pokazano na poniższej ilustracji:

Diagram przedstawiający wersjonowanie rozszerzenia pakietów NetAdapterCx.

Sterownik klienta, który rozumie, że nowe rozszerzenie może go używać. Inne sterowniki klienta mogą pominąć nowe pola. Pozwala to na niezależne wersje różnych części deskryptora pakietów.

Deskryptory pakietów i wydajność ścieżki danych

Funkcja rozszerzalności opisana wcześniej zapewnia korzyści, które pomagają sterownikom klientów spełnić wymagania dotyczące wydajności kart interfejsu sieciowego (NIC) obsługujących setki gigabitów na sekundę, z tysiącami kolejek.

  1. Deskryptory pakietów są przechowywane możliwie jak najbardziej kompaktowe, aby poprawić trafienia pamięci podręcznej procesora, ponieważ funkcje i rozszerzenia, które nie są używane, zajmują 0 bajtów miejsca w deskryptorach.
  2. Nie ma wyłuskiwania wskaźnika, tylko arytmetyka przesunięcia, ponieważ rozszerzenia są zintegrowane, co nie tylko oszczędza miejsce, ale także pomaga w trafieniach w pamięci podręcznej CPU.
  3. Rozszerzenia są przydzielane w momencie tworzenia kolejki, dzięki czemu sterowniki nie muszą przydzielać i zwalniać pamięci w aktywnej ścieżce danych ani zajmować się listami bloków kontekstu przeszukiwanego.

Używanie rozszerzeń pakietów

Ważne

Obecnie sterowniki klienta są ograniczone do istniejących rozszerzeń pakietów zdefiniowanych przez system operacyjny.

Rejestrowanie rozszerzeń pakietów

Pierwszym krokiem pracy z rozszerzeniami pakietów w sterowniku klienta karty sieciowej jest zadeklarowanie obsługiwanych odciążeń sprzętu. Podczas deklarowania wsparcia dla funkcji odciążających, takich jak suma kontrolna i LSO, NetAdapterCx automatycznie rejestruje skojarzone rozszerzenia pakietów w Twoim imieniu.

Aby zapoznać się z przykładem kodu dotyczącego odciążania sprzętu, zobacz Wprowadzenie do odciążeń sprzętu.

Wykonywanie zapytań dotyczących przesunięć rozszerzenia pakietów dla kolejek ścieżki danych

Po zarejestrowaniu rozszerzeń pakietów przez zadeklarowanie obsługi odciążania sprzętu konieczne będzie przesunięcie rozszerzenia w celu uzyskania dostępu do każdego z nich podczas przetwarzania pakietów. Aby zmniejszyć liczbę wywołań ze sterownika i zwiększyć wydajność, możesz wykonywać zapytania dotyczące przesunięć rozszerzeń podczas wywołania zwrotnego funkcji kolejki EvtNetAdapterCreateTx(Rx)Queue i przechowywać informacje o przesunięciach w kontekście kolejki.

Aby zapoznać się z przykładem przesunięcia rozszerzeń zapytań i przechowywania ich w kontekście kolejki, zobacz Przesyłanie i odbieranie kolejek.

Pobieranie rozszerzeń pakietów w czasie wykonywania

Po zapisaniu offsetów rozszerzeń w kontekście kolejki, można z nich korzystać w dowolnym momencie, gdy potrzebne są informacje w rozszerzeniu. Można na przykład wywołać metodę NetExtensionGetPacketChecksum podczas programowania deskryptorów do sprzętu dla kolejki transmisji:

    // Get the extension offset from the device context
    PMY_TX_QUEUE_CONTEXT queueContext = GetMyTxQueueContext(txQueue);
    NET_EXTENSION checksumExtension = queueContext->ChecksumExtension;

    // Get the checksum info for this packet
    NET_PACKET_CHECKSUM* checksumInfo = NetExtensionGetPacketChecksum(checksumExtension, packetIndex);

    // Do work with the checksum info
    if (packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_NO_OPTIONS ||
        packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_WITH_OPTIONS ||
        packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_UNSPECIFIED_OPTIONS)
    {
        if(checksumInfo->Layer4 == NET_PACKET_TX_CHECKSUM_REQUIRED)
        {
            ...
        }
    }
    ...

Wstępnie zdefiniowane stałe rozszerzenia pakietów i metody pomocnicze

NetAdapterCx zawiera definicje znanych stałych rozszerzeń pakietów.

Stały Definicja
NET_PACKET_EXTENSION_NIEPRAWIDŁOWE_PRZESUNIĘCIE Zabezpiecza przed nieprawidłowymi wielkościami przesunięcia.
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSION_1 Nazwa i wersja rozszerzenia pakietu sumy kontrolnej.
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 Nazwa i wersja dużego rozszerzenia pakietu odciążania (LSO).
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 Nazwa i wersja rozszerzenia pakietu scalania segmentów odbiorczych (RSC).

Ponadto netAdapterCx udostępnia metody pomocnicze, które działają jako otoki wokół metody NetExtensionGetData . Każda z tych metod zwraca wskaźnik do odpowiedniego typu struktury.

Metoda Struktura
NetExtensionGetPacketChecksum NET_PACKET_CHECKSUM
NetExtensionGetGso NET_PACKET_GSO
NetExtensionGetPacketRsc NET_PACKET_RSC

Używanie rozszerzeń fragmentów

Ważne

Obecnie sterowniki klienta są ograniczone do istniejących rozszerzeń fragmentów zdefiniowanych przez system operacyjny.

Rejestrowanie rozszerzeń fragmentów

NetAdapterCx automatycznie rejestruje większość rozszerzeń fragmentów, interpretując wyrażone możliwości sterownika. Jeśli na przykład sterownik wyraża, że obsługuje usługę DMA, platforma automatycznie doda rozszerzenie NET_FRAGMENT_LOGICAL_ADDRESS niezbędne do programowania DMA.

Wykonywanie zapytań względem przesunięć rozszerzenia fragmentu dla kolejek ścieżki danych

Aby uzyskać dostęp do rozszerzeń fragmentów, możesz wykonać ten sam proces uzyskiwania dostępu do rozszerzeń pakietów opisanych w artykule Querying packet extension offsets for datapath queues (Wykonywanie zapytań o przesunięcia rozszerzenia pakietów dla kolejek ścieżki danych).

Stałe wstępnie zdefiniowanego rozszerzenia fragmentu

NetAdapterCx zawiera definicje znanych stałych rozszerzeń fragmentów.

Stały Definicja
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 Nazwa i wersja rozszerzenia fragmentu buforu danych.
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 Nazwa i wersja rozszerzenia fragmentu adresu logicznego.
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 Nazwa i wersja rozszerzenia fragmentu MDL.
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 Nazwa i wersja rozszerzenia fragmentu kontekstu zwracanego.
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1 Nazwa i wersja rozszerzenia fragmentu wirtualnego adresu.