Route Selection and Filtering

MikroTik RouterOS 中的路由过滤使用类似脚本的语法来匹配前缀,并基于条件修改路由距离,其属性分为只读和可读/可写两类,供匹配器和动作使用。

路由选择与过滤

路由过滤

过滤语法

路由过滤规则使用类似脚本的语法。以下示例匹配来自子网 192.168.1.0/24 且前缀长度大于 24 的前缀,并将默认距离加 1。如果没有匹配,则将默认距离减 1。

/routing/filter/rule
  add chain=myChain \
  rule="if (dst in 192.168.1.0/24 && dst-len>24) {set distance +1; accept} else {set distance -1; accept}"

一条过滤规则可以由多个匹配器和动作组成:

if ( [matchers] ) { [actions] } else { [actions] }

属性有两种类型:

  • 只读 — 值只读且不能重写的属性。它们只能由匹配器使用。
  • 可读/可写 — 值可读且可写的属性。它们可以由过滤动作和匹配器使用。

仅对于数值属性,可读属性可以通过其他可读属性或使用布尔运算符的常量值进行匹配。

[matchers]:
[prop readable] [bool operator] [prop readable]

[actions]:
[action] [prop writeable] [value]

如果匹配器只有一种可能的操作,则不需要布尔运算符。

不带布尔运算符的示例:

if ( protocol connected ) { accept }

带布尔运算符的示例:

if ( bgp-med < 30 ) { accept }

对于可读标志属性,匹配器不需要布尔运算符或值。

if ( ospf-dn ) { reject }

信息

路由过滤链的默认动作是 reject。

只读属性

PropertyTypeDescription
Numeric properties
dst-len目标前缀长度
bgp-path-lenBGP AS-PATH 的当前长度
bgp-input-local-as前缀被发送到的本地对端的 AS 号
bgp-input-remote-as前缀从其接收的远程对端的 AS 号
bgp-output-local-as将通告该前缀的对端的 AS 号
bgp-output-remote-as该前缀将被通告到的对端的 AS 号
ospf-metric当前 OSPF 度量值
ospf-tag当前 OSPF 标记
rip-metric当前 RIP 度量值
rip-tag当前 RIP 标记
Flag properties
active指示该路由是否为活动路由
bgp-atomic-aggregate
bgp-communities-empty指示 BGP Communities 属性是否为空
bgp-ext-communities-empty指示 BGP Extended Communities 属性是否为空
bgp-large-communities-empty指示 BGP Large Communities 属性是否为空
bgp-network指示该前缀是否源自 BGP networks
ospf-dn指示该 OSPF 路由是否设置了 DN 位。
Prefix properties
dst目标
ospf-fwd当前 OSPF 转发地址
bgp-input-local-addr前缀被发送到的本地对端的 IP 地址
bgp-input-remote-addr前缀从其接收的远程对端的 IP 地址
bgp-output-local-addr将通告该前缀的对端的 IP 地址
bgp-output-remote-addr该前缀将被通告到的对端的 IP 地址
Other Properties
afiipv4 | ipv6 | l2vpn | l2vpn-cisco | vpnv4 | vpnv6该路由的地址族。
bgp-as-pathnumeric_regexpAS path regexp matching
bgp-as-path-slow-legacystring_regexp已弃用。极其缓慢的旧式 AS path 匹配。此参数只应在从旧 ROS v6 配置迁移时作为临时匹配器使用。 Read more>>
chainchain_name
originstring匹配路由的源实例,例如,它可以匹配从特定 OSPF 实例导入的路由:if (origin <instance_name>) {}
ospf-typeext1 | ext2 | inter | intra | nssa1 | nssa2OSPF 路由的类型:ext1 - 带 type1 度量的外部路由(Type 5 LSA)ext2 - 带 type2 度量的外部路由(Type 5 LSA)inter - 区域间路由(Type 3 LSA)intra - 区域内路由(Type 1/2 LSA)nssa1 - 带 type1 度量的 Type 7 LSAnssa2 - 带 type2 度量的 Type 7 LSA
protocolbgp | connected | dhcp | fantasy | modem | ospf | rip | static | slaac | vpn该路由从其导入的协议类型。
rpkiinvalid | unknown | valid | unverified该前缀的 RPKI 验证状态
rtabrouting_table_name该路由从其导入的路由表名称
vrfvrf_name该路由从其导入的 VRF 名称

