摘要

  • Jamal Hadi Salim 在 2026 年被公开认定为 Linux Traffic Control 的维护者,但tc仍然是一个由数十年积累的贡献者和用户共同塑造的集体系统。
  • 他的工作连接了 Netlink、IETF 的 ForCES 标准和 P4TC——这三种不同的尝试,旨在通过持久、可编程的接口暴露转发行为。
  • P4TC 的生产测试是操作性的,而非语言层面的:配置、权限、计数器、回滚和重放必须跨内核、控制器、驱动程序和硬件正常工作。
  • 通用的tc语法仍然可能掩盖不同的软件、回退和卸载行为,这使得能力发现和故障报告成为项目的决定性风险。

旧的tc接口如今承载着现代策略

2026 年,P4 社区资料将 Jamal Hadi Salim 标识为 Linux Traffic Control 的维护者和 P4TC 的负责人。这些头衔将他置于一个大多数用户看不到的边界。一条简短的tc命令可以设定带宽上限、挂载分类器、重定向流量、统计流数量,或者让网络接口卸载一条规则。这命令看起来很老旧;但其背后的契约仍在不断扩展。

流量控制最初只涉及队列和调度。如今,它已经成为一个由队列规范、类、过滤器和动作组成的通用分组控制平面。云主机和网络设备可以使用它来塑造出口流量、检查入口流量、镜像流量或强制执行策略。Netlink 在用户空间和内核之间传递指令,而驱动程序则决定是否可以将某些工作卸载到硬件上执行。

Salim 的职业生涯贯穿了这每一层。公开记录将他与 Mojatatu Networks、Netdev 社区、关于 Netlink 的 RFC 3549、IETF 的转发与控制单元分离(ForCES)工作,以及当前的 P4TC 工作关联起来。这段历史使他不仅仅是一个维护者传记中的主角。它提供了一种方式来审视一个困难的基础设施问题:Linux 如何能够接纳一个更可编程的分组处理流水线,同时又不破坏已经围绕tc构建的脚本、驱动程序和网络设备?

添加解析器或编译一个 P4 程序并不能回答这个问题。Linux 网络是内核代码、用户空间工具、硬件驱动程序、应用程序和运维人员之间的一份契约。一个新的 Netlink 属性可能会成为一个持久的用户空间应用程序二进制接口(ABI)。一条在软件中行为正确的规则,在网络接口卡(NIC)上可能只能被部分卸载。一个成功加载的流水线,在实时流量中可能仍然不安全地修改,或者在重启后无法重放。

Salim 职业生涯的大部分时间都花在了这个契约边界上。早期的tc工作帮助建立了可重用的分组动作和调度结构。Netlink 提供了一个结构化的控制通道。ForCES 试图标准化分离的控制单元和转发单元之间的关系。P4TC 现在试图将 P4 描述的流水线表示为 Linux Traffic Control 内部的一部分,而不是通过一个独立的软件交换机或供应商专用的软件开发工具包(SDK)。

这些项目属于不同的技术时代,没有一个只是另一个的早期版本。ForCES 并不是换个名字的 P4TC。Netlink 并不是一个通用的设备控制协议。流量控制不是一个单一的算法。它们之间的连续性在于每一项工作所需的纪律:定义一个可编程模型,通过一个其他软件可以依赖的接口来暴露它,并在最初的实现团队离开后仍然保持该接口的可支持性。

最后一个条件将基础设施与演示区分开来。一个研究原型可以改变其模式并重新构建。一个被路由器、云和网络设备使用的 Linux 接口不能随意修改。P4TC 的重要性将较少取决于一个演示是否能处理数据包,而更多取决于编译器、控制器、驱动程序和维护者是否能够就一个运维人员可以检查、升级和回滚的契约达成一致。

队列调度演变为通用分组控制框架

Linux 的分组处理路径上有几处可以应用策略的地方。在出口,数据包在传输前在队列中等待。在入口,数据包在进入更后的网络层之前可以被分类。流量控制通过具有不同职责的对象来组织这些功能。

队列规范(qdisc)决定了数据包如何排队和调度。有些 qdisc 很简单;其他一些则创建了具有各自速率和优先级的类。过滤器根据头部、元数据或其他键来匹配流量。动作在匹配后执行相应的操作。这种架构允许组装策略,而不是作为一个整体功能嵌入。

这种组合性创造了长期价值。运维人员可以替换一个调度器,而无需重写所有分类器。一个新的动作可以被多个过滤器重复使用。驱动程序开发者可以将特定的匹配和动作卸载到硬件上。研究系统可以在一个共同的框架内测试新的队列和分类思路。其代价是复杂性。一个数据包可能经过多个钩子和对象,每一个都有其自己的计数器、顺序和回退路径。

Salim 有文档记录的贡献包括帮助tc超越调度范畴的动作架构。像重定向和镜像这样的动作现在已是主机网络中普通的构建模块。它们允许将流量发送到另一个接口,复制以供观察,或使其经过一系列操作。在云和网络设备环境中,这些原语可以参与服务链和策略执行。

可组合性并不保证可理解性。调试失败策略的运维人员需要知道是哪个分类器匹配了,动作是在软件还是硬件中执行的,哪个计数器对应实际路径,以及驱动程序是否静默地拒绝了部分请求。如果一条规则被接受但未完全卸载,性能可能会改变,而语义看似完好。如果一个不支持的组合被拒绝,自动化必须正确解释这个错误。

