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 de para unir pacotes UDP
- Criar um driver de miniporta de URO
- Considerações sobre programação para drivers 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
eIpHeader.DestinationAddress
são idênticos para todos os pacotes.UdpHeader.SourcePort
eUdpHeader.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
eIPv6Header.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:
- Os drivers de LWF (filtro leve) definem o sinalizador
NDIS_FILTER_DRIVER_UDP_RSC_NOT_SUPPORTED
na estrutura NDIS_FILTER_DRIVER_CHARACTERISTICS. - Os drivers de protocolo definem o sinalizador
NDIS_PROTOCOL_DRIVER_UDP_RSC_NOT_SUPPORTED
na estrutura NDIS_PROTOCOL_DRIVER_CHARACTERISTICS.
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.