可写属性

PropertyTypeDescription
Numeric properties
distance路由距离
scope
scope-target目标 scope
bgp-weightBGP WEIGHT 属性
bgp-medBGP MED 属性是路由器本地的。它也会用于 iBGP 对端的输出。
bgp-out-med要发送到远程对端的 BGP MED 属性。应在 eBGP 对端的输出链中使用。
bgp-local-prefBGP LOCALPREF 属性
bgp-igp-metricBGP IGP METRIC
bgp-path-peer-prepend前置最后接收到的远程对端的 ASN。如果该前缀源自本路由器,则此参数在路由器输出上不会做任何事,因为 ASN 尚不存在。 如果在 BGP 输入中用作匹配器,则可以过滤超过一定前置次数的前缀。例如,如果远程对端将其 ASN 前置 5 次,但我们希望最多允许前置 4 次 ASN,那么可以使用:if (bgp-path-peer-prepend > 4) {reject} 此参数还会覆盖从远程对端收到的任何前置,例如,如果远程对端将其 AS 前置 3 次,我们可以通过在 BGP 输入中设置 bgp-path-peer-prepend 1 来移除此前置
bgp-path-prepend前置路由器的 ASN,应在 BGP 输出中使用。
ospf-ext-metricOSPF 外部路由度量值
ospf-ext-tagOSPF 外部路由标记
rip-ext-metricRIP 外部路由度量值
rip-ext-tagRIP 外部路由标记
Flag properties
ospf-ext-dn外部 OSPF 路由的 DN 位
blackholeBlackhole 路由
suppress-hw-offload是否 suppress L3 HW offloading
use-te-nexthop
Other properties
gwipv4/6 addressIPv4/IPv6 地址或接口名称。在 BGP 输出的情况下,可以在以下配置中调整网关:是 BGP reflector且 nexthop-choice 设置为 propagate且不是 eBGP 且未设置 nexthop-choice=force-self。
gw-llipv6 addressipv6 链路本地 nexthop 属性。在 BGP 输出的情况下,可以在以下配置中调整网关:是 BGP reflector且 nexthop-choice 设置为 propagate且不是 eBGP 且未设置 nexthop-choice=force-self。
gw-interfaceinterface_name网关的接口部分。如果需要为 next-hop 附加特定接口,例如(1.2.3.4%ether1),则应使用此参数
gw-checknone | arp | icmp | bfd | bfd-mh
pref-srcipv4/6 address
bgp-originigp | egp | incomplete
ospf-ext-fwdipv4/6 address外部 OSPF 路由的转发地址
ospf-ext-typetype1 | type2OSPF 外部路由类型
commentstring
bgp-communitiesinline_community_set | community_list_nameBGP Communities 属性定义于 RFC 1997。每个 community 的大小为 32 位。
bgp-ext-communitiesinline_ext_community_set | ext_community_list_nameBGP Extended Communities 属性定义于 RFC 4360。RouterOS 会解析 site-of-origin(前缀为 soo:)和 route-target(前缀为 rt:)扩展 community。例如,set bgp-ext-communities rt:1111:2.3.4.5; 可以设置/匹配 64 位十六进制的 RAW 扩展 community 值,例如,set bgp-ext-communities 0x.........;
bgp-large-communitiesinline_large_community_set | large_community_list_nameBGP Large Communities 属性定义于 RFC 8092。适用于包括 32 位 ASN 在内的所有 ASN。每个 community 长度为 12 字节,由 3 部分组成:global_admin:local_part_1:local_part_2。

命令

CommandParamsDescription
accept接受匹配的前缀并停止处理该链。
reject拒绝匹配的前缀并停止处理该链,该前缀将作为 "filtered" 存储在内存中,不会成为被选为最佳路径的候选。
return返回到父链
jumpjump chain_name跳转到指定的链
unsetunset prop_name用于取消设置以下属性的值:pref-src, bgp-med, bgp-out-med, bgp-local-pref
append追加到列表或字符串的末尾。可以追加以下属性值:bgp-communities, bgp-ext-communities, bgp-large-communities, comment
filterdelete 动作的逆操作(删除除指定值之外的所有内容)。可以过滤以下属性的值:bgp-communities, bgp-ext-communities, bgp-large-communities
delete删除指定属性的值。可以删除以下属性的值:bgp-communities, bgp-ext-communities, bgp-large-communities
setprop_writeable value该命令用于为可写属性设置新值。值可以从其他可读且类型匹配的属性中设置。对于数值属性,可以在值前添加 +/-,这会将当前属性值增加或减少给定数量。例如,set bgp-local-pref +1 会将当前 LOCAL_PREF 加一,或者从另一个可读数值属性中提取值,set distance +ospf-ext-metric
rpki-verifyrpki_group_name从指定的 RPKI 组在当前链中启用 RPKI 验证。

