以下要求和限制适用于 WFP 层。
转发层
如果为源自或发往计算机的地址的数据包启用了 IP 转发,并且数据包在与分配本地地址的接口不同的接口上发送或接收,则 IP 数据包将传递到转发层。 默认情况下,IP 转发处于禁用状态,可以使用 用于 IPv4 转发的 netsh 接口 ipv4 set 接口 命令或用于 IPv6 转发的 netsh 接口 ipv6 set 接口 命令来启用。
转发层可以在每个收到的片段到达时转发或保留 IP 有效负载的片段,直到所有片段到达,然后转发它们。 这称为 片段分组。 当禁用片段分组 (默认禁用) 时,转发的 IP 数据包片段将一次指示给 WFP。 启用片段分组后,会将片段指示给 WFP 两次:首先作为片段本身,再指示在 由NET_BUFFER_LIST 链描述的片段组中。 WFP 在将片段组指示为转发层标注时设置 FWP_CONDITION_FLAG_IS_FRAGMENT_GROUP 标志。 可以使用 netsh 接口 {ipv4|ipv6} 集全局 groupforwardedfragments=enabled 命令启用片段分组。 片段分组不同于重新组合,后者是在目标主机上重建原始 IP 数据包。
转发层处指示 的NET_BUFFER_LIST 结构可以描述完整的 IP 数据包、IP 数据包片段或 IP 数据包片段组。 当 IP 数据包片段遍历转发层时,它会在标注中指示两次:第一次是作为片段,另一次是作为片段组中的片段。
指示片段组时, FWP_CONDITION_FLAG_IS_FRAGMENT_GROUP 标志将作为传入值传递到标注驱动程序的 分类Fn 标注函数。 在这种情况下,NetBufferList 参数指向的NET_BUFFER_LIST结构是NET_BUFFER_LIST链的第一个节点,每个NET_BUFFER_LIST描述数据包片段。
向前注入的数据包不会呈现给任何 WFP 层。 可以再次向标注驱动程序指示注入的数据包。 若要防止无限循环,驱动程序应先调用 FwpsQueryPacketInjectionState0 函数,然后再继续调用 分类Fn 标注函数,并且驱动程序应允许将注入状态 FWPS_PACKET_INJECTION_STATE 设置为 FWPS_PACKET_INJECTED_BY_SELF 或 FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF 的数据包通过未更改。
可以使用以下命令查看系统的当前“组转发片段”设置: netsh 接口 {ipv4|ipv6} show global。
网络层
仅针对传入路径指示的 IP 数据包片段在此层的三点处表示:第一个作为 IP 数据包,再次作为 IP 片段,第三次作为重新组合的 IP 数据包的一部分。 WFP 在向网络层标注指示片段时设置 FWP_CONDITION_FLAG_IS_FRAGMENT 标志。
例如,如果将单个 IP 数据包划分为四个片段,则此数据包的指示如下所示:
- 每个“原始”IP 数据包的一个指示 (4 个分类,或调用标注的分类函数)
- 每个“原始片段”一个指示 (4 个分类)
- 一个指示最终重新组合的 IP 数据包 (1 分类)
添加筛选条件时, FWP_MATCH_FLAGS_NONE_SET 可以与 FWP_CONDITION_FLAG_IS_FRAGMENT 标志一起使用,以避免第二个指示 () 。 这些条件标志旨在阻止标注驱动程序不关心的分类。 如果标注仅检查 (未分段和重新组合) 的完整数据包,则必须分析 IP 标头以避免处理指示为 IP 数据包的片段。 标注可以执行以下步骤来实现此目的:
- 通过检查是否设置了“更多片段 (MF) ”标志和/或“片段偏移量”字段不为 0,跳过第一个指示 () 。
- 编写允许设置 FWP_CONDITION_FLAG_IS_FRAGMENT 的所有分类的筛选器。
- 对重新组合的数据包执行所需的任何处理。
或者,标注可以检查传输层上的数据包。
传输层和 ALE
为了能够与 IPsec 处理共存,在传入传输层检查数据包的标注还必须在 ALE 接收层和接受层注册。 此类标注可以检查/修改传输层的大部分流量,但它还必须允许分配给 ALE 接收/接受层的数据包。 此类标注还必须检查或修改来自 ALE 层的数据包。 WFP 在向传输层指示需要 ALE 检查的数据包时,设置 FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED 元数据标志。 IPsec 处理将延迟到创建初始“连接”的数据包和重新授权连接所需的数据包到达 ALE 层。
传输层和 ALE 层标注必须在权重低于通用子图层的子层上注册自身。 内置的 IPsec/ALE 强制标注驻留在通用子层上。
下表显示了可在 ALE 层指示的数据包类型。 请注意,某些 ALE 层并不总是具有与其指示关联的数据包。
ALE 层 | TCP 数据包 | UDP 数据包 |
---|---|---|
绑定 (资源分配) |
不适用 |
不适用 |
连接 |
无数据包 |
第一个 UDP 数据包 (传出) |
接收/接受 |
SYN (传入) |
第一个 UDP 数据包 (传入) |
已建立流 |
最终 ACK (传入&传出) |
第一个 UDP 数据包 (传入&传出) |