Поделиться через


Разгрузка контрольной суммы

NetAdapterCx поддерживает разгрузку задач контрольной суммы TCP/IP в процессе выполнения.

Прежде чем транспорт TCP/IP передаст структуру NET_PACKET драйверу клиента, он указывает информацию о контрольной сумме, связанной с NET_PACKET, в расширении пакета NET_PACKET_CHECKSUM.

Транспорт TCP/IP вычисляет сумму дополнения для псевдозаголовка TCP/UDP перед разгрузкой вычисления контрольных сумм для пакета TCP/UDP, как описано в разделе Разгрузка вычисления контрольных сумм.

Отключение разгрузки контрольной суммы при включенной функции универсальной сегментации (GSO) не мешает драйверу клиента вычислять и вставлять контрольные суммы в пакеты, созданные функцией GSO. Чтобы полностью отключить разгрузку контрольной суммы, вам также следует отключить GSO.

Ключевые слова INF для управления разгрузкой контрольной суммы

NetAdapterCx проверяет ключи реестра и учитывает их при включении активных функций разгрузки. Драйверу не нужно предпринимать никаких дальнейших действий.

Ключевые слова контрольной суммы, указанные в Использование значений реестра для включения и отключения разгрузки контрольной суммы, можно использовать для включения и отключения разгрузки контрольной суммы посредством настройки ключа реестра. Сгруппированные ключевые слова не поддерживаются.

Значения ключевых слов должны иметь тип REG_SZ.

Настройка разгрузки контрольной суммы

Клиентские драйверы изначально указывают возможности выгрузки контрольной суммы оборудования во время инициализации сетевого адаптера. Это может произойти в EvtDevicePrepareHardware обработчике обратного вызова перед тем как запустить сетевой адаптер.

Чтобы настроить разгрузку контрольной суммы передачи (Tx), драйвер клиента:

  1. Выделяет структуру NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES.

  2. Вызывает NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES_INIT для инициализации структуры.

  3. Вызывает NetAdapterOffloadSetTxChecksumCapabilities для регистрации структуры в NetAdapterCx.

Во время вызова NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES_INIT драйвер клиента предоставляет указатель на обратный вызов EVT_NET_ADAPTER_OFFLOAD_SET_TX_CHECKSUM. Система вызывает этот обратный вызов позже, если активные возможности разгрузки изменяются.

Чтобы настроить разгрузку контрольной суммы получения (Rx), драйвер клиента:

  1. Выделяет структуру NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES.

  2. Вызывает NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES_INIT для инициализации структуры.

  3. Вызывает NetAdapterOffloadSetRxChecksumCapabilities для регистрации структуры в NetAdapterCx.

Во время вызова NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES_INIT клиентский драйвер предоставляет указатель на обратный вызов EVT_NET_ADAPTER_OFFLOAD_SET_RX_CHECKSUM. Система вызывает этот обратный вызов позже, если активные возможности разгрузки изменяются.

Правила для указания возможностей контрольной суммы передачи оборудования

  1. Флаги Layer3Flags в структуре NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES должны быть установлены. Параметр Layer4Flags необязателен. Установка Layer3Flags и Layer4Flags указывает, на каких пакетах сетевой адаптер способен выполнять разгрузку контрольной суммы.

  2. Свойства Layer3HeaderOffsetLimit и Layer4HeaderOffsetLimit в NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES являются необязательными. Если ОС отправляет пакет со смещением заголовка, превышающим указанное ограничение, она не запрашивает NIC для вычисления контрольной суммы для этого слоя.

  3. Пакеты IP/TCP без параметров и расширений должны поддерживаться, если поддерживаются параметры и расширения.

Правила для обозначения возможностей аппаратных контрольных сумм

NetAdapterCx не требует, чтобы драйвер объявлял возможности оборудования по получению контрольной суммы. Если включена разгрузка контрольной суммы, сетевой адаптер должен выполнить разгрузку контрольной суммы на всех пакетах, которые он может обрабатывать. Если сетевой адаптер не может выполнить разгрузку контрольной суммы пакета, NetAdapterCx передаст эту задачу программному обеспечению.

В этом примере показано, как драйвер клиента может настроить возможности аппаратной разгрузки контрольных сумм.

