チェックサム オフロード

NetAdapterCx では、実行時の TCP/IP チェックサム タスクのオフロードがサポートされます。

TCP/IP トランスポートは、クライアント ドライバーに NET_PACKET 構造体を渡す前に、 NET_PACKET_CHECKSUM パケット拡張機能のNET_PACKETに関連付けられているチェックum 情報を指定します。

TCP/IP トランスポートは、「チェックサム タスクのオフロード」で説明されているように、TCP/UDP パケットのチェックum 計算をオフロードする前に、TCP/UDP 擬似ヘッダーの補数の合計を計算します。

汎用セグメント化オフロード (GSO) が有効になっている場合に チェックサム オフロードをオフにしても、クライアント ドライバーが GSO 機能によって生成されたパケットにチェックum を計算して挿入することを防ぐことはありません。 チェックサム オフロードを完全に無効にするには、GSO も無効にする必要があります。

チェックサム オフロードを制御するための INF キーワード (keyword)

NetAdapterCx はレジストリ キーワードをチェックし、アクティブなオフロード機能を有効にするときにそれらを優先します。 ドライバーはそれ以上の操作を行う必要はありません。

チェックサム キーワード (keyword)を使用して、レジストリ値を使用してタスク オフロードを 有効または無効にするで指定 すると、レジストリ キーの設定でチェックサム オフロードを有効または無効にすることができます。 グループ化されたキーワード (keyword)はサポートされていません。

キーワード値は、タイプ 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_TX_CHECKSUM_CAPABILITIES_INIT の呼び出し中に、クライアント ドライバーは EVT_NET_ADAPTER_OFFLOAD_SET_RX_CHECKSUM コールバックへのポインターを提供します。 システムは、アクティブなオフロード機能が変更された場合に、後でこのコールバックを呼び出します。

ハードウェア送信チェック機能を示す規則

  1. NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES 構造体の Layer3Flags を設定する必要があります。 Layer4Flags の設定は省略可能です。 Layer3Flags と Layer4Flags の設定は、NIC が チェックサム オフロードを実行できるパケットを示します。

  2. NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES の Layer3HeaderOffsetLimit と Layer4HeaderOffsetLimit は省略可能です。 OS は、指定された制限を超えるヘッダー オフセットを持つパケットを送信する場合、そのレイヤーのチェックサムを計算するように NIC に要求しません。

  3. オプション/拡張機能がサポートされている場合は、オプション/拡張機能のない IP/TCP パケットをサポートする必要があります。

ハードウェア受信チェック機能を示す規則

NetAdapterCx では、ドライバーがハードウェア受信チェックサム機能をアドバタイズする必要はありません。 チェックサム オフロードが有効になっている場合、NIC は、処理できるすべてのパケットに対して チェックサム オフロードを実行する必要があります。 NIC がパケットに対して チェックサム オフロードを実行できない場合、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の場合、NIC はそのレイヤーで チェックサム操作を実行すべきではありません。

    • フラグが NetPacketTxChecksumActionRequiredの場合、クライアント ドライバーは、 NET_PACKET_LAYOUT 構造体を使用して、その特定のパケット内のそのレイヤーで使用されているプロトコルを決定し、パケットの計算チェックを NIC に示す必要があります。

  3. クライアント ドライバーは、パケットを NIC に渡し、パケットの適切なチェックサムを計算します。

チェックサム 処理を受信する

クライアント ドライバーは、チェックsum タスクを実行する受信パケットの NET_PACKET 構造を示す前に、チェックを検証し、 NET_PACKET_CHECKSUM 構造体に適切なフラグを設定します。

フラグは次のいずれかを指定できます。

フラグ 説明
NetPacketRxChecksumEvaluationNotChecked NIC がパケットのチェックを検証できませんでした
NetPacketRxChecksumEvaluationValid パケットのチェックサムが有効です
NetPacketRxChecksumEvaluationInvalid パケットのチェックサムが無効です