数据平面解决的是一次转发:数据报到达路由器后,根据转发表从哪个端口离开。控制平面解决的则是转发表的来源:哪些网络可达,候选路径有哪些,应选哪一条,拓扑或政策变化时又如何更新。
这些问题没有一种统一的答法。自治系统内部更关心性能和快速收敛,自治系统之间还必须表达商业关系和路由政策。传统路由器把算法分散到每台设备上,SDN 则把决策逻辑移到逻辑集中的控制器中。而网络运行起来之后,还需要 ICMP 报告异常,用 SNMP 观测状态,再用 NETCONF/YANG 结构化地修改配置。
学习这部分内容时,始终区分三个对象:路由算法计算路径,路由协议让设备交换计算所需的信息,网络管理协议读取状态或修改配置。它们会协同工作,但不是同一类机制。
一台路由器可以粗略分成转发组件和路由选择组件。转发组件位于数据平面,它以线速查表,动作发生在微秒乃至纳秒尺度。路由选择组件位于控制平面,它处理邻居关系、可达前缀、链路代价和政策,通常以毫秒到秒为时间尺度。

在每路由器控制模式中,每台路由器都运行路由协议。它从相邻路由器收集信息,在本地执行路由算法,再把选中的结果安装进本机转发表。OSPF 和 BGP 都使用这种思路,只是它们交换的信息和选路目标不同。
“分布式”不表示路由器互不协作。恰恰相反,它们必须按照共同的消息格式和状态机交换信息。分布式说的是路径计算与决策不集中在一个单独组件上。
在逻辑集中模式中,控制器掌握网络设备和链路状态,网络控制应用根据这些状态计算转发规则,控制器再把规则下发给交换机。交换机不需要自己运行完整的网络级决策逻辑,只需要报告事件并执行流表。
逻辑集中不等于物理上只有一台控制器。生产网络通常用多个控制器实例做容错、分区与负载分担,对上层应用仍呈现统一的网络视图。
路由计算先要将网络抽象成图 。 是节点集合,在域内路由里通常表示路由器; 是链路集合。每条链路 都有代价 。无直连链路时,可把代价看作无穷大。
设一条路径 ,它的总代价是沿途链路代价之和:
最小代价路径是所有可行路径中 最小的一条。但“代价”并不天然等于延迟。管理员可以按链路带宽设置代价,也可以用固定值表达网络设计意图。只要所有路由器对代价的含义有一致理解,算法就能在这一目标下求最短路。
集中信息与分布信息。 链路状态算法在计算前需要完整拓扑和链路代价;距离向量算法只与邻居交换距离估计,不保存完整拓扑。
静态与动态。 静态路由变化很慢,通常依赖人工配置。动态路由能够在链路失效、设备加入或代价变化后重新计算。动态协议更灵活,但会引入消息开销和收敛过程。
负载敏感与负载不敏感。 若链路代价随当前拥塞程度变化,路由就会绕开繁忙链路。这听起来很合理,却容易造成同步摆动:大量流量同时离开一条路,又同时涌入另一条路。因此广泛部署的互联网路由协议通常不把瞬时负载直接写入链路代价。

链路状态算法的前提是:每个计算节点都已经拥有完整的拓扑和链路代价。这份信息可以由链路状态通告洪泛得到,也可以由逻辑集中的控制器收集。算法本身在本地运行,对于给定的源节点 ,生成一棵以 为根的最短路径树。
用 表示已确定最短路的节点集合, 表示当前从 到 的最小已知代价, 表示这条候选路径上 的前驱。
初始时只把源节点 放入 。对于 的直接邻居 ,设 ;其他节点的 设为无穷大。
使用数组直接实现时,每轮需扫描未确定节点,总复杂度为 。结合优先队列和邻接表后,在稀疏图上可以更高效。真正的工程成本还包括通告洪泛、数据库同步和拓扑变化后的重算。
以一个小型拓扑为例,源节点 与 的代价为 1,与 的代价为 2,与 的代价为 5。初始时 的候选距离最小,先被确定。若 到 的链路代价为 1,经 到 的新候选代价是 ,与直连代价打平;若 到 的代价为 2,则 从无穷大更新为 3。下一轮可以从 与其他同代价节点中按稳定规则破除平局。这个过程中, 值是距离, 值才能还原路径;只记距离而不记前驱,无法推出应选的下一跳。

