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


Разгрузка общей сегментации

Универсальная разгрузка сегментации (GSO) совместно обозначает разгрузку большого объема передачи (LSO) и разгрузку UDP отправки (USO).

Клиентские драйверы могут выгрузить сегментацию пакетов TCP/UDP, превышающих максимальное значение единицы передачи (MTU) сетевой среды. Драйверы должны указывать эту возможность для NetAdapterCx с помощью API GSO.

Ключевые слова INF для управления GSO

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

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

Ключевые слова USO, указанные в отключении сегментации UDP (USO), можно использовать для включения и отключения разгрузки USO с помощью настройки ключа реестра.

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

Настройка GSO

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

Чтобы настроить GSO, драйвер клиента:

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

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

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

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

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

Следующие правила применяются к структуре NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES:

  1. Драйвер должен задать Layer3Flags и Layer4Flags.

  2. Если сетевой адаптер поддерживает LSO, драйвер должен заполнить поле Layer4Flags флагом TCP NetAdapterOffloadLayer4FlagTcpWithoutOptions.

  3. Если сетевой адаптер поддерживает USO, драйвер должен заполнить поле Layer4Flags флагом NetAdapterOffloadLayer4FlagUdp UDP.

  4. MaximumOffloadSize и MinimumSegmentCount являются обязательными полями.

  5. Поле Layer4OffsetLimit является необязательным. Если ОС отправляет пакет со смещением заголовка, превышающим указанное ограничение, он не будет запрашивать выполнение GSO.

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

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

VOID
MyAdapterSetOffloadCapabilities(
    NETADAPTER NetAdapter
)
{
    // Configure the hardware's GSO offload capabilities
    NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES gsoOffloadCapabilities;

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

    auto const layer4Flags = NetAdapterOffloadLayer4FlagTcpNoOptions |
        NetAdapterOffloadLayer4FlagTcpWithOptions;
        NetAdapterOffloadLayer4FlagUdp;

    NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES_INIT(
        &gsoOffloadCapabilities,
        layer3Flags,
        layer4Flags,
        MY_GSO_OFFLOAD_MAX_SIZE,
        MY_GSO_OFFLOAD_MIN_SEGMENT_COUNT,
        EvtAdapterOffloadSetGso);

    gsoOffloadCapabilities.Layer4OffsetLimit = 127;

    // Set the current GSO offload capabilities and register the callback for future changes in active capabilities
    NetAdapterOffloadSetGsoCapabilities(NetAdapter, &gsoOffloadCapabilities);
}

Обновление аппаратных разгрузок

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

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

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

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

	// Store the updated information in the context
	adapterContext->LSOv4 = NetOffloadIsLsoIPv4Enabled(Offload) ? 
		GsoOffloadEnabled : GsoOffloadDisabled;
	adapterContext->LSOv6 = NetOffloadIsLsoIPv6Enabled(Offload) ?
		GsoOffloadEnabled : GsoOffloadDisabled;
	adapterContext->USOv4 = NetOffloadIsUsoIPv4Enabled(Offload) ? 
		GsoOffloadEnabled : GsoOffloadDisabled;
	adapterContext->USOv6 = NetOffloadIsUsoIPv6Enabled(Offload) ?
		GsoOffloadEnabled : GsoOffloadDisabled;

	// Enable hardware checksum if LSO/USO is enabled
	MyUpdateHardwareChecksum(adapterContext);
}