该框架的年龄增加了另一个约束。现有的 qdisc 和分类器有使用者,其配置可能永远不会出现在公共存储库中。网络设备可能搭载旧的脚本。发行版会向后移植功能。运维人员依赖输出格式和错误行为。因此,内核开发者将用户空间兼容性视为基础设施,而不是在重新设计时可以清理掉的不便。

Salim 的维护者角色在这里很重要。维护者并不拥有每一行代码,也不能单独决定什么进入 Linux。变更通过公共邮件列表、子系统审查和更高层级的网络树进行。然而,维护者携带着所需的隐性历史知识,以识别何时一个新的抽象重复了一个旧的抽象,打破了一个已确立的契约,或者创建了一个无法安全支持的接口。

流量控制之所以仍然与当前的可编程性工作相关,是因为它已经提供了周围的操作机制。它已经有钩子、对象生命周期、权限、统计信息、Netlink 编码和硬件卸载路径。在此基础上构建 P4 功能,可以重用已经安装的控制平面。但它也继承了数十年积累下来的所有模糊性和兼容性义务。

Netlink 将实现细节变成了对用户空间的承诺

Netlink 是一种结构化的消息机制,许多 Linux 网络工具通过它与内核通信。iptc实用程序使用它来创建和检查对象。控制器和管理系统可以直接构建相同的消息。Salim 参与编写的 RFC 3549(出版于 2003 年)在 IP 服务的语境中记录了 Netlink,并帮助使该接口在内核源代码之外变得可读。

其核心思想很简单。用户空间发送包含命令和类型属性的消息。内核验证它们,改变状态,并返回确认或数据。该格式是可扩展的:可以添加新的属性而无需替换整个协议。这种灵活性帮助 Linux 网络从基本的路由和地址发展成了一大批对象。

然而,可扩展性带来了治理工作。属性标识符不能随意重用。嵌套结构需要一致的规则。错误消息必须告诉应用程序哪个字段失败了。转储操作必须在状态改变时行为可预测。控制器需要知道旧内核是忽略、拒绝还是部分理解了一个新的属性。

内部数据结构可以通过重新编译内核来改变。一旦工具和自动化依赖于某个 Netlink 属性,它就成为了一个长久的用户空间承诺。这就是该接口隐藏的宪法角色。它不仅决定了一个功能今天如何配置,还决定了未来的软件如何发现能力并与旧部署共存。

P4TC 加剧了这个问题,因为一个可编程流水线包含许多对象类型:解析器、表、动作、外部、元数据和运行时条目。将它们编码为 Netlink 资源需要的不仅仅是分配编号。设计必须表达层次结构、标识、引用、权限和版本。它必须区分流水线模型的创建和已实例化流水线内表条目的修改。

Salim 在 2026 年 P4 开发者日的演讲描述了一个通过 Netlink 传递的、面向资源的运行时模型,该模型带有编译器生成的信息和注释,可帮助应用程序发现对象路径。使用来自 REST 的概念并不将接口变成 HTTP,也不会使其等同于 P4Runtime。这项工作是一个由内核 API 塑造的 Linux 特定控制模型。

其风险在于,开发过程中的便利性会变成运维人员的永久复杂性。编译器生成的一个路径名或 JSON 描述可能对一个控制器来说很容易消费。但它仍然需要在编译器版本和内核之间具有稳定的语义。如果一个对象移动或一个注释改变,系统需要一个迁移故事。如果内核拒绝一个条目,控制器必须知道这个失败反映了语法错误、权限问题、不支持的硬件还是资源不足。

因此,Netlink 锚定了 Salim 工作中的主要张力。它通过一个共同的通道使网络变得可编程,但每一个成功的使用都将设计选择变成义务。只有当这些义务被视为功能的一部分,而不是在分组路径工作之后才需要完善的文档时,P4TC 才能成为可信赖的基础设施。

ForCES 表明,一个完整的标准仍然需要一个部署联盟

在当前的 P4 生态系统之前,IETF 的转发与控制单元分离(ForCES)工作怀有类似的目标:允许控制单元通过一个标准的模型和协议来配置和查询转发单元。Salim 担任了该工作组的主席,并共同撰写了 RFC 家族的核心部分。

ForCES 模型将转发行为表示为逻辑功能块。转发单元可以暴露能力和状态,而控制单元使用一种协议来配置流水线。RFC 5810 定义了该协议。RFC 5812 提供了一个广泛的转发单元模型。其他文档涵盖了传输映射、互操作性、可编程性扩展以及转发单元之间的通信。

从任何标准来看,这项工作的规模都很大。它产生了详细的规范、多个实现和一份互操作性报告。但它也没有成为可编程网络的主流架构。这个结果在分析上是有用的,因为它表明标准不能保证什么。

一个协议可以很严谨,但仍然缺乏足够大的部署联盟。设备供应商可能更偏好他们现有的控制系统。运维人员可能看不到具有引人经济利益的迁移风险。竞争架构可能吸引更多的软件、硬件和开发者注意。标准可能覆盖一个广泛的问题,而市场采用的则是更容易集成的窄解决方案。

ForCES 也出现在一个软件定义网络以多种方式被定义的时代。OpenFlow 后来将注意力集中在交换机表的匹配-动作控制上。网络功能虚拟化将功能移入软件。P4 专注于为可编程目标描述分组处理行为。这些方法与 ForCES 在控制与转发的广泛分离上有重叠,但它们的模型、社区和实现路径不同。

