Sdílet prostřednictvím


Popisovače paketů a rozšíření

V NetAdapterCx popisovače paketů jsou malé, kompaktní a rozšiřitelné struktury, které popisují síťový paket. Každý paket vyžaduje následující:

  • Jedna základní charakteristika
  • Jeden nebo více popisovačů fragmentů
  • Nula nebo více rozšíření paketů

Základní popisovač paketu je struktura NET_PACKET. Obsahuje pouze nejzákladnější metadata použitelná pro všechny pakety, například rozložení rámování daného paketu a index prvního popisovače fragmentu paketu.

Každý paket musí mít také jeden nebo více popisovačů fragmentůnebo struktury NET_FRAGMENT, které popisují umístění v systémové paměti, kde se nacházejí data paketů.

rozšíření jsou volitelná a obsahují metadata pro jednotlivé pakety nebo fragmenty pro konkrétní funkce scénáře. Například rozšíření paketů mohou uchovávat informace pro kontrolní součet, vyvázání při velkém odesílání (LSO) a sloučení segmentů při přijetí (RSC), nebo mohou obsahovat podrobnosti specifické pro aplikaci. Rozšíření fragmentů můžou obsahovat informace o virtuálních adresách, informace o logické adrese DMA nebo jiné informace o fragmentu.

Společně tyto popisovače a rozšíření obsahují všechna metadata o síťovém paketu. Tady jsou dva příklady popisu paketu. První obrázek ukazuje scénář, ve kterém je celý paket uložený uvnitř jednoho fragmentu paměti, a offload kontrolního součtu je aktivováno.

Diagram znázorňující rozložení paketů s 1 fragmentem a rozšířením 1

Druhý obrázek znázorňuje paket rozprostřený přes dva fragmenty paměti, s aktivovaným RSC a offloadem kontrolního součtu.

Diagram znázorňující rozložení paketů se 2 fragmenty a 2 rozšířeními

Úložiště a přístup popisovače paketů

Popisovače paketů a popisovače fragmentů jsou uloženy v NET_RING strukturách. Klientský ovladač síťové karty přistupuje ke síťovým kruhům (net rings) a provádí s nimi operace prostřednictvím rozhraní Net Ring Iterator, které umožňuje ovladači spolupracovat s NetAdapterCx pro odesílání síťových dat do hardwaru a navracení zpracovaných dat zpět do operačního systému.

Další informace o síťových kroužcích a rozhraní Net Ring Iterátor viz Úvod do síťových kroužků.

Rozšiřitelnost popisovače paketů

Rozšiřitelnost je základní funkcí popisovače paketů NetAdapterCx, která tvoří základ pro škálovatelnost a výkon popisovače. Za běhu operační systém přiděluje všechny popisovače paketů pro každou frontu paketů v souvislém bloku spolu s případnými rozšířeními. Každý blok rozšíření je bezprostředně za popisovačem jádra, jak je znázorněno na následujícím obrázku:

Diagram znázorňující rozložení popisovače paketů NetAdapterCx se 3 rozšiřujícími bloky

Ovladače klientských síťových adaptérů nesmí natvrdo nastavovat posun k žádnému bloku rozšíření. Místo toho se musí během spuštění programu dotazovat na offset k jakémukoliv konkrétnímu rozšíření. Ovladač může například dotazovat posun k rozšíření B a získat zpět 70 bajtů, jak je znázorněno na následujícím obrázku.

Diagram znázorňující dotazování na posun k rozšíření jádra deskriptoru paketů

Jakmile se vytvoří fronta paketů a její popisovače, systém zaručuje, že všechny jejich posuny rozšíření zůstanou konstantní, takže ovladače nemusí často znovu dotazovat tyto posuny. Vzhledem k tomu, že systém v době inicializace fronty paketů předem přiděluje všechna rozšíření, není potřeba přidělit bloky za běhu, prohledávat seznam pro konkrétní popisovač nebo ukládat ukazatele na každé rozšíření paketů.

Možnosti správy verzí popisovače paketů

Základní popisovač paketů NetAdapterCx lze snadno rozšířit v budoucích verzích přidáním nových polí na konec, například na následujícím obrázku:

Diagram znázorňující správu verzí základního popisovače paketů NetAdapterCx

Novější klientské ovladače, které znají pole V2, k nim mají přístup, zatímco starší ovladače využívající pouze verzi V1 používají posuny rozšíření, aby přeskočily pole V2 a měly přístup k polím, kterým rozumí. Kromě toho může být každé rozšíření verzováno stejným způsobem, jak ukazuje následující obrázek.

Diagram, který zobrazuje verzování rozšíření paketů NetAdapterCx

Klientský ovladač, který rozumí novému rozšíření, ho může používat. Ostatní klientské ovladače mohou ignorovat nová pole. To umožňuje nezávislé verze různých částí popisovače paketů.

