Junos 导出策略:名称不是匹配条件
名为 EXPORT-STATIC 的策略不会按名称选择任何东西。阅读挂载点、有序条件和动作,然后对比实际通告的视图。
有人把一条策略命名为 EXPORT-STATIC,挂载上去,然后纳闷为什么来自 VPN 路由实例的前缀始终到不了远端。名称对选择没有任何影响。策略由定义加上挂载组成,它导出什么由匹配条件、有序条件和调用它的上下文决定。按这个顺序读这三者,谜团通常就收缩为一个从未匹配的条件。
名称只是标签,不是条件
Junos 不解释策略名称。一条按常理该叫静态导出的策略,可能匹配 static 协议,可能匹配某个地址前缀,也可能什么都不匹配并接受途经的一切。标签是创建者写下的文档,它的可信度只等于那个人对意图的记忆。
把出乎意料的导出结果当作读定义的请求,而不是挂载点坏了的证据。读定义,让定义去反驳标签。
先找挂载点,再看条件
定义正确但挂错位置,改变的是另一场交换。确认到底哪个路由实例、协议以及邻居或组在引用这条策略,因为挂在某个 BGP 组下的策略不影响另一个组,而挂在实例上的策略也未必适用于其中的每个协议。Junos 区分这些层级,当意图表达在实例层级时,组层级缺少导出是常见现象。
在阅读任何一个条件之前,先把挂载路径写下来。这类排查有一半到此结束:定义没动,只是导出语句换了位置。在变更日志里记下差异,免得有人把它当错误回滚。
条件按顺序求值,第一个决定即胜出
条件从第一条运行到最后一条,而接受或拒绝的条件是终止性决定。若前面的条件已经决定了路由的命运,后面那条看起来像预期例外的条件根本不会执行,所以策略从上到下读起来正确,行为却可能与意图相反。拿你关心的路由去核对顺序,而不是拿条件被输入的顺序。
省略动作的条件不会终止,求值继续走向下一条,最终结果取决于后面是什么以及适用的默认值。这确实是有用的构造,而一旦不是有意为之,它也是可靠的意外来源。
一个只导出静态路由的例子,挂载在组上:
policy-options {
policy-statement EXPORT-STATIC {
term statics { from protocol static; then accept; }
}
}
protocols bgp group TO-PEER { export EXPORT-STATIC; }通过 OSPF 学到、而非配置成静态路由的前缀匹配失败并被丢弃,无论策略叫什么名字。
动作改的是副本,不是原始路由
策略动作作用于为该通告求值的那份路由,也就是副本,而不是路由表里的条目。因此本地 show route 可能显示一条带某组属性的路由,而导出后的版本携带另一组属性,导出并不会重写原始路由。这一区别解释了若干争论:双方都正确,只是描述的是不同对象。每当两位工程师对某个路由属性有分歧,先说明你引用的是哪个视图。
接受和拒绝是终止性决定;属性修改则未必。不要以为设置 community 就结束了策略,求值可能继续进入你没有考虑过的条件。
把通告的视图与预期作对比
在真实对端上使用协议专属视图,例如 show route advertising-protocol bgp 192.0.2.1,并在正确的路由实例上下文中阅读。VRF 中存在的路由未必通过了导出策略,而出现在通告输出里的路由也未必被远端接受。这是三个彼此独立的状态,失败方式各不相同。
接受这样的设计:一个前缀必须被通告,另一个必须留在本地。这给策略一份可测试的契约,也避免了另一种改法——不断扩大导出范围,直到某条命名路由终于出现。