Partilhar via


Descarga de agrupamento de segmentos de recebimento de UDP (URO)

Do Windows 11, versão 24H2, em diante, a URO (Descarga de agrupamento de segmentos de recebimento de UDP) permite que as placas de interface de rede (NICs) agrupem segmentos de recebimento de UDP. As NICs podem combinar datagramas de UDP do mesmo fluxo que correspondem a um conjunto de regras em um buffer logicamente contíguo. Esses datagramas combinados são indicados para a pilha do sistema de rede do Windows como um único pacote grande.

O agrupamento de datagramas de UDP reduz o custo da CPU para processar pacotes em fluxos de alta largura de banda, resultando em maior taxa de transferência e menos ciclos por byte.

As seções a seguir descrevem as regras para aglutinar pacotes de UDP e como criar um driver de miniporta de URO.

Regras para agrupamento de pacotes de UDP

O agrupamento de URO só pode ser tentado em pacotes que atendem a todos os seguintes critérios:

  • IpHeader.Version é idêntico para todos os pacotes.
  • IpHeader.SourceAddress e IpHeader.DestinationAddress são idênticos para todos os pacotes.
  • UdpHeader.SourcePort e UdpHeader.DestinationPort são idênticos para todos os pacotes.
  • UdpHeader.Length é idêntico para todos os pacotes, exceto o último pacote, que pode ser menor.
  • UdpHeader.Length deve ser diferente de zero.
  • UdpHeader.Checksum, se diferente de zero, deve estar correto em todos os pacotes. Isso significa que o descarregamento da soma de verificação de recebimento deve validar o pacote.
  • Os cabeçalhos da camada 2 devem ser idênticos para todos os pacotes.

Se os pacotes forem IPv4, eles também deverão atender aos seguintes critérios:

  • IPv4Header.Protocol == 17 (UDP) para todos os pacotes.
  • EthernetHeader.EtherType == 0x0800 para todos os pacotes.
  • O IPv4Header.HeaderChecksum nos pacotes recebidos deve estar correto. Isso significa que o descarregamento da soma de verificação de recebimento deve validar o cabeçalho.
  • IPv4Header.HeaderLength == 5 (sem cabeçalhos de opção IPv4) para todos os pacotes.
  • IPv4Header.ToS é idêntico para todos os pacotes.
  • IPv4Header.ECN é idêntico para todos os pacotes.
  • IPv4Header.DontFragment é idêntico para todos os pacotes.
  • IPv4Header.TTL é idêntico para todos os pacotes.
  • IPv4Header.TotalLength == UdpHeader.Length + length(IPv4Header) para todos os pacotes.

Se os pacotes forem IPv6, eles também deverão atender aos seguintes critérios:

  • IPv6Header.NextHeader == 17 (UDP) para todos os pacotes (sem cabeçalhos de extensão).
  • EthernetHeader.EtherType == 0x86dd (IPv6) para todos os pacotes.
  • IPv6Header.TrafficClass e IPv6Header.ECN são idênticos para todos os pacotes.
  • IPv6Header.FlowLabel é idêntico para todos os pacotes.
  • IPv6Header.HopLimit é idêntico para todos os pacotes.
  • IPv6Header.PayloadLength == UdpHeader.Length para todos os pacotes.

Estrutura de pacotes URO

A SCU (unidade agrupada única) resultante deve ter um único cabeçalho IP e um cabeçalho UDP, seguidos pela carga de UDP para todos os datagramas agrupados concatenados juntos.

As indicações de URO devem definir o campo IPv4Header.TotalLength para o tamanho total do SCU ou o campo IPv6Header.PayloadLength para o tamanho da carga de UDP e o campo UdpHeader.Length para o tamanho das cargas agrupadas.

Se os cabeçalhos da Camada 2 (L2) estiverem presentes em datagramas agrupados, o SCU deverá conter um cabeçalho L2 válido. O cabeçalho L2 no SCU deve ser semelhante ao cabeçalho L2 dos datagramas agrupados.

Validação e indicação da soma de verificação

As indicações de URO devem definir os campos IPv4Header.HeaderChecksum e UdpHeader.Checksum como zero e preencher as informações de descarregamento de soma de verificação fora de banda no SCU indicando o sucesso da soma de verificação de IPv4 e UDP.

Um pacote que corresponda a todas as condições para ser agrupado, mas que não tenha falha na validação da soma de verificação, deve ser indicado separadamente. Os pacotes recebidos depois dele não deverão ser agrupados com os pacotes recebidos antes dele.

Por exemplo, suponha que os pacotes 1, 2, 3, 4 e 5 sejam recebidos do mesmo fluxo, mas o pacote 3 falhe na validação da soma de verificação. Os pacotes 1 e 2 podem ser agrupados, e os pacotes 4 e 5 podem ser agrupados, mas o pacote 3 não deve ser agrupado com nenhum dos SCU. Os pacotes 1 e 2 não devem ser agrupados juntamente com os pacotes 4 e 5. O pacote 2 é o último pacote em uma SCU, e o pacote 4 inicia uma nova SCU. Além disso, a SCU que contém os pacotes 1 e 2 deve ser indicada antes da indicação do pacote 3, e o pacote 3 deve ser indicado antes da SCU que contém os pacotes 4 e 5.

Agrupamento de pacotes e separação de fluxo

Pacotes de vários fluxos poderão ser agrupados em paralelo, conforme o hardware e a memória permitirem. Os pacotes de fluxos diferentes não devem ser agrupados.