Popisovače paketů a výkon cesty k datům

Funkce rozšiřitelnosti popsaná dříve poskytuje výhody, které pomáhají klientským ovladačům splňovat požadavky na výkon síťových adaptérů, které mají maximální kapacitu stovek gigabitů za sekundu s tisíci front:

  1. Popisovače paketů jsou co nejkomprimnější, aby se zlepšily přístupy do mezipaměti procesoru, protože funkce a rozšíření, které se nepoužívají, zabírají 0 bajtů místa v popisovačích.
  2. Neexistuje žádné dereferencování ukazatele, pouze aritmetika posunů, protože rozšíření jsou v rámci, což nejen šetří místo, ale také pomáhá při zásahu do mezipaměti procesoru.
  3. Rozšíření se přidělují při vytváření fronty, takže ovladače nemusí přidělovat a uvolňovat paměť v aktivní datové cestě nebo řešit seznamy kontextových bloků.

Použití rozšíření paketů

Důležitý

Klientské ovladače jsou v současné době omezeny na předem existující rozšíření paketů definovaná operačním systémem.

Registrace rozšíření paketů

Prvním krokem při práci s rozšířeními paketů v klientském ovladači síťové karty je deklarování podporovaných hardwarových snižování zátěže. Když oznamujete podporu pro odlehčení zátěže, jako jsou kontrolní součet a LSO, NetAdapterCx automaticky zaregistruje přidružená rozšíření paketů vaším jménem.

Příklad kódu reklamního snižování zátěže hardwaru naleznete v tématu Úvod k hardwarovým snižování zátěže.

Dotazování na posuny rozšíření paketů pro fronty datové cesty

Po registraci rozšíření paketů deklarováním podpory hardwarového offloadu budete potřebovat offsety rozšíření pro přístup k jednotlivým rozšířením při zpracování paketů. Aby se snížila zátěž ovladače a zlepšil se jeho výkon, můžete během funkce zpětného volání EvtNetAdapterCreateTx(Rx)Queue zjistit posuny pro vaše rozšíření a uložit informace o těchto posunech do kontextu fronty.

Příklad dotazování posunů rozšíření a jejich uložení do kontextu fronty najdete v tématu Přenos a příjem front.

Získání rozšíření paketů v době běhu

Jakmile uložíte posuny rozšíření v kontextu fronty, můžete je použít kdykoliv, když potřebujete informace v rozšíření. Můžete například volat metodu NetExtensionGetPacketChecksum při programování popisovačů hardwaru pro frontu přenosu:

    // 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)
        {
            ...
        }
    }
    ...

Předdefinované rozšiřující konstanty paketů a pomocné metody

NetAdapterCx poskytuje definice známých konstant rozšíření paketů.

Konstanta Definice
NET_PACKET_EXTENSION_INVALID_OFFSET Chrání před neplatnými velikostmi offsetu.
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSION_1 Název a verze rozšíření pro kontrolní součet.
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 Název a verze rozšíření paketů pro velké offload odesílání (LSO).
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 Název a verze rozšíření paketů pro sloučování přijímaných segmentů (RSC).

NetAdapterCx navíc poskytuje pomocné metody, které fungují jako obálky kolem metody NetExtensionGetData. Každá z těchto metod vrátí ukazatel na odpovídající typ struktury.

Metoda Struktura
NetExtensionGetPacketChecksum NET_PACKET_CHECKSUM
NetExtensionGetGso NET_PACKET_GSO
NetExtensionGetPacketRsc NET_PACKET_RSC

Použití rozšíření fragmentů

Důležitý

Klientské ovladače jsou v současné době omezené na předem existující rozšíření fragmentu definovaná operačním systémem.

Registrace rozšíření fragmentů

NetAdapterCx automaticky zaregistruje většinu rozšíření fragmentů interpretací vyjádřených schopností ovladače. Pokud například ovladač vyjadřuje podporu DMA, architektura automaticky přidá rozšíření NET_FRAGMENT_LOGICAL_ADDRESS, které je nezbytné pro programování DMA.

Dotazování na posuny rozšíření fragmentů pro fronty datové cesty

Pokud chcete získat přístup k rozšířením fragmentů, můžete následovat stejný postup pro přístup k rozšířením paketů popsaná v dotazování offsetů rozšíření paketů pro datové cesty.

Předdefinované rozšiřující konstanty fragmentu

NetAdapterCx poskytuje definice známých konstant rozšíření fragmentů.

Konstanta Definice
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 Název a verze rozšíření pro fragment vyrovnávací paměti dat.
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 Název a verze rozšíření fragmentu logické adresy.
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 Název a verze rozšíření fragmentu MDL.
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 Název a verze rozšíření fragmentu návratového kontextu.
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1 Název a verze rozšíření fragmentu virtuální adresy.