PD_BUFFER 结构 (ndis.h)

此结构表示 PacketDirect (PD) 数据包,或队列中 PD 数据包的一部分。

语法

typedef struct _PD_BUFFER {
  struct _PD_BUFFER   *NextPDBuffer;
  struct _PD_BUFFER   *NextPartialPDBuffer;
  PVOID               PDClientReserved;
  PVOID               PDClientContext;
  PUCHAR              DataBufferVirtualAddress;
  DMA_LOGICAL_ADDRESS DataBufferDmaLogicalAddress;
  ULONG               DataBufferSize;
  USHORT              PDClientContextSize;
  USHORT              Attributes;
  USHORT              Flags;
  USHORT              DataStart;
  ULONG               DataLength;
  union {
    struct {
      union {
        ULONG64 RxFilterContext;
        ULONG64 GftFlowEntryId;
      };
      ULONG                         RxHashValue;
      union {
        struct {
          ULONG RxIPHeaderChecksumSucceeded : 1;
          ULONG RxTCPChecksumSucceeded : 1;
          ULONG RxUDPChecksumSucceeded : 1;
          ULONG RxIPHeaderChecksumFailed : 1;
          ULONG RxTCPChecksumFailed : 1;
          ULONG RxUDPChecksumFailed : 1;
          ULONG RxHashComputed : 1;
          ULONG RxHashWithL4PortNumbers : 1;
          ULONG RxGftDirectionIngress : 1;
          ULONG RxGftExceptionPacket : 1;
          ULONG RxGftCopyPacket : 1;
          ULONG RxGftSamplePacket : 1;
          ULONG RxReserved1 : 4;
          ULONG RxCoalescedSegCount : 16;
          ULONG RxRscTcpTimestampDelta;
        };
        ULONG RxOffloads[2];
      };
      union {
        struct {
          ULONG TxIsIPv4 : 1;
          ULONG TxIsIPv6 : 1;
          ULONG TxTransportHeaderOffset : 10;
          ULONG TxMSS : 20;
          ULONG TxComputeIPHeaderChecksum : 1;
          ULONG TxComputeTCPChecksum : 1;
          ULONG TxComputeUDPChecksum : 1;
          ULONG TxIsEncapsulatedPacket : 1;
          ULONG TxInnerPacketOffsetsValid : 1;
          ULONG TxReserved1 : 11;
          ULONG TxInnerFrameOffset : 8;
          ULONG TxInnerIpHeaderRelativeOffset : 6;
          ULONG TxInnerIsIPv6 : 1;
          ULONG TxInnerTcpOptionsPresent : 1;
        };
        ULONG TxOffloads[2];
      };
      PD_BUFFER_VIRTUAL_SUBNET_INFO VirtualSubnetInfo;
      PD_BUFFER_8021Q_INFO          Ieee8021qInfo;
      USHORT                        GftSourceVPortId;
      ULONG                         Reserved;
      UINT64                        ProviderScratch;
    } MetaDataV0;
  };
} PD_BUFFER;

成员

NextPDBuffer

指向队列中下一 个PD_BUFFER 结构的指针。

NextPartialPDBuffer

指向队列中下一部分 PD_BUFFER 结构的指针。

PDClientReserved

预留给系统使用。 请勿使用。

PDClientContext

不允许客户端和提供程序修改此字段。 如果客户端为 ClientContextSize 分配了非零值的 PD_BUFFER ,则 PDClientContext 引用缓冲区大小 ClientContextSize。 否则,此字段为 NULL。

DataBufferVirtualAddress

此字段表示主机和软件可用于访问/修改数据包内容的地址。 实际数据包数据始终位于 DataBufferVirtualAddress+DataStart。 提供程序和平台在 初始化PD_BUFFER 后永远不会修改此字段的值。

DataBufferDmaLogicalAddress

此字段表示用于存储数据包数据的逻辑内存位置。 提供程序必须使用 DMA。 实际数据包数据始终位于 DataBufferDmaLogicalAddress+DataStart。 提供程序和平台不得在 初始化PD_BUFFER 后修改此字段的值。

DataBufferSize

