2.2 消息类型详解:控制器与交换机的对话


2.2 消息类型详解:控制器与交换机的对话

本节摘要:OpenFlow 1.3 定义了三十余种消息,分三大类:Controller-Switch(控制器发起的管理对话)、Asynchronous(交换机主动上报)、Symmetric(双方对等使用)。本节给出家族全景,并重点解剖 Packet-In、Flow-Mod、Packet-Out 三个出场率最高的消息体字段。

OpenFlow 1.3 消息分类图

OpenFlow 1.3 消息分类图

记忆锚点:Controller-Switch 是"上级问话/下命令",Asynchronous 是"下级汇报",Symmetric 是"同事寒暄"。

Packet-In:最频繁的上报

交换机遇到表不命中(或按指令要求上送)时,把包封装进 Packet-In 发给控制器。消息体的关键字段:

Packet-In { buffer_id: 包在交换机缓存中的句柄,0xFFFFFFFF 表示未缓存 total_len: 原始帧长 reason: 0 = NO_MATCH 表不命中 1 = ACTION 显式上送动作 match: 命中信息(reason=1 时是命中的那条规则) data: 以太网帧原文,默认截断 128 字节 }

reason 的两个取值对应完全不同的网络状况:满屏 NO_MATCH 说明 Table-Miss 缺失或新流汹涌;大量 ACTION 则是控制器应用有意"看一遍流量"。排障时先分这两类,方向就对了。

buffer_id 是个精巧的省带宽设计:包留在交换机里,控制器回 Packet-Out 时只需引用 buffer_id 加动作列表,不必把整个包背回来。但引用有时效——缓存被冲掉后 Packet-Out 会失败,控制器得能退回全包下发的模式。

Flow-Mod:唯一的写笔

流表的所有变更都走 Flow-Mod,五种命令:ADD(增)、MODIFY、MODIFY_STRICT(改,按优先级+匹配严格定位)、DELETE、DELETE_STRICT(删)。消息体在 2.3 节逐字段拆,这里先看三个行为标志:

  • send_flow_rem:条目失效时是否回 Flow-Removed,控制器靠它回收状态
  • check_overlap:安装前查重,防同优先级同匹配的冲突条目
  • reset_counts:修改时是否清零计数器

一个容易忽略的细节:Flow-Mod 没有应答。发出去就是发出去,控制器想知道"到底装上没有",要么看 Error 上报,要么发 Barrier-Request 等栅栏应答,要么 Multipart 查表确认。生产控制器普遍用 Barrier 做安装确认。

⚠️ 常见坑:把 MODIFY 当 UPDATE 用却忘了匹配不到任何条目时 MODIFY 是空操作——想"没有则加、有则改"得靠控制器的先查后写,或用 ADD 配 check_overlap。

💡 关键直觉:Packet-In 是问,Flow-Mod 与 Packet-Out 是答——这一问一答构成了 OpenFlow 网络的反射弧。

解剖实例:一条 Packet-In 的逐字段读法

拿 1.4 实验台的首流标本来拆 Packet-In。Wireshark 展开的字段树与字节流对照如下:

OpenFlow 1.3 Version: 0x04 (1.3) Type: 10 (OFPT_PACKET_IN) Length: 96 Transaction ID: 42 buffer_id: 0x00000000 <- 0 表示报文未被缓存,完整数据在本条消息里 total_len: 74 <- 原始以太帧长度(含帧头) reason: 0 (OFPR_NO_MATCH) <- 表不命中上送;1 则是显式 action=CONTROLLER table_id: 0 <- 在 0 号表漏掉的 cookie: 0 Ethernet Frame (74 bytes) Src: 00:00:00:00:00:01 <- h1 的 ARP 请求

逐行读出故障信息是排障的基本功。reason=0 且 table_id=0,说明包走完了 0 号表没命中任何规则,被 Table-Miss 兜底条款上送;如果控制器里明明装过应命中的规则却仍收到 reason=0,嫌疑按顺序排查:匹配字段是否写反(in_port 与 dl_src 是两回事)、优先级是否被更高优先级的兜底规则盖住、规则是否已被 idle 超时收走。buffer_id 非 0 时,Packet-In 只带前 128 字节(miss_send_len 可调),控制器回 Packet-Out 时引用 buffer_id 即可让交换机补全后半段,省的是控制通道带宽,代价是 buffer 有时效,引用过期的 buffer_id 会得到一条 Error。

消息出场率:哪些消息值得背熟

三十余种消息的出场频率极度不均。真实抓包里,Echo 两个方向可能占九成以上帧数(保活是常态),Packet-In/Flow-Mod/Packet-Out 占剩下的绝大多数,Features 与 Port-Status 一天出现不了几次。按"背熟优先级"排序:Echo(判断通道死活)、Packet-In 的 reason 字段(判断上送原因)、Flow-Mod 的 command 与 flags(写操作的全部形态)、Port-Status 的 reason(ADD/DELETE/MODIFY 三态)、Error 的 type/code 组合(所有谈判失败的最终归宿)。Error 的常见组合值得记三个:1/5 版本不兼容、3/2 无效端口、4/3 表项冲突——每一条都对应一个可复现的实验现场。

所有消息共用的八字节头

三十余种消息共享同一个八字节头,解剖任何报文都从它开始:version(1.3 为 0x04)、type(大类编码,Packet-In 是 10、Packet-Out 是 13、Flow-Mod 是 14)、length(整条消息含头部的字节数)、xid(事务号)。xid 是请求应答配对的钥匙:控制器发请求时带上自增的 xid,交换机应答原样回传,多请求并发时靠它分清"这条应答属于哪个请求"——若某应答的 xid 匹配不到任何在途请求,多半是超时重传或消息串帧。length 字段用于切分字节流:TCP 长连接上多条消息首尾相接,解析器先读四字节拿 type 与 length,再按 length 精确截出本条消息;截取错一位,整条通道的解码都会错位。

本节要点回顾

  • 三大类:Controller-Switch 管理对话、Asynchronous 主动上报、Symmetric 对等保活
  • Packet-In:reason 区分不命中与显式上送,buffer_id 引用省带宽
  • Flow-Mod:五种命令、三个标志,无应答需 Barrier 确认
  • 排障入口:先统计 Packet-In 的 reason 分布,再谈下一步

Flow-Mod 写进流表的东西长什么样?下一节解剖流条目本身。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U