转发表发生变化后,报文可能换一个出口,也可能在更高优先级规则处被丢弃。SDN 把控制逻辑与转发执行分开,OpenFlow 定义控制器操作交换机表项的协议,P4 则描述可编程包处理管线;三者不能当作同义词。

第 10 篇讨论路由器查表与转发,第 30 篇讨论 Linux 主机路径。本篇用固定软件模型验证规则变化,不把模型结果当作 Open vSwitch、P4 软件交换机或硬件 ASIC 的运行证据。

控制面安装规则,数据面逐包执行

OpenFlow 交换机包含一个或多个流表。流表项通常具有匹配字段、优先级、计数器和指令;报文按管线匹配后执行输出、修改、丢弃或转入下一张表等动作。表未命中时的行为也必须由配置或规范语义决定。

SDN 控制器根据拓扑和策略计算规则,再通过南向接口下发。控制器“希望安装”与交换机“已经安装并用于报文”是两个事件,需要事务回复、表项读取和数据面探测分别取证。

P4_16 描述 parser、可编程 control 和 deparser 等抽象。P4 程序能表达什么还受目标架构、表容量、动作能力、编译器和硬件资源限制。可编程不等于任意程序都能以线速运行。

模式提炼:程序、表项与报文结果三层对齐

管线定义 + 运行时表项 + 输入报文 = 数据面动作

只检查 P4 源码会漏掉运行时表项,只检查控制器状态会漏掉设备拒绝或部分更新,只发一个探测包又无法证明所有匹配域正确。

固定规则的前后对照

模型初始有两条前缀规则:10.0.0.0/24 → port 1,10.0.1.0/24 → port 2,其他目的地址丢弃。规则按优先级排序,相同优先级再选最长前缀。

更新后新增 10.0.0.42/32 → drop,并把 10.0.1.0/24 的出口改为 port 3。于是目的 10.0.0.42 从 port 1 变成丢弃,10.0.1.9 从 port 2 改到 port 3,未匹配地址继续丢弃。

这个前后差异证明模型遵守指定匹配与动作,不证明 OpenFlow bundle 原子性、控制器收敛顺序或真实硬件没有过渡状态。规则更新期间的包可能看到旧状态、新状态或实现允许的中间状态,必须由具体设备和更新机制说明。

软件交换模型验证

switch_model.py 读取两版规则和固定报文,输出每个报文的命中规则及动作。

1
2
python3 source/_posts/2026-09-24-计算机网络E04-SDN与可编程数据面/switch_model.py --help
python3 source/_posts/2026-09-24-计算机网络E04-SDN与可编程数据面/switch_model.py

素材包括规则与报文、软件交换模型、前后对照结果、资料与运行记录和审阅记录。

条件、限制和反例

逻辑规则正确不等于硬件可部署。TCAM 容量、匹配宽度、动作资源、管线级数和芯片目标可能让程序无法编译或表项无法安装。

控制面集中不等于单个进程承担一切。控制器可以分布式部署,设备也可能保留本地协议和快速故障处理。

命中计数增长不证明接收端处理成功。计数器只对应所在观察点,后续端口、链路和接收协议栈仍可能丢弃报文。

练习

练习一:在 /24 转发规则之上增加 /32 丢弃规则,分别说明优先级高于、低于和等于 /24 时模型应怎样选择,并指出真实 OpenFlow 表需要查哪个匹配规则。

练习二:控制器报告更新成功,但探测包仍走旧出口。列出控制面确认、交换机表项、端口计数和接收端抓包四个观察点能排除的解释。

模式速查表

层次 工件 验证问题
意图 控制器策略 想要什么路径
管线 OpenFlow/P4 定义 能匹配和执行什么
运行时 流表或 P4Runtime 实体 实际安装了什么
数据面 计数、抓包、接收结果 报文实际经历什么

官方一手参考资料

验证边界

已验证:Python 3 标准库实现固定 match-action 软件交换模型,验证两版规则下的命中、输出和丢弃差异,验证类型为 STATIC。

NOT_RUN:当前环境没有 Open vSwitch、OpenFlow 控制器、P4 编译器、BMv2 或可编程网卡/交换芯片,未验证真实规则下发、计数器、更新一致性、硬件容量和线速性能。