创建虚拟端口

(VPort) 的虚拟端口是一个数据对象,表示网络适配器的 NIC 交换机上的内部端口,该端口支持单根 I/O 虚拟化 (SR-IOV) 。 每个 NIC 交换机都有以下用于网络连接的端口:

  • 一个外部物理端口,用于连接到外部物理网络。

  • 连接到 PCI Express (PCIe) 物理功能 (PF) 或虚拟函数 (VF) 的一个或多个内部 VPort。

    PF 附加到 Hyper-V 父分区,并在该分区中运行的管理操作系统中作为虚拟网络适配器公开。

    VF 附加到 Hyper-V 子分区,并在该分区中运行的来宾操作系统中作为虚拟网络适配器公开。

有两种类型的 VPort:

默认 VPort
默认 VPort 提供与管理操作系统中运行的网络组件的网络连接。 默认 VPort 的标识符为 NDIS_DEFAULT_VPORT_ID。

当 PF 微型端口驱动程序创建并配置默认 NIC 开关时,驱动程序将隐式创建默认 VPort 并将其附加到 PF。 默认 VPort 无法附加到 VF。

默认 VPort 始终处于激活状态,无法显式删除。 PF 微型端口驱动程序仅在删除默认 NIC 开关时隐式删除默认 VPort。

有关如何在交换机上创建 NIC 交换机和默认 VPort 的详细信息,请参阅 创建 NIC 交换机

非默认 VPort
创建 NIC 开关时,不会隐式创建非默认 VPort。 过度分配的驱动程序(如虚拟化堆栈)通过发出 OID_NIC_SWITCH_CREATE_VPORT的 OID 方法请求显式创建这些端口。 非默认 VPort 可以附加到 PF 或 VF,并且只能在创建 NIC 开关后创建。

附加到 VF 的非默认 VPort 提供与来宾操作系统中运行的网络组件的网络连接。 创建 VF 并将其附加到 VF 后,非默认 VPort 处于激活状态。

附加到 PF 的非默认 VPort 为管理操作系统中运行的网络组件提供额外的网络卸载功能。 例如,PF 上的非默认 VPort 可用于提供类似于虚拟机队列 (VMQ) 接口的卸载功能。

注意 只有在创建 NIC 开关后才能创建非默认 VPort。

覆盖驱动程序发出对象标识符 (OID) OID_NIC_SWITCH_CREATE_VPORT 的方法请求,以在指定的 NIC 交换机上创建非默认 VPort。 此 OID 请求还会将创建的 VPort 附加到网络适配器的 PF 或以前分配的 VF。

NDIS_OID_REQUEST 结构的 InformationBuffer 成员包含指向NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构的指针。 从OID_NIC_SWITCH_CREATE_VPORT请求成功返回后,NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构的 VPortId 成员具有在 NIC 交换机上的 VPort 中唯一的 VPort 标识符。

overlying 驱动程序使用有关要创建的非默认 VPort 的配置信息初始化 NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构。 配置信息包括非默认 VPort 附加到的 PCIe 函数和非默认 VPort 的队列对数。

初始化 NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构时,过度覆盖的驱动程序必须执行以下操作:

  • SwitchId 成员必须设置为之前在网络适配器上通过 OID 方法请求OID_NIC_SWITCH_CREATE_SWITCH创建的 NIC 交换机的标识符。

    注意从 Windows Server 2012 开始,SR-IOV 接口仅支持网络适配器上的一个 NIC 交换机。 此开关称为 默认 NIC 开关。 创建非默认 VPort 时,上置驱动程序必须将 SwitchId 成员设置为NDIS_DEFAULT_SWITCH_ID标识符。

  • VPortId 成员必须设置为 NDIS_DEFAULT_VPORT_ID。

  • AttachedFunctionId 成员必须设置为要附加非默认 VPort 的 VF 或 PF 的标识符。

    值 NDIS_PF_FUNCTION_ID 指定 PF。 否则,必须将该值设置为 VF 的标识符,该 VF 的资源以前是通过 OID_NIC_SWITCH_ALLOCATE_VF 的 OID 方法请求分配的。

    注意 创建非默认 VPort 后,无法更改非默认 VPort 到 VF 或 PF 的附件。