运算符

匹配器运算符
OperatorDescriptionExample
&&逻辑 AND 运算符if (dst in 192.168.0.0/16 && dst-len in 16-32) {reject;}
||逻辑 OR 运算符if (dst in 192.168.0.0/16 || dst-len in 16-32) {reject;}
not逻辑 NOT 运算符if (not bgp-network) {reject; }
数值属性运算符
OperatorDescription
in如果值在所提供的数值范围内,则返回 true。数值范围可以按以下格式书写:{int..int}, {int-int}
==如果数值相等,则返回 true
!=如果数值不相等,则返回 true
>如果左侧数值大于右侧数值,则返回 true
<如果左侧数值小于右侧数值,则返回 true
>=如果左侧数值大于或等于右侧数值,则返回 true
<=如果左侧数值小于或等于右侧数值,则返回 true
前缀运算符
OperatorDescription
in如果前缀是所提供网络的子网,则返回 true。如果使用运算符从地址列表中匹配前缀(例如 dst in list_name),则它只会匹配精确的前缀。
!=如果前缀不等于所提供的值,则返回 true
==如果前缀等于所提供的值,则返回 true

信息

地址列表按设计匹配主机地址,这意味着它也会匹配属于地址列表中任何范围的 /32 前缀。从通告中排除 /32 前缀的变通方法是使用 dst-len if (dst in list_name && dst-len < 32) {}

BGP Community 运算符
OperatorDescriptionExample
equal如果所提供的 communities 等于路由的属性值,则返回 true
equal-list如果所提供的 community-list 中的 communities 等于路由的属性值,则返回 true
any如果路由的属性值包含至少一个所提供的 community,则返回 true
any-list如果路由的属性值包含所提供列表中的至少一个 community,则返回 true
includes如果路由的属性值包含指定的 communities,则返回 true
includes-list如果路由的属性值包含指定 communities-list 中的所有 communities,则返回 true
subset如果路由的 community 子集与列表中的 communities 匹配,则返回 true1:1,3:3 will match 1:1,2:2,3:3
subset-list与 subset 相同,但匹配 community 列表中的 communities。
any-regexp与 any 相同,但通过 regexp 匹配
subset-regexp与 subset 相同,但通过 regexp 匹配
字符串运算符
OperatorDescription
find检查所提供的子字符串是否是属性值的一部分
regexp匹配属性值的字符串 regexp

删除 BGP Communities

路由过滤器允许通过使用 delete 命令清除 BGP communities。delete 命令根据 community 类型接受多个参数:

  • communities:
    • wk - 将匹配并移除 well-known communities。
    • other - 将匹配并移除非 well-known 的其他 communities。
    • regexp - 用于匹配应删除的 communities 的 regexp 模式。
    • <community-list name> - 从指定的 community-list 删除 communities。
  • ext-communities:
    • rt - 将匹配并移除 RouteTarget。
    • soo - 将匹配并移除 Site-of-Origin。
    • other - 将匹配并移除不是 RT 或 SOO 的其他 ext communities。
    • regexp - 用于匹配应删除的 ext communities 的 regexp 模式。
    • <community-ext-list name> - 从指定的 community-ext-list 删除 communities。
  • large-communities:
    • all - 移除所有内容。
    • regexp - 用于匹配应删除的 large communities 的 regexp 模式。
    • <community-large-list name> - 从指定的 community-large-list 删除 large communities。

可以指定多种 community 类型,例如从 community-ext 列表中删除所有 SOO、其他类型的 ext communities 和特定的 RT:

/routing/filter/community-ext-list
add list=myRTList communities="rt:1.1.1.1:222"
/routing/filter/rule
add chain=myChain rule="delete bgp-ext-communities soo,other,myRTList;"

AS-PATH Regexp 匹配

