Descriptores y extensiones de paquetes
En NetAdapterCx, los descriptores de paquetes son estructuras pequeñas, compactas y extensibles en tiempo de ejecución que describen un paquete de red. Cada paquete requiere lo siguiente:
- Un descriptor principal
- Uno o varios descriptores de fragmentos
- Cero o más extensiones de paquete
El descriptor principal del paquete es la estructura NET_PACKET . Contiene solo los metadatos más básicos aplicables a todos los paquetes, como el diseño de trama de un paquete determinado y el índice al primer descriptor de fragmento del paquete.
Cada paquete también debe tener uno o varios descriptores de fragmentos, o NET_FRAGMENT estructuras, que describen la ubicación dentro de la memoria del sistema donde residen los datos del paquete.
Las extensiones son opcionales y contienen metadatos por paquete o por fragmento para características específicas del escenario. Por ejemplo, las extensiones de paquetes pueden contener información de descarga para la suma de comprobación, la descarga de envío grande (LSO) y la fusión del segmento de recepción (RSC) o pueden contener detalles específicos de la aplicación. Las extensiones de fragmento pueden contener información de direcciones virtuales, información de direcciones DMA lógicas u otra información para el fragmento.
Juntos, estos descriptores y extensiones contienen todos los metadatos sobre un paquete de red. Estos son dos ejemplos de cómo describen un paquete. En la primera ilustración se muestra un escenario en el que todo el paquete se almacena dentro de un único fragmento de memoria y se ha activado la descarga de suma de comprobación.
En la segunda figura se muestra un paquete almacenado en dos fragmentos de memoria, con la descarga de RSC y la suma de comprobación habilitada.
Acceso y almacenamiento de descriptores de paquetes
Los descriptores de paquetes y los descriptores de fragmentos se almacenan en estructuras de NET_RING . Un controlador de cliente NIC accede a los anillos netos y realiza operaciones en ellos mediante una llamada a la interfaz de iterador de anillo de red, que permite al controlador trabajar con NetAdapterCx para publicar datos de red en hardware y purgar los datos completados de nuevo en el sistema operativo.
Para obtener más información sobre los anillos netos y la interfaz iterador de anillos netos, consulte Introducción a los anillos netos.
Extensibilidad del descriptor de paquetes
La extensibilidad es una característica principal del descriptor de paquetes NetAdapterCx, que constituye la base para la capacidad de versión y el rendimiento del descriptor. En tiempo de ejecución, el sistema operativo asigna todos los descriptores de paquetes para cada cola de paquetes en un bloque contiguo, junto con cualquier extensión avaiable. Cada bloque de extensión está inmediatamente detrás del descriptor principal, como se muestra en la ilustración siguiente:
Los controladores de cliente NIC no pueden codificar de forma dura el desplazamiento en ningún bloque de extensión. En su lugar, deben consultar en tiempo de ejecución para el desplazamiento a cualquier extensión determinada. Por ejemplo, un controlador podría consultar el desplazamiento a la extensión B y recuperar 70 bytes como en la ilustración siguiente:
Una vez creada una cola de paquetes y sus descriptores, el sistema garantiza que todos sus desplazamientos de extensión sean constantes, por lo que los controladores no tienen que volver a consultar los desplazamientos a menudo. Además, dado que el sistema asigna previamente todas las extensiones en un bloque en el momento en que se inicializa la cola de paquetes, no es necesario asignar bloques en tiempo de ejecución, buscar una lista para un descriptor específico o tener que almacenar punteros a cada extensión de paquete.
Versionabilidad del descriptor de paquetes
El descriptor de paquetes principal de NetAdapterCx se puede ampliar fácilmente en futuras versiones agregando nuevos campos al final, como en la ilustración siguiente:
Los controladores de cliente más recientes que conozcan los campos V2 pueden acceder a ellos, mientras que los controladores de solo V1 antiguos usarán desplazamientos de extensión para omitir los campos V2 para que puedan acceder a los campos que comprendan. Además, cada extensión se puede versionar de la misma manera, como se muestra en la ilustración siguiente:
Un controlador de cliente que comprenda la nueva extensión puede usarla. Otros controladores de cliente pueden omitir los nuevos campos. Esto permite que las distintas partes del descriptor de paquetes se controle de forma independiente.
Descriptores de paquetes y rendimiento de la ruta de acceso de datos
La característica de extensibilidad descrita anteriormente proporciona ventajas para ayudar a los controladores de cliente a cumplir los requisitos de rendimiento de las NIC que son capabables de cientos de gigabits por segundo, con miles de colas:
- Los descriptores de paquetes se mantienen lo más compactos posible para mejorar los aciertos de caché de CPU, ya que las características y extensiones que no se usan ocupan 0 bytes de espacio en los descriptores.
- No hay ninguna desreferencia de puntero, solo la aritmética de desplazamiento porque las extensiones están en línea, que no solo ahorra espacio, sino que también ayuda con los aciertos de caché de CPU.
- Las extensiones se asignan en tiempo de creación de la cola, por lo que los controladores no tienen que asignar y desasignar memoria en la ruta de acceso de datos activa o tratar con listas de búsqueda de bloques de contexto.
Uso de extensiones de paquete
Importante
Actualmente, los controladores de cliente se limitan a las extensiones de paquetes preexistentes definidas por el sistema operativo.
Registro de extensiones de paquetes
El primer paso para trabajar con extensiones de paquetes en el controlador de cliente NIC es declarar las descargas de hardware admitidas. Al anunciar compatibilidad con descargas como suma de comprobación y LSO, NetAdapterCx registra automáticamente las extensiones de paquetes asociadas en su nombre.
Para obtener un ejemplo de código de las descargas de hardware de publicidad, consulte Introducción a las descargas de hardware.
Consulta de desplazamientos de extensión de paquetes para colas de rutas de datos
Después de registrar extensiones de paquete declarando la compatibilidad con la descarga de hardware, necesitará los desplazamientos de extensión para acceder a cada una de ellas a medida que procesa los paquetes. Para reducir las llamadas del controlador y mejorar el rendimiento, puede consultar los desplazamientos de las extensiones durante la función de devolución de llamada EvtNetAdapterCreateTx(Rx)Queue y almacenar la información de desplazamiento en el contexto de la cola.
Para obtener un ejemplo de consulta de desplazamientos de extensión y almacenarlos en el contexto de la cola, consulte Transmisión y recepción de colas.
Obtención de extensiones de paquetes en tiempo de ejecución
Una vez que haya almacenado desplazamientos de extensión en el contexto de la cola, puede usarlos cada vez que necesite información en una extensión. Por ejemplo, podría llamar al método NetExtensionGetPacketChecksum mientras programa descriptores en hardware para una cola de transmisión:
// 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 de extensión de paquetes predefinidas y métodos auxiliares
NetAdapterCx proporciona definiciones para constantes conocidas de extensión de paquetes.
Constante | Definición |
---|---|
NET_PACKET_EXTENSION_INVALID_OFFSET | Protege contra tamaños de desplazamiento no válidos. |
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSION_1 | Nombre y versión de la extensión de paquete de suma de comprobación. |
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 | Nombre y versión de la extensión de paquete de descarga de envío grande (LSO). |
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 | El nombre y la versión de la extensión de paquete de segmento de recepción (RSC). |
Además, NetAdapterCx proporciona métodos auxiliares que actúan como contenedores alrededor del método NetExtensionGetData . Cada uno de estos métodos devuelve un puntero al tipo de estructura adecuado.
Método | Estructura |
---|---|
NetExtensionGetPacketChecksum | NET_PACKET_CHECKSUM |
NetExtensionGetGso | NET_PACKET_GSO |
NetExtensionGetPacketRsc | NET_PACKET_RSC |
Uso de extensiones de fragmento
Importante
Actualmente, los controladores de cliente se limitan a las extensiones de fragmentos preexistentes definidas por el sistema operativo.
Registro de extensiones de fragmento
NetAdapterCx registra automáticamente la mayoría de las extensiones de fragmentos interpretando las funcionalidades expresadas de un controlador. Por ejemplo, si el controlador expresa que admite DMA, el marco agregará automáticamente la extensión NET_FRAGMENT_LOGICAL_ADDRESS necesaria para la programación DMA.
Consulta de desplazamientos de extensión de fragmento para colas de rutas de datos
Para acceder a las extensiones de fragmento, puede seguir el mismo proceso para acceder a las extensiones de paquetes que se describen en Consulta de desplazamientos de extensiones de paquetes para colas de rutas de datos.
Constantes de extensión de fragmento predefinidas
NetAdapterCx proporciona definiciones para constantes conocidas de extensión de fragmento.
Constante | Definición |
---|---|
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 | Nombre y versión de la extensión de fragmento de búfer de datos. |
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 | Nombre y versión de la extensión de fragmento de dirección lógica. |
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 | El nombre y la versión de la extensión de fragmento MDL. |
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 | Nombre y versión de la extensión de fragmento de contexto de retorno. |
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1 | Nombre y versión de la extensión de fragmento de dirección virtual. |