表不是一棵树
在真正量过一张表之前,我就写下了绘制 AS 图的三条规则。一张真实的全表把三条全灭了。
Michel Wijnberg
前十二篇都倚仗着同一个优势:在一个自治系统内部,路由器本身就是权威。无论模型怎么说,你都可以 去问设备。就连第三篇里跨 AS 的路径,也仍旧落在我能登录的网络里。 这个系列讲的是这一条不再成立之后会发生什么,因为它谈论的是别人的网络。
一张 BGP 表不是互联网的画像。它是从你所站的位置看出去的互联网画像,而运营者从中得出的几乎 每一个结论,都以没人标注的方式依赖于那个观测位置。四篇文章讲一张真表究竟长什么样,从任何要 构建 AS 视图的人都必须回答的最基本问题开始:
该怎么画?
我在量任何东西之前,就在设计文档里回答过这个问题。三条规则,写得很有把握。三条全错,而它们 错的方式比规则本身更有意思。
我写下的三条规则
Osprey 的 AS 流视图把你自己的 AS 放在中心,其余按距离环绕排布。设计固定了三条性质:
| # | 规则 | 它假设了什么 |
|---|---|---|
| 1 | 观测地平是一个环 | 超过某个距离,图就到头了 |
| 2 | 扇区宽度等于质量份额 | 每个 AS 只有一个前驱,因此圆盘可以干净地划分 |
| 3 | 起源方是叶子 (隐含) | 流量在边缘产生,在中间中转 |
先说一个词,因为它决定了后面怎么读。“前驱”和”父节点”是我的绘制术语,不是 BGP 广播的东西。 AS_PATH 是一个有序序列,它对层级只字未提。我所谓的前驱,是在我真正收到的某条路径上,离观测点 更近一步的那个 AS。这层关系是观察者从观察者的位置构造出来的,而这正是全部论点所在。
承重的是规则 2。如果每个 AS 都恰好通过一个前驱到达你,那么图就是一棵树,而树可以画成宽度代表 体量的嵌套扇区。你见过的每一种 BGP 图的层级化呈现都建立在这个假设上,而且通常并不说明。
然后我量了一张真的。
一张全表说了什么
一张完整的 IPv4 表:1,071,538 条最优路径,路径中任意位置出现的 AS 共 79,168 个, 一个带两条上游的观测点。(起源 AS 更少,78,538 个;这两个数回答的是不同的问题,本系列里两个 都会出现。)与之并列的是 DN42,一个完全独立、小一个数量级的网络。两者都是实测,都跑的同一套 代码。
| 假设 | DN42 | 全表 | 判定 |
|---|---|---|---|
| 每个 AS 一个前驱 | 1,138 中有 258 个是多前驱,最多 29 个 | 79,168 中有 22,371 个(28.3%),最多 202 个前驱 | 假 |
| 边缘质量经最重的父节点到达 | 18.3% 不是 | 17.5% 不是 | 假 |
| 无环 | 41–47 个二元环 | 240 个二元环 | 假 |
| 起源方是叶子 | 192 个中转中有 187 个(97.4%)自身也起源 | 11,186 中有 10,556 个(94.4%) | 假 |
| 路径很短 | 五跳及以上占 0.0% | 38.0%,最长 15 | 概念上错误 |
这两列并不是同一种数字,而这一点很重要。全表是一条我无法重跑的馈送的一张快照;DN42 则是一个活的 网络,我随时可以再查一遍,而 DN42 这一列是它在 2026-08-23 测出来的值。六天之前,同一条查询 给出的是离树 33.7%、二元环 138 个、五跳及以上质量 8.7%。没有任何东西坏掉,也没有一行代码改动: 只是 peer 来了又走,而图的每一项结构性质都随之移动。
其中一部分动得快得多。以四十五秒为间隔连续采样两个小时,二元环的数量在 41 到 47 之间游走, 那一格之所以是一个区间而不是一个数字,原因就在这里。而本文真正倚仗的那三个数字,也就是起源方数量、 离树占比,以及空无一物的外环,在同一批样本里纹丝未动。这正是本系列的论点提前登场,而且不请自来。
请再读一遍第二行,因为对任何以层级方式绘制的东西来说,这一行才是关键。从这个观测点看得见的 AS 中,超过四分之一拥有不止一个前驱,其中一个拥有 202 个。 没有任何扇区边界能容纳那个节点。 这不是一个靠更好的几何就能解决的布局问题;被绘制的那个形状根本不存在。
我为规则 2 写下的缓解办法是”把多父节点放到扇区边界上”。面对散布于整个圆盘的 202 个父节点, 这条指示毫无意义。
每一处失败夺走画面的东西各不相同
多父节点破坏了划分。 树形布局隐含着:顺着一个扇区向内看,就能知道那部分流量从哪来。在一张 有 17.5% 的边缘质量并非经最重父节点到达的图里,扇区讲述的是相对多数,而不是一条路由。不加说明 地画出来,就把多数变成了事实。
“起源方是叶子”破坏了减法。 几乎每个内部节点都起源自己的前缀。如果某种呈现展示了一个中转 AS 的体量,并允许你通过减去子节点的贡献来推断它自身起源的空间,那么它在 94% 的情形下都是错的。 自身起源必须在每一格里都作为独立的一项来画,绝不能由剩余部分隐含推出。
那个环从来就不是距离。 这一条我错在概念而不是数值。对于它给出的每一条路径,BGP 都会给出 完整的 AS_PATH:不存在某个距离之外协议开始截断的说法。路径确实会被缩短,但绝不是因为遥远。 你看不见的东西并不在地平线之外,它是因为某个原因而缺席:
- 它从未被广播给你,
- 你自己的策略拒绝了它,
- 聚合器把它抹进了
AS_SET, - 或者它位于一台透明路由服务器之后,而后者按设计根本不留下 AS_PATH 跳(RFC 7947)。
这些理由没有一个带半径。一个标着”此外皆在此处以远”的环,是一个协议并不支持的几何断言。Osprey 改为绘制在实际观测到的邻接关系之上的跳数距离,图例也正是这么写的,而不是暗示某个下限。
那就是本文所讲的视图,由 DN42 的馈送绘制而成。我在意的是顶部那条带:它把自己正在绘制的这张图的 形状说清楚了,包括任何树都容纳不下的那 18.3% 的质量,而不是任由读者以为这幅画是完整的。
两张图,都叫”AS 拓扑”
把两张并排放好,有意思的不是它们不同,而是它们在哪里不同:
| 性质 | DN42 | 全表 |
|---|---|---|
| 多父节点 AS | 22.7% | 28.3% |
| 不经最重父节点的边缘质量 | 18.3% | 17.5% |
| 自身也起源的中转 | 97.4% | 94.4% |
| 五跳及以上的路径 | 0.0% | 38.0% |
这四行里有三行足够接近,以至于照着其中任何一张调好的模型,放到另一张上看起来也还行。第四行不是 程度之差。在 DN42 上,五跳及以上压根空无一物;在一张真表上,那是远超三分之一的质量。用小网络验证 过的布局,放到大网络上并不是稍微调偏了:它是在一张外环空着的图上通过了验证,然后被交付给一张 外环恰恰住着互联网绝大部分的图。
这比我原本打算立的那个版本更糟,而它与实验网络对 IGP 所立的论点相同,只是往上抬了一层:你无法用 一个无法反驳模型的环境去验证那个模型。三行一致,正是让第四行变得危险的原因。小馈送不会告诉你, 它的哪些性质只是碰巧可以推广。
本系列开篇的那句拒绝
在这个系列画出任何东西之前,有一个推论值得先说清楚。
AS 图中的一条边是路径邻接,绝不是对等互联的断言。 两个 AS 在某条 AS_PATH 中相邻,观测到的 就只有这些。这不代表它们之间有会话,而上面那台透明路由服务器正是原因:它的两个客户彼此毫无关系 却在路径上相邻,因为 RFC 7947 规定该服务器不留下跳。
所以卡片上写的是”路径中的一次邻接,而非经过验证的对等会话”,并且在每一条边上都这么写。
恰好只有 一个地方可以做出更强的断言:触及你自己 AS 的那条边,而且仅当有独立的会话记录予以佐证时。那是 画面中的一圈,而这个断言是由第二个证据来源、而不是由位置来授权的。再往外的一切都是关于路径的 推断,贴上别的标签就等于在别人的网络之间凭空编造关系。
表实际交给我的东西
值得单独列出,因为上面失败的每一条规则,失败的方式都一样。
馈送给了我三样东西:带最优路径的前缀、每条路径上的 AS_PATH,以及它是从哪条会话到达的。观测到的 就只有这些。
本文中其余的一切都是我算出来的。前驱、跳数距离、边质量、离树的份额、某个 AS 是否也起源、乃至 图本身:全都是构造物,都是从一个位置出发做出来的,而只要位置变了,每一个数字都会变。
还有三样东西根本不在 BGP 表里,无论距离远近:
- 两个 AS 之间是否有会话,
- 沿着这一切流动的流量有多少,
- 以及我的上游选择不发给我的那些路径,它们连”被扣下过”的痕迹都不会留下。
我写下的三条规则,每一条都是把关于第二列的断言,打扮成了关于第一列的断言。“每个 AS 有一个父 节点”听起来像观测结果。它是一种绘制方式的性质,而正是测量让这个区别显形。
要点
我写下三条规则,一次测量把三条都反驳了。这是个好结果,而它之所以可得,正因为那些规则具体到 足以出错。
本系列其余部分要讲的更宽泛的主张是:一张 BGP 表是一个视角。它的形状、中心、骨干与地平线, 全都是”馈送从哪来”的产物。任何把这样一张表当作地理来画的工具,都是在只拥有关于一个观测点的 证据时,做出关于互联网的断言。
诚实的版本会画出它观测到的东西,并说明是哪个观测点产生了它。
于是留下了下一篇要谈的问题。一旦你放弃把表画成层级结构,你仍然得决定把什么放在列表最上面, 而这个问题比听上去要难。
下一篇:所有人都用来排序的那根轴,以及为什么互联网上最大的网络并不存在。 最大的 AS 并不存在。