Partilhar via


Descritores e extensões de pacotes

No NetAdapterCx, descritores de pacotes são estruturas pequenas, compactas e extensíveis em tempo de execução que descrevem um pacote de rede. Cada pacote requer o seguinte:

  • Um descritor principal
  • Um ou mais descritores de fragmentos
  • Zero ou mais extensões de pacote

O descritor principal do pacote é a estrutura NET_PACKET. Ele contém apenas os metadados mais básicos aplicáveis a todos os pacotes, como o layout de enquadramento de um determinado pacote e o índice para o primeiro descritor de fragmento do pacote.

Cada pacote também deve ter um ou mais descritores de fragmento , ou estruturas NET_FRAGMENT, que descrevem o local na memória do sistema onde os dados do pacote residem.

Extensões são opcionais e mantêm metadados por pacote ou por fragmento para recursos específicos do cenário. Por exemplo, as extensões de pacote podem conter informações de descarga para soma de verificação, descarga de envio grande (LSO) e coalescência de segmento de receção (RSC), ou podem conter detalhes específicos da aplicação. As extensões de fragmento podem conter informações de endereço virtual, informações de endereço DMA lógico ou outras informações para o fragmento.

Juntos, esses descritores e extensões contêm todos os metadados sobre um pacote de rede. Aqui estão dois exemplos de como eles descrevem um pacote. A primeira figura mostra um cenário em que todo o pacote é armazenado num único fragmento de memória e o offload de soma de verificação foi ativado.

Diagrama que mostra um layout de pacote com 1 fragmento e 1 extensão.

A segunda figura mostra um pacote armazenado em dois fragmentos de memória, com o RSC e o offload de checksum ativados.

Diagrama que mostra um layout de pacote com 2 fragmentos e 2 extensões.

Armazenamento e acesso ao descritor de pacotes

Os descritores de pacotes e os descritores de fragmentos são armazenados em estruturas NET_RING. Um driver de cliente NIC acessa os anéis de rede e executa operações neles chamando para a Interface do Iterador de Anel de Rede, que permite que o driver trabalhe com o NetAdapterCx para enviar dados de rede para o hardware e transferir os dados concluídos de volta para o sistema operacional.

Para obter mais informações sobre anéis de rede e a interface de iterador de anel de rede, consulte Introdução aos anéis de rede.

Extensibilidade do descritor de pacotes

A extensibilidade é um recurso central do descritor de pacotes NetAdapterCx, formando a base para a versionabilidade e o desempenho do descritor. No tempo de execução, o sistema operacional aloca todos os descritores de pacotes para cada fila de pacotes em um bloco contíguo, juntamente com todas as extensões disponíveis. Cada bloco de extensão está imediatamente atrás do descritor principal, como mostra a figura a seguir:

Diagrama que mostra o layout do descritor de pacotes NetAdapterCx com 3 blocos de extensão.

Os drivers de cliente NIC não têm permissão para codificar o deslocamento para qualquer bloco de extensão. Em vez disso, eles devem consultar em tempo de execução o deslocamento para qualquer extensão específica. Por exemplo, um driver pode consultar o deslocamento para a extensão B e receber 70 bytes como mostrado na figura a seguir.

Diagrama que mostra a consulta do deslocamento para uma extensão do descritor de pacote núcleo.

Uma vez que uma fila de pacotes e seus descritores são criados, todos os seus deslocamentos de extensão são garantidos pelo sistema para serem constantes, para que os drivers não precisem consultar novamente os deslocamentos com frequência. Além disso, como todas as extensões são pré-alocadas pelo sistema em um bloco no momento em que a fila de pacotes é inicializada, não há necessidade de alocação de blocos em tempo de execução, procurando uma lista por um descritor específico ou tendo que armazenar ponteiros para cada extensão de pacote.

Capacidade de versão do descritor de pacotes

O descritor de pacote principal do NetAdapterCx pode ser facilmente estendido em versões futuras adicionando novos campos ao final, como na figura a seguir:

Diagrama que mostra o versionamento do descritor de pacotes principais NetAdapterCx.

Os controladores de cliente mais recentes que têm conhecimento dos campos V2 podem acedê-los, enquanto os controladores mais antigos, que são apenas V1, usarão desvios de extensão para passar por cima dos campos V2 para que possam aceder aos campos que compreendem. Além disso, cada extensão pode ser versionada da mesma maneira, como mostra a figura a seguir:

Diagrama que mostra o versionamento da extensão de pacote NetAdapterCx.

Um driver de cliente que entende a nova extensão pode usá-lo. Outros drivers de cliente podem ignorar os novos campos. Isso permite que diferentes partes do descritor de pacote sejam versionadas independentemente.