将 P4TC 描述为 ForCES 的完成将是误导。在模型驱动的转发方面可能存在着知识上的连续性,并且 Salim 的经验跨越了两者。然而,P4TC 在 Linux Traffic Control 内部工作,使用 P4 描述,并依赖内核审查和 Netlink。ForCES 定义了不同的控制单元和转发单元之间的协议。技术对象和采用环境并不相同。

战略上的教训更为普遍。互操作性测试证明实现可以在定义的条件下通信。它们并不能证明供应商将广泛交付该功能,运维人员将培训员工,或者支持生态系统将持续存在。只有当组织围绕一个标准调整采购、维护和迁移时,它才能成为基础设施。

Salim 当前的 P4TC 工作似乎借鉴了那段历史。它试图将可编程性附加到一个运维人员已经在使用的平台上,而不是要求一个完全独立的转发架构。这可以降低采用障碍。但它也可能限制设计,因为 Linux 必须保留现有行为。已安装的基础既是优势也是负担。

P4TC 将 P4 带入 Linux 内部,而非围绕它

P4 是一种描述可编程网络目标如何解析数据包、应用表和动作、维护状态并生成结果的语言。它通常与交换机 ASIC 和软件交换机相关联,但语言本身是面向目标的。编译器将程序映射到一个架构和实现上。

P4TC 的主张是,Linux Traffic Control 可以作为这样的一个目标。通过内核对象表示 P4 描述的流水线,并在 Linux 的分组处理路径中执行。这为开发者提供了一种在 P4 中表达分组处理的方式,而无需将流量移入一个单独的用户空间交换机或要求专用的硬件。

这个吸引力是实际的。Linux 已经运行在服务器、网络设备和边缘系统上。它已经拥有安全和生命周期机制、网络命名空间、流量钩子以及一个成熟的运维社区。如果 P4TC 符合上游实践,一个应用程序可以在保持普通内核部署和打包的同时,使用 P4 概念。

短语“在 Linux 中运行 P4”隐藏了几个层次。编译器必须理解 P4 程序,并产生一个内核可以配置的形式。内核必须实例化解析器、表、动作和元数据,同时执行内存和权限限制。运行时控制器必须创建和更新条目。工具必须检查状态和计数器。硬件驱动程序可能会卸载某些功能。测试必须将预期的 P4 行为与实际运行的行为进行比较。

P4TC 将配置与运行时控制分离。配置建立流水线形态:存在的对象种类以及它们之间的关联。运行时操作操纵实例,如表条目。这是一个必要的操作区分。更改表条目可以是例行的。替换流水线模型可能改变数据包的解释,并需要一个协调的过渡。

这种分离也带来了回滚问题。如果新流水线在验证或性能目标上失败,旧的流水线能否保持活跃?更新期间运行时条目会怎样?计数器是否被保留?两个版本能否共存?实验室演示可以重启环境。生产主机可能正在承载成千上万工作负载的流量。

到 2026 年 8 月,公共记录描述了活跃的架构、API、论文和补丁工作。这些记录并不足以证明 P4TC 是一个普遍可用的 Linux 功能。上游状态和能力需要根据内核发布和补丁系列来检查。编译器支持必须匹配内核实现。运维指导应为每项声明标明日期。

这种谨慎并非对项目的批评。活跃的内核工作是变化的。正确的成熟度标签帮助开发者决定他们是在实验,是在构建一个受控的网络设备,还是在依赖一个由发行版支持的功能。夸大可用性将破坏 P4TC 试图实现的兼容性纪律。

加载流水线是一个操作变更,而不是编译步骤

一个可编程流水线常常作为源代码被讨论:编写一个 P4 程序,编译它,然后运行它。生产系统需要一个更详细的生命周期。代码必须经过审批,其资源需求必须被理解,其目标必须被验证,并且其部署必须与控制平面协调。

P4TC 的配置接口旨在描述内核将创建的流水线对象。解析器定义头部如何被识别。表定义匹配键和可能的动作。外部代表特定目标的能力。元数据连接各个阶段。配置的结果是运行时策略在其中操作的架构。

这一步类似于安装一个新的网络功能,而不是更改一个设置。解析器错误可能误解流量。表可能消耗比预期更多的内存。一个动作可能与现有的钩子交互不良。某个外部可能在一个内核或设备上不可用。在流量到达新路径之前,系统需要验证。

版本管理变得至关重要,因为编译器和内核共享对架构的责任。如果编译器发出了一个内核以不同方式解释的结构,程序可能加载但行为不正确。一个可靠的过程会记录编译器版本、内核版本、流水线标识符和能力集。它应该拒绝模糊的组合,而不是依赖于尽力而为。

权限也很重要。加载一个新的分组处理流水线是一个强大的操作。它可以重定向流量、绕过策略或暴露元数据。Linux 命名空间和能力可能会限制谁可以配置对象,但对于容器和多租户主机而言,安全模型必须明确。运行时接口不能仅仅因为它是程序性的,就被视为普通的应用程序 API。

操作可观测性必须在配置时就开始。工程师需要检查哪些对象被创建了,哪些功能不受支持,以及资源如何被分配。一次成功的确认不应暗示性能目标已经达到。一个流水线可以是有效的,但仍然会使 CPU 过载或引入延迟。

