三种 IGP,一张图
192 台路由器、三家运营商、三种路由协议在单一界面上是什么样子
Michel Wijnberg
我有一个实验室。它不是一张图纸,也不是一个模拟器。它是 192 台运行真实协议栈的真实 路由器,我每天都用它来开发 Osprey,因为它能真正反驳我。
这个实验室是刻意设计得不好对付的。它承载着三家彼此毫无共享的运营商:
| 租户 | ASN | IGP | 形态 |
|---|---|---|---|
| Harrier-Broadband | 200 | OSPFv2 和 OSPFv3 | 每种协议 15 个区域,同一批链路上双栈 |
| Kestrel-Dynamics | 100 | EIGRP,IPv4 + IPv6 | 扁平,因为 EIGRP 没有区域 |
| Merlin-Carrier | 300 | IS-IS,多地址族 | 17 个 level-1 区域,位于一个 level-2 骨干之下 |
三种协议,三套地址规划,三个 ASN,三套凭据。任何地方都没有共享的 IGP。这大概是能 扔给一个拓扑工具的最坏情况,而这正是我搭建它的原因。
下面的每一张图都是那个实验室的截图,写这篇文章时实时抓取。没有一张是编造的。
为什么层级先于图像
大多数拓扑工具从一张画布开始,事后再把结构硬拧上去。这种做法一直管用,直到同一台 物理路由器合情合理地同时属于两个不同的答案。在运营商网络里,这是家常便饭。
Osprey 把顺序倒过来。每个对象都挂在一条显式的层级链上:
Network → Autonomous System → Routing Domain → Protocol Instance → Area → Device
这条链不是装饰。它让产品无需猜测就能回答”哪个 OSPF 进程、在哪个 VRF 里、在哪个 AS 下、属于哪个租户”,也正因为如此,一台设备可以在一个实例里是 ABR、在另一个实例里只 是普通的内部路由器,而模型不会因此打结。
注意侧边栏在显示什么:OSPF 1 和 OSPFv3 1 (v6) 是两个独立的协议实例,各自带 着自己的 15 个区域、自己的 LSDB 和自己的 SPF。它们跑在同一批物理链路上。它们没有被 合并成一个一厢情愿的”IGP”抽象,因为它们本来就不是同一样东西。RFC 5340 给了 OSPFv3 自己的 LSDB 和自己的拓扑,一旦两者出现分歧,假装它们相同就会给出错误的答案。
Harrier-Broadband:OSPF,15 个区域,双栈
这是 AS 200,按区域着色:
64 台路由器,151 条链路,30 个区域(OSPFv2 里 15 个,OSPFv3 里 15 个)。中间那团蓝 色是区域 0.0.0.0,也就是骨干区域。挂在它周围的每一簇颜色都是一个非骨干区域,通过自 己的 ABR 连到骨干。
在这个规模上,图还读得动。规模再大五倍就读不动了,所以同一份拓扑可以折叠成它的区域:
每一朵云是一个区域;每一条线是一束跨区域邻接,上面标着数量(4×、8×、2×)。这
才是我真正用来回答”区域 19.5.1.0 与骨干的连接有多脆弱”的视图。这里的答案是”靠四条
链路”,这和旁边那些只有两条链路的区域是完全不同的风险画像。
Merlin-Carrier:IS-IS,而且地址族真的重要
AS 300 跑 IS-IS。物理形态相同,协议模型完全不同:
IS-IS 是很多工具悄悄翻车的地方,因为 IS-IS 不是”换了说法的 OSPF”。一个 IS-IS LSDB 可以同时承载 CLNS、IPv4 和 IPv6 的可达性,而正确的最短路径是按地址族计算的。
所以 Osprey 就按地址族来计算,并且告诉您正在看的是哪一个:
看那张逐跳表。因为地址族是 CLNS,每一跳是用 System ID(0100.6600.8003)和
电路来标识的,而不是用 IPv4 地址,后者在 CLNS 路径里毫无意义。把选择器切到 IPv4 或
IPv6,同一条路径就会用那个地址族真正使用的编址方式重新绘制。
(那张截图同时也承认了 IS-IS 里逐跳建模的一个问题。那是后面一篇文章的主题,我不打算把它埋在这里。)
Kestrel-Dynamics:EIGRP,它根本没有链路状态数据库
然后是 AS 100:
一种颜色。两个”区域”。这不是渲染出错。这是 EIGRP 对自己诚实。
EIGRP 是距离矢量协议,没有可以拼合的链路状态数据库,也没有可以用来着色的区域概念。
那两条条目只不过是 IPv4 和 IPv6 两个实例。EIGRP 确实会通过自己的 Hello 协议建立邻居
邻接,但邻接背后没有可遍历的链路状态数据库,也没有 SPF 可跑:邻居之间交换的是距离矢
量,不是一份同步的地图。所以 Osprey 以只读方式从 CISCO-EIGRP-MIB 读取,并根据每台
路由器对自己邻居的上报来重建邻接图。在这个实验室里,那是 580 条在线的邻居关系。
这个差别一路传导到路径计算,而且看得见:
那条路径上没有”总开销”,而且本来也不会有。EIGRP 的复合度量描述的是一整条路径,不是 单独一跳,所以把每跳开销相加只会得到一个毫无意义的数字。您得到的是每台路由器自己算出 来的、通往目的地的当前计算距离,沿着这条链递减:712704 → 710144 → 658944 → … → 128256。这正是您逐台登录路由器会读到的。(DUAL 的 Feasible Distance 是一个略有不同 的量:自这条路由上次进入 passive 状态以来的最小值,也就是可行性阈值。跳表把两者分开, 而不是拿其中一个当另一个的标签。)
三种协议,三个真正不同的模型,三个正确的答案。而不是一个假装它们相同的抽象。
图像之下:LSDB 本身
画布只是一种呈现。它底下的模型是链路状态数据库,Osprey 让它保持可浏览:
13,382 条 LSA,按类型划分:Router (1)、Network (2)、Summary (3)、ASBR (4)、External (5) 和 NSSA (7)。ABR 和 ASBR 标志是从 LSA 本身推导出来的,而不是靠命名约定。
仔细读标题下面那一行:
13382 LSAs reconstructed (LSAge, SeqNo, Checksum not available)
这些 LSA 是从 SNMP 遍历中重建的,不是通过协议邻接收到的。对 OSPF MIB 做 SNMP 遍历能 拿到 LSA 的内容,但拿不到实时的头部字段。所以 Osprey 显示内容,并直白地说明有三个字 段缺失,而不是画出三列看起来像数据的零。
这是件小事。但它也把整套设计哲学浓缩成了一行,也正是因为它,我才信得过那块屏幕上其余 的 13,382 个数字。
要点
地图不是产品。模型才是。
三家不共享协议、不共享地址规划、不共享 ASN 的运营商同处一个工具之中,没有任何一家被 压平成最小公分母。OSPF 保留它的区域和两份 LSDB,IS-IS 保留它的 level 和地址族,EIGRP 保留它的 DUAL 距离和它彻底不存在的链路状态数据库。
它们真正不同的地方,产品就跟着不同。它无法知道的地方,它就明说。
Osprey 是被动的:路由器上没有 agent,不注入路由,不转发报文。这到底是怎么做到的、 代价是什么,是下一篇文章的内容。