AS path 是自治系统号(ASN)的序列。例如,AS path 123 456 789 表示该路由源自 AS 789,并在到达目的地之前经过了 AS 456。要应用路由策略,可通过使用正则表达式(regexp)来匹配 AS path 中特定的 AS 号或 AS 号集合。

处理 AS path 数据有两种常见方式:

  • 将整个 AS path 转换为字符串,让 regexp 在字符串上操作(ROS v6 或 Cisco 风格)。
  • 让 regexp 将每个 AS path 条目作为数字进行操作(ROS v7,Juniper 风格)。

第一种方法按字符匹配。第二种方法按 AS 号匹配。第二种方法比字符串匹配方法更快且使用的资源更少。

这一变化要求管理员使用新的 regexp 策略。来自 RouterOS v6 的旧 regexp 模式不能直接复制粘贴,因为它们可能导致语法错误或意外结果。

以这条基本的 AS path 过滤规则为例:

/routing/filter/rule
add chain=myChain rule="if (bgp-as-path .1234.) {accept}"

此 regexp 模式匹配 AS path 中间任意位置的 ASN 1234。使用旧式字符串匹配方法时,同一模式会匹配任何包含至少六个字符的 ASN 且包含子字符串 1234 的 AS path。等效的旧式模式是 ._1234_.。

例如,旧字符串风格模式 1234[5-9] 会匹配字符串中任意位置的 12345 到 12349。这会产生诸如 12345 3434 和 11 9123467 22 之类的匹配。使用新式匹配器时,同一模式会匹配包含精确 ASN 1234 后跟 5 到 9 的 ASN 的 AS path,例如 1234 7 111 或 111 1234 5 222。它不会匹配 12345 3434。

危险

在不同实现之间复制 regexp 模式可能会产生意外或危险的结果。

不要直接从 ROS v6 或 Cisco 配置中复制 Regex 模式,它们并不直接兼容。在某些场景下,这可能导致意外甚至危险的配置。 信息

AS-Path 参数必须存在,regexp 匹配器才会被应用。这意味着无法使用正则表达式(即 ^$)匹配不存在(空)的 AS-Path。应改用 bgp-path-len。

Regex 测试工具

RouterOS 有一个内置的 regexp 检查工具,可帮助管理员验证 regexp。该工具还支持 num-list 值,因此你可以在将 regexp 应用到路由过滤器之前,针对任何 AS path 对其进行测试。

/routing/filter/num-list/add list=test range=100-1500

/routing/filter/test-as-path-regexp regexp="[[:test:]]5678\$" as-path="1234,5678"

支持的运算符

OperatorDescriptionExampleExample ExplainedExample Matches
^表示路径的开头^1234将匹配以 ASN 1234 开头的 AS-path
$表示路径的结尾1234$将匹配源 ASN 1234 的 AS-path
*所列 ASN 出现零次或多次^1234*$将匹配空 AS-path 或 ASN 1234 可能出现零次或多次的 AS-pathMatch: 1234 1234 1234 1234 Null path No Match: 1234 5678
+所列 ASN 出现一次或多次1234+将匹配 ASN 1234 至少出现一次的 AS-pathMatch: 1234 3 1234 6 No match: 12345 678
?所列 ASN 出现零次或一次^1234? 5678将匹配可能以 ASN 1234 出现一次开头、也可能不这样开头的 AS-path。Match: 5678 1234 5678 No match: 1234 1234 5678 12345 5678
.任一 ASN 出现一次^.$将匹配长度为 1 的任何 AS-path。Match: 12345 45678 No match: 1234 5678
|匹配两侧两个 ASN 之一^(1234|5678)将匹配以 ASN 1234 或 5678 开头的 AS-pathMatch: 1234 5678 1234 5678 No Match: 91011
[ ] [^ ]表示 AS 号的集合,其中列表中必须有一个 AS 号匹配。 在左括号后使用 ^ 可对集合取反。 也可以使用 [[:numset_name:]] 引用预定义的 num-lists,参见 num-list^[1234 5678 1-100]将匹配以 1234 或 5678 开头,或从 1 到 100 范围内开头的 AS-pathMatch: 1234 99 5678 No Match: 101
()要匹配的 regexp 项分组^(1234$|5678)将匹配以 1234 开头和结尾的 AS-path,或以 5678 开头的 AS-pathMatch: 1234 5678 9999 No Match: 1234 5678

