摘要
- BGP 用“可选、可传递”这一类别,让新属性能够穿过尚未实现其语义的旧设备。若不认识属性的路由器接受并继续通告该路径,就必须保留属性并把 Partial 置为 1;后续即使有人认识它,也不得把这个痕迹清零。
- Partial 是一处关于认知不完整的永久标记,不是完整性验证。它不说明是哪一跳不认识、不验证起源、不证明值合法,也不表示沿途网络同意这个属性的政策含义。
- RFC 7606 之后,错误可能通过“丢弃属性”或“将路由视为撤回”来局部处理,会话仍然保持 Established。因此监控必须连接原始属性、处置动作、RIB 变化和真实报文,不能只看邻居状态。
凌晨 2 点 10 分,一家网络运营商在两个受控站点之间试验新的策略属性。发起端已经升级,中间的传输路由器仍运行旧版本,接收端则刚刚装上支持该属性的版本。
第一条 UPDATE 在外层格式上完全正常:标志、类型、长度、值以及一条 IPv4 前缀。中转设备能确定属性从哪里开始、在哪里结束,却没有解释内部值的代码。Optional 与 Transitive 均为 1,于是它接受路径,保留未知属性,把 Partial 置为 1,再向下游发布。
下游设备认识类型,开始执行属性规范规定的校验,随后发现值不合法。它没有重置会话,而是把 UPDATE 中的路由视为撤回。TCP 连接还在,KEEPALIVE 仍然到达,中转设备的前缀计数也没有变化;只有依赖这条路径的客户流量断了。
这是一个合成场景,但权限边界真实存在。BGP 有意允许“未来的信息”穿过从未听说过它的路由器,否则任何扩展都可能要求全网同步升级。代价是:一个设备可能合规地保管自己无法验证的语义,而一次普通升级会把原先不透明的对象变成可解析、可拒绝的对象。
四个位,承诺的是四件不同的事
Path Attribute 的标志字节中,最高四个位各有职责。Optional 区分扩展属性与所有实现都必须认识的 well-known 属性;Transitive 决定未知的可选属性是否可以跨 BGP 边界;Partial 说明可选可传递属性中的信息是否不完整;Extended Length 只决定长度字段占一个还是两个字节。低四位保留,发送时为零,接收时忽略。
这四个词不能混用。Well-known 属性必须被认识,其 Transitive 位为 1,但 Partial 必须为 0。可选不可传递属性可以在少数支持者之间有意义;不认识它的接收者必须安静忽略,也不能向外转发,Partial 同样为 0。
真正为渐进部署留下空间的是“可选、可传递”。RFC 4271 不期待所有实现认识所有这类属性。携带未知可选可传递属性的路径通常应当被接受;一旦接受并继续通告,未知属性必须随路径一起传递,同时置上 Partial。
这是一份很窄的兼容承诺。路由器承诺保管字节,不承诺理解语义。它知道标志、类型码、长度和不透明的值,却不知道这个值是否经过商业授权、是否来自可信主体、是否满足内部语法,也不知道某个未来解码器会不会因它而改变路由结果。
Extended Length 也不提供更多保证。它只告诉接收者“长度字段本身有多长”,并不证明随后那么多字节符合属性内部的 TLV、计数或取值规则。旧设备能够完好地转发一个外框正确、内部错误的对象,因为它恰恰缺少发现错误的解析器。
Partial 不是信任分数
“Partial”这个名字很容易被读成“损坏”“未经验证”或“低可信”。协议给出的含义更克制,也更不令人安心。
当不认识属性的设备继续传播它时,Partial 被置为 1。后面若有设备认识这个属性,却发现 Partial 已经为 1,就不得清除。若非起源设备在路径中途新附加一个可选可传递属性,也要置上 Partial。它保留的是一个事实:从起源到当前节点,不能假定存在完整、连续的语义保管链。
它不会指出缺少支持的是哪个 AS,不记录每一跳认识或不认识的时间顺序,也不说明允许修改的中间节点是否真的改过值。它不证明发起者有权附加属性,更无法说明 route server、联盟成员或策略引擎看到的是不是同一组字节。
最重要的是,Partial 没有认证能力。它只是 UPDATE 内部的一个位,继承整条 BGP 会话与运营链的信任边界,不能替代起源验证、关系策略、传输保护、配置来源或报文证据。
它的价值正来自“不夸大”。它只承认:这个对象穿过了一个缺乏完整语义所有权的边界。这个事实应触发调查和局部策略,而不是自动信任,也不是一律拒绝。
一次升级会移动“认识”的边界
未知不是类型码的永久属性,而是相对于某个实现、版本、地址族和已启用功能而言。同一组字节,星期二还是不透明对象,星期三升级后就可能进入正式解析器。
属性未知时,设备只需保留它,不检查内部值。属性被认识后,设备会执行专门规范:允许的标志、长度、子结构、语义以及错误处置。一个已经穿越网络数月的值,可能在第一个认识它的节点上触发丢弃属性或 treat-as-withdraw;也可能因为现有节点升级,突然在原地触发相同结果。
这不一定是回归。新版本可能第一次有能力发现真正的格式错误。也不能据此认定中间设备失职,因为它可能完整执行了基础协议。故障来自三件事相遇:非同步部署、不透明传播,以及新激活的语义校验边界。
所以升级验收不能只比较配置和 capability。升级前要盘点携带未知属性的路由,至少保存类型码、标志、长度、值哈希、邻居、AFI/SAFI、受影响 NLRI 与 Partial 状态。升级后要回答:哪些类型从未知变成已知,新校验执行了什么,错误动作是什么,哪些路由因此变化。
没有这份盘点,升级后的路由丢失很容易被笼统归咎于“软件问题”。有了它,运营团队才能区分解析器缺陷、正确拒绝的坏值、过宽的隔离策略,以及违反属性合同的发送者。
缩小损害,不等于没有故障
早期 BGP-4 的错误模型常常因一个畸形属性重置整个会话,连同该会话上所有无关的正常路由一起删除。可选可传递属性尤其棘手:不认识它的路由器可能把未经语义检查的值扇出给大量下游,而真正认识它的设备才会出错。
RFC 7606 将许多故障收缩为三种相关动作。Session reset 仍是最强动作。Treat-as-withdraw 把错误 UPDATE 中的路由当作已经撤回,从 Adj-RIB-In 删除,但保留会话。Attribute discard 则删除出错属性,继续处理 UPDATE。
三者不是简单的风险等级。丢弃属性可能比撤回更隐蔽:可达性还在,但本来影响选路或安装的信息消失了。RFC 7606 因而限定,只有不会影响路由选择或安装的属性才应使用 discard,除非属性规范经过充分分析后另有规定。
Treat-as-withdraw 把语义失败表现为路由消失,却可能躲过传统监控。邻居仍为 Established,Hold Timer 没有超时,KEEPALIVE 正常;这些都无法说明某条 NLRI 是否还在。会话图可以全绿,客户前缀却已经不见。
标志冲突也必须单独处理。已知属性的 Optional 或 Transitive 与其规范矛盾时,RFC 7606 一般要求 treat-as-withdraw,除非该属性规范指定其他动作。重复的 MP_REACH_NLRI 或 MP_UNREACH_NLRI 会让该 UPDATE 中的全部路由按撤回处理,同时保留会话;其他属性重复时,通常保留第一次、丢弃后续实例。若一个 UPDATE 同时包含多种错误,就采用其中最强的动作。
因此,“设备支持 RFC 7606”不是完整控制。真正需要的是本次错误分类、属性专属规则和最终路由集合。实现可以完全合规地保住会话,同时造成严重业务中断。
本地网络仍然拥有隔离权
基础传播规则服务于可扩展性,却不意味着未知属性可以无条件穿越运营商的每一道生产边界。网络可以在确认来源、资源成本和下游影响之前,限制某些未知类型的传播。
Juniper 当前文档给出两种后果完全不同的控制:可以删除未知可选可传递属性但保留路由,也可以撤回携带此类属性的路由;还可以按类型码设置例外,并在全局、组或单邻居范围应用。相应的邻居输出能够读回哪些属性被丢弃、哪些属性导致路由撤回。
这些是实现特有的本地控制,不是通用 BGP 法则,更不能当作“一键加固”。删除属性可能让报文继续走,却抹掉下游服务依赖的语义;对所有陌生类型一律撤回路由,会把本可渐进的部署变成可达性事故;例外太宽,则重新打开原来的暴露面。
正确的问题不是“允不允许未知属性”,而是“哪个类型码,可以在什么关系、什么 AFI/SAFI 下穿越,在获得什么证据后通过,出现不确定性时采取什么动作”。客户、route server、内部 reflector、对等互联和受控试验可以有不同答案。
Cisco NX-OS 文档展示了需要的证据粒度:不仅能列出带未知或已丢弃属性的前缀,还能在单条路由上显示原始 flag、type、length 与 value。一个“发现未知属性”的总计数没有这种能力,它无法区分一个良性的试验类型与附着在几十万条路由上的异常对象。
传播是保管,不是同意
不认识属性的路由器保留并传播它,并不等于认可属性语义。它只是履行了协议对信息的传递合同。把两件事混为一谈,会制造错误的商业和安全结论。
假设属性表达某种服务等级。一个不认识它的 transit AS,不能被推定为已经执行服务承诺、验证客户资格或接受相关责任。Partial 不会把“代为携带”变成“同意条款”。下游网络仍按自己的合同和策略作决定。
安全结论也一样。未知数据不一定恶意,已经分配 IANA 类型码的数据也不一定安全。注册表给对象稳定身份,却不证明每个发送者遵循定义规范,也不证明每个解析器没有资源、边界检查或逻辑缺陷。
数据主权在这个细小层面同样实际存在。网络即使不理解字节的私有含义,仍决定它们是否进入日志、是否跨租户、是否离开域、是否触发路由动作,以及是否保留给事故调查。不透明不等于无主。
保管记录应保存接收和发送字节的哈希,而不是只保留 CLI 渲染文本。某些界面会规范化标志、缩写值,或在摘要视图中完全省略属性。原始 UPDATE 的捕获与 pre-policy、post-policy Adj-RIB 视图结合,才能证明本地系统是保留、修改还是移除了对象。
Canary 必须让“不理解”变得可观察
不要在公网路由表里随意发明一个类型码来测试。试验应位于实验室、受控双边环境,或严格遵循真实扩展规定的分配和程序。Canary 应尽量朴素:一对邻居、极少前缀、已知类型码、可逆策略,以及独立的数据面探测。
保存四个阶段。第一,起始 UPDATE 的精确标志、类型、长度、值与 NLRI。第二,不认识属性的中间跳:收到的字节、前后的 Partial、是否接受路径、再次通告的字节。第三,认识属性的节点:解析器版本、校验结果、错误动作与 Adj-RIB-In 结果。第四,数据面:所选路由、FIB 下一跳与探测是否成功。
至少准备三种值。合法属性应穿越并产生规范定义的效果;外框正确但语义错误的值,应触发属性规定的错误动作;未知且不可传递的对照属性,应被忽略并停在中间设备。这样才能证明试验观察到的是分类规则,而不是简单的“有没有这个属性”。
然后改变时间:升级原先不认识类型的中间设备,用同一条 UPDATE 重试。结果可能合理地发生变化。这才是生产前最重要的排练——认识能力移动了校验边界,运营合同也必须一起移动。
回滚需要两把互相独立的钥匙。一把在发送端删除或修正属性;另一把在接收端或边界隔离该类型,同时不重置无关会话。若任何一把钥匙都依赖紧急发布代码,试验就还没准备好。
“运行代码优先”在这里非常具体。标准提供扩展机制,真实部署链决定字节是否存活、路由是否可用。证据不是一句“可选可传递属性会传播”,而是捕获到的 UPDATE、不可逆地置上的 Partial、本地实际错误动作、RIB 结果和最终送达的报文。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