这是分配的数据缓冲区的总大小。 提供程序和平台不得在 初始化PD_BUFFER 后修改此字段的值。 由于发送卸载较大,此数据类型为 ULONG 而不是 USHORT

PDClientContextSize

如果此值为非零,则表示 PDClientContext 指向的缓冲区的大小。 此字段的值只能由平台修改。 PD_BUFFER 分配后 ,平台不会更改此字段的值。

Attributes

提供程序不得修改这些属性。 下表列出了此 PD_BUFFER 结构可以具有的属性。

Attribute 说明
PD_BUFFER_ATTR_BUILT_IN_DATA_BUFFER 使用自己的附带数据缓冲区分配 的PD_BUFFER 将设置此属性。 客户端或提供程序绝不能修改 PD_BUFFER 属性。

Flags

下表列出了此 PD_BUFFER 结构可以具有的标志。

标志 描述
PD_BUFFER_FLAG_PARTIAL_PACKET_HEAD 指示此缓冲区是部分数据包的头。

DataStart

此字段表示数据包相对于分配的数据缓冲区的原始起始地址的开始位置。 提供程序不得修改此字段。 提供程序将此值添加到 DataBufferDmaLogicalAddress 值,以派生数据包接收/传输的实际目标 DMA 地址。 例如,将PD_BUFFER发布到接收/传输队列时,硬件接收/传输描述符中的目标 DMA 地址值必须设置为 DataBufferDmaLogicalAddress+DataStart

DataLength

此数据包或部分数据包数据的长度。

MetaDataV0

MetaDataV0.RxFilterContext

提供程序将此设置为从将数据包引导到接收队列的匹配筛选器获取的筛选器上下文值。 筛选器上下文值在配置筛选器时由客户端指定。

MetaDataV0.GftFlowEntryId

如果设置了 RxGftExceptionPacket 或 RxGftCopyPacket 或 RxGftSamplePacket 位之一,则 RxFilterContext 值将被 GFT 流条目 ID 值覆盖。

MetaDataV0.RxHashValue

为使用 RSS 引导到接收队列的传入数据包计算的哈希值。

MetaDataV0.RxIPHeaderChecksumSucceeded

一个常见的 RX 卸载字段,指示 IP 标头校验和是否成功。

MetaDataV0.RxTCPChecksumSucceeded

一个常见的 RX 卸载字段,指示 TCP 校验和是否成功。

MetaDataV0.RxUDPChecksumSucceeded

一个常见的 RX 卸载字段,指示 UDP 校验和是否成功。

MetaDataV0.RxIPHeaderChecksumFailed

一个常见的 RX 卸载字段,指示 IP 标头校验和是否失败。

MetaDataV0.RxTCPChecksumFailed

一个常见的 RX 卸载字段,指示 TCP 校验和是否失败。

MetaDataV0.RxUDPChecksumFailed

一个常见的 RX 卸载字段,指示 UDP 校验和是否失败。

MetaDataV0.RxHashComputed

一个常见的 RX 卸载字段,指示是否计算哈希。

MetaDataV0.RxHashWithL4PortNumbers

一个常见的 RX 卸载字段,指示哈希是使用 L4 端口号计算的。

MetaDataV0.RxGftDirectionIngress

MetaDataV0.RxGftExceptionPacket

一个常见的 RX 卸载字段,指示这是 GFT 异常数据包。

MetaDataV0.RxGftCopyPacket

一个常见的 RX 卸载字段,指示这是 GFT 复制数据包。

MetaDataV0.RxGftSamplePacket

一个常见的 RX 卸载字段,指示这是一个 GFT 示例数据包。

MetaDataV0.RxReserved1

保留。

MetaDataV0.RxCoalescedSegCount

包含合并段量的常见 RX 卸载字段。

MetaDataV0.RxRscTcpTimestampDelta

包含 RSC 和 TCP 时间戳差异的常见 RX 卸载字段。

MetaDataV0.RxOffloads[2]

RX 卸载此缓冲区。

MetaDataV0.TxIsIPv4

一个常见的 TX 卸载字段,指示此数据包是 IPv4。

MetaDataV0.TxIsIPv6

