本节摘要:把 1.4 实验台的抓包标本逐帧摆上解剖台:从 TCP 握手、Hello 版本协商、能力查询,到 h1 ping h2 触发的 Packet-In / Packet-Out / Flow-Mod 链条,再到 Echo 保活。本节是第 2 章的综合演练,前面五节的概念在这里全部"对号入座"。
阅读完本节,你应当能够:

阶段一:建立(0–0.1 秒)。 TCP 三次握手后双方各发 Hello。解剖要点:两帧 Hello 的 version 都是 0x04,xid 都是 0,长度都是 8——纯头部消息。若这里出现 Error type=HELLO_FAILED,回 2.5 节查版本协商。
阶段二:能力盘点(毫秒级)。 控制器发 Features-Request,交换机回 Features-Reply,消息体里最重要的字段是 DPID(64 位交换机标识,Mininet 里默认 0000000000000001)与端口清单(端口号、名称、当前速率、支持的能力)。控制器由此建立设备档案。多表能力的协商靠之后的 Table-Features 消息族。
阶段三:首流上线(ping 第一包)。 这是最有解剖价值的一段:
在 Wireshark 里验证:ping 的后续包只引起 counters 增长,Packet-In 不再出现——这就是"反射弧建立,脊髓接管"的过程。
阶段四:巡航。 空闲期通道上只剩 Echo 对话(默认间隔各实现不同,OVS 常见 5–15 秒)。Echo 断供即判通道死亡,交换机进入 failover 模式(5.2 节细讲)。
在自己的抓包标本上按此核对:
[ ] 两帧 Hello 的 version 一致且等于协商结果 [ ] Features-Reply 的 DPID 与 dump-flows 目标一致 [ ] 首个 Packet-In 的 reason 值为 0(NO_MATCH) [ ] Packet-Out 的 actions 列表含 FLOOD 或具体端口 [ ] Flow-Mod 的 command=0(ADD)且带 cookie [ ] 之后同五元组的包不再产生 Packet-In
💡 关键直觉:会话的前三秒决定了网络的全部行为——能力怎么谈、未知流量怎么接、规则怎么铺。排障时把这段时间线摊开看,十有八九能定位问题。
图形界面适合单帧端详,复盘整个会话用 tshark 更高效。对着 1.4 的抓包标本执行:
tshark -r first-ping.pcap -Y openflow -T fields \ -e frame.time_relative -e of.version -e of.type -e of.xid \ -e of.reason -e of.command 2>/dev/null | head -24 # 2.430 4 3(PortStat) 4 <- 后台巡检与业务并行
这张表是排障时序思维的原型。健康会话的特征是:Hello 之后 1 毫秒内必有 Features 往返;业务流量只在首流时刻产生 Packet-In 尖峰,之后归于 Echo 与统计的安静背景。偏离这个形状即有病灶——Features 缺失说明握手卡死,Packet-In 持续密集说明流表没有被正确铺设(下一小节展开),Echo 突然消失超过三个周期说明通道假死,TCP 层还连着但控制器已无响应。
把 h1 到 h2 改成持续 iperf3 打流,若 tshark 表里 Packet-In 仍以流速率出现,说明 Flow-Mod 没有生效或没有覆盖到该流。三种根因按概率排序:下发失败的 Flow-Mod(前面某帧 Error 被忽略了,回到时间线找 type=1 的帧);规则被更高优先级规则遮蔽(回看 2.3 节优先级语义);规则带超时且流量特征导致 idle 钟反复到期(查 dump-flows 的 idle_age 与 duration 是否不断清零重计)。三种根因对应三种修法,诊断的分叉点就在"交换机里到底有没有那条规则"——所以排障第一步永远是 dump-flows,第二步才是看报文。
首流链条里还有两张消息值得在抓包里逐字段对照。Packet-Out(type 13):buffer_id 复用 Packet-In 的缓存句柄,0 表示未缓存、data 里带完整帧;in_port 是包"看起来来自哪个口",泛洪时常填 OFPP_CONTROLLER;actions 与 2.4 节同一套动作语义。Flow-Mod(type 14)的字段则决定它为何"写对了却没生效":cookie 与 cookie_mask 是控制器回收状态的钥匙,下发带上、删除按 cookie 精确删;priority 排在匹配字段之前,同类条目冲突时数字大的赢;table_id 指定写进哪张表,漏填默认 0 号表;idle_timeout 管"空闲多久失效",hard_timeout 无论有无流量到时强制失效,是避免死规则堆积的兜底。逐字段对完这两条,再看 Wireshark 底部十六进制字节,就能从原始字节流读出消息边界——解剖从看树升级成看线。
最后一段往往被忽略:控制器宕机或通道断开后,交换机行为受 fail-safe 配置控制。默认多走 emergency 语义,已下发的规则继续用,但收不到新指令;部分实现支持规则超时老化,让旧规则逐步蒸发。重连时双方重新 Hello,若控制器用新会话的数据库回放 Flow-Mod,必须警惕交换机侧残留旧规则与新规则并存——排障时看到"明明重下发了却双份计数",先查会话切换时有没有发 Flow-Mod DELETE 清场。
协议侧解剖完毕,下一章转向解剖台两侧的角色——控制器与交换机。