Pacotes de múltiplos recebimentos intercalados podem ser separados e agrupados com seus respectivos fluxos. Por exemplo, dados os fluxos A, B e C, se os pacotes chegarem na ordem A, A, B, C, B, A, os pacotes do fluxo A poderão ser agrupados em AAA, e os pacotes do fluxo B agrupados em BB, enquanto o pacote do fluxo C poderá ser indicado normalmente ou agrupado com uma SCU pendente do fluxo C.

Os pacotes dentro de um determinado fluxo não devem ser reordenados em relação uns aos outros. Por exemplo, os pacotes do fluxo A devem ser agrupados na ordem recebida, independentemente dos pacotes dos fluxos B e C recebidos entre eles.

Palavra-chave de INF para controlar URO

A palavra-chave a seguir pode ser usada para ativar/desativar o URO com uma configuração de chave do Registro.

*UdpRsc

As palavras-chave de INF padronizadas por enumeração têm os seguintes atributos:

SubkeyName
O nome da palavra-chave que você deve especificar no arquivo INF e que aparece no registro.

ParamDesc
O texto de exibição associado a SubkeyName.

Valor
O valor inteiro de enumeração associado a cada opção na lista. Esse valor é armazenado em NDI\params\ SubkeyName\Value.

EnumDesc
O texto de exibição associado a cada valor exibido no menu.

Padrão
O valor padrão do menu.

SubkeyName ParamDesc Valor EnumDesc
*UdpRsc URO 0 Desabilitadas
1 (Padrão) Enabled

Para obter mais informações sobre como usar palavras-chave de enumeração, confira Palavras-chave de enumeração.

Criar um driver de miniporta de URO

Da NDIS 6.89 em diante, a interface da NDIS para URO facilita a comunicação entre TCP/IP e o driver de miniporta da NDIS.

Relatar a capacidade de URO

Um driver de miniporta anuncia suporte para URO no membro UdpRsc da estrutura NDIS_OFFLOAD, que transmite para a função NdisMSetMiniportAttributes.

Consultar recurso de URO

Para verificar se um driver de miniporta é compatível com URO, os drivers da NDIS e outros aplicativos podem consultar o OID OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, que retorna a estrutura NDIS_OFFLOAD.

Consultar o estado de URO

Para determinar o estado de URO atual, os drivers da NDIS e outros aplicativos podem consultar a solicitação OID OID_TCP_OFFLOAD_CURRENT_CONFIG. A NDIS processa esse OID e não o transmite para a miniporta.

Alterar o estado de URO

O URO pode ser habilitado ou desabilitado emitindo a solicitação de OID OID_TCP_OFFLOAD_PARAMETERS. O OID usa uma estrutura NDIS_OFFLOAD_PARAMETERS. Nessa estrutura, o membro UdpRsc.Enabled pode ter os seguintes valores:

Valor Significado
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_NO_CHANGE
0
O driver de miniporta não deve alterar a configuração atual.
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED
1
O URO está desabilitado.
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_ENABLED
2
O URO está habilitado.

Quando um driver processa uma solicitação de OID_TCP_OFFLOAD_PARAMETERS com o sinalizador NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED definido, a NIC deve aguardar para concluir a solicitação até que todos os segmentos agrupados existentes e as indicações de URO pendentes sejam indicados. Isso garante a sincronização de eventos de habilitação/desabilitação de URO entre componentes da NDIS.

Depois que o driver de miniporta processar a solicitação de OID OID_TCP_OFFLOAD_PARAMETERS, o driver de miniporta deverá emitir uma indicação de status de NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG com o estado de descarregamento atualizado.

O sinalizador NDIS_OFFLOAD_PARAMETERS_SKIP_REGISTRY_UPDATE em NDIS_OFFLOAD_PARAMETERS permite a desabilitação somente em tempo de execução do URO. As alterações feitas com esse sinalizador não são salvas no registro.

Desativação do URO na NDIS 6.89 e posterior

Os drivers direcionados à NDIS 6.89 e posterior devem entender os pacotes de URO e manipulá-los normalmente. Para desativar URO:

Essa abordagem garante que os componentes que não estão familiarizados com o URO não recebam NBLs URO. A NDIS desabilita o URO na miniporta durante a associação caso um driver LWF ou de protocolo que não oferece suporte a URO esteja presente.

Considerações sobre programação para drivers URO

Considere os seguintes problemas ao implementar um driver de miniporta compatível com URO.

API URO do WinSock

Para obter informações sobre a API URO do Winsock, confira Opções de soquete IPPROTO_UDP. Veja as informações sobre UDP_RECV_MAX_COALESCED_SIZE e UDP_COALESCED_INFO.

Atualizações de pilha de TCP/IP do Windows

O transporte de TCP/IP da Microsoft habilita o URO no momento da associação com a NDIS, a menos que a configuração o impeça de fazê-lo.

Os textos explicativos de WFP podem usar FWP_CALLOUT_FLAG_ALLOW_URO em FWPS_CALLOUT2 para anunciar seu suporte para URO. Se um texto explicativo de WFP incompatível for registrado em uma camada sensível a URO, o sistema operacional desabilitará o URO enquanto o texto explicativo estiver registrado.

Se um soquete optar pelo URO com um tamanho máximo de agrupamento maior ou igual ao tamanho de descarregamento do hardware, a pilha entregará as NBLs do hardware não modificado para o soquete. Se um soquete optar por um tamanho máximo de agrupamento menor, a pilha interromperá o recebimento de agrupamento no tamanho menor para o soquete.

Se um soquete não aceitar o URO, a pilha criará um novo segmento para os recebimentos desse soquete. Na ausência de hardware de URO, o recurso de URO de software existente continuará disponível.