Compartilhar via


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

Do Windows 11, versão 24H2, em diante, a URO (descarga de agrupamento de segmentos de recebimento de UDP) permite que as placas de adaptador de rede (NICs) agrupem segmentos de recebimento de UDP. As NICs podem combinar datagramas 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.

A associação de datagramas 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 unir pacotes UDP e como escrever um driver de miniporto URO.

Regras para unir pacotes 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 não for zero, deve estar correto em todos os pacotes. Isso significa que o descarregamento da soma de verificação de recebimento deve validar o pacote.
  • Layer 2 headers deve ser idêntico 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.
  • Os pacotes recebidos devem ter o IPv4Header.HeaderChecksum 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* + comprimento(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 unidade única coalescida (UPU) resultante deve ter um único cabeçalho IP e cabeçalho UDP, seguido pela carga útil UDP de todos os datagramas coalescidos concatenados.

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

Se os cabeçalhos de Camada 2 (L2) estiverem presentes em datagramas unidos, 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 coalescidos.

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 devem ser unidos com 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 falha na validação da soma de verificação. Os pacotes 1 e 2 podem ser unidos e os pacotes 4 e 5 podem ser unidos, mas o pacote 3 não deve ser unido com nenhum dos SCU. Os pacotes 1 e 2 não devem ser agrupados com os pacotes 4 e 5. O pacote 2 é o último pacote em um SCU e o pacote 4 inicia um novo SCU. Além disso, o SCU que contém os pacotes 1 e 2 deve ser indicado antes que o pacote 3 seja indicado e o pacote 3 deve ser indicado antes do SCU que contém os pacotes 4 e 5.

Agrupamento de pacotes e separação de fluxo

Pacotes de vários fluxos podem ser coalescidos em paralelo, conforme permitido pelo hardware e pela memória. Pacotes de fluxos diferentes não devem ser combinados.

Pacotes de múltiplos recebimentos intercalados poderão 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 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 unidos na ordem em que foram recebidos, independentemente dos pacotes dos fluxos B e C recebidos entre eles.

Palavra-chave INF para controlar o URO

A palavra-chave a seguir pode ser usada para habilitar/desabilitar o URO com uma configuração de chave do Registro:

  • *UdpRsc

As palavras-chave 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 ao 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 que aparece 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, consulte palavras-chave de enumeração.

Criar um driver de miniporta de URO

A partir do NDIS 6.89, a interface NDIS para URO facilita a comunicação entre TCP/IP e o driver de miniporto 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. O NDIS gerencia essa OID e não a passa para o miniporto.

Alterar o estado de URO

O URO pode ser habilitado ou desabilitado emitindo a solicitação de OID OID_TCP_OFFLOAD_PARAMETERS. Essa 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 miniport 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 do URO entre componentes do 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.

Desativar o URO no NDIS 6.89 e versões posteriores

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. O NDIS desabilita o URO no miniporto durante a associação se um LWF ou driver de protocolo que não dá suporte ao URO estiver presente.

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

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

Winsock URO API

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

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

O transporte TCP/IP da Microsoft habilita o URO no momento da vinculação com o NDIS, a menos que a configuração impeça isso.

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

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 irá interromper o recebimento de agrupamento no tamanho menor para o soquete.

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