總和檢查碼卸載
NetAdapterCx 支援在執行時間卸載 TCP/IP 總和檢查碼工作。
TCP/IP 傳輸將 NET_PACKET 結構傳遞至用戶端驅動程式之前,它會指定與 NET_PACKET_CHECKSUM 封包擴充功能中NET_PACKET相關聯的總和檢查碼資訊。
TCP/IP 傳輸會先計算 TCP/UDP 虛擬頭的補數總和,再卸載 TCP/UDP 封包的總和,如 卸載總和總和檢查碼工作中所述。
啟用 一般分割卸 除 (GSO) 時關閉總和檢查碼卸載,不會防止用戶端驅動程式在 GSO 功能所產生的封包中計算和插入總和檢查碼。 若要完全停用總和檢查碼卸載,您也必須停用 GSO。
用於控制總和檢查碼卸載的 INF 關鍵字
NetAdapterCx 會檢查登錄關鍵字,並在啟用作用中的卸載功能時接受它們。 驅動程式不需要採取任何進一步的動作。
使用登錄值啟用和停用工作卸除中指定的總和檢查碼關鍵字可用來啟用/停用登錄機碼設定的總和檢查碼卸載。 不支援群組關鍵字。
關鍵字值的類型必須是 REG_SZ。
設定總和檢查碼卸載
用戶端驅動程式會在網路介面卡初始化期間先公告其硬體總和檢查碼卸載功能。 這可能會發生在其 EvtDevicePrepareHardware 回呼內,再啟動網路介面卡。
若要設定傳輸 (Tx) 總和檢查碼卸載,用戶端驅動程式:
呼叫 NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES_INIT 來初始化 結構。
呼叫 NetAdapterOffloadSetTxChecksumCapabilities 以向 NetAdapterCx 註冊結構。
在呼叫 NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES_INIT 用戶端驅動程式期間,會提供 EVT_NET_ADAPTER_OFFLOAD_SET_TX_CHECKSUM回 呼的指標。 如果作用中的卸載功能變更,系統稍後會叫用此回呼。
若要設定接收 (Rx) 總和檢查碼卸載,用戶端驅動程式:
呼叫 NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES_INIT 來初始化 結構。
呼叫 NetAdapterOffloadSetRxChecksumCapabilities 以向 NetAdapterCx 註冊結構。
在呼叫 NET_ADAPTER_OFFLOAD_RX_CHECKSUM_CAPABILITIES_INIT 用戶端驅動程式會提供 EVT_NET_ADAPTER_OFFLOAD_SET_RX_CHECKSUM回 呼的指標。 如果作用中的卸載功能變更,系統稍後會叫用此回呼。
指示硬體傳輸總和檢查碼功能的規則
必須設定 NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES 結構中的 Layer3Flags。 設定 Layer4Flags 是選擇性的。 設定 Layer3Flags 和 Layer4Flags 表示 NIC 能夠執行總和檢查碼卸載的封包。
NET_ADAPTER_OFFLOAD_TX_CHECKSUM_CAPABILITIES 中的 Layer3HeaderOffsetLimit 和 Layer4HeaderOffsetLimit 是選擇性的。 如果 OS 傳送標頭位移大於指定限制的封包,則不會要求 NIC 計算該層總和檢查碼。
如果支援選項/延伸模組,則必須支援不含選項/延伸模組的 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 堆疊或過度通訊協定驅動程式要求變更 net adapter 的作用中功能,NetAdapterCx 會叫用用戶端驅動程式 的EVT_NET_ADAPTER_OFFLOAD_SET_TX_CHECKSUM 或EVT_NET_ADAPTER_OFFLOAD_SET_RX_CHECKSUM在配接器初始化期間註冊的 回 呼。 在這些函式中,系統會在 NETOFFLOAD 物件中提供更新的功能,用戶端驅動程式會查詢以更新其卸載功能。
用戶端驅動程式可以呼叫下列函式,以判斷已啟用哪些總和檢查碼卸載:
- NetOffloadIsTxChecksumIPv4Enabled
- NetOffloadIsTxChecksumTcpEnabled
- NetOffloadIsTxChecksumUdpEnabled
- NetOffloadIsRxChecksumIPv4Enabled
- NetOffloadIsRxChecksumTcpEnabled
- NetOffloadIsRxChecksumUdpEnabled
下列範例示範用戶端驅動程式如何更新其 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);
}
傳輸總和檢查碼處理
用戶端驅動程式通常會在傳輸路徑上執行下列總和檢查碼處理:
用戶端驅動程式會使用封包索引呼叫 NetExtensionGetPacketChecksum 函式,以取得 NET_PACKET_CHECKSUM 結構。
用戶端驅動程式會測試NET_PACKET_CHECKSUM結構中的圖層特定旗標。
如果旗標為
NetPacketTxChecksumActionPassthrough
,則 NIC 不應該在該層中執行總和檢查碼作業。如果 旗標為
NetPacketTxChecksumActionRequired
,用戶端驅動程式應該使用 NET_PACKET_LAYOUT 結構來判斷該特定封包中使用該層的通訊協定,並指示 NIC 其應該計算封包的總和檢查碼。
用戶端驅動程式會將封包傳遞至 NIC,以計算封包的適當總和檢查碼。
接收總和檢查碼處理
在指示執行總和檢查碼工作的接收封包 NET_PACKET 結構之前,用戶端驅動程式會驗證總和檢查碼,並在 NET_PACKET_CHECKSUM 結構中設定適當的旗標。
旗標可以是下列其中一項:
旗標 | 描述 |
---|---|
NetPacketRxChecksumEvaluationNotChecked |
NIC 無法驗證封包總和檢查碼 |
NetPacketRxChecksumEvaluationValid |
封包總和檢查碼有效 |
NetPacketRxChecksumEvaluationInvalid |
封包總和檢查碼無效 |