汎用セグメント化オフロード (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 を構成するには、クライアント ドライバー:
NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES構造体を割り当てます。
NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES_INITを呼び出して構造体を初期化します。
NetAdapterOffloadSetGsoCapabilities を呼び出して、構造体を NetAdapterCx に登録します。
NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES_INITの呼び出し中に、クライアント ドライバーはEVT_NET_ADAPTER_OFFLOAD_SET_GSOコールバックへのポインターを提供します。 アクティブなオフロード機能が変更された場合、システムは後でこのコールバックを呼び出します。
ハードウェア GSO 機能を示す規則
NET_ADAPTER_OFFLOAD_GSO_CAPABILITIES構造体には、次の規則が適用されます。
ドライバーは 、Layer3Flags と Layer4Flags を設定する必要があります。
NIC が LSO をサポートしている場合、ドライバーは、
NetAdapterOffloadLayer4FlagTcpWithoutOptionsTCP フラグを Layer4Flags フィールドに設定する必要があります。NIC が USO をサポートしている場合、ドライバーは、
NetAdapterOffloadLayer4FlagUdpUDP フラグを Layer4Flags フィールドに設定する必要があります。MaximumOffloadSize と MinimumSegmentCount は必須フィールドです。
Layer4OffsetLimit フィールドは省略可能です。 指定した制限を超えるヘッダー オフセットを持つパケットが OS から送信された場合、GSO の実行は求められません。
オプション/拡張機能がサポートされている場合は、オプション/拡張機能のない 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 オブジェクトに更新された機能を提供します。
クライアント ドライバーは、有効になっているオフロードを決定する次の関数を呼び出すことができます。
- NetOffloadIsLsoIPv4Enabled
- NetOffloadIsLsoIPv6Enabled
- NetOffloadIsUsoIPv4Enabled
- NetOffloadIsUsoIPv6Enabled
次の例は、クライアント ドライバーが 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);
}