分阶段推出的必要性显而易见。新流水线应该在仿真或实验室中测试,在预发布主机上加载,对照预期的数据包踪迹进行比较,并在真实负载下监控。回滚需要经过演练,而不能只是假设。这些实践属于部署架构,而不是外部的操作手册。

Salim 坚持使用 Linux 已建立的控制框架,为项目提供了一个实现这些控制的地方。这也意味着 P4TC 无法回避内核社区对清晰语义和可维护接口的要求。配置是语言特性成为一个持久的运维承诺的地方。

运行时控制必须暴露状态、能力和故障

一旦流水线存在,控制器就需要填充表、读取计数器和更新策略。P4TC 的运行时 API 处理这个阶段。项目演示描述了资源路径、注释和编译器生成的 JSON,这些允许应用程序通过 Netlink 发现和操纵对象。

设计目标是减少控制器与一个特定 P4 程序之间的紧耦合。如果控制器可以检查对象模型,它可以动态地构造操作。这对于管理多个流水线或版本的编排系统具有吸引力。

但仅靠发现并不能创造可移植性。两个 P4 程序可能使用相似的对象名称,但含义不同。编译器可能发出不同的注释。目标可能支持不同的外部和资源限制。错误处理可能取决于执行发生在软件还是硬件中,而有所不同。运行时需要足够强大的惯例,以至于自动化不会将语法相似性与语义等价性混淆。

与 P4Runtime 的关系也需要精确。P4Runtime 是一个用于 P4 编程设备的标准控制平面 API。P4TC 的运行时模型通过 Linux Netlink 传递,反映了内核对象和权限。这两个项目可以共享概念,而不必在每个环境中都是替代品。在两者之间做出选择的操作员,同时也在选择一个目标和生命周期模型。

运行时更新会产生一致性问题。一个控制器可能更改几个应同时生效的表条目。数据包可能在更新之间到达。一个失败的操作可能留下部分状态。如果流水线跨主机复制,版本可能产生分歧。随着策略的增长,事务、生成标识符和清晰的故障语义变得更加重要。

计数器也需要同等程度的审查。控制器可能在流量实际上是卸载时读取软件计数器。硬件可能以不同的方式聚合值,或以不同的节奏更新。回退到软件可能会产生突然的性能变化,同时保留规则的表面状态。可观测性必须识别执行发生的位置。

这些问题在网络自动化中很常见,但 P4TC 将它们集中在一个可编程数据平面中。流水线的表达能力越强,其控制状态与运维意图不一致的方式就越多。减少可编程性并不能解决这个问题。运行时契约必须使状态、能力和故障变得明确。

到 2026 年 8 月,该契约仍然是活跃的工作。进展最好是体现在稳定的对象语义、跨内核和编译器的测试、文档化的回滚以及独立实现上达成一致的行为,而不是对 P4 兼容性的广泛声明。

硬件卸载是通用语法停止保证通用行为的地方

Linux Traffic Control 已经通过驱动程序接口支持硬件卸载。一个过滤器或动作可以被转换为 NIC 或交换机硬件,允许数据包被处理而无需消耗主机 CPU。这对于性能和功耗很重要。但它也暴露了抽象的结构性限制。

硬件具有有限的表、特定的匹配字段、动作组合和排序约束。一个设备可能支持一个重定向后跟修改;另一个可能不支持。一个驱动程序可能卸载规则的一部分,而将剩余部分留在软件中。有些系统拒绝不支持的组合;其他系统使用回退。因此,相同的tc命令可能产生不同的性能,并且在处理不佳的情况下产生不同的行为。

P4TC 并没有消除这种差异。P4 程序是为具有特定架构的目标编译的。一个内核软件目标可以实现 NIC 无法卸载的结构。供应商可能暴露专有的外部。运维人员需要一个能力模型和针对已部署目标的测试,以及源程序。

可移植性的承诺在卸载边界处最容易被夸大。一种通用语言可以使意图更易于表达,工具更易于共享。它不能创造不存在的硬件资源。它不能确保两个设备以相同方式处理计数器、老化、错误或原子更新。可移植性是一个范围,由在目标之间保留的行为子集来衡量。

Salim 的工作处于一个异常困难的结合点,因为tc已经跨越了软件和硬件路径。维护者必须考虑语义契约,而驱动程序作者实现卸载,供应商决定哪些功能获得工程资源。P4TC 为这种关系添加了一种更丰富的语言和架构。

运维人员应该要求明确的执行状态。一条规则应该揭示它是在软件、硬件还是混合路径中。不支持的对象应该清晰地失败。计数器的来源应该可见。性能测试应包括回退和故障,而不仅仅是理想的卸载情况。

硬件生命周期进一步使支持复杂化。一个内核 API 可能保持稳定多年,而一代 NIC 被替换。驱动程序可能被向后移植或由供应商修改。固件更新可能改变行为。开放的接口减少了对一个特定 CLI 的依赖,但它并没有消除对供应商实现和支持窗口的依赖。

一个完全统一的数据平面是不太可能的。P4 描述、Linux 对象和硬件能力将不得不协商出一个可行的子集。这种协商的质量将决定 P4TC 是成为可靠的基础设施,还是主要保持为一个实验平台。

计数器和重放决定了流水线是否可操作

