泛型分段卸载
通用分段卸载 (GSO) 共同表示 大型发送卸载 (LSO) 和 UDP 发送卸载 (USO) 。
客户端驱动程序可以卸载大于网络媒体的最大传输单元 (MTU) 的 TCP/UDP 数据包分段。 驱动程序必须使用 GSO API 向 NetAdapterCx 指示此功能。
用于控制 GSO 的 INF 关键字
NetAdapterCx 检查注册表关键字,并在启用活动卸载功能时遵循它们。 驱动程序无需执行任何进一步操作。
使用注册表值启用和禁用任务卸载中指定的 LSO 关键字可用于使用注册表项设置启用/禁用 LSO 卸载。
UDP 分段卸载 (USO) 中指定的 USO 关键字可用于使用注册表项设置启用/禁用 USO 卸载。
关键字 (keyword) 值的类型必须为 REG_SZ。
配置 GSO
客户端驱动程序在 Net 适配器初始化期间首先播发其硬件的 GSO 功能。 在启动 net 适配器之前,这可能在其 EvtDevicePrepareHardware 回调中发生。
若要配置 GSO,客户端驱动程序:
调用 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,驱动程序必须使用 TCP 标志填充 Layer4Flags 字段
NetAdapterOffloadLayer4FlagTcpWithoutOptions
。如果 NIC 支持 USO,驱动程序必须使用 UDP 标志填充 Layer4Flags 字段
NetAdapterOffloadLayer4FlagUdp
。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);
}