假设链路代价与当前承载流量成正比。某一时刻,右侧路径较轻,各路由器都会把流量切到右侧;下一次计算时,右侧变成高代价,流量又集体切回左侧。即使每次 Dijkstra 都正确求出了当时的最短路,整个反馈系统仍可能不稳定。降低代价对瞬时流量的敏感度,或让不同路由器错开计算时间,能够减少这种同步震荡。
距离向量算法不让节点持有全网地图。节点 只需知道它到直接邻居 的代价 ,保存自己到每个目的地 的估计 ,并接收每个邻居的距离向量。它的核心是 Bellman-Ford 方程:
这个式子的语义是:从 出发的第一跳必然是某个直接邻居 。如果选 作为第一跳,总代价就是 到 的直连代价,加上 宣告的“到 的代价”。把所有邻居的结果比较后取最小值,就得到新的估计和下一跳。
距离向量是分布式、迭代式和异步的。节点不需要在同一时钟下一起更新;当本地链路代价变化,或收到邻居的新向量并导致自身向量改变时,才需要把新结果发给邻居。只要链路代价稳定且消息持续传递,各节点的估计会收敛到最小代价。
例如, 有两个邻居 和 ,直连代价分别为 2 和 5。 宣告自己到目的地 的代价是 3, 宣告的代价是 1。那么 会比较经 的 与经 的 ,选 为下一跳。注意, 不知道 到 究竟经过哪些中间节点,它信任邻居提供的距离估计。这种局部知识降低了单节点的拓扑存储需求,也是过期信息容易形成环路的根源。
若一条链路代价降低,相邻节点很快就能宣告更小的距离,这个“好消息”会向外扩散。若链路代价大幅上升或目的地失效,相邻节点可能互相把对方的过期通告当成备选路径。它们在小环路里不断增加距离估计,直到认清目的地不可达,这就是计数到无穷问题。
毒性逆转可减少两节点环路。如果 到目的地 的路径要经过 ,那么 向 通告到 的距离时,故意报为无穷大。这样 就不会反过来选 去往 。它不能阻止所有多节点环路,因此实际协议还会结合最大度量、触发更新和超时机制。

互联网不会让所有路由器在同一个平面上运行同一套路由算法。它先按管理边界划分成自治系统(AS)。一个 AS 内的路由器在同一管理机构控制下,具有共同的域内路由政策。OSPF 是基于链路状态的域内路由协议。
OSPF 路由器向 AS 内的其他路由器洪泛链路状通告。通告不只在链路变化时发送,也会周期性刷新。每台路由器用收到的通告构建一致的链路状态数据库,再以自己为根运行 Dijkstra 算法,从最短路径树推导转发表。
OSPF 通告直接封装在 IP 数据报中,而不是使用 TCP 或 UDP 承载。协议并不依赖应用层的可靠传输,而是自己定义消息交换和数据库同步机制。
新邻居建立关系时,双方先用 Hello 消息发现对方并确认参数兼容,然后交换数据库摘要,请求自己缺少或过期的通告,最后对收到的链路状态更新进行确认。这个过程的目标不是让两台路由器交换完整转发表,而是让它们的链路状态数据库达到同步。
OSPF 支持为链路设置代价,因而可以用代价引导流量。当多条路径代价相同时,可以使用等代价多路径。协议还支持身份验证,以减少伪造路由信息被接受的风险。

