2026/10/15 6:26:38

华为BGP选路实验:从Local_Pref到MED逐条验证优先级规则

华为BGP选路实验:从Local_Pref到MED逐条验证优先级规则 做BGP选路实验最怕的不是命令敲错而是看着路由表里两条一模一样的前缀搞不清设备为什么选了这条、没选那条。我在华为设备上把这个流程完整跑了一遍从Local_Pref到AS_Path再到MED把每条规则单独拎出来验证期间踩了不少坑最后总算把BGP选路的优先级顺序彻底捋清了。这篇文章适合刚开始接触BGP、或者被选路逻辑绕晕的网络工程师你可以按下面的拓扑把环境搭起来一步步复现搞清楚每个属性到底什么时候生效、什么时候会被前面一条规则抢先拍板。1. BGP选路实验的思路与规则速查1.1 为什么用双EBGP拓扑做实验底座BGP选路规则的验证最讲究“控制变量”。路由表里同一前缀来了好几条路径BGP会按照固定顺序逐条比较属性一旦某条规则分出胜负后面的规则就完全没机会上场。所以实验设计的第一步不是急着敲命令而是想清楚怎么让每一条规则都有机会被单独验证。我选择的是最基础的三台路由器拓扑一台核心路由器R1分别连接两个不同自治系统里的R2和R3三条BGP会话全部是EBGP。R2和R3各自发布一个完全相同的网段172.16.1.0/24这样R1的BGP表里必然出现两条等价前缀。为什么不用更复杂的IBGP加反射器因为EBGP场景下属性传递路径最短Local_Pref、MED、Origin这些值都是“一手”属性没有IBGP内部传递和反射器带来的干扰适合做单点验证。等你把属性规则吃透了再去扩展IBGP场景思路会清晰很多。这个实验的底层逻辑是理解BGP选路“逐条比较、一项定胜负”的机制。比如两条路由Local_Pref完全相同才会比到下一条AS_PathAS_Path分不出高下才轮到OriginOrigin再打平才看MED。很多人配置了MED策略却不生效就是因为AS_Path或Origin在前面已经把结果定了MED连上场机会都没有。这种“前序规则优先”的思路也是生产环境排查选路问题的钥匙。1.2 华为设备BGP选路规则完整速查表华为VRP上BGP路由的选路顺序核心规则如下表。不同版本细节略有差异但主框架一致。优先级规则名称比较方式实验中如何修改1Preferred ValuePrefVal华为私有越大越优apply prefval2Local_Preference越大越优apply local-preference3本地聚合/Network生成路由本地生成优先于从对等体学习本地network/aggregate4AS_Path长度越短越优apply as-path ... additive5Origin类型IGPi优于EGPe优于Incomplete?network/import-route切换6MED越小越优apply med7EBGP路由与IBGP路由EBGP优先于IBGP改变拓扑和邻居AS号8到BGP下一跳的IGP度量越小越优修改IGP开销9Cluster_List长度越短越优路由反射器场景10Router ID越小越优修改router-id11对端IP地址越小越优调整邻居接口地址这里要特别提醒一个非常常见的误区BGP路由的“协议优先级”管理距离和“BGP选路规则”是两码事。华为VRP里BGP路由默认优先级是255那是与其他路由协议竞争时用的BGP路由内部选路走的是上面这张表不要把两个概念混在一起。另外所有参与选路的路由都必须满足一个前提路由有效且下一跳可达。下一跳不可达的路由再漂亮也不会参与比较这在IBGP场景里尤其坑后面排错章节我会专门说。1.3 实验工具与前置知识这个实验我是在华为网络设备模拟环境里跑的用eNSP或是其他常见模拟器都行只要设备镜像支持BGP命令AR系列路由器基本没问题。如果你手头有真机直接把接口规划和配置套上去即可命令语法一致。动手之前建议先确认自己掌握三件事一是理解EBGP和IBGP的区别二是知道Peer建立会话的基本过程三是了解Route-Policy里的if-match和apply是怎么回事。Route-Policy是这个实验的核心操作工具如果对它不熟后面代码块可能会看晕建议先花半小时把route-policy的基础语法过一遍。2. 实验拓扑与基础配置2.1 地址规划与网络拓扑说明拓扑采用三台路由器全部使用私有AS号R1属于AS 65001R2属于AS 65002R3属于AS 65003。R1与R2之间用一条直连链路R1与R3之间用另一条直连链路。R2、R3各自在Loopback1上配置172.16.1.1/24和172.16.1.2/24属于同一网段并通过BGP network命令发布172.16.1.0/24制造两条相同前缀的竞争路径。设备接口规划如下表设备AS号接口IP地址Router IDR165001GE0/0/0连R210.0.12.1/2410.255.0.1R165001GE0/0/1连R310.0.13.1/2410.255.0.1R165001Loopback010.255.0.1/3210.255.0.1R265002GE0/0/0连R110.0.12.2/2410.255.0.2R265002Loopback1172.16.1.1/2410.255.0.2R365003GE0/0/0连R110.0.13.3/2410.255.0.3R365003Loopback1172.16.1.2/2410.255.0.3这个规划有几个细节值得说明。第一Loopback0用来做Router ID稳定且不依赖物理接口状态第二业务前缀用的是172.16.1.0/24和互联地址10.0.12.0/24、10.0.13.0/24分开避免后续看BGP表时被一堆直连前缀干扰第三R2和R3的Loopback1是同一网段这在模拟器里完全没问题因为BGP network通告的是本机路由表里的精确路由不需要对端网段唯一。2.2 三台设备的BGP基础配置先把基础BGP配置全部贴出来这几段配置是整个实验的底子。R1配置sysname R1 interface GigabitEthernet0/0/0 ip address 10.0.12.1 255.255.255.0 interface GigabitEthernet0/0/1 ip address 10.0.13.1 255.255.255.0 interface LoopBack0 ip address 10.255.0.1 255.255.255.255 bgp 65001 router-id 10.255.0.1 peer 10.0.12.2 as-number 65002 peer 10.0.13.3 as-number 65003R2配置sysname R2 interface GigabitEthernet0/0/0 ip address 10.0.12.2 255.255.255.0 interface LoopBack0 ip address 10.255.0.2 255.255.255.255 interface LoopBack1 ip address 172.16.1.1 255.255.255.0 bgp 65002 router-id 10.255.0.2 peer 10.0.12.1 as-number 65001 network 172.16.1.0 255.255.255.0R3配置sysname R3 interface GigabitEthernet0/0/0 ip address 10.0.13.3 255.255.255.0 interface LoopBack0 ip address 10.255.0.3 255.255.255.255 interface LoopBack1 ip address 172.16.1.2 255.255.255.0 bgp 65003 router-id 10.255.0.3 peer 10.0.13.1 as-number 65001 network 172.16.1.0 255.255.255.0配置完成后到R1上执行display bgp peer看到R2和R3两个邻居的状态都是Established就说明BGP会话正常建立。如果状态不是Established先检查接口地址、AS号以及路由是否可达BGP建立TCP连接时源目IP都要能通。这里还要提醒一个network命令的经典坑network不是“通告一个网段”而是“通告本机IP路由表中已经存在的精确路由”。R2的Loopback1配置为172.16.1.1/24后路由表里才会有172.16.1.0/24这条直连路由network 172.16.1.0 255.255.255.0才能成功。如果你把Loopback1配成172.16.1.1/32那network 172.16.1.0/24就完全不会生效因为路由表里没有这个精确前缀。建议发布前先执行display ip routing-table 172.16.1.0 24确认。2.3 Route-Policy基础与使用须知实验后半程几乎全靠Route-Policy修改属性这里必须打好基础。Route-Policy由多个node组成每个node里有if-match匹配条件和apply动作。匹配时从最小node号开始一旦某个node匹配成功并permit就停止往后找。如果所有node都不匹配路由会被隐式拒绝。给路由打标签之前先用ip-prefix精确圈定目标前缀。我在实验里反复用这个前缀列表ip ip-prefix PRE_172 index 10 permit 172.16.1.0 24然后定义一个route-policy比如修改Local_Prefroute-policy LP_R2 permit node 10 if-match ip-prefix PRE_172 apply local-preference 200最后在BGP视图下把这个策略应用到指定邻居和方向bgp 65001 peer 10.0.12.2 route-policy LP_R2 import方向是Route-Policy里最容易搞错的地方。import表示对“从邻居收到的路由”生效export表示对“发给邻居的路由”生效。你站在设备内部看数据流进来要走import策略出去要走export策略。实验里验证Local_Pref必须在R1上对两个邻居分别做import方向的route-policy验证AS_Path和MED既可以在R2/R3上做export也可以在R1上做import两者效果类似但我建议你在R2/R3的出方向做更接近真实网络的CE侧控制。还有一点必须记住配置完route-policy后BGP表不会立刻变化需要执行软刷新。入方向策略用refresh bgp all import出方向策略用refresh bgp all export。如果不想区分直接reset bgp all也会生效但会打断BGP会话生产环境慎用。很多实验者改了route-policy后看到选路没变第一反应是策略写错实际只是忘了刷新。3. 逐步实操让每条选路规则现出原形3.1 先看基线默认两条EBGP路由谁胜出基础配置完成后在R1上执行display bgp routing-table 172.16.1.0 24正常情况下可以看到两条可达路径其中一条前面带*标记另一条只带*。*表示这条路由有效表示被选为最优路由。也就是说带*的就是当前正在进行BGP转发的路径。现在先分析一下为什么默认会选其中一条。两条路由都来自EBGP邻居PrefVal都是0Local_Pref都是100AS_Path长度都是1分别是65002和65003Origin都是IGP因为都用network发布MED都是0EBGP/IBGP也一样下一跳IGP度量也相同。一路比下来前面规则全部打平最后会落到Router IDR2的Router ID是10.255.0.2R3是10.255.0.3R1会选择Router ID更小的对端也就是来自R2的这条路径。这个基线结果非常重要。后面做属性实验时你要能随时回到这个基线状态否则多个策略叠加后你根本分不清到底是哪个属性让它改道的。我建议每个属性实验做完都把对应的route-policy删掉再用refresh bgp all import刷新确认选路恢复原状再进行下一个。3.2 验证Local_Pref本地优先级越大越优Local_Pref本地优先级是AS内部非常关键的选路属性值越大越优先。实验里可以直接在R1的入方向为不同邻居设置不同的Local_Pref观察选路会不会改。我在R1上配置两个策略来自R2的路由Local_Pref设为200来自R3的路由Local_Pref设为300。ip ip-prefix PRE_172 index 10 permit 172.16.1.0 24 route-policy LP_R2 permit node 10 if-match ip-prefix PRE_172 apply local-preference 200 route-policy LP_R3 permit node 10 if-match ip-prefix PRE_172 apply local-preference 300 bgp 65001 peer 10.0.12.2 route-policy LP_R2 import peer 10.0.13.3 route-policy LP_R3 import配置后执行refresh bgp all import再看BGP表最优路径会变成来自R3的那条。R3的Router ID明明更大却被选为最优这就是Local_Pref压过了Router ID的结果。你可以再把两个值对调比如R2设为300、R3设为200选路会立刻倒向R2非常直观。这里要注意Local_Pref是一个AS内传递的属性从EBGP收到的路由默认是100在入方向修改是真实网络里很通用的做法比如运营商给某个客户设置更高的Local_Pref让流量优先走某条出口。但反过来把Local_Pref放到export方向发给EBGP邻居通常没有意义因为EBGP邻居不会把Local_Pref当作有效选路属性去处理。3.3 验证AS_Path路径越短越优先验证完Local_Pref先把R1上的两个inbound route-policy删掉恢复到基线状态。然后我去R2的出方向给172.16.1.0/24追加两个AS号人为把AS_Path拉长。R2上的配置ip ip-prefix PRE_172 index 10 permit 172.16.1.0 24 route-policy AS_PATH_ADD permit node 10 if-match ip-prefix PRE_172 apply as-path 65004 65005 additive bgp 65002 peer 10.0.12.1 route-policy AS_PATH_ADD exportadditive关键字很关键表示在原有AS_Path后面追加如果不写会直接覆盖成新的AS_Path。刷新出方向后在R1上执行refresh bgp all export实际上这个命令应该在R2上执行因为策略在R2的出方向在R1上要执行refresh bgp all import请求邻居重新发送这里整理一下R2出方向策略变了需要在R2上执行refresh bgp all export或者R1执行refresh bgp all import触发路由刷新。两种都可以我习惯在配置策略的设备本端执行export刷新再看BGP表最优路径应该改选到R3。原因很简单R2这条路径的AS_Path变成了[65002, 65004, 65005]长度3R3那条还是[65003]长度1。Local_Pref到达一样后面还没比到OriginAS_Path规则就直接判定R3胜出。想在这个环节做得更专业一点可以再用as-path-filter来做正则匹配。比如我只想针对来自特定AS的路径追加属性可以这样定义ip as-path-filter 1 permit ^65003$ route-policy AS_PATH_MATCH permit node 10 if-match as-path-filter 1 apply as-path 65004 65005 additive这样策略只会命中AS_Path为65003的路由不会影响其他前缀。正则表达式里的^和$用来锚定起始和结束网络工程师日常排查时很常用。3.4 验证MED值越小越优先但不是每次都能生效MED是最容易“骗人”的规则因为它的生效条件太容易被前面的规则截胡。先恢复基线然后在R2出方向设置MED 50R3出方向设置MED 100。R2配置route-policy MED_50 permit node 10 if-match ip-prefix PRE_172 apply med 50 bgp 65002 peer 10.0.12.1 route-policy MED_50 exportR3配置route-policy MED_100 permit node 10 if-match ip-prefix PRE_172 apply med 100 bgp 65003 peer 10.0.13.1 route-policy MED_100 export刷新后如果你直接看选路结果很可能发现还是原来的R2胜出这不一定是因为R2的MED更小而是因为R1默认根本不比较来自不同AS的MED值。华为设备默认情况下MED只在相同AS来源的路由之间比较R2来自AS 65002R3来自AS 65003默认不比较。要解决这个问题在R1的BGP视图下开启bgp 65001 compare-different-as-med再次刷新这次R1会比较MEDR2的MED是50R3是100选R2。你可以把两边的MED反过来比如R2设为100、R3设为50选路就会倒向R3这就证明MED确实生效了。这个坑在生产环境里非常典型。很多双运营商出口场景两个上游AS分别宣告了相同前缀并且带有不同MED但本端设备就是不去比较MED因为默认规则禁止跨AS比较。要不要开compare-different-as-med需要结合业务场景判断乱开会引起选路意外翻转千万别为了实验一时爽就直接照抄到生产环境。3.5 验证OriginIGP优于IncompleteOrigin类型在真实网络中基本只有两种IGPi和Incomplete?。用network发布的路由是IGP用import-route引入的路由是Incomplete。EGP类型几乎没有可以忽略。为了让Origin规则独立出场先恢复基线。R2保持network发布Origin为IGP。R3改成import-route direct并只放行172.16.1.0/24这样R3发布的路由Origin就是Incomplete。R3配置ip ip-prefix PRE_172 index 10 permit 172.16.1.0 24 route-policy DIRECT_TO_BGP permit node 10 if-match ip-prefix PRE_172 bgp 65003 undo network 172.16.1.0 255.255.255.0 import-route direct route-policy DIRECT_TO_BGP注意这里如果用import-route direct不加route-policy会把R3所有直连网段都带进BGP包括与R1互联的10.0.13.0/24没必要。用route-policy精确匹配172.16.1.0/24才是干净做法。刷新后在R1上查看两条路径的详细属性display bgp routing-table 172.16.1.0 24 verbose可以看到R2那条路径的Origin为IGPR3那条为Incomplete。由于Local_Pref一致、AS_Path长度一致、MED一致最终Origin规则生效R1选R2。如果反过来R2改成import-route、R3保持network选路也会倒向R3实验室里可以把两边的发布方式互换复测一次。这个实验能帮你想明白一件事平时配置BGP时尽量用network方式发布核心网段能让Origin保持IGP在选路规则链上处于更有利位置。用import-route批量引入虽然省事但Origin会变成Incomplete在某些场景下可能会不占优势。3.6 验证PrefVal华为私有属性一言九鼎PrefVal是华为设备的私有BGP属性优先级排在所有标准属性之前。它只在本地路由器上有效不会通告给邻居非常适合做“本地强制选路”。我在R1上对来自R3的路由设置PrefVal 100来自R2的路由保持默认0。即便此时R2那条路径的Local_Pref更高只要PrefVal有差距R1还是会选R3。配置如下route-policy PREF_R3 permit node 10 if-match ip-prefix PRE_172 apply prefval 100 bgp 65001 peer 10.0.13.3 route-policy PREF_R3 import刷新后观察选路最优路径会立刻变成R3。你可以把PrefVal调高到200、300效果不变它永远压着Local_Pref走。反过来如果你把PrefVal设成0或撤销策略选路马上恢复到原有规则。这个属性在真实设备上做主备切换时非常方便。比如你希望某台路由器对某条路由永远选A出口不需要去协商各种标准属性直接在入方向给A路由加PrefVal即可。但要注意它不能跨设备传递该路由器自己说了算对端路由器的选路不会受影响。3.7 扩展验证EBGP优先于IBGP的思路前面几步都在双EBGP拓扑下完成还差一条EBGP优于IBGP的规则没验证。如果想把这套实验继续做下去可以调整拓扑把R2并入AS 65001让R1与R2变成IBGP邻居R2与R3之间建EBGPR1与R3继续保持EBGP。R3发布172.16.1.0/24后R1会从两条路径学到它一条是直连EBGP邻居R3另一条是R2从R3学到后通过IBGP传进来的。默认情况下R1会选直连R3的EBGP路径因为AS_Path、Origin、MED等全部打平EBGP优于IBGP这条规则生效。如果给R3直连路径的AS_Path追加长度R1会改选IBGP路径这就证明了AS_Path规则的优先级高于EBGP/IBGP规则。这个扩展实验不需要贴全部配置你只要理解拓扑变化和选路逻辑即可。在实际网络里IBGP和EBGP并存是常态很多疑难选路问题都出在这种混合场景。掌握了“前序规则优先”的思路这类问题基本都能定位到具体是哪条规则在起决定性作用。4. 常见问题与排错实录4.1 路由始终不优不参与选路实验中最常遇到的情况是BGP表里看到了某条前缀但它前面没有标记甚至没有*标记。这通常意味着路由无效最常见的原因是下一跳不可达。EBGP场景下R1收到R2通告的172.16.1.0/24路由下一跳是10.0.12.2直连接口地址一般不会出问题。但到了IBGP或路由反射器场景下一跳可能是远端设备地址如果IGP里没有这条路由BGP路由就会变成无效路由。排错时先执行display bgp routing-table 172.16.1.0 24看Nexthop字段然后拿着这个地址去查display ip routing-table 10.0.12.2下一跳在IP路由表里必须有一条可达路由否则BGP路由不可能带上标记。4.2 Network命令发布不出去Network命令发不出去最常见的原因是路由表里没有精确匹配的条目。R2的Loopback1配置为172.16.1.1/24路由表里会有172.16.1.0/24如果你把Loopback1改成172.16.1.1/32BGP里network 172.16.1.0/24就永远不会生效。发布前习惯性查一下display ip routing-table 172.16.1.0 24另外BGP会话没建立时就算路由表里有精确路由network也通告不出去。所以遇到发布问题先看peer状态再看路由表最后看network配置基本能解决九成问题。4.3 Route-Policy配置了但选路没变这个问题我见得太多了。总结起来就三类原因第一忘了刷新。route-policy配置完不会立即生效必须执行refresh bgp all import或export或者reset。我在实验里每个环节都写了刷新命令真机操作时最容易漏。第二方向挂反。把import策略挂到export方向或者反过来策略不会生效。判断方法很简单你想改的是“从邻居收到的路由”就用import想改“发给邻居的路由”就用export。第三if-match没匹配上。ip-prefix的匹配逻辑很严格前缀和掩码长度都要对。如果你写permit 172.16.1.0 24而实际路由是172.16.1.0/25那就匹配不上。建议配置后先执行display this查看route-policy确认必要时用display bgp routing-table 172.16.1.0 24 verbose看属性变化就知道策略到底有没有打中路由。还有一个隐蔽的坑一个邻居同时只能应用一个import策略和一个export策略重复执行peer ... route-policy会覆盖之前的配置而不是叠加。如果你发现前面配的策略“消失”了大概率是后面又执行了新的route-policy挂到同一方向。4.4 MED不生效的几种原因MED是我这次实验里绕了最多弯的地方把它单拎出来说。MED不生效按下面顺序排查先确认AS_Path或Origin是否已经分出胜负。这是最容易被忽略的BGP选路是串行比较前面定了后面就不看了。用display bgp routing-table 172.16.1.0 24 verbose把两条路由的AS_Path、Origin列出来对齐确认打平再谈MED。再确认两条路由是不是来自不同AS。华为默认不比较不同AS的MED来自不同邻居的两条EBGP路由想要让MED参与比较必须在BGP视图下开启compare-different-as-med。最后确认MED值有没有真的写入路由。给邻居出方向配置apply med 50后在本地看verboseMED字段应该能看到50而不是0。如果看到0说明route-policy没打中往if-match方向排查。4.5 排错命令速查表日常做BGP排错我常用的命令整理成下表命令作用display bgp peer查看BGP对等体状态确认Establisheddisplay bgp routing-table查看BGP路由表所有前缀及优劣标记display bgp routing-table 172.16.1.0 24查看指定前缀的所有路径信息display bgp routing-table 172.16.1.0 24 verbose查看指定前缀的详细属性display ip routing-table 下一跳地址检查下一跳是否可达display current-configurationsection bgprefresh bgp all import/refresh bgp all export软刷新BGP路由使策略生效reset bgp all重置BGP会话谨慎使用这里提醒一句debugging bgp update这类调试命令慎用尤其是生产网络输出量巨大而且可能影响设备性能。模拟器上学习可以玩真机上还是优先看路由表和配置输出尽量不依赖debug。5. 实验后的经验总结与扩展方向这次实验做完我自己最大的体会是BGP选路从来不是“背下11条规则”就够的关键是要养成“逐条对齐属性”的排错习惯。实验里一共验证了Local_Pref、AS_Path、MED、Origin、PrefVal这五个可改属性加上默认基线里的Router ID兜底已经覆盖了日常工作中八成以上的选路问题。你再遇到路由不按预期走不要凭感觉猜先把verbose打出来从PrefVal开始一条一条比对找到第一个分出胜负的属性问题就定位了。后续想继续深入的话可以把这套控制变量的方法套到BGP Community、路由反射器的Cluster_List、BGP多路径负载分担这些方向上。我还打算把同一条选路规则在双EBGP和IBGP混合拓扑下的表现再整理一份对比毕竟真实网络里不会只有单纯的EBGP链路那个场景下的“前序规则优先”会更加明显。希望这篇实验记录能让你少踩几个坑。