警告

不支持重复范围 {}。

Community 和 Num 列表

常用数字列表可以从 /routing/filter/num-list 菜单配置。这些数字列表可以在过滤规则中使用,以简化过滤器设置过程。

以类似的方式,你也可以定义 community、extended community 和 large community 列表。Community 集合可用于匹配、追加和设置。

例如,匹配列表中的 communities 并清除该属性:

/routing/filter/community-list
add communities=111:222 list=myCommunityList

/routing/filter/rule
add chain=myChain rule="if (bgp-communities equal-list myCommunityList) {delete bgp-communities wk,other; accept;}"

路由选择

路由选择规则控制如何从可用的候选路由中选择输出路由。默认情况下,如果未设置任何选择规则,输出会选择最佳路由。

以下路由表显示了两条候选路由和一条最佳路由。默认情况下,当 BGP 选择要发送的路由时,它会选择活动路由。

[admin@4] /routing/route> print where dst-address=1.0.0.0/24
Flags: A - ACTIVE; b, y - COPY
Columns: DST-ADDRESS, GATEWAY, AFI, DISTANCE, SCOPE, TARGET-SCOPE, IMMEDIATE-GW
   DST-ADDRESS  GATEWAY         AFI  DISTANCE  SCOPE  TARGET-SCOPE  IMMEDIATE-GW
 b 1.0.0.0/24   10.155.101.217  ip4        19     40            30  10.155.109.254%ether1
Ab 1.0.0.0/24   10.155.101.232  ip4        20     40            30  10.155.109.254%ether1
 b 1.0.0.0/24   10.155.101.231  ip4        20     40            30  10.155.109.254%ether1

如果你需要对非活动路由给予偏好,请使用选择规则。

RouterOS 中的选择规则从 /routing/filter/select-rule 菜单配置。

选择规则也可以调用路由过滤器,从而通过过滤规则来选择路由。例如,要模拟默认的输出选择,请使用以下规则集:

/routing/filter/rule
add chain=get_active rule="if (active) {accept}"

/routing/filter/select-rule
add chain=my_select_chain do-where=get_active

选择规则也可以用于限制为 BGP Add-path 选取多少条额外路径,例如最多 3 条路径:

/routing/filter/select-rule add chain=select-for-addpath do-take=3

路由过滤向导

由于使用类似脚本的语法编写过滤规则更为复杂,因此引入了路由过滤向导,它可生成具有类似 ROSv6 语法的过滤规则。

快速演示:

[admin@CCR2004_2XS_111] /routing/filter> filter-wizard <tab>
action        dst                   ospf-type         scope-target      set-gw-check                use-te-nexthop
afi           dst-len               protocol          set-bgp-...       set-scope
bgp-...       gateway               routing-table     set-blackhole     set-scope-target
blackhole     jump-target-chain     rpki              set-comment       set-suppress-hw-offload
chain         match-chain           rpki-verify       set-distance      set-use-te-nexthop
distance      ospf-metric           scope             set-gateway       suppress-hw-offload

[admin@CCR2004_2XS_111] /routing/filter> filter-wizard action=accept chain=vpn-in afi=vpnv4 set-bgp-ext-communities=rt:2:2
  result: Filter rule 'if (afi vpnv4) { set bgp-ext-communities rt:2:2; accept; }' added

[admin@CCR2004_2XS_111] /routing/filter> /routing/filter/rule/print
Flags: X - disabled, I - inactive
 0   ;;; added by filter-wizard
     chain=vpn-in rule="if (afi vpnv4) { set bgp-ext-communities rt:2:2; accept; }"

过滤向导会将其规则添加到列表的末尾,并为其添加注释 added by filter-wizard。

当你尝试添加带有不可接受值的过滤器时返回的错误会打印在 CLI 中,并以 route,error 主题记录在系统日志中。

[admin@CCR2004_2XS_111] /routing/filter> filter-wizard action=accept chain=vpn-in afi=vpnv4 match-chain=vpn-in
  result: Error adding 'if (chain vpn-in && afi vpnv4) { accept; }'match with 'vpn-in' creates chain loop (6)

[admin@CCR2004_2XS_111] /routing/filter> /log/print
 2025-05-19 13:05:15 route,error Error adding 'if (chain vpn-in && afi vpnv4) { accept; }'match with 'vpn-in' creates chain loop (6)