若整个 AS 只有一个洪泛范围,设备和链路越多,每台路由器要存储的状态和执行的计算就越多。层次化 OSPF 把 AS 划分为多个区域,并使用一个主干区域连接它们。
区域内路由器只需要掌握本区域的详细拓扑。区域边界路由器连接区域与主干,将到区域内网络的距离摘要告诉主干。主干再把区域间可达性送到其他边界路由器。去往另一区域的数据报,先到本区域边界,再经主干到目标区域边界,最后在目标区域内转发。
不要把“所有路由器都有链路状态数据库”理解为 OSPF 是集中式协议。在每个区域内,数据库是通过分布式洪泛形成的,并且每台路由器独立运行最短路算法。
BGP 的目的地不是一台具体主机,而是 IP 前缀,例如 138.16.68.0/22。它完成两件事:一是让路由器知道某个前缀通过哪些 AS 可达;二是让每个 AS 按自己的政策选择路由,并把选中的可达性传播给合适的邻居。
不同 AS 的网关路由器之间建立 eBGP 会话,同一 AS 内的 BGP 路由器之间建立 iBGP 会话。两者都通过 TCP 连接交换 BGP 消息,端口为 179。TCP 提供可靠字节流,BGP 自己则维护会话、通告前缀属性和撤销失效路由。
假设前缀 起源于 AS3。AS3 的网关通过 eBGP 告诉 AS2 的网关“ 可经 AS3 到达”。AS2 通过 iBGP 把这条可达性传给内部其他 BGP 路由器。若 AS2 允许把这条路由通告给 AS1,则它会通过 eBGP 发出携带 AS2 AS3 路径的新通告。
AS_PATH 首先有防环作用。路由器收到一条通告时,若发现自己的 AS 号已经在路径中,就拒绝该路由。NEXT_HOP 则把 BGP 选中的域间路径与 OSPF 等域内协议连在一起:内部路由器要先根据域内路由计算出到 NEXT_HOP 的路径。
对同一前缀学到多条路由后,路由器先过滤不符合导入政策的候选,再按顺序缩小集合:
AS_PATH 较短的路由。NEXT_HOP 的域内代价较小的路由,也就是尽快把包送出本 AS 的“热土豆路由”。这个顺序说明 BGP 不是全球最短路协议。一条 AS_PATH 更长的路由,只要本地优先级更高,仍然会胜出。至于某条路由是否能被导入、是否向某个邻居导出,更是明确的政策问题。
热土豆路由特别容易和“全程最短”混淆。假设两条 BGP 候选在前两轮比较后仍打平,一条的出口离当前路由器的 OSPF 代价是 5,另一条是 20。选代价 5 的出口,只表示本 AS 尽快把数据包交给外部网络,它没有比较从出口之后到目的网络的真实延迟或带宽。这种决策减少了本 AS 承担的内部传输成本。

路由政策反映 AS 之间的经济关系。一个客户网络付费让提供商为它连接其余互联网,所以提供商通常会把客户前缀广泛通告出去。两个对等网络愿意交换各自客户的流量,却通常不愿免费替对方承载前往第三方的转运流量。
因此,导出规则不会把所有已知路由无条件地发给所有邻居。这也解释了为什么域间路由不能只用统一链路代价求最短路:每个 AS 拥有独立的管理权和经济目标,并不会公开内部代价。
若多个地理位置都宣告同一 IP 前缀,互联网上的路由器会按各自的 BGP 视图选出一条路由。用户流量因而会被送往路由意义上“更近”的服务站点。这种 IP 任播常用于 DNS 等服务,但路由改变可能让后续数据包转向另一地点,因此对长时间会话需要额外评估。
一个组织要把自己的网络连入互联网,首先需要可全球路由的 IP 前缀,以及与互联网服务提供商的连接。小型网络往往使用提供商分配的地址块,由提供商用更大的聚合前缀对外宣告。需要独立多宿的组织则可能申请独立前缀和 AS 号,与多个提供商建立 BGP 会话。
前缀获得方式会影响可聚合性。来自同一提供商的连续地址块可以合并为一条较短前缀对外通告,减少全球路由表条目。独立多宿网络若要让多个提供商都能到达它,通常需要单独宣告更具体的前缀,这会增加全球路由表规模。
对外通告只是可达性链条的一半。组织内部还要用 OSPF 或静态路由让网关知道前缀对应的真实子网在哪里,并要保证返回路径、过滤规则和入口流量策略相互匹配。
SDN 将数据平面交换机、控制器与网络控制应用拆成可独立演进的组件。它有四个显著特征:转发以流为单位;数据平面与控制平面分离;控制功能位于数据平面交换机之外;决策通过软件应用表达。