Descritores de pacotes e desempenho do caminho de dados

O recurso de extensibilidade descrito anteriormente fornece benefícios para ajudar os controladores de cliente a atender aos requisitos de desempenho de NICs que são capazes de processar centenas de gigabits por segundo, com milhares de queues.

  1. Os descritores de pacotes são mantidos o mais compactos possível para melhorar os acessos ao cache da CPU, já que recursos e extensões que não são usados ocupam 0 bytes de espaço nos descritores.
  2. Não há desreferenciação de ponteiros, apenas aritmética de deslocamento, pois as extensões são integradas, o que não só economiza espaço, mas também melhora os acessos ao cache da CPU.
  3. As extensões são alocadas no momento da criação da fila, para que os drivers não precisem alocar e desalocar memória no caminho de dados ativo ou lidar com listas de espera de blocos de contexto.

Usando extensões de pacote

Importante

Atualmente, os drivers de cliente estão limitados a extensões de pacote pré-existentes definidas pelo sistema operacional.

Registrando extensões de pacote

A primeira etapa para lidar com extensões de pacote no driver do cliente NIC é declarar os descarregamentos de hardware suportados. Quando você anuncia suporte para descarregamentos, como checksum e LSO, o NetAdapterCx registra automaticamente as extensões de pacote associadas em seu nome.

Para obter um exemplo de código de descarregamentos de hardware de publicidade, consulte Introdução aos descarregamentos de hardware.

Consultando deslocamentos de extensão de pacote para filas de caminho de dados

Depois de registrar extensões de pacote declarando seu suporte de descarregamento de hardware, você precisará dos deslocamentos de extensão para acessar cada uma delas enquanto processa seus pacotes. Para reduzir as chamadas ao seu driver e melhorar o desempenho, pode-se consultar os deslocamentos das suas extensões durante a função de retorno de chamada EvtNetAdapterCreateTx(Rx)Queue e armazenar as informações de deslocamento no contexto da fila.

Para obter um exemplo de como consultar deslocamentos de extensão e armazená-los no contexto de fila, consulte Transmitir e receber filas.

Obtendo extensões de pacote em tempo de execução

Depois de armazenar os deslocamentos de extensão no teu contexto de fila, podes usá-los sempre que precisares de informações numa extensão. Por exemplo, você pode chamar o método NetExtensionGetPacketChecksum enquanto programa descritores para hardware para uma fila de transmissão:

    // 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 extensão de pacote predefinidas e métodos auxiliares

NetAdapterCx fornece definições para constantes de extensão de pacote conhecidas.

Constante Definição
OFFSET_INVÁLIDO_DE_EXTENSÃO_DE_PACOTE_NET Protege contra tamanhos de deslocamento inválidos.
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSÃO_1 O nome e a versão da extensão de pacote de soma de verificação.
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 O nome e a versão da extensão de pacote de envio grande (LSO).
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 O nome e a versão da extensão de pacote RSC (Receive Segment Coalescence).

Além disso, NetAdapterCx fornece métodos auxiliares que atuam como wrappers em torno do NetExtensionGetData método. Cada um desses métodos retorna um ponteiro para o tipo apropriado de estrutura.

Método Estrutura
NetExtensionGetPacketChecksum Verificação_de_Soma_do_Pacote_de_Rede
NetExtensionGetGso NET_PACKET_GSO
NetExtensionGetPacketRsc NET_PACKET_RSC

Usando extensões de fragmento

Importante

Atualmente, os drivers de cliente estão limitados a extensões de fragmento pré-existentes definidas pelo sistema operacional.

Registrando extensões de fragmento

NetAdapterCx registra automaticamente a maioria das extensões de fragmento interpretando os recursos expressos de um driver. Por exemplo, se o driver expressa que suporta DMA, a estrutura adicionará automaticamente a extensão de NET_FRAGMENT_LOGICAL_ADDRESS necessária para a programação DMA.

Consultando deslocamentos de extensão de fragmento para filas de datapath

Para acessar extensões de fragmento, você pode seguir o mesmo processo para acessar extensões de pacote descritas em Consultando deslocamentos de extensão de pacote para filas de caminho de dados.

Constantes de extensão de fragmento predefinidas

NetAdapterCx fornece definições para constantes de extensão de fragmento conhecidas.

Constante Definição
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 O nome e a versão da extensão de fragmento do buffer de dados.
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 O nome e a versão da extensão do fragmento de endereço lógico.
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 O nome e a versão da extensão de fragmento MDL.
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 O nome e a versão da extensão de fragmento de contexto de retorno.
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1 O nome e a versão da extensão do fragmento de endereço virtual.