一个分组处理系统仅仅因为接受一个程序并正确地转发一个测试数据包,还不能用于生产。运维人员需要知道什么被安装了,在哪里运行,多少数据包匹配了,为什么一个更新失败了,以及他们读到的状态是否正是数据平面实际使用的状态。这些问题与语言设计相比显得平凡,但它们决定了一个可编程流水线能否在凌晨三点得到支持。

流量控制已经包含了几种形式的操作证据。队列规范暴露数据包、字节、丢弃和超过限制的计数器。过滤器和动作可以报告命中和结果。Netlink 转储允许用户空间重建配置的对象。扩展确认可以携带比简单的失败代码更有用的错误消息。硬件卸载路径可能添加它们自己的统计信息,或表明规则是在软件中而不是在设备中被接受的。这些证据的质量和一致性因对象和驱动程序而异,这正是 P4TC 不能将可观测性视为事后考虑的原因。

P4 流水线引入了一个更丰富的状态模型。一个表条目可能引用一个动作配置文件、一个计数器、一个计量器、一个寄存器或由程序定义的元数据。编译器可能分配标识符并编码类型。一个控制器可能通过运行时 API 安装状态,而另一个进程读取计数器或更改默认动作。如果这些对象只能通过创建它们的控制器来可见,那么通用的 Linux 接口就变得不那么有用了。如果内核在不保留其 P4 含义的情况下暴露它们,运维人员将接收到难以与源程序关联的原始对象。

2026 年的 P4TC 材料试图通过面向资源的路径和编译器生成的描述来弥合这一差距。重点不在于装饰性的命名。控制器需要一种稳定的方式来处理对象并理解其类型。诊断工具需要以工程师能够与 P4 源代码联系起来的方式显示相同的对象。当流水线发生变化时,系统需要一条规则,规定旧条目是否仍然有效、被转换还是必须被拒绝。不匹配应该足够明显地失败,以至于自动化不会将部分状态误认为成功。

当资源是有限的时候,错误报告变得尤其重要。软件表可能接受的条目比 NIC 可以卸载的要多。一个动作在语言中可能有效,但驱动程序不支持。一个计量器可能需要硬件无法表示的粒度。控制器应该能够区分格式错误的输入、缺少的能力、耗尽的资源和瞬态故障。将所有四种情况都视为EINVAL或一个通用的拒绝更新,将把昂贵的解释工作推给每个运维人员的自动化。

计数器也有类似的模糊性。一个数据包计数器可能在硬件、软件回退路径或两者中计数。它可能在规则被替换时重置,在设备特定的宽度处回卷,或者因为轮询而滞后。一个读取值而不了解其执行位置的控制器可能会对流量得出错误的结论。对于计费、安全或容量规划来说,这不是一个小差异。它改变了测量的含义。

这个问题并非 P4TC 独有。Linux 网络长期以来一直在努力为具有不同硬件的设备提供统一的统计信息。但变化的语义表面的规模。一个 P4 程序可以定义在编写驱动程序时不存在的对象。因此,系统需要能力发现和故障语义,这些语义对自动化来说足够精确,但对内核 ABI 来说足够稳定。

重放是另一个实际测试。在主机重启后,驱动程序重置或控制器故障转移后,所需的流水线和条目必须被重建。内核可以在进程重启后保留一些状态,但不能在每次故障中都保留。控制器需要一个权威的期望状态存储,以及一种将其与数据平面进行比较的方法。一次忽略依赖关系或以不稳定顺序返回对象的转储会使恢复变得复杂。一个编译器的标识符在构建之间发生变化的流水线,即使 P4 源代码看起来没有变化,也可能使重放变得不安全。

良好的操作设计会使这些案例变得可测试。自检可以创建一个流水线,填充相关资源,强制一个错误,转储状态,重启一个控制器,并确认计数器和条目的含义保持不变。硬件资质测试可以在卸载开启的情况下重复该序列,并验证哪些步骤保留在设备中。文档可以说明原子性在哪里结束,而不是让用户通过中断来发现。

Salim 在 Netlink 和 tc 方面的长期工作为 P4TC 在这里提供了优势。该项目始于一个已经将内省、转储和错误代码作为 API 一部分的生态系统。它也继承了该生态系统的不一致性。决定性的工程工作不仅仅是添加更多的对象类型。而是使它们的生命周期对那些没有编写编译器或驱动程序的运维人员来说是可读的。

Linux 已经拥有多个数据平面,P4TC 适合其中之一

P4TC 进入了一个已经拥挤的 Linux 景观,这里已经有很多处理分组的方式。eBPF 程序可以在网络栈的多个点上挂载。XDP 在接收路径的早期运行,用于过滤、负载均衡和拒绝服务防御。DPDK 让用户空间应用程序直接控制核心、内存和 NIC 队列。Open vSwitch 提供了一个可编程的虚拟交换机模型。FD.io 的 VPP 将分组功能组织成一个向量处理图。供应商 SDK 可能暴露对特定 ASIC 的最深访问。

这些系统重叠,但不可互换。它们的差异始于它们在哪里运行以及它们准备拥有什么。XDP 在工作应该发生在完整内核栈之前时具有吸引力。eBPF 有一个验证器、映射、助手和一个庞大的附着生态系统。DPDK 在应用程序可以投入资源并为数据平面负责时具有吸引力。Open vSwitch 和 VPP 提供了更广泛的交换或路由框架。流量控制位于已经用于分类、流量控制、整形和与 Linux 设备相关联的动作的入口和出口边界。

