搞网络的朋友应该都有过这种经历BGP邻居状态明明全部Up路由表里也确实学到了多条路径结果某个网段的流量就是“走窄了”——绕了一大圈到一个次优出口业务侧卡顿、时延飙高你查了半天配置和策略最后才在BGP路由表的属性列里发现问题根源。这不是配置语法错误而是“选路逻辑”没吃透。BGPBorder Gateway Protocol边界网关协议作为核心网与广域网互联的关键路由协议它身上最值钱的东西从来不是“怎么建立邻居”而是如何从一堆可达路径里挑出最合适的那条。这个“挑”的过程就是BGP属性、选路原则与路由优选的组合拳。这篇文章我把这块内容彻底拆开从属性分类讲到选路顺序从华为设备实操讲到双出口流量调度尽量用大白话把原理讲透也把ensp模拟器里能直接验证的配置和排查命令给你列清楚。适合正在备考HCIP、或者工作中要处理BGP路由选路和流量调优的工程师参考。1. 一个真实的选路问题为什么明明有两条路流量却走了绕远那条先说一个我实际遇到过的现象理解了它你就能明白BGP属性和选路原则到底是干什么用的。某单位有两条出口链路分别接到两个本地运营商A和B和两个运营商分别建立了eBGP邻居。A链路带宽大、时延低B链路做备份。结果上线之后发现内网用户访问某个业务网段时流量全部从B出口出去了B链路瞬间打满A链路却闲着。有人在BGP配置里加了一句preference或者调整了路由优先级但没什么效果。这种问题的本质是BGP根本不像静态路由那样“你写哪条就走哪条”它有一套固定的、多轮比较的“选美比赛”规则。每条学到的BGP路由都携带一堆标签也就是我们今天要说的BGP属性比如谁的AS路径短、谁的本地优先级高、谁宣告的MED值小、谁是从eBGP学来的、谁的下一跳IGP开销低……BGP把自己学到的所有路由按固定的顺序逐条比较这些属性最终选出一条唯一的最优路由放进IP路由表。换句话说如果你的选路结果不符合预期不是BGP“抽风”而是你没有通过属性去影响这套比较流程。BGP的选路原则是死的但属性是活的你可以通过修改属性来“操控”这个选美比赛的结果这就是路由优选和流量调度最核心的思路。要弄清这一点得先把“参赛选手”身上的标签——也就是BGP属性——认全。2. BGP属性路由身上的背景信息选路全靠它打分2.1 属性分类哪些必须带哪些可以不带BGP属性是描述一条路由的各种参数它随着路由一起在邻居之间传递。为了规范这些属性的行为RFC 4271把它们分成了四类类别属性举例特点公认必遵Origin、AS_PATH、Next_Hop所有BGP路由必须携带所有设备必须能识别公认自决LOCAL_PREF所有设备必须能识别但要不要携带是可选行为通常只在AS内部传递可选传递Community、Extended Community不要求所有设备认识但即使不认识也要原样传递给下一个邻居可选非传递MED不要求所有设备认识不认识就直接忽略不传递给下一个AS这个分类决定了你能用哪些属性来施加影响。比如你想在本AS内提升某条路由的优先级就用LOCAL_PREF因为它只在AS内部传不会把内部策略泄露给外部运营商。你想让对端AS在访问你家网段时优先走某条链路就用MED因为它只发给对端一个AS不会继续往下传。理解分类还有一个实际好处排查问题的时候看到某条路由的属性就能判断它是从哪个方向来的。比如LOCAL_PREF非默认值说明这个AS内有管理员做过策略调整比如AS_PATH尾部带了你自己的AS号说明收到了环路路由。2.2 核心属性逐个拆解值越小越好还是越大越好AS_PATHAS路径这是BGP防环和选路最核心的属性。一条路由每经过一个AS就把这个AS号追加到路径里。选路时AS路径越短越优。注意AS路径长度为1表示路由是直连的邻居AS宣告过来的。本地AS号如果出现在收到的路由里说明存在环路直接丢弃。长度计数时AS_SET无序集合按1个AS计算AS_CONFED联盟内部不参与选路比较。实操中经常用AS路径来做“入向流量调度”。比如本地AS 65001有两条上联分别接AS 65002和AS 65003你想让运营商A那边访问你的业务网段时少走运营商B绕一圈可以给自己宣告出去的网段人为追加AS路径让通过运营商B学到路由的代价变大。华为设备上就是apply as-path加上additive。LOCAL_PREF本地优先级本地优先级是越大越优默认值是100只在本AS内部传播不会发给eBGP邻居。它是AS内部影响出向流量最直接的手段——所谓“出向”是指本AS内的用户访问外部网络时流量选择哪个出口。比如你想让内网用户访问某外部网段优先走A链路就在从A邻居学到的路由上设置更高的LOCAL_PREF。华为设备上配置LOCAL_PREF有两种方式bgp 65001下手动设置默认值bestroute local-preference 200。使用route-policy对特定前缀设置apply local-preference 300。MED多出口区分度量MED是越小越优默认值为0。它是发给对端AS的“建议”用来影响对端AS访问本AS时的入向流量选择。打个比方你有两个出口都接到了同一个运营商你希望运营商那边访问你家网段时尽量走你的A出口那么你在A出口发出去的路由上设置更小的MED。比较MED时有一个容易踩的坑华为设备默认只比较来自同一个AS的eBGP路由的MED。如果两条路由来自不同的AS那MED就不比较了。你可以通过compare-different-as-med命令强制不同AS之间的路由也比MED但默认情况下不要想当然。Origin起源属性表示路由的起源方式IGP0通过network命令发布、EGP1老协议EGP基本见不到了、INCOMPLETE2通过重发布等其他方式引入。选路时优先级是IGP EGP INCOMPLETE。现实中ORIGIN对选路的影响通常很小因为三条路径很难在其他条件都相同的情况下只在这里分出高下但考试和原理上都爱考。Next_Hop下一跳BGP有一个特征叫“BGP的下一跳不是直连的”从eBGP学到的路由传递给iBGP邻居时默认保持原来的下一跳地址不变。这就导致一个关键问题iBGP设备在优选路由前必须先确认下一跳在IGP里是可达的。如果下一跳不可达这条路由就是无效的不参与选路。华为设备上有next-hop-local命令可以在向iBGP邻居发布路由时把下一跳改成自己的接口地址目的就是规避IGP可达性问题。Community团体属性团体属性本质上是一组32位的“标签”可以附加在路由上配合路由策略做灵活的“按标签操作”。比如互联网上常见的NO_EXPORT团体值表示“这条路由可以传给eBGP邻居但对方不能再往外传”NO_ADVERTISE表示“不能通告给任何邻居”。自己也可以定义私有团体值比如100:100表示某些内部标记然后在route-policy里用if-match community-filter匹配后执行apply。(实际使用中团体属性是把“策略意图”编码到路由本身的一种方式非常方便。比如核心路由器从运营商学到默认路由并打上NO_EXPORT就不会把自己的默认路由到处乱传播。)3. BGP选路原则从第一跳到最后一跳为什么是这个顺序3.1 完整选路顺序华为设备的十一步“选美”BGP的路由优选是一个逐步淘汰的过程。设备会把每条候选路由依次按下面的顺序比较只要在某一步分出胜负就不再往后比了。我以华为设备为准把顺序列出来步骤优选条件“更优”的含义1Preferred Value华为私有越大越优本地手工指定2LOCAL_PREF越大越优默认1003本地生成路由本地network/aggregate/import优于从邻居学来的4AS_PATH长度越短越优5Origin类型IGP优于EGP优于INCOMPLETE6MED越小越优默认07eBGP优于iBGP下一跳是eBGP学来的更优8下一跳IGP度量到下一跳开销越小越优9能否负载均衡如果配置了负载分担可多条同时使用10路由来源稳定性老的eBGP路由优于新的iBGP路由11Router ID越小越优比较的是通告者的Router ID或Originator ID注意Preferred Value是华为私有的参数类似思科的Weight。它只在本地设备上起作用不会传给任何邻居适合做本地的强制选路。这个顺序是BGP的核心“宪法”任何BGP路由优选都绕不开它。理解它的关键是不要死记硬背而是弄清楚每个步骤解决什么问题前3步解决的是“本地意志优先”。管理员想让哪条路由优直接改Priority和LP自己产生的路由永远优先于别人教的。第4、5、6步解决的是“网络路径质量”。AS路径短表示跳数少ORIGIN表示来源更可信MED表示对端给你的“建议成本”。第7、8、9步解决的是“归属和物理距离”。eBGP学到的路由在行政上比iBGP转发的更可信下一跳在IGP里的开销越小说明物理上越近。最后几步是万不得已的“名次判定”保证最终永远只选出唯一一条除非配置了负载分担。3.2 为什么是这个顺序背后是稳定性和可控性的权衡很多人问为什么LOCAL_PREF排在AS_PATH前面而不是反过来因为这反映了一个设计哲学管理员的意图永远优先于路由的客观质量。如果AS路径短的优先你作为管理员费尽心思设置的本地优先级就没有意义了流量控制会完全失控。所以LOCAL_PREF必须排在前列。再比如为什么MED排序在eBGP优于iBGP之前因为MED是从对端AS随路由发过来的对端希望影响你的选择。对端的“建议”应当在天然属性eBGP/iBGP前面否则一个对端做了MED优化结果因为另一条路由是eBGP学来的就无效了那MED的设计初衷就废了。理解了设计哲学遇到厂商差异时你也能快速反应过来。比如华为和思科在整体流程上大致相同但思科把“Weight”放在最前面、新增了“邻居类型”、“隧道封装”等比较项华为Preferred Value对应的也是第一优先级。不同厂商在某些细节排序上有细微差别但主干都是RFC 4271那套公认的顺序。提示BGP优选是逐跳进行的。只要前面某一步出了结果后面的比较就不会执行。所以排查选路问题时就从第1条开始往下捋看哪一步把两条路由分开了。3.3 三大终极目标选路规则和现实场景的对应把顺序背下来不算本事关键是能对应到真实场景里。我把最常见的三类场景和它们对应的选路阶段说一下场景一强制某条路由优。不需要管后面什么AS_PATH、MED直接给这条路由设置极大的Preferred Value或LOCAL_PREF在前3步直接终结比赛。这也是大网里常用的手段。场景二引导入向流量。你要影响的是对端AS怎么选你只能输出MED、AS路径、团体属性给对方。对端收到后通过这些属性决定走到你这边的哪条链路。场景三实现负载均衡。BGP默认只选一条最优路由但华为设备上用maximum load-balancing ebgp或maximum load-balancing ibgp可以让多条等价路由同时承担流量。不过要注意只有在前面8步都完全相同、无法分出高下时才能进入负载分担。4. 实操在ensp里配置BGP基础并观察属性对选路的影响4.1 实验拓扑与需求定义光讲原理容易飘我建议你在ensp里搭一个最简拓扑华为HCIP考试也是这个套路三台路由器R1、R2、R3AS号分别是65001、65002、65003。R2同时连接R1和R3R1后面挂一个业务网段10.0.0.0/24要求R3能够学到这个网段并且能通过display bgp routing-table清楚看到AS路径和MED的变化。R1AS 65001与R2建eBGP邻居发布10.0.0.0/24。R2AS 65002与R1、R3建eBGP邻居把10.0.0.0/24传给R3。R3AS 65003与R2建eBGP邻居观察学习到的路由属性。这个拓扑虽然简单但足够演示BGP属性的传递过程AS路径如何追加、MED如何透传、LOCAL_PREF如何在AS内部生效。4.2 基础配置别在地址互联上翻车先配接口IP和IGP。我直接给出R2的关键配置做参考其他设备同理# R2配置 system-view sysname R2 interface GigabitEthernet0/0/0 ip address 192.168.12.2 255.255.255.0 # interface GigabitEthernet0/0/1 ip address 192.168.23.2 255.255.255.0 # bgp 65002 router-id 2.2.2.2 peer 192.168.12.1 as-number 65001 peer 192.168.12.1 connect-interface GigabitEthernet0/0/0 peer 192.168.23.3 as-number 65003 peer 192.168.23.3 connect-interface GigabitEthernet0/0/1 ipv4-family unicast peer 192.168.12.1 enable peer 192.168.23.3 enable这里两个细节要注意一是手工指定router-id并且在每台设备上唯一否则BGP邻居会Down二是用connect-interface明确指定建立TCP连接的源接口避免因为多接口导致源地址不一致。R1上发布业务网段# R1配置 bgp 65001 router-id 1.1.1.1 peer 192.168.12.2 as-number 65002 ipv4-family unicast peer 192.168.12.2 enable network 10.0.0.0 255.255.255.0等邻居Up后在R3上执行display bgp routing-table能看到10.0.0.0/24的AS路径是65002 65001说明经过了两个AS。这个观察很有价值BGP的属性不是配置出来的是每一跳传递过程中自然累积出来的。4.3 属性“打招呼”验证路由表中隐藏的信息在R3上查看详细属性display bgp routing-table 10.0.0.0 255.255.255.0 verbose输出里你会看到一堆关键信息比如Network NextHop MED LocPrf PrefVal Path/Ogn字段。LocPrf如果标了100就是默认值。Path/Ogn那列显示i表示ORIGIN是IGP。如果有多个邻居学习到同一前缀会列出多条候选路径并且标记 * 的是最优路由。很多人到这里以为就完了其实真正有价值的是开始“做手脚”。在R2上配一条route-policy把发给R3的路由的MED设置为200然后再看R3的选路结果和MED值。这样你就亲手制造了一次“属性影响选路”的全过程# R2上配置 route-policy SET_MED permit node 10 apply cost 200 # bgp 65002 peer 192.168.23.3 route-policy SET_MED export执行完在R3上再看display bgp routing-table 10.0.0.0MED列已经变成200。这说明MED确实是从对端AS带过来了并且随着路由一起传递。如果你把R2的出口策略删掉再查看会发现MED又回到了0。5. 实战BGP路由优选策略route control的落地思路5.1 控制出向流量LOCAL_PREF是首选武器所谓出向流量是本AS的用户对外访问时选择哪条链路出去。控制手段就是在入口方向对从邻居学来的路由打上LOCAL_PREF数值越大该路径越优。假设你的AS 65001有两条上联分别是AS 65002和AS 65003你希望内网用户访问外网时特定业务网段的流量优先走AS 65002那条链路。你不需要动其他路由只需要在AS 65002邻居的方向上对特定前缀应用route-policy修改LOCAL_PREF。我在ensp里实测过这样的配置# 在入口路由器上 acl number 2000 rule 5 permit source 8.8.8.0 0.0.0.255 # route-policy LP_IN permit node 10 if-match acl 2000 apply local-preference 200 # bgp 65001 peer 192.168.12.2 route-policy LP_IN import这样从AS 65002学到的、匹配8.8.8.0/24网段的路由LOCAL_PREF就是200而其他默认路由还是100。在选路第2步就会胜出。实际工程里出口路由器上可以用多条route-policy配合前缀列表、AS路径过滤器对不同网段打不同优先级实现细粒度的出向调度。5.2 控制入向流量MED和AS_PATH都是“寄给对端”的信入向流量是对端AS的用户访问你时从你的哪个入口进来。这你说了不算只能“建议”建议的手段就是修改你发送出去的路由的MED和AS_PATH。MED方式你有两个出口接同一个运营商改对应出口方向发出去的MED即可。AS_PATH方式如果对端是多运营商MED只在同AS之间比较跨AS不可靠这时可以给你不希望对端选择的路径上人为追加AS号人为拉长AS路径。两种方式各有优劣MED语义清晰但只适用于同一个对端ASAS_PATH适用范围更广但会污染路由信息其他邻居也会看到变长后的路径。工程上有时会用两者结合。一个真实的双出口例子本地AS 65001分别连接运营商X和运营商Y向两端都宣告业务网段172.16.0.0/16。想让运营商X的用户优先通过X链路访问就在X方向发布路由时不加任何策略MED保持0在Y方向发布时MED设为500。运营商X、Y同时收到这条网段X这边MED 0比Y的MED 500小自然优选X链路回程。5.3 route-policy as-path-filter组合按路径特征批量控制当路由数量多、路径特征复杂时光靠ACL匹配前缀不够要用as-path-filter来匹配路由携带的AS路径特征。比如你想把“从AS 65010及其下游学到的路由”整体提高优先级可以这样写ip as-path-filter 10 permit _65010$ # route-policy AS_PATH_LP permit node 10 if-match as-path-filter 10 apply local-preference 300 # bgp 65001 peer 192.168.12.2 route-policy AS_PATH_LP import这里的正则_65010$表示匹配“AS路径以65010结尾”的路由也就是从AS 65010直接学到的路由。_是AS路径正则里的分隔符。如果想要匹配经过65010及其下游的可以写_65010_。团体属性也可以做类似的事。比如某些运营商用团体属性标记路由类型例如国际路由、省际路由、本地路由你可以按团体值对整类路由统一做策略而不必逐条匹配前缀。这就是社区里常说的“route control”的高级玩法把策略意图通过团体值编码进路由网络拓扑变化时策略自动跟随不用频繁改配置。提示if-match as-path-filter匹配的是AS路径字符串不是AS号数值所以正则语法必须写对。多写几个实验案例把_、^、$、[0-9]*的用法练熟这是HCIP考试和实战都很容易失分的点。6. 常见问题与排查技巧实录6.1 设置了LOCAL_PREF为什么路由优选结果没变最常见的原因是LOCAL_PREF比较发生在第2步第1步的Preferred Value已经把比赛终结了。如果你在入口方向用了peer ... preferred-value那它优先于LOCAL_PREF。另外检查一下route-policy是否真的匹配到了目标路由——用display route-policy查看策略用display bgp routing-table看LOCAL_PREF是否已经变化。如果LOCAL_PREF还是默认100说明策略根本没有命中。还有一种隐蔽情况你在A路由器上改了LOCAL_PREF但最优路由是从B路由器学来的iBGP路由iBGP路由在学习时不会重新应用“入方向”的route-policy除非你对iBGP邻居也做策略。所以多路由器拓扑里策略要放到整个AS的边界入方向而不是某一台设备。6.2 AS路径长短的判断误区AS路径比较是“按AS_SET和AS_SEQUENCE整体计算长度”不是简单数逗号个数。AS_SET类型出现时即使里面写了10个AS号长度也只算1。另外本地AS号不会出现在收到的路由里所以你看路由表的Path列长度是n实际经过了n个AS。还有自己的AS号出现在路径尾部表示路由环路了设备直接不学习不会参与优选。6.3 MED比较条件不同AS之间的路由不比较这是很多人栽过跟头的地方。华为设备默认只比较来自同一AS的eBGP路由的MED。如果你从AS 65002学到MED 300从AS 65003学到MED 100BGP不会拿它们比MED而是跳到后面eBGP优于iBGP、Router ID等步骤。所以想用MED影响跨AS负载要确认对端AS是否相同或者显式开启compare-different-as-med。6.4 为什么学到的路由在IP路由表里没有生效BGP下一跳不可达是常见元凶。iBGP传递路由时不改下一跳如果路由器上没有到下一跳的IGP路由BGP路由始终是无效状态无法加表。排查时在BGP视图执行display bgp routing-table看路由的Status列是不是*如果有才是优选的并注入IP路由表。再配合display ip routing-table看下一跳是否存在。解决办法是让IGP能路由到iBGP下一跳或者配置peer X.X.X.X next-hop-local让iBGP邻居收到后改写下一跳。6.5 路由振荡刷新策略后到底要不要软重置修改了route-policy、as-path-filter、团体过滤器之后BGP不会自动重新跑一遍优选你需要触发刷新。华为设备上推荐用软重置避免中断邻居refresh bgp all import如果配置了出口方向的策略需要软重置出口方向refresh bgp all export在真实核心设备上不要轻易reset bgp all它会断开所有BGP会话导致路由表重新收敛可能引发流量中断。软重置只重新计算路由不影响TCP会话安全得多。我在实际维护中养成的习惯是每次修改策略后先display current-configuration | section route-policy确认配置没写错再refresh bgp all import然后立刻看display bgp routing-table和display bgp routing-table x.x.x.x verbose确认最终优选结果。验证通过后再观察一段时间确认没有振荡和流量抖动才认为策略生效。7. 关于BGP优选我最后想说的几句实在话BGP选路原则这东西初学的时候感觉就是一张表一条条记用多了才发现它其实是整个BGP协议设计思想的浓缩。任何一个属性都不是拍脑袋定的它们组合起来保证了协议既能防环、又能稳定、还能让管理员有充足的手段控制流量走向。所以我建议你在ensp里不要只搭一遍实验就扔试着在这个三台路由器的拓扑上把LOCAL_PREF、MED、AS_PATH、Preferred Value都分别改一遍每次改完都打开display bgp routing-table观察哪一步分出了胜负这样比单纯背十一步顺序有效得多。如果你手头有现成的双出口项目或者备考HCIP我特别推荐你把“入向流量调度MED/AS_PATH”和“出向流量调度LOCAL_PREF”这两个场景做成一套完整的实验记录拓扑怎么搭、策略怎么配、验证看哪些字段、怎样回滚。这套技能在运营商、数据中心出口、企业总部多链路互联这些场景里几乎每周都会用上提前练熟后面遇到流量路径不合理的问题时你至少能快速判断是该改本地优先级还是该改MED而不是对着路由表发呆。最后再给一个我自己的小经验如果生产环境里出现了选路不符预期先别急着改配置把display bgp routing-table全量视图连同注释一起截图保存然后把两条候选路由的详细属性做一次逐字段对比就能定位到是哪一步split了。很多时候问题不是策略没配而是路由策略命中的是另一条你没注意到的路径属性对比图一拉出来真相往往一眼就能看出来。