Descripteurs de paquets et extensions

Dans NetAdapterCx, les descripteurs de paquets sont des structures petites, compactes et extensibles au runtime qui décrivent un paquet réseau. Chaque paquet nécessite les éléments suivants :

  • Un descripteur principal
  • Un ou plusieurs descripteurs de fragments
  • Zéro ou plusieurs extensions de paquets

Le descripteur principal du paquet est la structure NET_PACKET . Il contient uniquement les métadonnées de base applicables à tous les paquets, telles que la disposition de cadrage d’un paquet donné et l’index du premier descripteur de fragment du paquet.

Chaque paquet doit également avoir un ou plusieurs descripteurs de fragments, ou NET_FRAGMENT structures, qui décrivent l’emplacement dans la mémoire système où résident les données du paquet.

Les extensions sont facultatives et contiennent des métadonnées par paquet ou par fragment pour les fonctionnalités spécifiques au scénario. Par instance, les extensions de paquets peuvent contenir les informations de déchargement pour la somme de contrôle, le déchargement d’envoi volumineux (LSO) et la fusion de segments de réception (RSC), ou elles peuvent contenir des détails spécifiques à l’application. Les extensions de fragment peuvent contenir des informations d’adresse virtuelle, des informations d’adresse DMA logique ou d’autres informations pour le fragment.

Ensemble, ces descripteurs et extensions contiennent toutes les métadonnées relatives à un paquet réseau. Voici deux exemples de la façon dont ils décrivent un paquet. La première figure montre un scénario dans lequel le paquet entier est stocké dans un fragment de mémoire unique et où le déchargement de la somme de contrôle a été activé.

Diagramme montrant une disposition de paquets avec 1 fragment et 1 extension.

La deuxième figure montre un paquet stocké sur deux fragments de mémoire, avec le déchargement RSC et la somme de contrôle activés.

Diagramme montrant une disposition de paquets avec 2 fragments et 2 extensions.

Stockage et accès du descripteur de paquets

Les descripteurs de paquets et les descripteurs de fragments sont tous deux stockés dans des structures NET_RING . Un pilote client de carte réseau accède aux anneaux réseau et effectue des opérations sur ceux-ci en appelant l’interface d’itérateur Net Ring, ce qui permet au pilote de travailler avec NetAdapterCx pour publier des données réseau sur le matériel et drainer les données terminées vers le système d’exploitation.

Pour plus d’informations sur les anneaux réseau et l’interface d’itérateur Net Ring, consultez Présentation des anneaux réseau.

Extensibilité du descripteur de paquets

L’extensibilité est une fonctionnalité de base du descripteur de paquets NetAdapterCx, qui constitue la base de la capacité de version et des performances du descripteur. Au moment de l’exécution, le système d’exploitation alloue tous les descripteurs de paquets pour chaque file d’attente de paquets dans un bloc contigu, ainsi que toutes les extensions pouvant être autorisées. Chaque bloc d’extension se trouve immédiatement derrière le descripteur principal, comme illustré dans la figure suivante :

Diagramme montrant la disposition du descripteur de paquets NetAdapterCx avec 3 blocs d’extension.

Les pilotes clients de carte réseau ne sont pas autorisés à coder en dur le décalage sur un bloc d’extension. Au lieu de cela, ils doivent interroger au moment de l’exécution le décalage vers une extension particulière. Par exemple, un pilote peut interroger le décalage vers l’extension B et récupérer 70 octets comme dans la figure suivante :

Diagramme montrant l’interrogation du décalage vers une extension du descripteur de paquet principal.

Une fois qu’une file d’attente de paquets et ses descripteurs sont créés, tous leurs décalages d’extension sont garantis par le système comme étant constants, les pilotes n’ont pas à interroger souvent les décalages. En outre, étant donné que toutes les extensions sont pré-allouées par le système dans un bloc au moment de l’initialisation de la file d’attente de paquets, il n’est pas nécessaire d’allouer des blocs au runtime, de rechercher un descripteur spécifique dans une liste ou de devoir stocker des pointeurs vers chaque extension de paquet.

Capacité de version du descripteur de paquets

Le descripteur de paquet principal de NetAdapterCx peut être facilement étendu dans les versions ultérieures en ajoutant de nouveaux champs à la fin, comme dans la figure suivante :

Diagramme montrant le contrôle de version du descripteur de paquets principal NetAdapterCx.

Les pilotes clients plus récents qui connaissent les champs V2 peuvent y accéder, tandis que les pilotes V1 plus anciens utilisent des décalages d’extension pour ignorer les champs V2 afin qu’ils puissent accéder aux champs qu’ils comprennent. En outre, chaque extension peut être versionnée de la même façon, comme le montre la figure suivante :

Diagramme montrant le contrôle de version de l’extension de paquets NetAdapterCx.

Un pilote client qui comprend la nouvelle extension peut l’utiliser. D’autres pilotes clients peuvent ignorer les nouveaux champs. Cela permet à différentes parties du descripteur de paquets d’être versionnée indépendamment.

