跳转至

p4net

Python 实现的 Mininet 风格 P4 SDN 沙盒。

它是什么

p4net 在 Linux 网络命名空间中拉起真实的 simple_switch_grpc(BMv2) 数据平面,用 veth 对将主机和交换机相连,用 tc netem 注入链路损伤, 然后通过 P4Runtime 进行控制——这与真实硬件 P4 控制器的工作方式完全一致。 Python API 的形态参考 Mininet:声明一个由 HostP4SwitchLink 组成的 Topology,交给 Network,就能拿到一个运行中的实验环境。

该框架面向 P4 开发与教学场景:课堂实验、控制器原型、转发逻辑回归测试, 以及任何更看重「几秒钟就能起一个多主机拓扑」而非「精确模拟某款交换机 ASIC」的实验。工具链由 p4csimple_switch_grpc 和内核命名空间原语 组成;不依赖 Docker、OpenFlow,也不需要 Open vSwitch。

包含哪些组件

  • 拓扑 DSL —— HostP4SwitchLinkTopology,构造期即做 静态校验(接口名长度、IP 冲突、对称与非对称损伤的相互排斥关系)。
  • 基于 p4c 的编译,配套位于 ~/.cache/p4net/compiler/ 的内容 寻址缓存——只在源码或参数发生变化时才重新编译。
  • BMv2 生命周期管理 —— 启动、就绪等待、停止、gRPC 端口分配, 以及 atexit / signal 兜底清理。
  • P4Runtime gRPC 客户端 —— 表项编程、间接计数器读取、组播组管理, 以及通过 StreamChannel 进行的 CPU 端口数据包 I/O。
  • 基于 tc netem 的逐方向链路损伤 —— bandwidthdelayjitterloss_pct 既可对称配置,也可拆成 *_a_to_b / *_b_to_a 两个方向,或者在对称基础上叠加 *_extra
  • IPv4 与 IPv6 主机寻址,每个接口具备独立的 sysctl 门控 (未显式启用 IPv6 的接口不会自动生成 link-local 地址)。
  • 交互式 CLI —— p4net <topology.py> 启动一个 Shell,提供表内容 转储、ping 矩阵、数据包发送/监听、拓扑可视化等命令。
  • 拓扑可视化,由 Topology.to_graphviz()Topology.render_graphviz() 提供,输出 DOT、PNG、SVG、PDF 等格式。
  • 统一的 p4net.* logger 层次,附带级别约定与 CLI 详细度开关 (-v / -vv);参见日志

安装

pip install p4net

详细步骤包括外部依赖 p4c 与 BMv2,请参见 安装

30 秒示例

from pathlib import Path
from p4net import Network
from p4net.topo import Topology

topo = Topology()
h1 = topo.add_host("h1", ip="10.0.0.1/24", mac="00:00:00:00:00:01")
h2 = topo.add_host("h2", ip="10.0.0.2/24", mac="00:00:00:00:00:02")
s1 = topo.add_switch("s1", p4_src=Path("port_swap.p4"))
topo.add_link(h1, s1, port_b=1)
topo.add_link(h2, s1, port_b=2)

with Network(topo) as net:
    h1, h2 = net.host("h1"), net.host("h2")
    h1.exec(["ip", "neigh", "replace", "10.0.0.2",
             "lladdr", "00:00:00:00:00:02",
             "dev", "h1-eth0", "nud", "permanent"])
    print(h1.ping(h2))   # True

配套的 port_swap.p4 源码位于 examples/quick_start/

接下来读什么

  • 快速上手 —— 上面这个示例的逐步 说明,附带 P4 程序源码。
  • 教程 —— 一个更长的讲解,覆盖双栈转发、运行时 表项编程、非对称链路损伤、CPU 端口数据包 I/O。
  • 架构 —— 各包的职责与背后设计取舍。
  • 示例 —— 七个可运行的拓扑,从端口翻转、 L3 转发,一直到带内网络遥测(INT)。
  • CLI 参考 —— 每条 Shell 命令的说明与示例输出。
  • API 参考 —— 由 Python docstring 自动生成。

项目状态

p4net 当前为 v1.7.0——稳定版本。公共 API 已按 API 稳定性做出承诺:标为稳定的符号在 1.x 内不会 被破坏。补丁版本只修 bug;小版本以追加方式新增功能。在 v1.0.0 稳定性基础之上,1.1–1.5 加入了单交换机与多跳 INT 示例、统一的 p4net.* logger 层次、按方向叠加的链路损伤、P4RuntimeClient 的 寄存器读写 API、用于跨交换机 INT 对齐的 RunningSwitch.boot_timestamp_usNetwork.boot_timestamps, 以及环境变量驱动的协调文件路径以避免并行多跳 INT 拓扑互相覆盖。 v1.6 引入 AsyncP4RuntimeClient——基于 grpc.aio 的异步并行客户端——并以 RunningSwitch.async_client 惰性暴露;v1.7 在真实使用磨合期后将这些符号由「临时」升级为 稳定,兑现 1.6 在 API 稳定性页中的承诺。 完整版本历史见 变更日志;已知边界见 已知限制;后续计划见 路线图

许可证

Apache-2.0