这种比较很重要,因为声称 P4TC“将 P4 带给 Linux”可能会被误解为取代这些替代方案的承诺。但架构并不支持这一点。P4TC 为 P4 定义的分组处理提供了一个 tc 表示和 Netlink 控制平面。它不会自动提供 XDP 的最早钩子、DPDK 的用户空间执行模型、VPP 的向量图或交换机 ASIC 的完整流水线。

P4 本身带来了一种不同的优势:一种为描述解析器、匹配-动作表、元数据和逆解析器而设计的语言。这种结构可以使数据平面比一组不相关的钩子程序更容易理解。它可以允许控制器使用命名的表和动作,而不是加载器特定的字节码。对于已经在交换机或 SmartNIC 中使用 P4 的团队来说,一个 Linux 目标可以减少硬件和主机处理之间的概念距离。

其代价是另一个工具链和语义层。eBPF 开发者使用 Clang、libbpf、BTF 和内核助手。P4TC 开发者需要一个理解内核目标并发出配置 API 所需信息的 P4 编译器。这两个生态系统有不同的安全模型。eBPF 验证器对字节码和内核交互进行推理。P4 流水线通过语言和编译器规则检查,然后被转换为 tc 对象和内核执行。这两种模型都不能免除验证生成行为的需要。

性能比较也需要纪律。XDP 可以通过在套接字分配之前操作来避免工作。DPDK 可以投入整个核心进行轮询。tc 可以重用内核的设备和调度上下文。结果取决于数据包大小、动作复杂性、CPU、NIC、缓存行为以及硬件卸载是否可用。一个显示某个系统在狭窄测试中获胜的基准并不能决定哪种操作模型更易于维护。

运维人员经常将这些机制结合起来。XDP 可能会丢弃明显的攻击流量,tc 可能会执行策略和塑造出口流量,而 DPDK 应用程序可能处理一项专门的服务。eBPF 分类器长期以来一直与 tc 一起使用。硬件卸载可能转换 tc flower 规则的一个子集,而软件处理其余部分。因此,真正的问题不是哪个框架获胜,而是它们的边界是否足够明确,以避免重复或矛盾的策略。

例如,一个 P4TC 流水线可能对一个已经被 XDP 程序修改过的流量进行分类。元数据可能不会按照应用程序期望的形式在钩子之间传递。两个控制系统可能更新重叠的规则。计数器可能跨层分割。然后,故障排除需要在多个执行环境中构建一个数据包的生命历程。可编程性已经增加了意图可以存在的多个位置。

通用的生命周期实践比意识形态的纯粹性更重要。一个生产团队需要所有权规则:哪一层处理准入,哪一层处理整形,哪一层可以重定向流量,哪个系统对每个计数器具有权威性。变更需要协调的推出。紧急回滚需要在即使一个控制器不可用时也能工作。开源生态系统提供了选择;它并没有使这些选择自我协调。

P4TC 的机会在于那些匹配 tc 已建立角色并受益于 P4 结构化模型的工作。它可以使复杂的分类和动作在 Linux 主机上更具可移植性,并可能卸载到目标上。它可以为其他情况下会用供应商规则或定制的 tc 命令编码的一类流水线提供一种通用语言。它不需要成为唯一的数据平面才能产生影响。

Salim 更广泛的记录支持这种更为温和的解读。ForCES 是一个创建显式控制和转发模型的尝试,而不是要废除每一种设备架构。流量控制通过组合机制而不是取代整个栈而成长。P4TC 可以以同样的方式成功:通过为 Linux 提供一种持久的新的词汇,同时尊重不同的分组路径是为了不同的操作交易而存在这一事实。

维护者的权力在于拒绝 Linux 无法维持的契约

Salim 作为 Linux Traffic Control 维护者的当前身份很容易被误读为所有权。Linux 维护者更接近被委托的监护权。维护者可以审查、请求更改、拒绝一个接口,并为下一个集成步骤组装补丁。这种权力是实质性的,因为一个被接受的 Netlink 属性或动作可能成为一个使用多年的契约。但它仍然受到同行审查、更高级别的网络维护者、发布实践以及贡献者维护他们所添加内容的意愿的限制。

归因在这里很重要,因为编写的代码行数只是影响力的一个衡量标准。Salim 的记录包括标准、子系统架构、审查和社区工作。一位维护者可能通过坚持某个功能使用通用的对象模型、暴露统计信息或保持兼容性来塑造它,即使另一名工程师编写了大部分代码。相反,签署一份补丁并不意味着维护者发明了补丁中的每一种机制。

流量控制子系统使这种形式的权力异常持久。运维人员将tc命令嵌入到启动脚本、编排工具、容器平台和供应商设备中。一个看似晦涩的语法或默认值可能成为生产依赖。之后将其移除可能会破坏维护者看不到的系统。因此,审查不仅衡量一个补丁是否工作,还衡量在原始贡献者更换雇主或兴趣后,该接口是否可以被支持。

P4TC 提高了赌注,因为它邀请更广泛的工具链依赖于内核。编译器生成的对象描述、控制器 API 和硬件驱动程序可能都编码了对共同契约的假设。一个为早期原型做出的决定,一旦这些层交付,可能会变得难以修改。维护者最有价值的干预可能是减缓该功能,直到故障语义和版本管理变得清晰。

