汎用セグメンテーションオフロード

汎用セグメント化オフロード (GSO) は、Large Send Offload (LSO) と UDP 送信オフロード (USO) をまとめて表します。

クライアント ドライバーは、ネットワーク メディアの最大伝送単位 (MTU) を超える TCP/UDP パケットのセグメント化をオフロードできます。 ドライバーは、GSO API を使用して NetAdapterCx にこの機能を示す必要があります。

GSO を制御するための INF キーワード

NetAdapterCx は、レジストリ キーワードをチェックし、アクティブ オフロード機能を有効化する際にそれらに従います。 ドライバーは、それ以上のアクションを実行する必要はありません。

「 レジストリ値を使用してタスク オフロードを有効または無効にする」 で指定された LSO キーワードを使用して、レジストリ キー設定を使用して LSO オフロードを有効または無効にすることができます。

UDP セグメント化オフロード (USO) で指定された 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. NIC が LSO をサポートしている場合、ドライバーは、NetAdapterOffloadLayer4FlagTcpWithoutOptions TCP フラグを Layer4Flags フィールドに設定する必要があります。

  3. NIC が USO をサポートしている場合、ドライバーは、NetAdapterOffloadLayer4FlagUdp UDP フラグを Layer4Flags フィールドに設定する必要があります。

  4. MaximumOffloadSize と MinimumSegmentCount は必須フィールドです。

  5. Layer4OffsetLimit フィールドは省略可能です。 指定した制限を超えるヘッダー オフセットを持つパケットが OS から送信された場合、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);
}