路由控制实战:route-policy、Filter-Policy、PBR与MQC详解
网络里搞路由控制绕不开这几样东西route-policy、Filter-Policy、PBR、MQC。很多朋友学到这里就犯晕感觉每个技术都差不多好像都能“控制路由”但又说不清到底谁管谁。我刚接触那会儿也是这状态看了不少文档命令也会敲可真到排障和做方案的时候才发现脑子里全是浆糊。后来在项目里被真实场景反复锤了几轮才慢慢把这几样东西的脾气摸清楚。这篇东西我就聊聊这几个技术到底怎么用各自适合什么场景命令怎么敲以及那些文档里不会写明白的坑。内容偏向实际干活的经验适合刚接触路由策略的工程师也适合那些命令会敲但思路还不太清楚的兄弟参考。1. 路由引入一切控制的前提讲策略之前得先把“路由引入”这个源头捋清楚。路由控制不是凭空造路由控制的对象是已经存在于路由表里的东西或者正在从一种协议往另一种协议里“搬运”的路由。这个搬运的过程就叫路由引入。1.1 为什么需要路由引入真实网络里极少存在单协议跑到底的情况。内部跑OSPF和外部对接可能要用BGP或者早期网络用了静态路由后来又上了动态协议。协议之间互相不认识直连和静态路由虽然也在路由表里但OSPF不会自动把它们告诉邻居BGP也不会。这时候就需要路由引入。比如我在某项目里做过一个园区网改造核心和汇聚之间跑OSPF但出口到运营商是两条静态默认路由。为了让内部所有设备都知道“去外网走核心”就得在核心设备上把静态路由引入OSPF。如果不做这一步内部设备只会学到OSPF域内的路由出去就断。路由引入的本质就是在协议边界上做一次“翻译”让一种协议学习到的路由能被另一种协议传递。但这个翻译不是白给的引入的时候路由的“出身”就变了随之而来的就是优先级、开销值这些属性的变化。1.2 引入时的两个经典问题第一个问题是优先级。不同协议对同一条目的信任程度不同华为设备里直连优先级是0静态是60OSPF是10BGP是255。OSPF内部算出来一条路由优先级是10你把静态路由引入OSPF之后这台设备自己路由表里这条路由的优先级可能还是60但传给OSPF邻居之后邻居认为这是一条OSPF路由优先级就变成了10。同一个目的网段如果设备上既有OSPF学的又有静态配的谁优谁劣就可能和你想的不一样。第二个问题是开销值。OSPF引入外部路由默认开销值是1。IS-IS引入外部路由默认开销是0。这就会导致一个现象你辛辛苦苦规划了路径结果因为引入开销值没调所有流量都挤到一条链路上去了。我遇到过最典型的一个场景两台核心设备做双机出口各接一条运营商线路内部跑OSPF。规划是让左边核心带左边的流量右边核心带右边的流量结果两边都把默认路由引入OSPF之后因为开销值一样所有访问外网的流量在汇聚层就被负载分担了来回路径不一致防火墙会话全部乱掉。排了半天最后就是把其中一边引入的默认路由开销值调大让另外一边成为主用。解决这两个问题的标准手法就是在引入的时候挂上route-policy对引入路由的属性做精确控制。这也是为什么绕不开route-policy的原因。2. route-policy路由控制的瑞士军刀route-policy是这几个技术里最灵活、最核心的一个。它干的事情本质上就是“按条件匹配路由按需求修改属性”。你可以把它理解成路由的“安检贴标签”流程符合条件的路由放行并且贴上指定的属性标签不符合条件的可以选择拒绝也可以选择放行但什么都不改。2.1 核心结构if-match和apply一条route-policy由若干个节点node组成每个节点里有if-match子句和apply子句。if-match负责“匹配什么”。它能匹配的东西很多ACL、前缀列表、IP前缀、接口、路由类型、开销值、标签、团体属性等等。匹配是路由控制里最关键的一步因为很多策略看似没问题实际排障下来发现是匹配条件写错了路由根本没被选中。apply负责“怎么改”。能改的属性也很多开销值、开销类型、标签、MED、本地优先级、AS路径、下一跳、团体属性等等。节点之间是“或”的关系路由从上往下匹配命中了就执行没命中就继续看下一个节点。节点内部各个if-match之间是“与”的关系必须全部满足才会执行apply。这个逻辑用大白话讲就是一个路口有多条车道节点你开车到路口先看自己符不符合第一条车道的所有条件该车道内的所有if-match符合就走这条道不符合就去下一条车道看。如果所有车道都不符合那就看整个route-policy最后有没有“兜底”的permit节点。2.2 permit和deny的行为细节deny不是简单的“拒绝”。如果一个node是deny而且匹配上了那路由就被丢弃不再往下匹配也不会进入下一个节点。但是要注意如果一个node是deny没有任何if-match那它等于拒绝了所有路由这就是个黑洞一般没人这么写。permit也分两种有apply的和没apply的。有apply的匹配上就执行修改修改完反正也是放行的没apply的匹配上就直接放行不改任何东西。还有一个特别容易踩坑的点如果一条route-policy里所有节点都没匹配上路由的最终结局取决于route-policy的“默认行为”。在华为设备上如果route-policy里最后一个有效节点是deny那没匹配上的路由会被放行还是拒绝答案是拒绝。别问为什么记住就好。华为route-policy的默认终结行为是deny就算你整个route-policy只有一个permit节点路由没匹配上任何节点最终结果依然是“不通过”。所以很多人在配置route-policy的时候习惯在末尾加一条空的permit节点就是没有if-match、没有apply的permit专门用来“放行其他所有路由”。这个习惯很好尤其是在做路由引入过滤的时候不然一不小心就把路由全滤掉了。2.3 配置route-policy的实操示例比如说我现在要把OSPF域内的几条特定路由在引入BGP的时候打上特定的团体属性方便对端根据团体做策略。# 先写一个前缀列表匹配目标网段 ip ip-prefix TARGET permit 10.1.0.0 16 greater-equal 24 less-equal 24 # 再写route-policy匹配前缀列表打团体属性 route-policy SET_COMMUNITY permit node 10 if-match ip-prefix TARGET apply community 100:100 route-policy SET_COMMUNITY permit node 1000node 10负责干活node 1000是“兜底放行”。如果不加node 1000没匹配上的路由全部会被拒掉BGP表里就会莫名其妙少很多路由。这种错误非常隐蔽因为BGP邻居还是能建立对端也不会报错就是路由不全排查起来很费劲。如果要在引入的时候做过滤就直接在协议视图里调用bgp 100 import-route ospf 1 route-policy SET_COMMUNITY引入OSPF路由进BGP的时候只有匹配TARGET前缀列表的路由会被引入并且打上团体属性。这里的核心思路是匹配条件决定了“谁受影响”apply决定了“受什么影响”最后的空permit节点决定了“其他人怎么办”。这三个问题想清楚一条route-policy就写对了。2.4 route-policy的常见使用误区第一个误区把route-policy当成只能过滤的工具。其实它的核心能力是修改属性。过滤只是它顺带能干的活deny节点更多时候我们用它来打属性、改开销、改下一跳。第二个误区if-match ACL和ip-prefix混用。ACL匹配的是“通配掩码”ip-prefix匹配的是“前缀范围”。两者匹配逻辑不一样ACL匹配路由时匹配的是路由的前缀和掩码但掩码的匹配逻辑是通配的容易出偏差。做路由匹配我更推荐用ip-prefix精确、直观、好排查。第三个误区route-policy匹配路由的时候如果匹配条件是ACL要注意ACL的permit/deny和route-policy节点permit/deny的关系。其实ACL在这里只负责“匹配”不负责“动作”真正决定“动作”的是route-policy节点的permit/deny。ACL里permit了说明“匹配上了”进入节点逻辑ACL里deny了说明“没匹配上”继续看下个节点。这个逻辑绕得很好多老手都会在这里翻车。3. Filter-Policy轻量级的路由过滤利器route-policy功能强但配置量大如果只是单纯想过滤路由不想改任何属性用Filter-Policy更合适。它就是在路由接收、发布或者本地转发的时候加一道筛子。3.1 三个方向的Filter-PolicyFilter-Policy最容易被搞混的地方就是它作用的方向。方向一对“接收”的路由进行过滤。在接口或协议视图下配置filter-policy import意思是“从邻居收到的路由先过一遍筛子符合要求的才放进路由表”。要注意这只影响本地路由表不影响通告给其他邻居的路由也不影响已经收到的路由在协议内部的存在。OSPF里这个命令在接口视图下配BGP里配合peer做命令位置和作用范围都不一样。方向二对“发布”的路由进行过滤。配置filter-policy export意思是“我要通告给邻居的路由先过一遍筛子”。OSPF里这个命令只在ASBR上配置才有效因为只有ASBR才会产生Type5外部路由。你在普通区域路由器上配filter-policy export想去过滤区域间路由是不生效的。这个坑我踩过当时在ABR上配了export方向的过滤想着把某个网段的路由滤掉不让它传到别的区域结果怎么配都没反应后来查资料才知道OSPF的export过滤只作用于ASBR普通路由器上根本没这个逻辑。方向三对“本地转发”的路由进行过滤。Filter-Policy还可以作用在本地路由表上用filter-policy import配合路由策略可以决定哪些路由能进入本地路由表。这个用法常用于BGP配合peer的add-path或者路由接收控制能实现一些比较精细的选路控制。3.2 Filter-Policy和route-policy怎么选实际项目中我一般遵循几个简单的原则如果只是想简单屏蔽某几条路由用Filter-Policy加前缀列表配置量小逻辑清晰排障也快。如果需要修改路由属性比如调MED、调本地优先级、打团体那必须用route-policy。如果过滤条件复杂比如要基于路由的下一跳、基于路由的标签、基于团体属性来过滤那Filter-Policy就不够用了得上route-policy。这里面还有一层意思Filter-Policy的过滤能力是“有”还是“没有”是二元的route-policy的过滤能力是“改”还是“不改”是属性的。两者不是替代关系是互补关系。3.3 配置示例假设现在OSPF区域里有192.168.10.0/24这个网段我想让它在区域内部正常传递但不想让它被引入到BGP里。那直接在BGP进程下做引入过滤bgp 100 import-route ospf 1 route-policy NO_EXPORT route-policy NO_EXPORT deny node 10 if-match ip-prefix BLOCK route-policy NO_EXPORT permit node 1000 ip ip-prefix BLOCK permit 192.168.10.0 24注意deny节点要先写而且要把需要拒绝的路由精确匹配出来。后面的空permit节点兜底放行其他所有路由。这个思路跟上面医疗团体属性那个例子是一样的只是动作从apply变成了deny。如果只是想在本机路由表里做过滤不让某条OSPF路由出现在本机路由表里ospf 1 filter-policy ip-prefix BLOCK import配完之后本机路由表里就不会有匹配BLOCK前缀列表的路由了但OSPF邻居关系不受影响其他路由器之间的路由传递也不受影响。4. PBR不按路由表出牌的“策略路由”前面聊的route-policy和Filter-Policy控制的核心都是“路由表里有什么”流量最终怎么走还是要看路由表的查表结果。神马意思就是路由表告诉你去哪里你就得去哪里。但很多时候我们需要打破这个规则。比如两条出口链路一条是电信一条是联通。路由表里默认走电信。但我想让访问某个特定网段的流量走联通。路由表里没有这个规则传统的路由控制也做不到因为路由表只是“目的地址→下一跳”的映射不考虑源地址、端口这些信息。PBRPolicy-Based Routing策略路由就是干这个的。4.1 PBR和route-policy的本质区别很多教程会说PBR是“基于策略的路由”route-policy是“基于路由的策略”。听着玄乎我换个说法route-policy是“路由的搬运工”它作用在路由协议之间决定哪些路由被搬、怎么搬、搬的时候贴什么标签。它影响的是路由表。PBR是“流量的交警”它直接作用在报文转发路径上决定某个报文走哪条路。它不影响路由表只影响转发结果。光这一条区别就能解释很多网络现象。比如我配了route-policy想影响报文转发结果发现流量根本不走那条路一查路由表才发现路由是改了但报文查表走的是另一条优先级更高的路由。反过来我配了PBR想控制某段流量走特定出口结果发现路由表还是那样但流量就是按PBR走了因为PBR的优先级高于路由表查询。在华为设备上PBR分为接口下的traffic-filter和全局的local-policy前者作用于转发平面后者作用于本机发起或终结的流量。实际项目里接口PBR更常用。4.2 PBR配置实操举个例子我有一台双出口的设备分别接两条运营商线路。我想让来自192.168.1.0/24网段的流量去访问外网的时候强制走第一条出口的下一跳192.168.1.254。先做流分类匹配源地址acl number 3000 rule 5 permit ip source 192.168.1.0 0.0.0.255再做流行为指定下一跳traffic behavior BELL_NEXT_HOP redirect ip-nexthop 192.168.1.254做流策略把分类和行为绑定traffic policy PBR_TEST classifier C1 behavior BELL_NEXT_HOP最后在接口下应用interface GigabitEthernet0/0/1 traffic-policy PBR_TEST inbound这个比route-policy直观多了匹配的是“报文”动作是“重新指定下一跳”完全绕开路由表。还有一个细节PBR有个隐藏的“默认行为”。如果报文没有匹配上任何流分类那PBR就放行走正常路由表转发。这和route-policy默认deny的套路完全不同。新手配PBR容易搞混总觉得没匹配上的会被丢弃其实不会。4.3 PBR的常见坑坑一PBR只对“转发”流量生效对“本机”流量不一定生效。设备自己发起的报文比如设备去ping、去建立BGP邻居走的是local策略不是接口PBR。想控制本机流量要么配local-policy要么用维护/管理口单独放一条路由。坑二redirect下一跳的时候下一跳必须可达而且不能是“负路由”。否则PBR虽然匹配了报文但下一跳无效报文还是会走原路由表或者直接被丢弃。坑三PBR和NAT的顺序问题。如果出口设备上有NATPBR匹配的是NAT转换之前的报文还是之后的报文这取决于PBR应用的位置和NAT的生效顺序。华为设备上接口inbound方向的PBR匹配的是入向原始报文如果有NAT outbound那PBR执行重定向之后可能还要考虑NAT的转换顺序。这个排障的时候最容易迷糊建议直接在设备上抓包确认。5. MQC模块化QoS命令行不只是限速MQCModular QoS Command-line这个名字听起来和路由控制关系不大毕竟是QoS的东西。但它和PBR用的是同一套框架就是“流分类流行为流策略”三件套。只是PBR的流行为里写的是redirect而MQC的流行为里写的是remark、car、queue这些QoS动作。所以学会PBR之后学MQC基本是零成本。反过来你理解了MQC的框架再回头看PBR也会觉得简单。5.1 MQC的三板斧MQC的核心就三步第一步匹配流量。用ACL、前缀列表、或者基于应用、基于协议等更高级的匹配方式把关注的流量挑出来。第二步定义动作。动作包括重标记remark、限速car、流量整形gts、队列调度queue等等。第三步绑定生效。用流策略把分类和行为绑在一起然后应用在接口、VLAN或者全局。举一个实际例子。公司出口带宽有限领导要求视频会议流量必须优先保障P2P下载必须限速。先匹配视频会议流量。假设这网络里视频会议服务器的IP是10.1.10.10端口是TCP 8000-8100acl number 3001 rule 5 permit tcp destination 10.1.10.10 0.0.0.0 destination-port range 8000 8100再做流分类traffic classifier VIDEO if-match acl 3001定义两个行为一个优先保障一个限速traffic behavior EF remark dscp ef queue ef 低时延 car cir 5000 pir 8000traffic behavior LIMIT car cir 1000 pir 2000绑定traffic policy VIDEO_POLICY classifier VIDEO behavior EF classifier P2P behavior LIMIT应用到接口interface GigabitEthernet0/0/0 traffic-policy VIDEO_POLICY inbound这种方法的好处是同一个策略里可以塞多个分类每个分类配不同的行为互不干扰。QoS的调度策略也能在这个框架下统一管理比早年的“逐命令配置”干净太多了。5.2 MQC和路由控制的关系有人会问MQC是QoS的框架和路由控制有什么关系关系在于两点。第一MQC可以配合策略路由使用。PBR在华为设备上就是用MQC框架实现的traffic classifier、traffic behavior、traffic policy这“三件套”本来就是MQC的一部分。只不过PBR的behavior里写的是redirect而MQC传统的behavior里写的是car和queue。第二MQC的remark动作可以改报文的优先级、DSCP等标记这些标记后续可以被route-policy匹配也可以被其他设备上的QoS策略识别。也就是说你可以在入口设备上通过MQC打标记下一跳设备再基于标记执行路由策略实现跨设备的联动控制。5.3 MQC的配置注意事项注意点一流分类里没有默认匹配所有未匹配流量的“兜底”行为。如果你想对所有其他流量做处理需要单独定义一个分类不写if-match或者用匹配全部的ACL。注意点二car限速支持单桶双桶但实际配置时很多人搞不清cir和pir的关系。cir是保证速率pir是峰值速率。如果只配cir不配pir峰值速率等于cir等于没有突发能力。视频这种有突发特征的流量建议配pir。注意点三MQC和接口上的其他过滤器有先后顺序问题。如果接口上既有traffic-filter又有traffic-policy先执行哪个不同产品形态可能不一样最好用display命令确认实际生效顺序别靠猜。6. 综合实战把四个工具串起来用单独讲每个工具都懂但真实项目里往往要配合着用。我分享一个典型的综合场景大家感受一下这四个东西怎么协同。场景是这样的某公司有两台出口路由器分别接运营商A和运营商B跑BGP。内部跑OSPF。需求有四个内网默认走A出口当A出口链路挂了的时候自动切到B。财务网的流量强制走B出口不管A链路是否健康。内网访问某个特定业务网段的流量需要走A出口并且需要给这个业务打上特定的QoS优先级。所有流量在出口做带宽控制下载类应用限速视频会议优先。这个场景里路由控制和QoS控制全齐活了。先解决需求1和2。默认走A链路挂了切B这其实靠的是BGP选路策略。在BGP路由引入的时候用route-policy给两条出口运营商的默认路由做属性调整route-policy BGP_DEFAULT permit node 10 if-match ip-prefix DEFAULT apply local-preference 200A出口的默认路由local-preference设为200B出口的设为100。这样BGP选路时A出口优先级更高A挂了B的路由自动顶上。解决需求2财务网强制走B出口这个是PBR的活直接匹配财务网源地址重定向到B出口的下一跳。解决需求3访问特定业务网段走A出口并打QoS优先级。这里要在一个入口设备上同时做两件事PBR重定向到A出口MQC重标记DSCP。用MQC框架可以一气呵成traffic classifier BUSINESS if-match acl 3002 traffic behavior BUSINESS_ACTION redirect ip-nexthop 10.1.1.254 remark dscp af41这样一条策略既做了转发路径控制PBR的活又做了优先级标记MQC的活。同一个框架两件事都干了。解决需求4这是纯MQC的活在出口接口上做car限速。这个场景之所以经典是因为四个工具各干各的各自管一层互不干扰。BGP的route-policy管的是“路径怎么选”PBR管的是“报文往哪送”MQC管的是“送的过程中待遇怎么样”Filter-Policy则可以在前面三者都搞不定的时候做最后一道闸门。理顺了这层关系再复杂的策略也不怕了。7. 常见问题与排查经验我把自己在项目里遇到过的、以及帮别人排过的几个典型问题整理一下给各位兄弟做个参考。7.1 问题速查表现象可能原因排查思路路由引入之后邻居收不到路由route-policy默认deny把路由滤掉了检查route-policy末尾有没有空permit节点route-policy匹配不生效if-match条件写错或匹配顺序不对逐条查看route-policy的匹配情况确认节点顺序OSPF过滤区域间路由不生效在非ASBR设备上配了export过滤确认OSPF的export过滤只对ASBR生效流量不按PBR走接口PBR没匹配上报文或下一跳不可达查看流分类命中计数确认下一跳路由存在PBR生效但有时丢弃报文redirect的下一跳设备上没配对应路由检查重定向目标设备的路由表和ARPMQC限速没效果流分类没匹配上或接口方向错误查看分类命中计数确认应用方向是inbound还是outbound修改了MED但不生效对端设备没有开启比较MED的开关确认BGP选路过程里MED比较的条件团体属性打上了对端不识别对端设备没有配置团体属性接收策略检查对端BGP进程是否配置了import-route和团体过滤7.2 排障的核心心法排路由策略类故障我有几条心法仅供参考第一先看“匹配”再看“动作”最后看“生效位置”。匹配没命中后面全是白搭。华为设备上可以直接敲命令看统计display route-policy display traffic classifier statistics看命中计数一眼就能看出策略有没有匹配上。第二分清“路由表”和“转发表”。有些故障看起来像路由策略没生效其实是报文查表走到了一条你没注意的路由上。碰到这种问题直接看设备的FIB表项确认报文实际走的下一跳。第三改策略前先备份当前配置改完之后立刻验证别攒一堆改动一起提交。网络策略出问题通常是叠加出来的一条条验证才能精准定位。第四别迷信命令。同一套命令在不同型号、不同版本上可能有差异。真有奇怪现象优先对照产品的配置手册确认命令的实际行为和限制。8. 写在最后的经验之谈这套东西我一开始学的时候也是硬背命令背完就忘遇到故障还是一脸懵。后来我把重心放在“这个场景要解决什么问题”上反向去查该用哪个工具才慢慢把体系理顺。我的个人习惯是拿到一个新需求先问自己三个问题我要控制的是“路由表里的路由”还是“实际转发的报文”我要做的是“过滤”还是“修改属性”我的策略要作用在“哪个方向、哪个位置”这三个问题想清楚了工具自然就选对了。route-policy管路由属性Filter-Policy管路由过滤PBR管报文转发路径MQC管报文待遇。至于怎么组合那纯粹看业务需求没有固定的“标准答案”。最后再分享一个我自己的小习惯所有route-policy和MQC策略命名尽量带清业务含义比如TO_BGP_LOW_PRIORITY、VIDEO_PRIORITY别用一堆没人看得懂的编号。网络出问题的时候设备上一个清晰易懂的策略名能帮你节省至少半小时的排障时间。