4. Junos路由策略语言基础

Junos 的路由策略不是“在协议里随手加几个过滤条件”,而是一门独立的策略语言。它由 policy-statement 组织,内部用 term 划分判断分支,每个 term 又由 from 匹配条件和 then 执行动作组成。理解这套结构,是后续做 BGP 路由过滤、属性修改和流量工程的前提。

policy-statement 的整体结构

一条策略语句的基本骨架如下:

policy-options {
    policy-statement PS-EXAMPLE {
        term T1 {
            from {
                protocol bgp;
                neighbor 192.0.2.1;
                route-filter 10.10.0.0/16 exact;
            }
            then {
                local-preference 200;
                community add NO-EXPORT;
                accept;
            }
        }
        term T2 {
            from {
                protocol bgp;
            }
            then reject;
        }
    }
}

这里 policy-statement 是策略的名字,term 是内部按顺序排列的判断分支,from 描述“什么样的路由会被这个 term 命中”,then 描述“命中后做什么”。一个 policy-statement 可以包含多个 term,Junos 会从上到下依次评估,一旦某个 term 的 from 条件全部满足,就执行该 term 的 then 动作;如果 then 中没有 accept 或 reject,则继续向下评估后续 term。

from 匹配条件

from 是策略的“入口条件”,常见匹配对象包括:

  • 协议与邻居:protocol bgp、neighbor 192.0.2.1,用于限定路由来源。
  • 前缀:route-filter 10.10.0.0/16 exact,支持 exact、orlonger、longer、upto /24 等匹配方式。
  • AS_PATH:as-path AS-PATH-NAME,配合正则表达式匹配 AS 号序列。
  • 社区:community COMMUNITY-NAME,可匹配标准社区、扩展社区或大社区。
  • 其他属性:local-preference、metric、next-hop、interface 等。

多个 from 条件之间是“与”关系,必须同时满足才会命中该 term。例如同时写 protocol bgp 和 neighbor 192.0.2.1,表示只匹配来自该邻居的 BGP 路由。

then 动作

then 决定命中后的处理方式,常见动作分为三类:

  • 终止类:accept 接受路由,reject 拒绝路由并返回通知,discard 静默丢弃。
  • 属性修改类:local-preference 200、metric 50、community add NO-EXPORT、as-path prepend 65001 65001。
  • 跳转类:next term 继续下一个 term,next policy 跳到下一条策略。

需要特别注意:如果 then 中只写了属性修改而没有 accept/reject,Junos 会继续评估后续 term。因此通常会在最后一个 term 中显式写 then reject,形成“默认拒绝”的兜底逻辑。

策略链与 apply-path

多条 policy-statement 可以组成策略链,通过 import 或 export 按顺序引用:

protocols bgp {
    group EBGP {
        import [ PS-FILTER-BOGON PS-SET-LP PS-ACCEPT ];
        export [ PS-EXPORT-OWN ];
    }
}

策略链按列表顺序执行,前一条策略的结果会影响后一条。如果某条策略中执行了 accept/reject,链就终止;如果只是修改属性而没有终止动作,则继续执行下一条策略。

apply-path 是 Junos 中一个非常实用的“动态引用”机制。它可以从配置中自动提取一组对象,而不需要手工维护列表。例如:

apply-path "protocols bgp group <*> neighbor <*>"

这条语句会自动收集所有 BGP group 下配置的 neighbor 地址,生成一个动态列表。当新增或删除邻居时,引用该列表的策略会自动更新,避免手工同步遗漏。

正则表达式匹配 AS_PATH 与社区

AS_PATH 正则表达式是 BGP 策略中最常用的匹配手段之一。Junos 使用 as-path 定义正则表达式,常用符号包括:

  • ^ 表示 AS_PATH 开头,$ 表示结尾。
  • . 匹配任意单个 AS 号,.* 匹配任意长度序列。
  • () 分组,| 表示“或”。
  • {m,n} 表示重复次数范围。