Performances des descripteurs de paquets et des chemins de données

La fonctionnalité d’extensibilité décrite précédemment offre des avantages pour aider les pilotes clients à répondre aux exigences de performances des cartes réseau qui peuvent atteindre des centaines de gigabits par seconde, avec des milliers de files d’attente :

  1. Les descripteurs de paquets sont conservés aussi compacts que possible pour améliorer les accès au cache du processeur, car les fonctionnalités et les extensions qui ne sont pas utilisées occupent 0 octet d’espace dans les descripteurs.
  2. Il n’y a pas de déréférencement de pointeur, seulement l’arithmétique de décalage, car les extensions sont en ligne, ce qui permet non seulement d’économiser de l’espace, mais également d’aider les accès au cache du processeur.
  3. Les extensions étant allouées au moment de la création de la file d’attente, les pilotes n’ont pas besoin d’allouer et de libérer de la mémoire dans le chemin de données actif ou de gérer des listes de lookaside de blocs de contexte.

Utilisation d’extensions de paquets

Important

Actuellement, les pilotes clients sont limités aux extensions de paquets préexistantes définies par le système d’exploitation.

Inscription d’extensions de paquets

La première étape de l’utilisation des extensions de paquets dans votre pilote client de carte réseau consiste à déclarer vos déchargements matériels pris en charge. Lorsque vous publiez la prise en charge des déchargements tels que la somme de contrôle et l’authentification LSO, NetAdapterCx inscrit automatiquement les extensions de paquets associées en votre nom.

Pour obtenir un exemple de code de déchargements matériels publicitaires, consultez Présentation des déchargements matériels.

Interrogation des décalages d’extension de paquets pour les files d’attente de chemins de données

Après avoir inscrit des extensions de paquets en déclarant la prise en charge de votre déchargement matériel, vous aurez besoin des décalages d’extension pour accéder à chacune d’elles au fur et à mesure que vous traitez vos paquets. Pour réduire les appels hors de votre pilote et améliorer les performances, vous pouvez interroger les décalages de vos extensions pendant la fonction de rappel EvtNetAdapterCreateTx(Rx)Queue et stocker les informations de décalage dans votre contexte de file d’attente.

Pour obtenir un exemple d’interrogation des décalages d’extension et de leur stockage dans le contexte de file d’attente, consultez Transmettre et recevoir des files d’attente.

Obtention d’extensions de paquets au moment de l’exécution

Une fois que vous avez stocké les décalages d’extension dans votre contexte de file d’attente, vous pouvez les utiliser chaque fois que vous avez besoin d’informations dans une extension. Par exemple, vous pouvez appeler la méthode NetExtensionGetPacketChecksum pendant que vous programmez des descripteurs sur du matériel pour une file d’attente de transmission :

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

Constantes d’extension de paquets prédéfinies et méthodes d’assistance

NetAdapterCx fournit des définitions pour les constantes d’extension de paquet connues.

Constant Définition
NET_PACKET_EXTENSION_INVALID_OFFSET Protège contre les tailles de décalage non valides.
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSION_1 Nom et version de l’extension de paquet de somme de contrôle.
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 Nom et version de l’extension de paquet de déchargement d’envoi volumineux (LSO).
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 Nom et version de l’extension de paquet RSC (Receive Segment Coalescence).

En outre, NetAdapterCx fournit des méthodes d’assistance qui agissent comme des wrappers autour de la méthode NetExtensionGetData . Chacune de ces méthodes retourne un pointeur vers le type de structure approprié.

Méthode Structure
NetExtensionGetPacketChecksum NET_PACKET_CHECKSUM
NetExtensionGetGso NET_PACKET_GSO
NetExtensionGetPacketRsc NET_PACKET_RSC

Utilisation d’extensions de fragments

Important

Actuellement, les pilotes clients sont limités aux extensions de fragment préexistantes définies par le système d’exploitation.

Inscription d’extensions de fragments

NetAdapterCx inscrit automatiquement la plupart des extensions de fragments en interprétant les fonctionnalités exprimées d’un pilote. Par exemple, si le pilote exprime qu’il prend en charge DMA, le framework ajoute automatiquement l’extension NET_FRAGMENT_LOGICAL_ADDRESS nécessaire pour la programmation DMA.

Interrogation des décalages d’extension de fragment pour les files d’attente de chemins de données

Pour accéder aux extensions de fragments, vous pouvez suivre le même processus d’accès aux extensions de paquets décrit dans Interrogation des décalages d’extension de paquets pour les files d’attente de chemin de données.

Constantes d’extension de fragment prédéfinies

NetAdapterCx fournit des définitions pour les constantes d’extension de fragment connues.

Constant Définition
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 Nom et version de l’extension de fragment de mémoire tampon de données.
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 Nom et version de l’extension de fragment d’adresse logique.
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 Nom et version de l’extension de fragment MDL.
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 Nom et version de l’extension de fragment de contexte de retour.
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1 Nom et version de l’extension de fragment d’adresse virtuelle.