Share via


卸載總和檢查碼工作

NDIS 支援在執行時間卸載 TCP/IP 總和檢查碼工作。

注意

 總和檢查碼卸載頻外 (OOB) 資料會儲存在 NET_BUFFER_LIST 資訊陣列中。 如需 OOB 資料的詳細資訊,請參閱 存取 TCP/IP 卸載NET_BUFFER_LIST資訊

在傳遞至迷你埠驅動程式之前,迷你埠驅動程式將執行總和檢查碼工作的封包NET_BUFFER_LIST結構,TCP/IP 傳輸會指定與NET_BUFFER_LIST結構相關聯的總和檢查碼資訊。 這項資訊是由 NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO 結構所指定,這是與NET_BUFFER_LIST結構相關聯的 (頻外資料) NET_BUFFER_LIST資訊的一部分。

卸載 TCP 封包的總和檢查碼計算之前,TCP/IP 傳輸會計算 TCP 虛擬頭的補數總和。 TCP/IP 傳輸會計算虛擬標題中所有欄位的補數總和,包括來源 IP 位址、目的地 IP 位址、通訊協定,以及 TCP 封包的 TCP 長度。 TCP/IP 傳輸會在 TCP 標頭的 [總和] 欄位中輸入虛擬標頭的補數總和。

TCP/IP 傳輸所提供虛擬header 的補數總和,可讓 NIC 提早開始計算傳送封包的實際 TCP 總和。 若要計算實際的 TCP 總和檢查碼,NIC 會計算 TCP 總和檢查碼的變數部分, (TCP 標頭和承載) 、將此總和新增至 TCP/IP 傳輸所計算之虛擬標頭的補數總和,並計算總和檢查碼的 16 位總和。 如需計算這類總和檢查碼的詳細資訊,請參閱 RFC 793 和 RFC 1122。

注意

TCP/IP 傳輸會使用與 TCP 封包相同的步驟,計算 UDP 封包虛擬標頭的補數總和,並將值儲存在 UDP 標頭的 Checksum 欄位中。

請注意,TCP/IP 傳輸一律可確保封包 IP 標頭中的總和檢查碼欄位設定為零,再將封包傳遞至基礎迷你埠驅動程式。 迷你埠驅動程式應該忽略 IP 標頭中的總和檢查碼欄位。 迷你埠驅動程式不需要確認總和檢查碼欄位設定為零,而且不需要將此欄位設定為零。

在其 MiniportSendNetBufferListsMiniportCoSendNetBufferLists 函式中收到NET_BUFFER_LIST結構之後,迷你埠驅動程式通常會執行下列總和檢查碼處理:

  1. 迷你埠驅動程式會使用TcpIpChecksumNetBufferListInfo的_Id來呼叫NET_BUFFER_LIST_INFO宏,以取得NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構。

  2. 迷你埠驅動程式會測試NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構中的 IsIPv4IsIPv6 旗標。 如果未設定 IsIPv4IsIPv6 旗標,NIC 就不應該在封包上執行任何總和檢查碼作業。

  3. 如果已設定 IsIPv4IsIPv6 旗標,迷你埠驅動程式會測試 TcpChecksumUdpChecksumIpHeaderChecksum 旗標,以判斷 NIC 應該計算封包的總和檢查碼。

  4. 迷你埠驅動程式會將封包傳遞至 NIC,以計算封包的適當總和檢查碼。 如果封包同時具有通道 IP 標頭和傳輸 IP 標頭,則支援 IP 總和檢查碼卸載的 NIC 只會在通道標頭上執行 IP 總和檢查碼工作。 TCP/IP 傳輸會在傳輸 IP 標頭上執行 IP 總和檢查碼工作。

在指示執行總和檢查碼工作的接收封包 NET_BUFFER_LIST 結構之前,迷你埠驅動程式會驗證適當的總和檢查碼,並在NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO結構中設定適當的 XxxChecksumFailedXxxChecksumSucceeded 旗 標。

啟用大型傳送卸載 (LSO) 時關閉位址總和檢查碼卸載,不會防止迷你埠驅動程式在 LSO 功能所產生的封包中計算和插入總和檢查碼。 若要停用位址總和檢查碼卸載,在此情況下,使用者也必須停用 LSO。