控制器是平台,控制应用才表达具体策略。例如,路由应用从状态层读取拓扑,计算最短路后通过 API 把规则交给控制器;控制器再转换为每台交换机可执行的流表修改。
OpenFlow 是一种控制器到交换机的通信协议。控制器可以读取交换机特性和计数器,添加、删除或修改流表项,也可以指示交换机发出某个数据包。交换机可以上报端口状态变化,或把未匹配现有流表项的数据包送给控制器。
OpenFlow 消息可按发起方向理解。控制器主动发出的配置、修改状态和读取状态消息,用于管理设备和流表;交换机主动发出的 packet-in、流表项移除和端口状态消息,用于上报数据包与事件;双方还会使用握手、回显和错误消息建立会话、检测存活和报告异常。
以链路失效后重算路径为例:交换机先上报端口状态,控制器更新链路状态,路由应用收到状态变化通知并计算新路径,控制器最后修改受影响交换机的流表。每个组件只处理自己那层的工作,这是 SDN 可编程性的来源。
控制器失效不能让全网失去控制,所以状态需要复制,实例需要故障转移。复制又带来一致性问题:不同控制器在很短时间内可能看到不同的拓扑版本。系统还要考虑设备与控制器之间的时延、大规模事件的处理速度,以及应用之间规则冲突。
控制平台也不应把上层应用锁定在某一种南向协议上。一个实用控制器可以通过插件同时管理 OpenFlow 交换机、NETCONF 设备和传统协议设备,向上层暴露统一的拓扑与意图接口。OpenDaylight 与 ONOS 这类控制平台展示了这种思路:南向适配多种设备协议,核心层维护抽象网络状态,北向接口供路由和策略应用调用。
IP 本身尽力而为地传送数据报,但主机和路由器还需要一种机制报告“目的不可达”“TTL 已用尽”或“回显请求已收到”。ICMP 就承担这个角色。ICMP 报文封装在 IP 数据报中,包含类型、代码和检验和,差错报告还会携带触发错误的原 IP 首部和部分载荷,便于源主机识别具体流量。
traceroute 如何逐跳显示路径traceroute 发送一组 TTL 从 1 开始递增的探测报文。TTL 为 1 时,第一跳路由器将其减到 0,丢弃数据报并返回 ICMP 超时报文;TTL 为 2 时,第二跳返回超时。以此类推,源主机从返回报文的源地址中得到途经路由器。
以 UDP 探测为例,当数据报终于到达目标主机时,它指向一个不会被使用的目的端口,目标因而返回 ICMP 端口不可达。源主机看到这个信号后知道探测已经到达终点。不同实现也可以使用 ICMP 回显或 TCP 探测,但逐步增加 TTL 的原理相同。