对于急于展示能力的研究人员和供应商来说,这种谨慎可能看起来保守。从运维人员的角度来看,这是一种创新保险。Linux 的成功部分在于新的机制进入一个具有长期兼容性期望的系统。其代价是,上游化可能比维护一个私有分支要慢。

私有分叉提供速度并集中风险。供应商可以为其编译器或设备定制 P4TC,并在上游设计确定之前交付产品。然后,客户依赖于该内核、工具链和支持合同。上游审查是使有用部分能够成为共享接口的途径,但前提是供应商愿意根据社区要求调整其实现。

Salim 跨越 Netlink、ForCES 和 P4TC 的职业生涯使他的意义不在于某一种发明,而在于这种转化。标准定义了一个模型;代码暴露了一个 Linux 接口;维护者决定模型是否适合操作系统的义务。这种权力之所以真实,正是因为它通过约束而不是个人所有权来行使。

付费工程决定了公共品的哪些部分得到维护

开源基础设施常常被描述成代码似乎来自一个中立社区,与普通经济学无关。Linux 网络并非如此。贡献者受雇于云公司、硬件供应商、发行版、咨询机构和运维商。会议需要赞助商。测试系统需要机器和员工。维护者需要时间来阅读补丁系列,这些补丁的商业价值可能惠及那些永远不会出现在提交日志中的组织。

Salim 通过 Mojatatu Networks 的工作就处于这一现实之中。公开记录支持他作为与该公司相关的工程师和社区领导者的角色,但记录并未提供针对 tc 或 P4TC 的逐项目预算。合理的结论不是缺乏资金。而是劳动模式是分布式的,并且只有部分可见。

对于上游项目来说,商业支持可能是健康的。一家咨询公司可以帮助运维人员部署一个不熟悉的功能,将生产故障转化为补丁,并资助那些同时理解客户问题和内核流程的工程师。当一个赞助商的私人路线图被误认为是社区共识,或者当基本的维护依赖于一份可能毫无预兆就消失的合同时,工作就变得危险了。

P4TC 还有一个额外的经济挑战,因为它跨越了组织边界。编译器开发者、内核维护者、NIC 供应商和控制器团队可能由不同的雇主资助。只有当他们所有人都完成了兼容的工作时,一个功能才可能有价值。没有任何一个组织能获得足够的收入来支付各层之间不起眼的集成工作。

这种协调问题有助于解释为什么成熟的标准仍然可能未被充分利用。ForCES 定义了接口,但供应商和运维人员需要一个商业理由来构建和支持双方。P4TC 可以重用 Linux 和 P4 生态系统,但它仍然需要发行版来打包工具,硬件供应商来实现卸载,控制器开发者来支持 API,以及运维人员来发布需求。一个工作演示比一个可支持的供应链便宜。

通过使依赖关系可见,治理可以减少风险。公开路线图应该区分已资助的工作和希望获得的贡献。维护者文件和审查记录应该显示专业知识集中的地方。测试基础设施不应该依赖于一个无法访问的实验室。文档应该使软件执行即使在硬件支持不完整时也有用,这样项目就不会被某个特定设备绑架。

兼容性也提出了谁为其付费的问题。当 Linux 支持其硬件时,供应商受益,但社区无限期地承担 ABI。因此,维护者会问一个接口是否足够通用以证明这种负担是合理的。一个控制器供应商可能更偏好一个能整齐映射到其产品的特性,而内核需要其他控制器也能使用的语义。这些分歧不是阻挠。它们是私人需求被转化为公共基础设施的机制。

Salim 横跨公司工作、标准和社区论坛的位置,让他在这种转化中拥有影响力。这并没有给他结果的所有权。这个角色的价值在于维持不同群体之间的对话,这些群体使用不同的完成定义:RFC 编辑想要一个连贯的规范;内核审查者想要一个安全的接口;硬件工程师想要可实现的原子操作;运维人员想要可预测的故障行为。

可持续发展的考验是知识是否传播到目前付费持有它的人之外。文档、自检、公开演示和指导将雇主资助的努力转变为社区资产。没有这些,开放的代码仍然可以有效上是专有的,因为只有一个团队理解它是如何工作的。

P4TC 还足够早期,以至于其劳动结构是技术风险的一部分。一个小团体可以快速移动并保持概念上的统一。但它也可能成为一个瓶颈。更广泛的参与可能会减缓设计决策,但提高了 API 在雇主优先级变化中存活下来的机会。这种平衡不能通过宣布项目开放来解决。它必须通过可重复的审查和共享的操作证据来构建。

Netdev 审查是社交控制平面

Linux 网络常常通过代码和 API 来描述,但其连续性依赖于审查社区。补丁在邮件列表上被讨论,针对当前的树进行测试,并根据维护者的意见进行修订。像 Netdev 这样的会议将内核开发者、研究人员、供应商和运维人员带入相同的技术对话中。

Salim 是该社区的核心组织者,Mojatatu 支持了该会议。这个角色很重要,因为像 P4TC 这样的新兴思想需要的不仅仅是一个代码仓库。它们需要一个地方,让实现者可以比较假设,暴露性能结果,并听取将承担故障风险的运维人员的意见。