覆盖驱动程序还可以指定分配给 VPort 的队列对数。 队列对是分配给 VPort 的网络适配器上的传输和接收队列。 如果网络适配器支持非默认 VPort 的非对称队列对,则超载驱动程序可能会为驱动程序创建的每个 VPort 指定不同数量的队列对。 有关详细信息,请参阅 队列对的对称和非对称分配

覆盖驱动程序调用 NdisOidRequest 以向基础 PF 微型端口驱动程序发出 OID_NIC_SWITCH_CREATE_VPORT 请求。 在 NDIS 将 OID 方法请求转发到微型端口驱动程序之前,它会执行以下操作:

  1. NDIS 验证 NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构中的参数。 如果参数出错,NDIS 将失败 OID 方法请求,并且不会将请求传递给 PF 微型端口驱动程序。

  2. NDIS 为从 1 到 (NumVPorts – 1) 范围内的非默认 VPort 分配标识符,其中 NumVPorts 是微型端口驱动程序在网络适配器上配置的 VPort 数。 驱动程序在 NDIS_NIC_SWITCH_INFO 结构的 NumVPorts 成员中指定此数字。 驱动程序通过 OID_NIC_SWITCH_ENUM_SWITCHES 的 OID 查询请求返回此结构。

    注意 NDIS_DEFAULT_VPORT_ID的 VPort 标识符是为默认 NIC 交换机上附加到 PF 的默认 VPort 保留的。

分配的 VPort 标识符唯一标识网络适配器的 NIC 交换机上的非默认 VPort。

  1. NDIS 使用分配的 VPort 标识符设置 NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构的 VPortId 成员。

向 PF 微型端口驱动程序发出 OID 请求时,驱动程序将分配与指定的非默认 VPort 关联的硬件和软件资源。 成功分配所有资源后,PF 微型端口驱动程序将通过从 MiniportOidRequest 返回NDIS_STATUS_SUCCESS成功完成 OID。

如果 OID_NIC_SWITCH_CREATE_VPORT 请求成功完成,则 PF 微型端口驱动程序和 overlying 驱动程序必须保留非默认 VPort 的 VPortId 值,以便连续操作。 VPortId 值在以下操作期间使用:

以下几点适用于创建非默认 VPort:

  • 在 VPort 上配置媒体访问控制 (MAC) 和虚拟 LAN (VLAN) 标识符的接收筛选器。 过分驱动程序通过发出 OID_RECEIVE_FILTER_SET_FILTER的 OID 方法请求来动态设置这些接收筛选器。 接收筛选器还可以通过 OID_RECEIVE_FILTER_MOVE_FILTER的 OID 集请求从一个 VPort 移动到另一个 VPort。

  • 附加到 VF 的非默认 VPort 在创建时处于激活状态。 如果 VPort 附加到 VF,则无法将其停用。

    附加到 PF 的非默认 VPort 在创建时处于停用状态。 在成功创建 VPort 后,Hyper-V 可扩展交换机模块等过度驱动程序显式激活附加到 PF 的非默认 VPort。 这是通过向 PF 微型端口驱动程序发出 OID_NIC_SWITCH_VPORT_PARAMETERS 的 OID 方法请求来完成的。

    当 overlying 驱动程序发出此 OID 请求时,它会传递 VPortState 成员设置为 NdisNicSwitchVPortStateActivated的 NDIS_NIC_SWITCH_VPORT_PARAMETERS 结构。

    非默认 VPort 处于激活状态后,PF 微型端口驱动程序可以通过调用 NdisAllocateSharedMemory 为 VPort 分配共享内存。 驱动程序必须将 NDIS_SHARED_MEMORY_PARAMETERS 结构中的 VPortId 成员设置为 VPort 的标识符值。

注意 当非默认 VPort 处于激活状态时,仅当通过 OID_NIC_SWITCH_DELETE_VPORT的 OID 集请求将其删除时,它才会设置为停用状态。