Generic Segmentation Offload

汎用セグメント化オフロード (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. ドライバーは、 Layer3FlagsLayer4Flags を設定する必要があります。

  2. NIC で LSO がサポートされている場合、ドライバーは Layer4Flags フィールドに NetAdapterOffloadLayer4FlagTcpWithoutOptions TCP フラグを設定する必要があります。

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

  4. MaximumOffloadSizeMinimumSegmentCount は必須フィールドです。

  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);
}