社区领导力并不赋予单方面的内核权力。流量控制的变更仍然通过子系统和网络维护者进行。Linus Torvalds 的主线流程坐在它们之上。赞助支持活动,但不会购买合并决策。这种分离对于开放基础设施的合法性至关重要。

然而,这个过程可能集中影响力。拥有长期历史知识的维护者可以识别出偶尔的贡献者遗漏的风险。他们的时间也有限。一个复杂的补丁系列可能因为审查者无法吸收而停滞。雇主资助的团队比独立开发者有更多的能力来回应。公开审查使这种不平衡变得可见,但并不能消除它。

P4TC 的广度将考验这个系统。它触及内核分组处理、用户空间 API、编译器、测试,并可能涉及硬件卸载。审查必须在专家之间分布,但最终的接口需要连贯性。一个项目可以积累技术上正确的部分,但不能形成一个可维护的整体。

指导是一种回应。Salim 参与 P4 社区项目和 Netdev 有助于创建既理解语言概念又理解内核惯例的贡献者。这不是辅助活动。在成熟的子系统中,继任风险是真实的。如果只有少数人能审查tc、Netlink 和 P4 之间的交互,那么该功能的长期支持将是脆弱的。

透明的治理也有助于运维人员评估成熟度。邮件列表讨论、自检和发布历史表明一个功能是否得到积极维护,以及分歧如何解决。市场宣传材料可以宣布可编程性;上游审查揭示了使其安全所付出的成本。

因此,社交过程是技术架构的一部分。一个稳定的 API 依赖于抵制走捷径的审查者。互操作性依赖于愿意测试的供应商。生产采用依赖于报告故障的运维人员。Salim 的职业生涯说明了网络可编程性有多少是由这些关系决定的,而不是由一份设计文档决定的。

开放接口转移了锁定,而不是消除它

P4TC 常被标榜为对专有分组处理系统的开放替代方案。这种描述在方向上有用,但不完整。运维人员可能避开特定供应商的 CLI,并通过 P4 和 Netlink 来表达策略。但它仍然可能变得依赖于一个编译器、内核版本、驱动程序、硬件目标和编排系统。

相关的问题是这些依赖是否可检查和可替换。开源允许组织审查代码并构建自己的版本。在实践中,维护一个内核数据平面和编译器需要专门的知识。大多数运维人员将依赖发行版、供应商或集成商。经济优势来自竞争性支持和共享接口,而不是来自每个用户都能成为维护者的假设。

一个共通的控制平面可以改善议价能力。应用程序可以针对 Linux 而不是某一个设备。供应商可以实现卸载,而无需拥有整个策略模型。研究人员可以在广泛可用的系统上测试新流水线。即使在完美的可移植性缺失的情况下,这些好处也是有意义的。

代价转向集成。运维人员必须资质编译器与内核的组合,验证卸载,监控状态并计划升级。系统变得越可编程,配置就越像软件。版本控制、代码审查和测试不是从开发者那里借用的可选实践;它们是网络-安全机制。

ForCES 的经验警告我们不能假设开放和标准化会自动产生采用。一个强大的生态系统需要维护者、文档、测试基础设施以及供应商支持接口的商业理由。如果主要的硬件路径仍然不完整,运维人员可能会选择专有 SDK,尽管有锁定,因为性能和支持更清晰。

因此,P4TC 最强势的位置可能是在那些重视 Linux 集成多于目标独立性的环境中:软件设备、边缘系统、研究平台以及内核生命周期已经得到管理的主机。更广泛的采用将需要令人信服的证据,证明相同的策略可以在硬件和发行版之间移动,而无需昂贵的重新工程。

Salim 的贡献不是承诺一个无锁定的网络。而是持续尝试使控制边界变得公开和可编程。这是一个更可防御的目标。它为运维人员提供了要求稳定语义和替代实现的基础,即使底层的执行仍然专业化。

成功意味着运维人员不再需要猜测

一个头条基准测试不会决定 P4TC 的未来。决定性的证据将是一个从 P4 描述到一个已配置的 Linux 流水线、一个运行时控制器以及(如果可用)硬件卸载的稳定操作路径。每一层都必须报告它接受了什么,执行发生在哪里,以及当请求的任何部分无法被满足时会发生什么。

流量控制为 P4TC 提供了一个已安装的架构和庞大的用户基础。它也提供了由脚本、驱动程序、发行版和网络设备积累的兼容性义务。Netlink 属性、对象生命周期和错误行为在用户空间一旦依赖它们后就不能被视为临时的脚手架。

Salim 早期的工作解释了为什么这种纪律很重要。ForCES 表明了严格的规范本身并不会产生采用。Netlink 表明了一个可扩展的控制通道如何成为一份持久的公共契约。流量控制表明了可组合的动作如何在支持多种用途的同时,使执行路径更难阅读。

当运维人员能够配置一个带版本的流水线,在负载下更新它,检查来自实际执行路径的计数器,在控制器或驱动程序故障后恢复,并在无需从日志重建意图的情况下回滚时,该项目将看起来像基础设施。独立的编译器和控制器应该达到相同的结果,而驱动程序应该明确说明它们保留了哪些行为。

Salim 既不是独自发明了 Linux Traffic Control,也不会单方面决定它的未来。他的影响力在于子系统设计、标准工作、审查和社区维护之间的连续性。P4TC 可观察的测试是,这种连续性能否产生一个其意义超越当前构建者而存续的接口。