一个常见的 TX 卸载字段,指示此数据包是 IPv6。

MetaDataV0.TxTransportHeaderOffset

包含数据包标头偏移量的常用 TX 卸载字段。

MetaDataV0.TxMSS

包含此数据包的最大段大小的常见 TX 卸载字段。

MetaDataV0.TxComputeIPHeaderChecksum

一个常见的 TX 卸载字段,指示已计算 IP 标头校验和。

MetaDataV0.TxComputeTCPChecksum

一个常见的 TX 卸载字段,指示计算 TCP 校验和。

MetaDataV0.TxComputeUDPChecksum

一个常见的 TX 卸载字段,指示已计算 UDP 校验和。

MetaDataV0.TxIsEncapsulatedPacket

一个常见的 TX 卸载字段,指示数据包已封装。

MetaDataV0.TxInnerPacketOffsetsValid

一个常见的 TX 卸载字段,指示内部数据包偏移量有效。

MetaDataV0.TxReserved1

保留。

MetaDataV0.TxInnerFrameOffset

包含内部帧偏移量的常见 TX 卸载字段。

MetaDataV0.TxInnerIpHeaderRelativeOffset

包含内部 IP 标头相对偏移量的常用 TX 卸载字段。

MetaDataV0.TxInnerIsIPv6

一个常见的 TX 卸载字段,指示内部数据包是 IPv6。

MetaDataV0.TxInnerTcpOptionsPresent

一个常见的 TX 卸载字段,指示存在内部 TCP 选项。

MetaDataV0.TxOffloads[2]

TX 卸载此缓冲区。

MetaDataV0.VirtualSubnetInfo

虚拟子网信息。

MetaDataV0.Ieee8021qInfo

IEEE 802.1Q 信息。

MetaDataV0.GftSourceVPortId

GFT 源虚拟端口 ID。

MetaDataV0.Reserved

预留给系统使用。

MetaDataV0.ProviderScratch

当PD_BUFFER位于提供程序队列 ((即客户端发布但尚未被客户端) 排空)时,PD 提供程序可用于自己的目的的暂存字段。 客户端排空PD_BUFFER后,无法保证保留此字段的内容。

注解

如果 L2 数据包由多个 PD_BUFFER 结构表示,则第一个 PD_BUFFER 必须设置PD_BUFFER_ATTR_BUILT_IN_DATA_BUFFER标志,NextPartialPDBuffer 字段必须指向构成整个数据包的部分 PD_BUFFER 结构。 每个部分 PD_BUFFER 结构必须使用 NextPartialPDBuffer 而不是 NextPDBuffer 字段指向下一个部分 PD_BUFFER 。 除头缓冲区外,在所有部分 PD_BUFFER 结构中,NextPDBuffer 字段必须为 NULL。 除头缓冲区之外的所有部分PD_BUFFER结构都必须清除PD_BUFFER_ATTR_BUILT_IN_DATA_BUFFER标志。 最后一 个部分PD_BUFFER 必须将 NextPartialPDBuffer 字段设置为 NULL。 L2 数据包的总长度是每个部分 PD_BUFFER的 DataLength 字段之和。 头 PD_BUFFER 必须最多包含 IP 传输 (TCP、UDP、SCTP 等) 标头。 在封装或双封装的情况下,最内部的 IP 传输标头必须包含在头 PD_BUFFER中。

发布 PD_BUFFER 结构以接收队列时,提供程序 (会忽略 DataLength。有关详细信息,请参阅 NDIS_PD_QUEUE_PARAMETERS 结构) 中的 ReceiveDataLength 说明。 从接收队列中清空已完成 PD_BUFFER 结构时,提供程序会将收到的数据包的长度存储在 DataLength 字段中。 长度不包括 FCS 或任何去除的 801Q 标头。 发布 PD_BUFFER 结构以传输队列时,DataLength 表示要发送的数据包的长度。 从传输队列中排空已完成 PD_BUFFER 结构时,提供程序未修改 DataLength 字段。

要求

要求
最低受支持的客户端 Windows 10
最低受支持的服务器 Windows Server 2016
标头 ndis.h