本主题介绍 Hyper-V 可扩展交换机转发扩展如何指定数据包传递到一个或多个目标端口。 这些扩展还可以将数据包转发到绑定到可扩展交换机外部网络适配器的单个物理网络适配器。
注意 只有转发扩展或交换机本身才能将数据包转发到可扩展交换机端口或单个网络适配器。
下图显示了通过适用于 NDIS 6.40 (Windows Server 2012 R2) 及更高版本的可扩展交换机驱动程序堆栈的数据包流量的数据路径。 这两个图还显示了与可扩展交换机端口连接的网络适配器的数据包流量的数据路径。
              
               
              
              
            
下图显示了通过适用于 NDIS 6.30 (Windows Server 2012) 的可扩展交换机驱动程序堆栈的数据包流量的数据路径。
              
               
              
              
            
每个可扩展交换机目标端口由 NDIS_SWITCH_FORWARDING_DESTINATION_ARRAY 结构中的 NDIS_SWITCH_PORT_DESTINATION 元素指定。 此数组包含在数据包NET_BUFFER_LIST结构的带外 (OOB ) 转发上下文中。 有关此上下文的详细信息,请参阅 Hyper-V 可扩展交换机转发上下文。
如果在可扩展交换机驱动程序堆栈中绑定并启用了转发扩展,则它负责确定从可扩展交换机入口数据路径获取的每个数据包的目标端口,除非数据包是 NVGRE 数据包。 有关此数据路径的详细信息,请参阅 Hyper-V 可扩展交换机数据路径概述。 有关 NVGRE 数据包的详细信息,请参阅 混合转发。
注意 如果未在驱动程序堆栈中绑定或启用转发扩展,则可扩展交换机将确定它从入口数据路径获取的数据包的目标端口。
转发扩展在确定在入口数据路径上获取的数据包的目标端口时,必须遵循以下准则:
- 扩展必须使用目标端口信息初始化 NDIS_SWITCH_FORWARDING_DESTINATION_ARRAY 结构中的NDIS_SWITCH_PORT_DESTINATION结构。 - 如果目标端口未连接到外部网络适配器,则扩展必须将 NDIS_SWITCH_PORT_DESTINATION 结构的 NicIndex 成员设置为NDIS_SWITCH_DEFAULT_NIC_INDEX。 - 如果目标端口连接到可扩展交换机外部网络适配器,则扩展可以指定要将发送请求转发到的基础物理网络适配器的索引。 扩展通过将 NicIndex 成员设置为绑定到外部网络适配器的目标网络适配器的非零NDIS_SWITCH_NIC_INDEX值来执行此操作。 - 有关详细信息,请参阅 将数据包转发到物理网络适配器。 
- 扩展必须将目标端口添加到数据包的 OOB 数据,仅适用于具有活动网络适配器连接的端口。 如果扩展转发了 OID_SWITCH_NIC_DISCONNECT 请求,则不得添加与断开连接的网络适配器关联的目标端口。 
- 若要提高性能,扩展必须仅添加对数据包传送有效的端口目标。 在这种情况下,扩展必须将目标端口NDIS_SWITCH_PORT_DESTINATION结构的 IsExcluded 成员设置为 FALSE。 
- 若要在数据包传送到端口之前保留 802.1Q 虚拟局域网 (VLAN) 数据,扩展会将 PreserveVLAN 成员设置为 TRUE。 - 若要在数据包传送到端口之前删除 802.1Q 虚拟局域网 (VLAN) 数据,扩展会将 PreserveVLAN 成员设置为 FALSE。 
- 若要在数据包传递到端口之前保留 802.1Q 优先级数据,扩展会将 PreservePriority 成员设置为 TRUE。 - 若要在数据包传递到端口之前删除数据包中的 802.1Q 优先级数据,扩展会将 PreservePriority 成员设置为 FALSE。 
- 如果转发扩展为数据包添加多个目标端口,则必须执行以下步骤: - 该扩展首先使用 NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL 宏访问数据包 的NDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO 结构。 然后,该扩展读取 NumAvailableDestinations 成员,以确定目标端口数组中有多少个未使用的目标端口元素可用。 如果扩展需要的目标端口数超过数组中可用的端口数,则必须调用 GrowNetBufferListDestinations 函数,为数组中的其他目标端口分配空间。 - 当扩展调用 GrowNetBufferListDestinations 时,它将 NumberOfNewDestinations 参数设置为要添加到数据包的新目标端口数。 - 扩展还会将 NetBufferLists 参数设置为指向数据包 NET_BUFFER_LIST 结构的指针。 - 注意 如果数组中有可用的目标端口,则扩展不应调用 GrowNetBufferListDestinations。 
- 如果 GrowNetBufferListDestinations 函数成功返回,则它已将其他目标端口添加到 NDIS_SWITCH_FORWARDING_DESTINATION_ARRAY 结构中目标数组的末尾。 指向此结构的指针在 Destinations 参数中返回。 - 注意 如果 GrowNetBufferListDestinations 函数无法分配请求的目标端口数,则返回NDIS_STATUS_RESOURCES。 
- 扩展在 NDIS_SWITCH_FORWARDING_DESTINATION_ARRAY 结构中指定新的目标端口元素。 该扩展将每个新目标端口初始化为 NDIS_SWITCH_PORT_DESTINATION 结构。 - 该扩展从 NumDestinations 偏移量开始初始化数组的新目标端口。 NumDestinations 是 NDIS_SWITCH_FORWARDING_DESTINATION_ARRAY 结构的成员。 
- 扩展完成添加或修改目标端口元素后,必须调用 UpdateNetBufferListDestinations 来提交这些更改。 
 
