For the complete documentation index, see llms.txt. This page is also available as Markdown.

VPP 移植到了 FreeBSD:基础用法

Vector Packet Process (VPP) 是高性能框架,用于在用户空间处理数据包。得益于 FreeBSD 基金会和 RGNets 的项目,我获得资助将 VPP 移植到 FreeBSD,非常高兴与《FreeBSD 期刊》的读者分享一些基本用法。

VPP 使得转发和路由应用程序可以在用户空间编写,并提供 API 可控的接口。通过 DPDK(在 Linux 上)和 DPDK 及 netmap(在 FreeBSD 上),VPP 实现了高性能的网络处理。这些 API 允许直接零拷贝访问数据,并可用于创建可以显著超过主机转发性能的转发应用程序。

VPP 是完整的网络路由器替代方案,因此需要一些主机配置才能使用。本文展示了如何在 FreeBSD 上使用 VPP 的完整示例,大多数用户应该能够通过自己的虚拟机来跟随这些步骤。VPP 在 FreeBSD 上也可以运行在真实硬件上。

本文将介绍如何在 FreeBSD 上使用 VPP,并给出设置示例,展示如何在 FreeBSD 上完成各种任务。VPP 的资源可能较难找到,项目在 https://fd.io 的文档质量很高。

构建一个路由器

FreeBSD 上 VPP 基本用法示意图

VPP 可以用于许多用途,其中最常见且最容易配置的是作为某种形式的路由器或桥接器。以将 VPP 用作路由器为例,我们需要构建包含三个节点的小型网络——客户端、服务器和路由器。

为了展示如何在 FreeBSD 上使用 VPP,我将构建最小开销的示例网络。你只需要 VPP 和 FreeBSD 系统。我还将安装 iperf3,以便我们能够生成并观察通过我们的路由器传输的一些流量。

在具有最新 Ports 的 FreeBSD 系统中,可以使用 pkg 命令安装我们所需的两个工具,如下所示:

要为我们的网络创建三个节点,我们将利用 FreeBSD 最强大的功能之一——VNET jail。VNET jail 为我们提供了完全隔离的网络堆栈实例,它们的操作方式类似于 Linux 的网络命名空间(Network Namespaces)。要创建 VNET,我们需要在创建 jail 时添加选项 vnet,并传递它将使用的接口。

最后,我们将使用 epair 接口连接我们的节点。epair 接口提供了以太网电缆两端的功能——如果你熟悉 Linux 上的 veth 接口,它们提供类似功能。

我们可以通过以下 5 个命令构建我们的测试网络:

在这些 jail 命令中需要注意的标志是 persist,如果没有这个选项,jail 将会因为没有运行进程而自动删除;vnet 使这个 jail 成为 VNET jail;和 vnet.interface=,它将指定的接口分配给 jail。

当接口被移到新的 VNET 时,它的所有配置都会被清除——这是需要注意的,因为如果你配置了接口然后将其移到 jail,可能会困惑于为什么无法工作。

设置对等端

在转到 VPP 之前,我们先设置网络的客户端和服务器端。每一方都需要分配 IP 地址,并将接口设置为启用状态。我们还需要为客户端和服务器 jail 配置默认路由。

我们的客户端和服务器 jail 现在有了 IP 地址,并且配置了通向 VPP 路由器的路由。

Netmap 要求

在我们的示例中,我们将使用 VPP 与 Netmap,Netmap 是高性能的用户空间网络框架,作为 FreeBSD 的默认组件提供。使用 Netmap 之前,接口需要一些配置——接口需要处于启用状态,并且需要配置选项 promisc

现在我们可以开始使用 VPP 了!

VPP 的基本命令

VPP 非常灵活,支持通过配置文件、命令行接口和具备成熟 Python 绑定的 API 来配置。VPP 需要基础配置,告诉它从哪里获取命令,和它使用的控制文件的名称(如果这些文件不是默认的)。我们可以在命令行中将最小配置文件作为 VPP 的参数。对于这个示例,我们让 VPP 进入交互模式——提供给我们 CLI,并告诉 VPP 只加载我们将使用的插件(netmap),这是合理的默认设置。