ICMP 没有应答不能单独证明目标主机已离线。防火墙可能丢弃 ICMP,路由器可能对差错报文限速,回程路径也可能出现故障。诊断时应把 ICMP 结果与路由表、接口计数器和应用层测试一起解读。
网络管理不只是“看设备是否在线”。一套完整的管理系统包含管理服务器、被管设备、设备数据、设备上的管理代理和管理协议。管理员通过管理服务器发起读取或修改,代理把通用协议操作转换成设备本地动作,并返回结果或主动发出通知。
设备数据可以分为三类。配置数据表示期望设备如何运行,如接口地址和路由政策;运行状态表示当前结果,如邻居表和已选路由;运行统计是随时间累积的计数器,如入站字节数、丢包数和 CRC 错误。故障定位时,三类数据需要相互印证。
SNMP 使用管理器-代理模型。管理器可以发送请求读取或修改被管对象,代理返回响应;代理也可以在链路下线等异常发生时主动发送 Trap 通知。请求-响应适合查询当前值,Trap 则减少了只靠周期轮询才发现紧急事件的延迟。
GetRequest 用已知 OID 读取对象,GetNextRequest 按 MIB 树的次序读取下一个对象,因而可用于遍历表格;GetBulkRequest 能在一次交互中读取更多连续对象;SetRequest 尝试修改可写对象;Response 携带查询结果或错误状态。异步 Trap 本身不像请求-响应那样依赖确认,所以告警系统仍需结合主动轮询确认最终状态。
MIB 是被管对象的结构化集合。每个对象有唯一的 OID,对象名称、类型和语义由数据定义模块规定。例如接口表中可以有管理状态、操作状态、入出字节数和错误计数。管理系统不是在屏幕上读取一段不确定格式的 CLI 文字,而是通过 OID 定位具有明确类型的对象。
SMI(管理信息结构)规定 MIB 对象如何命名、使用哪些基本数据类型,以及如何将对象组织成模块。SMI 定义规则,MIB 模块按规则声明具体对象,SNMP 则在网络上读写这些对象实例。把三者区分开,就不会把“数据定义”与“传输操作”混为一谈。
SNMP 通常使用 UDP。管理器需要处理超时和重试,并避免在大量设备上同时发起过密轮询。早期版本使用社区字符串,安全性较弱;SNMPv3 可提供身份验证、完整性与加密,生产环境应配合管理网隔离和最小权限使用。
NETCONF 是网络配置协议。它在安全传输上交换结构化 RPC,能读取配置,也能针对配置数据库执行编辑、锁定、解锁、提交和丢弃变更。与逐条发送 CLI 命令相比,这些操作能更明确地表达候选配置、原子提交和失败回滚。
NETCONF 会话开始时,管理器与设备先通过 hello 交换能力,确认支持的数据库和扩展。running 表示当前生效配置,支持 candidate 的设备可以先把变更写入候选库,验证后再一次提交。对目标数据库执行锁定,可阻止多个管理会话交错修改同一批配置。设备对每个 RPC 返回 rpc-reply,管理系统因而能把成功与具体错误关联到一次交易。
YANG 不是传输协议,而是数据建模语言。模型定义容器、列表、叶子节点、数据类型、值域与约束,也能描述 RPC 和通知。一个“接口是否启用”字段可以被定义为布尔值,“MTU”可以定义允许范围,同一模型可供配置工具、验证器和设备共同理解。
假设用户反馈某个远程服务突然不可达。粗暴地“重启路由器”会丢失现场,还可能扩大影响。更可靠的方法是沿控制平面与数据平面之间的关系逐步排查。
先界定故障范围。用多个源、多个目的地和不同协议交叉测试,区分是单主机、单前缀、单出口还是整个网络受影响。
再检查数据平面。查看接口是否上线,错误和丢包计数器是否突增,对目标前缀的最长前缀匹配结果是否指向预期下一跳。
接着检查控制平面。在域内确认 OSPF 邻居、链路状态数据库和到出口的路径;在域间确认 BGP 会话、前缀是否收到、属性是否被政策过滤,以及最优路由是否已安装。
用 ping 和 traceroute 补充端到端证据,但不把单次 ICMP 无响应当作最终结论。结合 SNMP 计数器、设备日志和路由协议状态,找出变化最早发生在哪一层。
这条诊断链把本章的机制连起来:路由协议提供可达性,算法和政策决定候选路径,转发表执行结果,ICMP 暴露部分差错,管理协议提供可观测与可审计的变更通道。
从不在 中的节点里选出 最小的 ,把 加入 。因为链路代价非负,此时不会再找到一条绕过其他未确定节点的更低代价路径。
检查 的每个邻居 。若 比当前 更小,就更新 ,并把 改为 。
重复选择和更新,直到所有节点都进入 。沿前驱指针回溯,就能得到源节点到每个目的节点的路径和第一跳。
修复前先验证意图和影响范围。使用 YANG 模型验证结构化配置,通过 NETCONF 在候选配置库中编辑并保留回滚路径,提交后再重新检查状态和数据平面结果。