相信点开这篇文章的朋友八成都是被BGP那十几条选路规则折磨过的。我在刚接触BGP的时候也是一样拿着文档死记硬背“优先选Weight、然后Local Preference、然后AS路径短……”可一到实际设备上show完路由表就懵了——明明配置了MED为什么流量还是绕远路为什么两条链路带宽差那么多BGP就是不走快的那条后来被一位老工程师点醒BGP选路压根不看带宽和延迟它只看自己手里那一堆“投票属性”。想让它按你的意图走就得学会给这些属性“做手脚”。这篇文章就是我基于一个经典的小实验场景把BGP选路的核心逻辑、调优手段、验证方法从头到尾捋一遍。实验拓扑只有4台路由器但覆盖了选路规则里最常用、也最容易出错的几种手段Preferred Value、Local Preference、AS_PATH加长、MED。我会把每条规则背后的“为什么”讲清楚给出完整的华为VRP配置片段和验证命令还附上我实测踩过的坑。适合正在学BGP的、备考认证的、或者准备面试前突击选路知识的朋友看完你至少能独立搭一个选路实验并且面对“为什么路由不走我预期路径”这类问题时知道往哪个方向排查。1. BGP选路到底在选什么一张图看懂规则优先级说实话BGP选路规则本身并不难背难的是你在真实环境里把配置和规则对应起来。我建议先别急着敲命令先建立一张“投票表”每一轮投票淘汰一个候选者票数高的留下直到剩下最后一个就是最优路径。这跟选秀节目淘汰赛是一个道理。1.1 从Highest Weight到Router ID完整选路链条以华为设备为例BGP选择最优路由时会依次比较以下属性一旦在某一步分出胜负后续规则不再比较Preferred Value首选值本地设备私有属性只对配置的特定邻居生效数值越大越优先。Local Preference本地优先级AS内传递用于控制流量离开本AS时的出口选择数值越大越优先。本地起源路由网络直连、静态导入等方式产生的BGP路由优先于从对端学习到的路由。AS_PATH长度越短越优先。Origin类型IGPi优于EGPe优于Incomplete?。MED多出口鉴别器数值越小越优先默认只在相邻AS之间比较。路由来源eBGP路由优先于iBGP路由。IGP Metric到达下一跳的IGP开销越小越优先。其他条件包括Router ID大小、对端IP地址等用于打破平局。很多初学者会陷入一个误区以为选路规则是“机器学习的智能判断”。实际上BGP是一个非常“死心眼”的协议它不关心链路带宽、不关心延迟、更不关心链路负载。它只认这些数值属性而且必须在前面所有规则都打平的情况下才进入下一条比较。1.2 两条链路场景里最常被忽略的规则我在实验里设计了一个典型场景存在A、B两条链路都能到达同一个目的地A链路物理带宽100M、B链路10M。从直觉上讲肯定希望流量走A。但如果BGP选路链走到“eBGP优先于iBGP”这一步就已经分出胜负而这条规则只看路由来源根本没给带宽投票的机会那流量就只会傻乎乎地走B。理解这一点极其重要因为它解释了生产环境里一个非常普遍的现象为什么你买了两条运营商线路流量却死活不按你的期望走。不是设备出了问题是BGP根本没有“带宽”这个概念。想让流量按你规划的路径走唯一的办法是改变那些BGP能看懂的属性值这就是我们做选路实验的核心价值。1.3 实验设计思路一个能复现所有核心规则的拓扑回到标题“BGP选路小实验”我设计的拓扑用4台路由器构建两条完全独立的三跳路径。R1上有一个Loopback地址充当业务网段R5是这个网段的最终汇聚点。R1访问R5的Loopback时路径A走R2、路径B走R3两条路径的AS属性不同可调参数位置也不同。为什么要设计两条路径而不是三条因为实验的目标不是堆砌复杂度而是把每条选路规则独立抽出来演示。两条路径足够对比出差异又不用在不同路径排列组合里迷失方向。如果后面还想验证“AS路径完全相同且需要比较Router ID”这种极端场景再临时加一条路径也不迟。2. 实验环境准备用什么设备、怎么搭拓扑选路实验最理想的载体是真实设备但对大多数人来说手里没有那么多硬件模拟器就是最现实的选择。我实验环境用的是eNSP华为网络仿真平台当然你用GNS3、EVE-NG加载思科镜像或者直接拿设备刷机做实验逻辑完全一致区别只在命令风格。2.1 模拟器与版本选择选eNSP的主要原因是我手上这套实验的配置命令是华为VRP风格的而eNSP里预置的AR路由器足够完成BGP配置和选路验证。如果你用的是Cisco设备那对应关系大概是Preferred Value对应Cisco的Weightdisplay bgp routing-table对应show ip bgproute-policy对应route-map逻辑完全一样就是名字和命令格式不同。这类实验用模拟器的好处是随时可以重置配置重新来而且即使配置错了也不会造成生产事故非常适合反复练习和试错。唯一要注意的是eNSP启动设备的时候占资源比较严重建议一台台启动不要一次性把所有设备全开否则老电脑容易卡死。2.2 拓扑与IP规划表拓扑中四台设备角色说明R1源端设备业务网段挂在Loopback0上与R2、R3建立eBGP邻居。R2路径A的中间设备AS 200。R3路径B的中间设备AS 300。R5目的端设备Loopback0作为业务网段与R2、R3建立eBGP邻居。关键点在于R1和R5不能直接建立BGP邻居否则后面的选路实验就失去了意义。通过中间AS转发路由R1收到同一条R5业务网段路由时会分别从R2和R3两个邻居学到路径A和路径B此时BGP选路规则才开始发挥作用。具体规划设备接口IP地址所属AS对端设备R1G0/0/012.1.1.1/24100R2 G0/0/0R1G0/0/113.1.1.1/24100R3 G0/0/0R1Loopback01.1.1.1/32100-R2G0/0/012.1.1.2/24200R1 G0/0/0R2G0/0/125.1.1.2/24200R5 G0/0/0R3G0/0/013.1.1.3/24300R1 G0/0/0R3G0/0/135.1.1.3/24300R5 G0/0/0R5G0/0/025.1.1.5/24500R2 G0/0/0R5G0/0/135.1.1.5/24500R3 G0/0/0R5Loopback05.5.5.5/32500-2.3 基础配置先把底子打好这一步没什么技术含量但容易出错的地方恰恰是最基础的接口地址和AS号。很多新手做实验失败最后发现是IP地址配错了或者AS号看反了。我建议先把接口地址全部配好并验证互通再动BGP的配置不要一上来就想一步到位。R1基础配置system-view sysname R1 interface GigabitEthernet0/0/0 ip address 12.1.1.1 255.255.255.0 undo shutdown interface GigabitEthernet0/0/1 ip address 13.1.1.1 255.255.255.0 undo shutdown interface Loopback0 ip address 1.1.1.1 255.255.255.255R2的基础配置就是把接口地址换成12.1.1.2和25.1.1.2R3换成13.1.1.3和35.1.1.3R5换成25.1.1.5和35.1.1.5再加Loopback0地址5.5.5.5。配置完成后先用ping验证直连链路互通再做BGP邻居建立。2.4 BGP邻居与路由发布配置在R1上建立两条eBGP邻居bgp 100 peer 12.1.1.2 as-number 200 peer 13.1.1.3 as-number 300R5上的配置相对复杂一点它需要和AS 200、AS 300分别建立eBGP邻居同时还要在自己的BGP进程里发布Loopback0网段bgp 500 peer 25.1.1.2 as-number 200 peer 35.1.1.3 as-number 300 network 5.5.5.5 255.255.255.255R2上的配置是桥接R1和R5之间的路由它同时是AS 200的成员与R1、R5分别建立eBGP邻居并且要把从R5学到的5.5.5.5路由传给R1、把从R1学到的1.1.1.1路由传给R5这靠BGP自身的传播机制自动完成不需要额外配置路由引入。R3同样做这个桥接逻辑。邻居状态验证命令display bgp peer正常情况下所有邻居的State应该是Established。这个状态是BGP能够交换路由的前提如果看到Active或者Connect优先检查接口地址、AS号配置和IP连通性。3. 核心实操四种调优手段逐一验证实验环境搭好之后就要进入正题了。我准备在R1上查看BGP路由表观察5.5.5.5这条路由当前选择了哪条路径然后逐一修改选路属性观察路径切换的变化。每做一步实验都要执行验证命令记录切换结果这样才能真正理解规则。3.1 实验初始状态默认选路结果怎么看先做一件事在R1上执行display bgp routing-table 5.5.5.5在没有做任何选路调优的情况下R1收到两条5.5.5.5路由一条来自R2AS 200一条来自R3AS 300。这两条路由的AS_PATH长度完全一致都是500三跳、Origin类型一致、MED默认都为0、都是eBGP路由、下一跳IGP开销也基本相等。走到“Router ID”这一步之前就会分出胜负。实际上华为设备在这里的比较规则会走到对端Router ID最终选出的路径可能看起来是“随机”的但其实背后有确定性的数值比较逻辑。这就是初始状态选出了一个结果但你没做过任何干预它默认就是这么选的。我在实操中发现一个非常实用的验证技巧通过以下命令查看路由的详细属性display bgp routing-table 5.5.5.5 verbose这个命令会告诉你这条路径携带的所有BGP属性值——AS_PATH是什么、Origin是什么、MED是多少、Preferred Value是多少、Local Preference是多少。做完任何调优之后再执行这个命令对比属性值的变化你会非常直观地看到是哪条规则起了作用。3.2 Preferred Value调优只影响单台设备的“死命令”第一个实验需求是让R1只信任来自R2方向的路径也就是强制路径A成为最优。最直接的办法是配置Preferred Value。配置命令bgp 100 peer 12.1.1.2 preferred-value 100这条命令的含义是从邻居12.1.1.2学习到的所有BGP路由Preferred Value都设为100。而默认情况下R1从R3学习到的路由Preferred Value是0。比较选路规则第一条100比0大路径A直接胜出后面的规则连比较的机会都没有。配置完成后验证display bgp routing-table 5.5.5.5可以看到最优路径已经从默认路径切换到下一跳12.1.1.2的路由。我用中文说下对这个属性的理解Preferred Value是本地私有属性它只影响配置了该命令的这台设备不会传递给任何BGP邻居。这就像单位里领导直接拍板“我就用这个人”其他人再不服也没办法。在生产环境里Preferred Value通常用于对特定邻居进行定向调优比如明确指定“从某个上游学来的路由优先级最高”。注意事项做过几次实验后我发现一个坑如果你想让Preferred Value发挥“压倒性”作用数值要拉开差距不要配置1和2这种差值。虽然规则确实是比较数值大小但一旦后面还有其他调优手段叠加差值太小的Preferred Value会掩盖不了其他属性差异排查时反而增加认知负担。实验里直接配100和默认0对比一眼就能看出效果。3.3 Local Preference调优AS内部统一的出口决策第二个实验需求是不仅R1要走路径A整个AS 100内部的所有设备都倾向于从R2方向出去。这就要用到Local Preference。它是AS内传递的属性路由进入AS后打上这个标签发给AS内所有iBGP邻居时都会保留最终影响整个AS的出口选择。配置思路是在R1上对从外部邻居学到的路由应用route-policy设置Local Preference为200而默认值是100。创建route-policyroute-policy LP permit node 10 apply local-preference 200然后在BGP邻居上调用这个策略bgp 100 peer 12.1.1.2 route-policy LP import这里route-policy的生效方向是import方向也就是对从R2这条eBGP邻居收到的路由打上Local Preference标签。验证命令display bgp routing-table 5.5.5.5路径A同样成为最优。但和上个实验不同的是如果AS 100内还有其他iBGP设备这些设备从R1学到这条路由时Local Preference 200会跟着一起传过去在全AS生效。我做实验时会对比一下Preferred Value和Local Preference在实际效果上的差异前者只管本机后者管整个AS。这背后对应真实场景里两种不同的需求——只需要单台设备改变转发行为就用Preferred Value需要整个AS统一出口策略就用Local Preference。注意事项有一类很常见的错误是route-policy的方向搞反。BGP的import和export方向是一个高频坑对从邻居收到的路由做策略要挂在import方向对发给邻居的路由做策略要挂在export方向。我见过不少人把Local Preference的策略挂到export方向结果发现本机选路根本不变折腾半天不知道问题出在哪。想清楚数据流方向再配置能省很多时间。3.4 AS_PATH加长调优让路径“看起来”更远第三个实验需求是让R1默认走路径B通过R3即把路径A“变差”。在不改动其他属性、也不配置Preferred Value和Local Preference的前提下最经典的手段是AS_PATH加长也就是AS路径前缀追加。原理不复杂BGP选路规则里有一条是AS_PATH越短越优先。正常路径A的AS_PATH可能是“500 200”路径B是“500 300”两者长度一样。如果在路径A发布给R1时额外在AS_PATH里追加几个AS号让它的AS_PATH变成“500 200 200 200”长度就变成4比路径B的2长选路时路径B胜出。配置在R2上完成对发给R1的路由应用route-policy使用as-path-loophole和as-path-additive命令追加AS号。华为VRP中用apply as-pathroute-policy AS_PATH permit node 10 apply as-path 200 200 200 additive然后在R2的BGP视图里调用方向是exportbgp 200 peer 12.1.1.1 route-policy AS_PATH export配置完成后在R1上查看display bgp routing-table 5.5.5.5路径B下一跳13.1.1.3已经变成最优。说到AS_PATH加长很多人第一反应是“这样流量会不会绕远”但要注意AS_PATH是BGP在控制平面上的“投票器”它跟数据转发的物理路径是否绕路没有必然关系。AS_PATH加长只是让BGP认为这条路由的AS跳数变多了从而在选路时降低优先级。真正决定数据包走哪条链路的是每台设备上RIB和FIB的最终选路结果。注意事项做AS_PATH加长实验时追加的AS号可以用任意值不要求真实存在因为BGP做AS_PATH环路检测时只检查路径里是否包含自己的AS号其他不认识的AS号不会被拒绝。但千万别追加成自己的AS号那会导致路由被判定为环路而直接丢弃。3.5 MED调优多出口场景下的精细化流量引导第四个实验需求是做了一个更贴近生产场景的假设AS 100和AS 500之间有多条链路我们希望来自R5的流量进入AS 100时优先走某一条链路。这里就用到了MED属性——Multi-Exit Discriminator。MED是一个非传递属性本质上是告诉相邻AS“你从我这边多个入口进来时优先走这个入口。”数值越小越优先。在字面理解上MED和Local Preference刚好是一对一个影响出口选择一个影响入口选择而选路方向可以理解为本地AS内部路由传递给邻居时MED影响邻居的入口选择。配置思路是在R5上对发给R2邻居的路由设置较低MED值比如设置R5发给R2的MED为50发给R3的保持默认0然后对比路径变化。但为了让实验更清晰我会反过来操作把R5发给R2的MED设为100把发给R3的MED保持默认0。这样在R1选路时路径B的MED是0比路径A的MED 100小B胜利。配置命令route-policy MED permit node 10 apply cost 100在R5的BGP视图里应用注意方向是对R2的exportbgp 500 peer 25.1.1.2 route-policy MED export验证命令还是那句display bgp routing-table 5.5.5.5你会发现R1上连AS_PATH都不用改路径A的MED被调大后路径B已经成为最优。这演示了一个经典结论MED是BGP在相邻AS之间协调入口流量最常用的属性。但这里有一个老生常谈的坑MED只在相邻AS之间比较如果中间隔着多个AS默认不会跨AS比较。也就是说AS 100从AS 200接收到MED 100、从AS 300接收到MED 0这个比较只在AS 100内部发生AS 200和AS 300内部怎么处理是它们自己的事。华为设备默认也是按这个行为逻辑实现。如果希望跨AS比较需要依靠一些复杂策略但生产环境通常不建议这么干。4. 看完选路再看转发路由表对验证结果的最终落实很多人在模拟器里做完选路实验看到BGP路由表的最优路径已经切换了就很兴奋地认为实验成功了。但这里我要强调一个重要概念BGP最优路径不代表数据转发路径。真正参与数据转发的是全局路由表IP RIB而BGP只是喂给全局路由表的其中一个来源。BGP协议通过路由优先级路由协议preference和开销值决定自己产生的最优路由能否进入全局路由表并最终下发到FIB。4.1 用display ip routing-table确认最终生效路径在R1上查看全局路由表确认5.5.5.5对应的出接口和下一跳display ip routing-table 5.5.5.5如果BGP最优路径已经切换但全局路由表里的下一跳没变那说明有其他优先级更高的路由协议比如静态路由或OSPF在同一条目的前缀上压过了BGP。这也是实验中经常出现“BGP明明选好了但流量不走”的根本原因之一。我在实验中遇到过这种情况为了让BGP邻居互通顺手配了一条默认静态路由结果这条静态路由优先级比BGP高导致不管BGP怎么调优流量都走静态路由让我一度以为BGP选路配置写错了。排查了半天才发现是路由协议优先级在作怪。4.2 用tracert链路验证真实转发路径如果全局路由表里的下一跳已经符合预期可以进一步在R1上执行tracert 5.5.5.5观察第一跳地址是否是你期望的路径。这是最直观的端到端验证手段也是我在实验报告里最喜欢放的数据。它能把你从控制平面看到的结果和实际数据平面的行为对应起来。5. 常见问题与排查技巧实录实验做多了总会遇到一些“常规文档里没人写”的问题。我在这里把最常见的几个整理成速查表每个都是我自己实际遇到过并且花了不少时间才摸清楚的。5.1 邻居状态始终无法Established遇到BGP邻居无法建立先别怀疑配置用这条命令看原因display bgp peer verbose常见原因无非几类接口地址配错、AS号不匹配、直连链路之间有防火墙或ACL拦截、或者模拟器中接口shutdown了忘了undo。还有一个我在eNSP里踩过的特殊坑如果设备版本太老BGP邻居建立需要配置ebgp-max-hop参数才能跨多跳建邻而实验拓扑里全是直连设备正常不需要这个参数但如果有人照着网上跨跳建邻的教程抄了这条命令反而可能导致邻居状态异常。5.2 路由学了但不出现在BGP表有可能是邻居学到了路由但本机因策略或环路检测拒绝了。查看路由是否被接收display bgp routing-table 5.5.5.5如果表里只能看到自己的路由看不到邻居发来的用这条命令检查display bgp routing-table peer 12.1.1.2 received-routes如果received-routes有路由但主表看不见大概率是你路由策略里用filter-policy或route-policy把路由过滤掉了或者AS_PATH环路检测判定路由里包含了本AS号。5.3 调完策略后路径不变这是选路实验里最让人抓狂的问题没有之一。我的排查顺序基本是固定的确认策略有没有正确应用到了对应的邻居和方向。确认策略里的匹配条件是否真的匹配到了目标路由。在route-policy里用if-match子句匹配前缀或AS_PATH时最容易出问题的是匹配条件写得太宽或太窄导致策略根本没有生效。建议先用display route-policy确认策略内容再用display bgp routing-table verbose确认路由属性是否真的被修改。确认最优路径比较是否在更早的规则上已经分出胜负。如果前面有属性差异已经决定了胜负你修改后面的属性当然不会改变结果。关于第3点举个例子如果你已经配置了Preferred Value让路径A胜出然后再去调MED想把路径B拉上来结果大概率是无效的——因为选路规则第一条就已经分出了胜负后面的MED根本轮不到比较。这也是初学者最容易陷入的认知黑洞以为改动任何一个属性就能影响选路结果实际上面向的优先级顺序才是决定因素。5.4 路由震荡与策略冲突实验后期如果你同时配置了多种调优手段可能会出现路径在两条链路之间反复切换的情况这就是路由震荡。原因通常是多个属性之间的差值不足以形成稳定压倒性优势比如两条路径的Local Preference相差很小而AS_PATH长度又不时变化BGP每次收到路由更新都会重新计算最优路径结果就在两条之间摇摆。生产环境里遇到这种情况要格外谨慎因为路由震荡会带来CPU占用飙升和会话抖动。实验里则是很好的反面教材调优属性值要拉开足够大的差距不要用“刚刚好比对方大一点”的策略除非你有意测试边界情况。6. 实验扩展思路从实验室走向生产环境这个BGP选路实验做完之后你已经掌握了这张“选路规则表”里最核心的四个调优开关。但实验终归是实验生产环境里的BGP选路要复杂得多我建议按下面几个方向做扩展每个方向都能把现有实验的复杂度再提升一个量级。6.1 引入iBGP与路由反射器当前实验全部是eBGP直连邻居没有涉及iBGP。但在真实网络中AS内部通常用iBGP传递外部路由这时就会遇到iBGP全互联问题、水平分割问题、路由反射器问题。把R1所在的AS 100内部再加一台反射器你就会看到Local Preference如何在iBGP邻居之间传递以及反射器如何打破iBGP全互联的限制。6.2 叠加路由聚合与Community属性路由聚合会改变AS_PATH和Origin属性影响选路结果尤其是聚合路由丢失了原有的AS路径详细信息可能导致最优路径判断发生变化。Community属性则是一种更高级的路由标记手段可以让你对不同类别的路由批量应用选路策略而不需要逐条写匹配规则。6.3 抓包分析BGP Update报文最后建议你做一个进阶验证在R1和R2之间的链路上开启抓包观察BGP Update报文里携带的路径属性。这是最直观地理解“选路属性到底怎么在网络上传递”的方式。当你看到AS_PATH、MED、Local Preference这些字段实实在在地出现在报文里那些选路规则就不再是抽象的条文了。我在做这个实验的时候有个很深的体会BGP选路规则之所以让人头疼不是因为它难而是因为它和人类直觉不在一个维度上。它不管你的链路好不好、快不快只认属性数值。一旦接受了这个设定一切配置行为都有了明确的指向性——你要做的不过是找到那个合适的属性在合适的位置给它设置合适的数值。希望这篇实验记录能帮你少走一些弯路。如果你在复现实验时遇到了文档里没提到的问题建议优先用display bgp routing-table verbose查看属性差异再对照选路规则表逐条排除大多数问题都能在这个过程里水落石出。