2026/10/17 8:35:44

BGP选路:三台路由器验证Weight、LocalPref、ASPath、MED

BGP选路:三台路由器验证Weight、LocalPref、ASPath、MED 做网络这么多年BGP选路规则我从头到尾背过很多遍Weight、Local Preference、AS Path、MED背得滚瓜烂熟但一碰到现网里“为什么这条流量不走我想让它走的那条链路”的问题还是得搬白板重新捋。真正让我把整套决策链变成肌肉记忆的是一个周末用三台路由器搭出来的BGP选路小实验。实验拓扑小到连交换机都没用就是把三个AS用直连线串起来然后依次调整各个BGP属性观察最优路径的变化。这篇文章就完整复现这套实验适合刚学BGP的、准备认证考试的、以及正在做多线接入选路方案的朋友。照着敲一遍比我单写三千字原理都管用。1. 为什么用三台路由器搭这个BGP选路实验1.1 现实问题出站和入站是两个方向BGP选路这件事平时问得最多的就两类。一类是“我本地访问某个目的网段能不能优先走A出口”这是控制出站流量另一类是“外网用户访问我的业务地址能不能少走某条上游链路”这是控制入站流量。这两种场景对应的BGP属性完全不同而且经常有人把方向搞反。出站方向你自己AS内部的策略就可以说了算常用的是Weight和Local Preference入站方向你说了不算得靠影响对方AS的选路决策常用的是AS Path和MED或者干脆在路由通告上做手脚。想理解这层关系光看文档很难有感觉必须亲手把两条上游链路摆出来看着最优路径在属性改动前后发生切换印象才深刻。1.2 最小拓扑三个AS、三台路由器我搭的实验拓扑如下完全不需要额外设备[R2] AS 200 | | 10.0.12.0/30 | [R1] AS 100 | | 10.0.13.0/30 | [R3] AS 300R1属于AS 100模拟本地网络R2属于AS 200模拟上游一R3属于AS 300模拟上游二。R2和R3各自宣告同一个测试前缀202.100.1.0/24这样R1会从两条EBGP路径里学到同一个网段选路结果可以直接用show ip bgp观察。为什么不把拓扑做得更大因为BGP选路实验的关键不在设备数量而在路径数量。只要R1能从两个不同AS各自收到一条前往同一前缀的路径整套决策链就能完整跑起来。三台路由器是最小复现模型出问题也好排查一眼就能看到哪台设备的哪条配置影响了路由。1.3 基础配置从接口到BGP邻居我用的是类IOS命令行换成其他厂商的设备思路一样命令差异不大。R1的配置如下interface GigabitEthernet0/0/0 ip address 10.0.12.1 255.255.255.252 ! interface GigabitEthernet0/0/1 ip address 10.0.13.1 255.255.255.252 ! router bgp 100 bgp router-id 1.1.1.1 neighbor 10.0.12.2 remote-as 200 neighbor 10.0.13.2 remote-as 300R2这边除了互联接口还需要一个Loopback接口来承载测试前缀interface GigabitEthernet0/0/0 ip address 10.0.12.2 255.255.255.252 ! interface Loopback100 ip address 202.100.1.1 255.255.255.0 ! router bgp 200 bgp router-id 2.2.2.2 neighbor 10.0.12.1 remote-as 100 network 202.100.1.0 mask 255.255.255.0R3和R2基本一样就是把互联地址改成10.0.13.0/30这一侧router-id用3.3.3.3邻居指向10.0.13.1。配置完成后三台设备之间EBGP邻居应该都能起来。这里有个小细节如果模拟器里默认关闭了BGP同步等兼容开关不需要额外处理如果遇到学到的路由不生效优先检查同步开关、路由是否被策略过滤以及接口状态。2. 基线实验不配置任何策略时BGP的默认胜负手2.1 让R1看到两条路由邻居起来后在R1上执行show ip bgp正常情况下会看到202.100.1.0/24有两条路径一条下一跳是10.0.12.2另一条下一跳是10.0.13.2Network Next Hop Metric LocPrf Weight Path * 202.100.1.0/24 10.0.12.2 0 0 200 i * 202.100.1.0/24 10.0.13.2 0 0 300 i标记“*”的就是当前最优路径。这里最优路径是走R2也就是AS 200。很多初学者看到这里就直接背结论“优先选择先收到的路由”。严格说思科系设备在两条EBGP路径各项属性完全相同的情况下确实会先比较“最老EBGP路由”也就是哪条路径先进入BGP表就先保持哪条如果两条差不多同时进来再比Router ID小的优先。所以在我这个实验里因为我是先把R2的邻居配好、再配R3R2这条路径先进入表默认就赢了。这个现象本身值得停一下。BGP的设计哲学是“稳定优先”只要最优路径没有消失哪怕后来进来一条属性完全一样的路径它也不愿意来回切换。这可以避免路由震荡。但代价就是实验里如果不主动做软重置或者清BGP进程光改属性可能看不到预期效果。2.2 默认选路顺序的完整链条先不急着配置策略把BGP完整的选路决策顺序摆在这里后面对照着看就会很清晰优先级比较项备注1Weight 最高优先思科私有属性仅本地有效2Local Preference 最高优先AS内部传递3本地始发路由优先network/aggregate优于重分布4AS Path 最短优先每经过一个AS加长一次5Origin类型IGP优于EGP优于incomplete一般很少用到差异6MED 最低优先跨AS比较在不同厂商实现下有争议7EBGP优于IBGP同一条前缀两种来源时8到下一跳的IGP metric最低需要IGP路由参与9最老EBGP路由优先思科特有为稳定性服务10Router ID最小优先终于轮到它11对端Router ID最小、Cluster List最短等极少数情况才走到这个表基本就是我做实验时的对照清单。后面的每一步改动都会在这个链条上找到一个明确的位置。基线的意义在于先把默认状态摸清知道现在是哪些因素让R2胜出后面每改一个属性就能明确判断到底是谁改变了结果。3. Local Preference实验从出站方向拨动选路3.1 实验设计与配置Local Preference是控制出站方向的常用属性默认值是100只在本地AS内部有意义越大越优先。实验思路很简单在R1上针对来自AS 200方向的这条路由设置一个更高的Local Preference让它赢过AS 300方向。R1上的配置如下ip prefix-list TO_202 permit 202.100.1.0/24 ! route-map PREFER_R2 permit 10 match ip address prefix-list TO_202 set local-preference 200 ! router bgp 100 neighbor 10.0.12.2 route-map PREFER_R2 in这里route-map挂在neighbor 10.0.12.2的in方向意思是“凡是从这个邻居学进来的路由只要匹配到202.100.1.0/24就把Local Preference改成200”。in方向这个细节很关键它影响的是R1自己学到的路由的本地属性而不是发给对方的路由。配置完成后执行软重置让BGP重新评估路径clear ip bgp * soft再show ip bgp会看到两条路径都还在但标记“*”的仍然是10.0.12.2那条而且LocPrf列已经从默认的100变成了200。如果此时把R2的路径手动失效或者把Local Preference撤掉R1就会立刻切到R3那边。这就是出站流量控制的基本玩法。3.2 作用域边界Local Preference只在AS内部有效这里必须强调一个边界Local Preference只在本AS内有意义。你在R1上设置的Local Preference影响的是R1自己的决策如果R1还有IBGP邻居这个属性会随着BGP路由一起传给AS内部的其它路由器从而让整个AS对外出站都保持一致偏好。但R2、R3完全看不到这个值更不可能因为这个值改变它们自己的选路。很多人在这一步开始犯迷糊为什么我改了本地Local Preference外网访问我业务的流量没有变化因为Local Preference根本不控制入站。外网流量怎么进来取决于对方AS的选路决策而不是你本地策略。想控制入站得用后面说的AS Path prepend或者MED。这也是为什么我坚持做分组实验的原因把每一个属性的作用方向亲手验证一遍方向混淆的问题自然就消失了。4. AS Path prepend实验在入站方向逼开某条上游4.1 prepend的配置与预期现在模拟一个入站控制的场景。假设R1的业务前缀也通过R2和R3向外部通告外网用户访问这个前缀时我希望他们尽量少从AS 200这条路径进来因为这条链路质量差。可是外网用户所在AS的选路策略是对方的事我唯一能做的就是把自己通告出去的这条路径“变难看”。AS Path prepend就是在对外通告时故意把AS号重复追加几次让路径长度变长。在R2上对R1方向的出站路由做prependroute-map PREPEND_TO_R1 permit 10 set as-path prepend 200 200 200 ! router bgp 200 neighbor 10.0.12.1 route-map PREPEND_TO_R1 out注意这次route-map是挂在R2的neighbor 10.0.12.1的out方向因为R2要把这条“变胖”的路由发给R1。配置后软重置R2的BGPclear ip bgp * soft回到R1上show ip bgp会看到来自10.0.12.2这条路径的Path列变成了“200 200 200”长度从1变成了3。对照决策顺序表AS Path是第四顺位低于Local Preference现在两条路径都没有额外Local Preference配置的话R1会毫不犹豫地选择AS 300那条路径因为“300”比“200 200 200”短。这就是AS Path prepend影响入站方向的原理你不是控制自己而是通过改变路由属性让上游和邻居的BGP选路算法觉得你这条路径不够优。4.2 一个被Local Preference“压住”的典型场面这个实验最有教学价值的地方在于如果你在做完Local Preference实验后没有撤销R1上的策略直接跑prepend实验你会看到prepend根本不生效R1仍然走10.0.12.2。这不是配置错了而是决策顺序在起作用。Local Preference是第二顺位AS Path是第四顺位只要R1给来自R2的路径设了200的Local Preference哪怕这条路径的AS Path已经长到天上去R1依然会选它。遇到这种情况应该老老实实先撤销上一组实验的策略再验证下一组属性。router bgp 100 no neighbor 10.0.12.2 route-map PREFER_R2 in这个撤配置的动作看起来不起眼但在真实网络里特别重要。很多排障半天都找不到原因就是因为旧策略没清理干净新策略叠加在上面结果完全被旧的属性优先级压制。实验环境里可以随便改动生产环境里这种叠加状态很容易变成“看不见的坑”。5. Weight实验本地路由器的终极优先级5.1 Weight是本地属性不是协议属性思科系设备还有一个本地属性叫Weight默认值是0本地上宣告的路由Weight是32768。它的特点是只在当前路由器上有效不会传给任何BGP邻居而且优先级排在整个决策链的第一位比Local Preference还高。这很容易理解成“本地自嗨属性”。但在多出口场景里它是最快、最粗暴的选路控制手段你不用设计route-map、不用匹配前缀直接给某个邻居的所有路径设一个Weight立刻就能让这个邻居发来的所有路由在本地获得最高优先。用R1做实验给来自R3的邻居设置一个高于默认值的Weightrouter bgp 100 neighbor 10.0.13.2 weight 200执行软重置后show ip bgp应该立刻看到“*”切换到10.0.13.2这条路径。5.2 与Local Preference叠加时谁说了算为了验证Weight的绝对优先级我故意做了一组叠加测试一边保留R1上来自R2的Local Preference 200一边给来自R3的邻居设置Weight 200。结果R1选的是R3而不是R2。因为决策顺序里Weight先比Local Preference再优也只能排在后面。这个实验等于亲手证明了那张决策表的第1行和第2行。很多人背规则的时候知道Weight最高但真正遇到“两条路径一条Weight高但Local Preference低另一条Weight低但Local Preference高”的情况还是会愣一下。做完这个叠加测试之后这个问题在我这里彻底不会再错。Network Next Hop Metric LocPrf Weight Path * 202.100.1.0/24 10.0.13.2 0 200 300 i * 202.100.1.0/24 10.0.12.2 0 200 0 200 i上面这个输出里10.0.13.2这条路径的Weight是200LocPrf是默认10010.0.12.2这条路径的LocPrf是200Weight是0。最终胜出的是Weight更高的后者不对应该说是Weight更高的R3路径。注意看输出里的“*”位置它落在Weight为200的那一行哪怕这一行的LocPrf只是100。这组输出我用文字描述可能容易看混但实验现场一行命令就能让你明白Weight赢在起点。6. MED实验跨AS有争议换同AS双出口才说服自己6.1 为什么三台设备的跨AS MED不太靠谱MED也是影响入站方向常用的属性默认值是0越小越优先。按理说在R2给R1通告的前缀上设置一个大的MED在R3设置一个小的MEDR1就会倾向于从R3走。但这个实验放在三台设备、两个不同AS的拓扑里有个隐藏问题MED的跨AS比较在不同厂商、不同IOS版本下的行为不完全一致。严谨地说BGP标准里MED比较通常是“来自同一个相邻AS的多条路径之间比较”才有明确意义。不同实现下跨AS的MED可能被直接忽略可能需要额外的配置开关也可能通过扩展团体属性传递。做实验如果在这个地方卡住不是你的配置错了而是场景本身选得不严谨。所以在基础三设备拓扑里我建议不要用跨AS MED作为结论性实验。想验证MED应该换一个更严谨的拓扑让R1从同一个AS的两个不同边界路由器分别学到同一条前缀。6.2 同AS双出口扩展实验让MED真正说话扩展拓扑只需要在R2和R3之间加一条链路并让他们同属AS 200同时都向R1建立EBGP邻居[R2]---------[R3] | \ / | | \ / | | \ / | [R1] AS 200 | | | ------------这里我画得比较抽象意思就是把原来的R2、R3从两个独立AS改成同一个AS 200的双出口R2和R3之间跑IBGP保证AS内部路由视图一致。此时R1到202.100.1.0/24的两条路径AS Path完全相同都是从AS 200学到的MED就比较即可生效。在R2上设置route-map SET_MED_50 permit 10 set med 50 ! router bgp 200 neighbor 10.0.12.1 route-map SET_MED_50 outR3上设置route-map SET_MED_100 permit 10 set med 100 ! router bgp 200 neighbor 10.0.13.1 route-map SET_MED_100 outR1上show ip bgp时两条路径的Metric列会分别显示50和100最优路径会是MED更小的50那条。反过来把50和100互换最优路径立刻换边。这个扩展实验也解释了一个现实场景企业同时从同一家上游的两个POP点接入想控制流量从哪个入口进入MED是标准手段。前提是对方两个POP之间确实属于一个AS并且愿意配合调整MED。7. 复盘这些细节最容易让实验结果“看起来不对”7.1 策略改了不生效先做软重置最常遇到的假故障就是路由不切换。配置改完后BGP不会马上重新评估所有路径必须主动触发一次刷新。思科设备的软重置命令通常是这样clear ip bgp * soft如果inbound方向没有开soft-reconfiguration有些老版本会提示不支持这时就需要硬清或者配好soft-reconfiguration再软清。实验环境里随便硬清生产环境一定要评估影响。7.2 方向挂反、属性压制、路由未安装三类问题逐个排查我把自己在实验里踩过的坑整理成了排查表遇到“结果不符合预期”时按顺序过一遍现象首要怀疑验证方法配置了策略但路径不切换没有soft reset或者旧策略叠加执行clear再看show ip bgpprepend不生效更高级别的属性仍在压制按决策顺序逐项对比LocPrf和Weightroute-map挂了但路由没变化in/out方向挂反show run确认邻居下挂的方向两个邻居路径被同时选中做了负载均衡相关配置show ip bgp看是否有 multipath 标志测试地址ping不通BGP路由没有安装进路由表show ip route确认是否有B前缀其中方向挂反的问题尤其隐蔽。我的经验是凡是写“in”方向的route-map一定要问自己“这个策略影响的是我学到的路由还是我发出去的路由”凡是写“out”方向的route-map一定要问的是“对方收到后它的选路会怎么变”。这两个问题想清楚了至少能少走一半弯路。7.3 实验之后的几个好习惯这套小实验做完之后我给自己定了几个规矩。第一每验证完一个属性立刻把当前所有策略撤销让实验回到基线状态绝不带着旧策略跑下一组实验。第二每次改动前都先show running-config看一下当前BGP相关的route-map和邻居配置确认没有残留的weight、local-preference、prepend。第三所有实验都用独立的测试前缀和独立路由进程避免污染现有网络。我还有一个习惯是勤做“对比快照”改动前保存一份show ip bgp的输出改动后再保存一份用diff直接看变化。这个习惯在真实网络排障时同样好用能快速确认一条策略到底影响了哪些前缀而不是凭感觉猜。整组实验下来我最想分享的一句话是做BGP选路实验的时候先分清你是在影响自己的决策还是在影响邻居的决策。本地出站方向Weight和Local Preference足够想让外网流量绕开你某条链路AS Path prepend和MED才是正路。这个判断顺序一旦建立以后再看任何复杂的选路问题都能很快定位到该调哪一层的属性。