卸载校验和任务
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 传输提供的伪标头的补码总和使 NIC 提前开始计算发送数据包的实际 TCP 校验和。 为了计算实际的 TCP 校验和,NIC 计算 TCP 标头和有效负载) 的 TCP 校验和 (的变量部分,将此校验和添加到 TCP/IP 传输计算的伪标头的补数之和中,并计算校验和的 16 位补数。 有关计算此类校验和的详细信息,请参阅 RFC 793 和 RFC 1122。
注意
TCP/IP 传输使用与 TCP 数据包相同的步骤计算 UDP 数据包伪标头的补码总和,并将值存储在 UDP 标头的校验和字段中。
请注意,TCP/IP 传输始终确保在将数据包传递到基础微型端口驱动程序之前,数据包的 IP 标头中的校验和字段设置为零。 微型端口驱动程序应忽略 IP 标头中的校验和字段。 微型端口驱动程序不需要验证校验和字段是否设置为零,也不需要将此字段设置为零。
在其 MiniportSendNetBufferLists 或 MiniportCoSendNetBufferLists 函数中收到 NET_BUFFER_LIST 结构后,微型端口驱动程序通常会执行以下校验和处理:
微型端口驱动程序使用 tcpIpChecksumNetBufferListInfo_Id调用 NET_BUFFER_LIST_INFO 宏以获取NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO结构。
微型端口驱动程序在NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO结构中测试 IsIPv4 和 IsIPv6 标志。 如果未同时设置 IsIPv4 和 IsIPv6 标志,则 NIC 不应对数据包执行任何校验和操作。
如果设置了 IsIPv4 或 IsIPv6 标志,微型端口驱动程序将测试 TcpChecksum、 UdpChecksum 和 IpHeaderChecksum 标志,以确定 NIC 应为数据包计算哪些校验和。
微型端口驱动程序将数据包传递给 NIC,该 NIC 计算数据包的相应校验和。 如果数据包同时具有隧道 IP 标头和传输 IP 标头,则支持 IP 校验和卸载的 NIC 仅在隧道标头上执行 IP 校验和任务。 TCP/IP 传输对传输 IP 标头执行 IP 校验和任务。
在指示其执行校验和任务的接收数据包 的NET_BUFFER_LIST 结构之前,微型端口驱动程序会验证相应的校验和,并在NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO结构中设置相应的 XxxChecksumFailed 或 XxxChecksumSucceeded 标志。
启用大型发送卸载 (LSO) 时关闭地址校验和卸载不会阻止微型端口驱动程序计算校验和并在 LSO 功能生成的数据包中插入校验和。 在这种情况下,若要禁用地址校验和卸载,用户还必须禁用 LSO。