VOID
MyAdapterSetOffloadCapabilities(
    NETADAPTER NetAdapter
)
{
    // Configure the hardware's Tx checksum offload capabilities
    NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES txChecksumOffloadCapabilities;

    auto const layer3Flags = NetAdapterOffloadLayer3FlagIPv4NoOptions |
        NetAdapterOffloadLayer3FlagIPv4WithOptions |
        NetAdapterOffloadLayer3FlagIPv6NoExtensions |
        NetAdapterOffloadLayer3FlagIPv6WithExtensions;

    auto const layer4Flags = NetAdapterOffloadLayer4FlagTcpNoOptions |
        NetAdapterOffloadLayer4FlagTcpWithOptions |
        NetAdapterOffloadLayer4FlagUdp;

    NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES_INIT(
        &txChecksumOffloadCapabilities,
        layer3Flags,
        EvtAdapterOffloadSetTxChecksum);

    txChecksumOffloadCapabilities.Layer4Flags = layer4Flags;

    txChecksumOffloadCapabilities.Layer4HeaderOffsetLimit = 127;

    // Set the current Tx checksum offload capabilities and register the callback for future changes in active capabilities
    NetAdapterOffloadSetTxChecksumCapabilities(NetAdapter,
        &txChecksumOffloadCapabilities);

    // Configure the hardware's Rx checksum offload capabilities
    NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES rxChecksumOffloadCapabilities;

    NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES_INIT(
        &rxChecksumOffloadCapabilities,
        EvtAdapterOffloadSetRxChecksum);

    // Set the current Rx checksum offload capabilities and register the callback for future changes in active capabilities
    NetAdapterOffloadSetRxChecksumCapabilities(NetAdapter,
        &rxChecksumOffloadCapabilities);
}

Обновление разгрузок оборудования

Если стек TCP/IP или вышестоящий драйвер протокола запрашивает изменение активных возможностей сетевого адаптера, то NetAdapterCx вызывает обратные вызовы драйвера клиента EVT_NET_ADAPTER_OFFLOAD_SET_TX_CHECKSUM или EVT_NET_ADAPTER_OFFLOAD_SET_RX_CHECKSUM, зарегистрированные во время инициализации адаптера. В этих функциях система предоставляет обновленные возможности в объекте NETOFFLOAD, который драйвер клиента запрашивает для обновления своих возможностей разгрузки.

Клиентские драйверы могут вызывать следующие функции для определения, какие разгрузки по контрольной сумме активированы.

В следующем примере показано, как драйвер клиента может обновить свои возможности разгрузки контрольной суммы Tx/Rx:

VOID
MyEvtAdapterOffloadSetTxChecksum(
    NETADAPTER  NetAdapter,
    NETOFFLOAD  Offload
)
{
    PMY_NET_ADAPTER_CONTEXT adapterContext = MyGetNetAdapterContext(NetAdapter);

    // Store the updated information in the context
    adapterContext->TxHardwareIpChecksum = NetOffloadIsTxChecksumIPv4Enabled(Offload);
    adapterContext->TxHardwareTcpChecksum = NetOffloadIsTxChecksumTcpEnabled(Offload);
    adapterContext->TxHardwareUdpChecksum = NetOffloadIsTxChecksumUdpEnabled(Offload);

    // Update the new hardware Tx checksum offload capabilities
    MyUpdateHardwareChecksum(adapterContext);
}

VOID
MyEvtAdapterOffloadSetRxChecksum(
    NETADAPTER  NetAdapter,
    NETOFFLOAD  Offload
)
{
    PMY_NET_ADAPTER_CONTEXT adapterContext = MyGetNetAdapterContext(NetAdapter);

    // Store the updated information in the context
    adapterContext->RxHardwareIpChecksum = NetOffloadIsRxChecksumIPv4Enabled(Offload);
    adapterContext->RxHardwareTcpChecksum = NetOffloadIsRxChecksumTcpEnabled(Offload);
    adapterContext->RxHardwareUdpChecksum = NetOffloadIsRxChecksumUdpEnabled(Offload);

    // Update the new hardware Rx checksum offload capabilities
    MyUpdateHardwareChecksum(adapterContext);
}

Передача обработки контрольной суммы

Драйвер клиента обычно выполняет следующую обработку контрольной суммы на пути передачи:

  1. Драйвер клиента вызывает функцию NetExtensionGetPacketChecksum с индексом пакета, чтобы получить структуру NET_PACKET_CHECKSUM.

  2. Драйвер клиента проверяет флаги, специфичные для уровня, в структуре NET_PACKET_CHECKSUM.

    • Если флаг NetPacketTxChecksumActionPassthrough, сетевой адаптер не должен выполнять операции контрольной суммы в этом слое.

    • Если флаг NetPacketTxChecksumActionRequired, драйвер клиента должен определить протокол, используемый на этом уровне в указанном пакете, с помощью структуры NET_PACKET_LAYOUT и указать сетевому адаптеру, какой контрольную сумму он должен вычислить для пакета.

  3. Драйвер клиента передает пакет сетевому адаптеру, который вычисляет соответствующие контрольные суммы для пакета.

Получение обработки контрольной суммы

Перед указанием структуры NET_PACKET для пакета приёма, на котором драйвер клиента выполняет задачи контрольной суммы, драйвер клиента проверяет контрольные суммы и устанавливает соответствующие флаги в структуре NET_PACKET_CHECKSUM.

Флаги могут быть одним из следующих:

Флаг Описание
NetPacketRxChecksumEvaluationNotChecked Сетевой адаптер не может проверить контрольную сумму пакета.
NetPacketRxChecksumEvaluationValid Контрольная сумма пакета действительна
NetPacketRxChecksumEvaluationInvalid Контрольная сумма пакета недействительна