- 如果扩展为数据包添加单个目标端口,则必须执行以下步骤: - 扩展在扩展分配的 NDIS_SWITCH_PORT_DESTINATION 结构中初始化数据包的目标端口信息。 
- 扩展调用 AddNetBufferListDestination 以提交对数据包 NET_BUFFER_LIST 结构的更改。 扩展在 Destination 参数中传递 NDIS_SWITCH_PORT_DESTINATION 结构的地址。 - 注意 扩展不应调用 UpdateNetBufferListDestinations 函数将更改提交到只有一个目标端口的数据包。 
 
- 当转发扩展调用 AddNetBufferListDestination 或 UpdateNetBufferListDestinations 来提交目标端口的更改时,可扩展交换机接口不会删除 在 NDIS_SWITCH_FORWARDING_DESTINATION_ARRAY 结构的元素中指定的可扩展交换机端口。 数据包发送或接收操作完成后,接口可以根据需要删除端口。 - 注意转发扩展将目标端口的更改提交到转发上下文后,无法删除目标端口,并且只能更改目标端口NDIS_SWITCH_PORT_DESTINATION结构的 IsExcluded 成员。 有关详细信息,请参阅 排除到可扩展交换机目标端口的数据包传送。 
- 转发扩展必须将其对象标识符的处理 (OID) OID_SWITCH_NIC_DISCONNECT 集请求与其为断开连接的网络适配器添加目标端口的代码同步。 - 如果为OID_SWITCH_NIC_DISCONNECT请求调用转发扩展的 FilterOidRequest,该扩展可以执行以下操作之一: - 如果名为 NdisFOidRequest 的扩展转发此 OID 请求,则它不得将具有断开连接的网络适配器的端口指定为数据包的目标端口。 - 注意 如果数据包的唯一目标端口是已断开连接的网络适配器,则扩展必须删除数据包。 
- 扩展可以返回NDIS_STATUS_PENDING异步完成请求。 这允许扩展添加具有断开连接的网络适配器的端口,作为数据包的目标端口。 这也允许扩展调用 AddNetBufferListDestination 或 UpdateNetBufferListDestinations ,并完成向数据包添加目标端口。 - 扩展可能希望对在拆毁之前必须转发到端口的数据包执行此操作。 - 注意 如果扩展返回NDIS_STATUS_PENDING,则还可以调用 ReferenceSwitchPort 来递增具有断开连接的网络适配器的端口的引用计数器。 但是,扩展在调用 DereferenceSwitchPort 以递减端口的引用计数器之前,无法转发 OID 请求。 
 
- 如果目标端口数为零,则转发扩展必须调用 NdisMSendNetBufferListsComplete 来删除数据包。 扩展还必须调用 ReportFilteredNetBufferLists ,以通知可扩展交换机接口丢弃的数据包。 - 注意 如果转发扩展从入口数据路径中为多个数据包获取了 NET_BUFFER_LIST 结构的链接列表,则应创建单独的已删除数据包列表。 通过执行此操作,扩展只需调用一次 NdisMSendNetBufferListsComplete 和 ReportFilteredNetBufferLists 。 
- 如果目标端口数大于零,则转发扩展必须调用 NdisFSendNetBufferLists ,以将数据包通过入口数据路径转发到可扩展交换机的微型端口边缘。 - 注意 如果转发扩展从入口数据路径中为多个数据包获取 NET_BUFFER_LIST结构的链接 列表,则应创建一个单独的转发数据包列表。 通过执行此操作,扩展只需调用一次 NdisFSendNetBufferLists 即可转发数据包列表。 此外,扩展应维护单独的列表,以转发具有相同目标端口的数据包。 有关详细信息,请参阅 Hyper-V 可扩展交换机发送和接收标志。