例如,匹配“从 AS 65001 始发、且 AS_PATH 中只包含 65001”的路由:

as-path AS-ORIGIN-65001 "^65001$";

匹配“经过 65001 且后面还有任意 AS”的路由:

as-path AS-TRANSIT-65001 "^65001 .*";

匹配“AS_PATH 中出现 65001 两次以上”的路由:

as-path AS-LOOP-65001 "65001{2,}";

社区匹配则通常配合 community 定义和 from community 使用。标准社区格式为 AS:VALUE,例如 65001:100。可以定义社区列表:

community NO-EXPORT members 65001:100;
community FROM-CUSTOMER members [ 65001:200 65001:201 ];

然后在 from 中引用:from community FROM-CUSTOMER。对于大社区,Junos 支持 large-community,格式为 AS:VALUE1:VALUE2,匹配方式与标准社区类似。

实践提示:在写 AS_PATH 正则时,建议先用 show route receive-protocol bgp <neighbor> detail 观察实际 AS_PATH,再根据观察结果编写正则,避免凭记忆写出错误表达式。正则表达式中的空格在 Junos 中表示 AS 号分隔,不能随意省略。

策略评估流程可视化

下面这张图展示了从 BGP 路由进入策略链,到最终 accept/reject 的完整判断路径,包括 term 顺序、from 条件匹配、then 动作执行以及策略链的衔接关系。

Junos 策略评估流程:policy-statement → term → from/then → 策略链 BGP 路由进入 import / export 策略链 策略链(按列表顺序执行) policy-statement PS-FILTER-BOGON term T1 from: protocol bgp route-filter 10.0.0.0/8 orlonger term T2 from: as-path AS-BOGON then: reject term T3 from: protocol bgp then: accept policy-statement PS-SET-LP term T1 from: community CUST then: local-pref 200 term T2 from: community PEER then: local-pref 100 term T3 then: next policy (不终止,继续) policy-statement PS-ACCEPT term T1 from: protocol bgp then: accept term T2 then: reject (默认拒绝兜底) 最终结果 accept / reject 图例 from 匹配条件 then 属性修改 终止动作 accept/reject next policy 继续

图中可以看到,策略链中的每条 policy-statement 按顺序执行,term 内部按 from 条件匹配、then 动作执行。PS-FILTER-BOGON 负责过滤 bogus 前缀和 AS_PATH,PS-SET-LP 负责根据社区设置 local-preference,PS-ACCEPT 负责最终接受合法 BGP 路由并默认拒绝其余路由。这种“过滤—修改—兜底”的三段式结构,是 Junos 策略链中最常见的组织方式。

常见配置要点与排错思路

在实际配置中,有几个容易出错的点值得注意:

  • term 顺序:Junos 按 term 从上到下匹配,先匹配到的 term 先执行。如果宽泛条件写在前面,后面的精确条件可能永远不会命中。
  • 隐式继续:then 中没有 accept/reject 时,策略会继续向下评估。如果忘记写终止动作,可能导致路由被后续 term 意外处理。
  • 策略链顺序:import/export 列表中的策略按顺序执行,前一条策略的 accept/reject 会终止整个链。
  • 正则表达式转义:AS_PATH 正则中的 ^、$、.、* 等符号需要按 Junos 语法书写,空格表示 AS 号分隔。
  • apply-path 动态引用:使用 apply-path 时,确保引用的配置路径存在且格式正确,否则生成的列表可能为空。
排错建议:当策略未按预期生效时,先用 show route receive-protocol bgp <neighbor> detail 确认路由的实际属性(AS_PATH、community、local-preference),再用 show policy-options 检查策略定义,最后用 test policy PS-NAME <prefix> 模拟策略执行结果。test policy 命令可以显示路由经过每条策略和每个 term 时的匹配情况,是定位策略问题的首选工具。