如果我们不禁用所有插件,我们将需要配置机器使用 DPDK,或者单独禁用该插件。禁用插件的语法与启用 netmap 插件的语法相同。

如果一切设置正确,你将看到 VPP 的横幅和默认的 CLI 提示符(vpp#)。

VPP 命令行界面提供了很多选项,用于创建和管理接口、像桥接一样的组、添加路由和用于检查 VPP 实例性能的工具。

接口配置命令的语法类似于 Linux 的 iproute2 命令——对于来自 FreeBSD 的用户来说,这些命令可能稍显陌生,但一旦开始使用,它们还是相当清晰的。

我们的 VPP 服务器还没有配置任何主机接口,show int 只列出了默认的 local0 接口。

要在 VPP 中使用我们的 netmap 接口,我们需要先创建它们,然后再配置。

创建命令允许我们创建新的接口,我们使用 netmap 子命令和主机接口。

每个 netmap 接口都以 netmap- 为前缀创建。接口创建完成后,我们可以配置它们以供使用,并开始将 VPP 用作路由器。

命令 show int addrshow interface address 的简写)确认了我们的 IP 地址分配成功。然后,我们可以将接口启用:

配置好接口后,我们可以使用 ping 命令测试 VPP 的功能:

如果我们跳到客户端 jail,我们可以验证 VPP 正在充当路由器:

作为初始设置的最后一步,我们将在服务器 jail 中启动 iperf3 服务器,并使用客户端做 TCP 吞吐量测试。

VPP 分析

现在通过 VPP 发送了一些流量后,show int 命令的输出包含了更多信息:

接口命令现在给出了通过 VPP 接口传输的字节和数据包的摘要。这在调试流量如何流动时非常有用,尤其是当数据包丢失时。

VPP 中的 V 代表向量(vector),这在项目中有两层含义。VPP 旨在使用向量化指令加速数据包处理,同时它还将一组数据包打包成向量,以优化处理。其理论是将一组数据包一起通过处理图,从而减少缓存争用并提供最佳性能。

VPP 提供了许多工具来查询数据包处理过程中的情况。深度调优超出了本文的讨论范围,但了解 VPP 内部发生情况的初步工具是运行时命令。

运行时数据会在每个向量通过 VPP 处理图时收集,记录每个节点的遍历时间和处理的向量数量。

要使用运行时工具,最好有一些流量。可以像这样启动长时间运行的 iperf3 吞吐量测试:

现在在 VPP jail 中,我们可以清除迄今为止收集到的运行时统计信息,稍等片刻,然后查看我们的运行情况:

show runtime 输出中的列为我们提供了关于 VPP 内部运行的很好的了解。它们告诉我们自从运行时计数器被清除以来,哪些节点被激活,它们的当前状态,每个节点被调用的次数,所使用的时间,和每次调用处理的向量数量。默认情况下,VPP 的最大向量大小是 255。

最终的调试任务是使用 show vlib graph 命令检查整个数据包处理图。此命令显示每个节点和可能导向它的潜在父节点、子节点。

下一步

VPP 是一款令人印象深刻的软件——解决了兼容性问题后,VPP 的核心部分就相对容易移植。即使仅做最小调优,VPP 在 FreeBSD 上与 netmap 配合使用时也能够达到相当出色的性能,而如果配置了 DPDK,它的表现会更好。VPP 的文档正在逐步增加关于在 FreeBSD 上运行的信息,但开发者确实需要更多 FreeBSD 上 VPP 的使用案例。

从这个简单网络的例子开始,将其移植到拥有更快接口的大型网络上应该是相对简单的。


Tom Jones 是 FreeBSD 提交者,致力于保持网络堆栈的高效运行。

VPP 文章配图

最后更新于