资讯详情

BGP状态机详解:从Idle到Established的六个状态

📅 2026/10/17 15:58:07 | 华诺云谱 👁 阅读
BGP状态机详解:从Idle到Established的六个状态
BGP是互联网的“路由骨架”这句话很多学网络的人估计都听腻了可真要上手BGP基础原理和状态机绝对能劝退不少人六个状态来回跳报文类型一堆属性更是排成串刚觉得看懂了遇到故障该懵还是懵。我这些年跟BGP打交道不少最深的体会是——BGP的难点不在于它有多高深而在于它把TCP连接、协议协商、策略控制好几层东西叠在一起面上一看全是术语底下其实是一条很清晰的流水线。这篇文章不聊复杂的选路策略只把BGP的最底层骨架——基础原理和状态机——掰开揉碎讲清楚。你只要搞明白每个状态背后到底发生了什么再看状态机就像看一条流水线哪个环节堵了一目了然。内容适合刚学BGP的工程师也适合被会话状态折腾过、想系统理一遍的同学。1. BGP基础概念它到底在解决什么问题1.1 从一张“互联网络图”看BGP的定位先把视角拉到足够高。互联网并不是一张局域网而是由大大小小的自治系统AS拼起来的“联邦”。运营商是一个AS云厂商是一个AS某些大型企业也有自己的AS号。每个AS内部怎么跑路由、用什么协议是自己说了算的可一旦要把路由信息从一个自治系统传到另一个自治系统就必须有一个共同的协议来对话这个协议就是BGP。为什么AS内部不能用OSPF或者IS-IS来跨域因为OSPF这类IGP的设计前提是“全网互相信任、拓扑可控、收敛要快”它会把整个网络当作一张图来算最短路径。这个前提在单个园区网、单个数据中心里是成立的放到全球规模就不成立了路由条目太多链路变化太频繁策略需求太复杂。互联网更需要的是“我知道去哪儿但我愿不愿意告诉你怎么走”的控制逻辑这正是BGP的设计目标。所以BGP被设计成一种路径矢量协议。它不计算最短路径而是把“到达某个目的地需要经过哪些AS”这一整条路径信息传出去每经过一个AS就追加自己的AS号。收到路由的一方看到完整路径可以自己去判断我要不要用这条路我要不要继续告诉别人这种设计天然适合策略控制代价是收敛速度没法跟IGP比但互联网的规模下控制力比速度重要得多。顺便澄清一个常见误区BGP并不只用于AS之间。它同样可以在AS内部跑负责把从外部学到的路由在内部传递这就是下一小节要说的iBGP。1.2 eBGP与iBGP的“内外有别”BGP一上来就有两个让人头大的缩写eBGP和iBGP。区分它们其实就看一点邻居是否属于同一个AS。两个不同AS之间的BGP会话叫eBGP同一个AS内部的BGP会话叫iBGP。这个区别不是定义上的洁癖它直接决定了TTL、下一跳、防环机制、路由属性处理方式全都不一样。对比项eBGPiBGP邻居AS号不同相同TCP报文TTL默认1默认64左右路由下一跳默认会改为通告者的地址保持原下一跳不变防环核心AS_PATH环路检测iBGP水平分割规则典型使用场景AS之间跨域互联AS内部传递外部路由eBGP的防环依赖AS_PATH。路由每经过一个AS发送方会把自己的AS号追加到AS_PATH最前面接收方如果发现这条路由的AS_PATH里已经有自己的AS号说明路由绕了一圈绕回来了直接丢弃。这个过程在BGP选路时是强制检查的第一关。iBGP不一样因为AS_PATH里都是同一个AS号没法用这套逻辑防环。iBGP的防环规则简单粗暴从某个iBGP邻居学到的路由不再通告给其他iBGP邻居。这就是所谓的水平分割规则。代价是iBGP在逻辑上通常需要全网状连接否则路由传不开。往下学到的路由反射器、联盟机制本质上都是在绕开“全网状连接”这个硬性要求。1.3 四类报文与一次完整建连BGP整个交互过程只依赖四类报文这个数量在路由协议里确实算少的但每一类都不可替代。报文类型发送时机核心作用OPENTCP连接建立后第一个发送自我介绍协商版本、AS号、Hold Time、Router-ID等UPDATE路由发生变化时通告新路由、撤销旧路由KEEPALIVE周期性发送维持会话防止Hold Time超时NOTIFICATION检测到错误时通知对端错误原因随后立即断开打个不严谨但好记的比方OPEN是双方第一次见面交换名片KEEPALIVE是日常问好证明自己还活着UPDATE是更新通讯录里的联系信息NOTIFICATION是发现对方不对劲直接报警并摔门。整个状态机推进的过程本质上就是在等这四类报文的到达。一次完整的建连流程是这样的双方先完成TCP三次握手主动方先发OPEN报文对端收到后也回一个OPEN报文随后双方互相发送KEEPALIVE都收到之后状态机进入Established。到了这个状态UPDATE报文才能正儿八经地传路由。注意一个容易忽略的点TCP握手只是“会话管道的建立”BGP状态机里专门有一大段流程是在做“协议层的自我介绍和确认”这跟TCP完全是两码事但很多人排障时会混为一谈。理解这一点后面看状态机就顺了。2. BGP状态机六个状态全拆解从Idle到Established2.1 为什么BGP需要状态机路由协议里凡是涉及“建立对等关系”的几乎都有自己的邻居状态机OSPF有IS-IS有BGP也有。原因很简单两个独立系统之间要建立一个有状态的会话必须有一套明确的流程来规定“谁先说话、说到哪一步、下一步做什么”不然双方都不知道对方到底进行到哪了。BGP的状态机还有一个实际价值它就是排障时的第一诊断信息。生产环境中我判断BGP会话是否正常从来不看配置而是直接看邻居状态。状态是Established会话基本没问题状态卡在Active大概率TCP没通状态卡在OpenSent大概率是OPEN报文协商出了问题。可以说状态机不光是协议规程更是一台“故障指示表”。这也是为什么面试网络岗总爱考点状态机——它考察的是你懂不懂BGP的建连本质。2.2 六个状态的行为细节BGP状态机一共有六个状态Idle、Connect、Active、OpenSent、OpenConfirm、Established。很多人背得很熟但背出来和真搞懂是两回事。逐个过一遍每个状态的核心动作和出发条件。状态核心行为离开条件Idle初始状态不发起TCP连接等待开始事件收到启动事件后进入ConnectConnect正在等待TCP连接完成TCP成功进OpenSent失败进ActiveActive主动发起TCP连接但之前的连接尝试失败了TCP成功进OpenSent定时器超时回ConnectOpenSent已发送OPEN报文等待对端OPEN收到合法OPEN进OpenConfirm异常回IdleOpenConfirm已收到对端OPEN等待KEEPALIVE收到KEEPALIVE进Established收到错误回IdleEstablished会话建立完成正常交换UPDATE/KEEPALIVEHold Time超时或收到错误回IdleIdle是整个状态机的起点也是所有异常结束后的落脚点。这个状态下设备不会发起任何连接只有收到开始事件比如配置了BGP邻居并激活、或者管理员手动重启BGP进程才会启动ConnectRetry定时器并尝试建立TCP连接。如果连接一直失败有些实现会做退避避免疯狂重连这算是实现层面的自我保护。Connect状态是第一次尝试建立TCP连接后的等待期。这个状态下TCP握手还在进行定时器还没超时。如果TCP成功设备会立刻发送OPEN报文并进入OpenSent如果TCP失败就转到Active。Active状态是最容易跟Connect混淆的。区别在于Connect是“我发起连接了正在等结果”Active是“我刚才失败了但我还在继续试着连”。两个状态之间来回跳是TCP连接始终建立不起来的典型症状。看到这种循环第一反应应该是检查TCP三要素源地址、目的地址、端口可达性而不是去翻BGP属性。OpenSent状态下本端已经发出OPEN报文正在等对端回OPEN。TCP连接是通的但协议层的协商还没完成。如果收到合法的OPEN报文就进入OpenConfirm如果OPEN报文格式错误或者对端不支持某些关键参数本端会发NOTIFICATION并直接回到Idle。OpenConfirm是一个很短暂的状态表示双方OPEN报文已经交换完了就差最后一脚等对端的KEEPALIVE。收到KEEPALIVE说明对端也确认了会话没问题双双进入Established。如果收到NOTIFICATION说明协商最终还是失败了回Idle重新来。Established就是最终稳定状态。到这里双方可以正常交换UPDATE和KEEPALIVE。但这不代表高枕无忧——Hold Time超时、收到NOTIFICATION都会让状态机瞬间从Established跌回Idle这也是生产环境里最常见的BGP中断原因。2.3 状态转换全景完整事件表把整个状态机压成一张转换表看起来会非常直观。这张表建议收藏排障的时候对着看。当前状态发生的关键事件下一状态Idle启动事件配置激活/手动启动ConnectConnectTCP连接建立成功OpenSentConnectTCP连接建立失败ActiveActiveTCP连接建立成功OpenSentActiveConnectRetry定时器超时ConnectOpenSent收到合法OPEN报文OpenConfirmOpenSent收到异常报文/发送NOTIFICATIONIdleOpenConfirm收到KEEPALIVEEstablishedOpenConfirm收到NOTIFICATIONIdleEstablished收到KEEPALIVE/UPDATEEstablished保持EstablishedHold Time超时/收到NOTIFICATIONIdle这张表里最值得玩味的是Active和Connect的循环。很多新手不理解为什么BGP要把“连不上”分成两种状态。再看一次Connect是初始连接尝试后的等待Active是连接尝试失败后继续尝试的重试状态两者合起来构成了BGP对TCP连接失败的完整响应。看到它们来回跳就不是“某个偶然事件”而是“TCP连接一直没有建立成功”的明确信号。另一个细节是状态机回到Idle之后并不代表一切停止。只要BGP配置还处于激活状态设备会自动触发新一轮的启动事件重新开始整个流程。所以生产环境里常见的现象是状态一直没有停在某处而是一直在Idle和Active之间反复横跳这比单纯停在某个状态更能说明问题。3. 驱动状态转换的核心参数与定时器3.1 三个必须吃透的定时器BGP状态机不是凭空转的背后有三个定时器在驱动节奏分别是ConnectRetry、Hold Time、KeepAlive。这三个参数搞懂很多故障现象就解释得通了。ConnectRetry是TCP连接建立失败后的重试间隔默认通常是120秒。它在Connect和Active两个状态之间起作用TCP连接失败后BGP不会无限重试而是等这个定时器超时后再发起下一次尝试。生产环境中如果看到两个状态每两分钟跳一次基本就是这个定时器在起作用。Hold Time是会话维持时间的上限默认180秒。它表示“如果在这段时间内没有收到对端的任何BGP报文就认为对端不可用”。这里说的报文包括KEEPALIVE和UPDATE不限于KEEPALIVE。Hold Time在OPEN报文里协商最终取双方通告值的较小者。如果双方有一方通告Hold Time为0那么双方协商出的Hold Time就是0表示不超时同时也不发送KEEPALIVE。KeepAlive是维持会话的心跳间隔默认60秒通常取Hold Time的三分之一。KeepAlive必须小于Hold Time否则对端在收到下一个KeepAlive之前就已经Hold Time超时了。实际抓包时可以看到正常情况下每60秒有KEEPALIVE报文一旦这个节奏中断再等一个Hold Time周期邻居状态就会掉。生产环境里我一般不主张把Hold Time调得太小。虽然现在很多设备支持最低1秒甚至更低的配置但BGP走的往往是跨长距离的链路中间任何一次抖动都可能让KEEPALIVE丢失Hold Time越小误判风险越大。默认值180秒虽然收敛慢但稳。3.2 OPEN报文中的“协商现场”OPEN报文是BGP建连时的“自我介绍信”搞清楚里面每个字段就搞清了状态机为什么会在OpenSent阶段卡住。核心字段包括Version目前是4My AS Number本端AS号Hold Time本端愿意接受的Hold时间BGP Identifier也就是Router-IDOptional Parameters能力协商字段比如4字节AS号支持、多协议扩展等。版本字段是硬性的双方版本不一致直接协商失败。AS号不匹配是最常见的OpenSent失败原因之一比如本端配了AS 65001对端却以为你AS 65002双方OPEN报文里AS号对不上状态就起不来。Hold Time如果对端通告了非法值比如小于实现支持的最小值也会触发OPEN错误。Router-ID则要求全网唯一否则会出现冲突检测BGP发现两个连接的BGP Identifier相同会保留其中一条丢弃另一条表现就是两边邻居状态反复震荡。这里有个很实用的抓包技巧卡在OpenSent时直接抓包看OPEN报文里的AS号、Hold Time、Router-ID跟本地配置逐项对照比闭着眼睛猜高效得多。我排过不少看似诡异的建连失败最后都发现是OPEN报文字段不匹配造成的。3.3 TCP层与BGP层的配合关系BGP最特殊的一点是它选择TCP作为传输层。路由信息用TCP承载意味着可靠性、重传、流量控制都是TCP负责的BGP自己不需要实现这些东西。但这同时也引入了一个新的坑TCP层的故障会完全阻断BGP状态机前进。BGP监听的是TCP 179端口。正常情况下主动配置方会发起TCP连接但实际运行中两端都会尝试建连。这里最关键的是源地址和TTL问题。eBGP场景下TCP报文TTL默认是1意味着只能直连中间隔一台路由器TTL就耗尽TCP握手根本没机会完成。如果要跨多跳建eBGP必须显式配置增大TTL的选项常见叫法是ebgp-multihop并指定跳数。iBGP场景里物理链路可能很多条一般会建议用Loopback接口作为源地址也就是配置update-source否则从物理接口发出去的包源地址不固定对端可能因为源地址不对直接丢弃。排障时最该养成的习惯是分层判断TCP层的问题就盯TCPBGP层的问题才盯状态机。怎么判断先ping对端地址确认IP层通不通再用telnet方式测对端179端口是否能通最后抓包看TCP SYN和SYN-ACK是否正常往返。如果TCP根本建不起来BGP状态机再清楚也没有用。4. 状态机卡住与抖动排查实录与速查表4.1 长期停留在Idle或Active循环故障现场最常见的就是状态在Idle和Active之间来回跳永远到不了OpenSent。这个现象几乎可以断定是TCP层的问题。我排过的一个典型场景是这样的两台设备分别属于两个AS都配置了BGP邻居但状态就是反复横跳。ping对端Loopback地址能通IP层没问题。排查telnet对端179端口时发现不通再仔细一看本端配置里没有指定update-source导致TCP连接从物理接口的地址发起而对端只允许Loopback地址作为BGP源直接把报文丢弃了。加上update-source之后状态一下子从Active跳到了Established。这个案例说明一个很硬的经验BGP邻居配置远不止“加一条peer”那么简单。源地址、目的地址、TTL、ACL四样东西任何一个不对TCP都不可能建起来。顺序建议是先ping物理连通性再telnet 179端口验证TCP可达接着查ACL、查update-source、查ebgp-multihop。这几项全过一遍基本能找到问题。还有一种容易忽略的情况对端根本没有配置BGP邻居或者配置的AS号不对。单边配置BGP的时候对端不会响应TCP连接表现同样是Active循环。所以排查时务必确认两端配置都在且配置的邻居关系是对称的。4.2 卡在OpenSent与OpenConfirm如果状态停在了OpenSent说明TCP已经通了问题出在BGP协议层的OPEN报文协商上。最常见的几个原因AS号不匹配、Hold Time非法、Router-ID冲突、必要的能力参数对端不支持。卡在OpenConfirm的情况相对少见但一旦出现意味着OPEN报文已经交换完毕就差等对端的KEEPALIVE。这种时候要重点看两端KeepAlive间隔和Hold Time的协商结果。比如一端Hold Time配得很短另一端KeepAlive间隔按默认配置发得很慢可能就会出现“还没来得及收到心跳就被判超时”的尴尬局面。还有一个很容易误判的点如果两端配置了TCP认证但认证密码不一致抓包看到的症状五花八门有的表现为TCP连接反复重置有的表现为卡在Active极少能走到OpenSent。因为认证是在TCP层做的报文在TCP层就被丢弃了BGP根本看不到。排查这类故障时认证配置要单独列出来逐端核对不要被状态机带偏。4.3 Established后反复跌落Established之后反复掉是最让人头疼的一类问题因为“看起来是通的却又总断”。先排除人为操作比如管理员重置了BGP会话然后去查看NOTIFICATION报文里的错误码和错误子码这是最直接的线索。Hold Time超时是最常见的跌落原因。表现为KEEPALIVE报文有一段时间完全没有收到Hold Time归零后主动断开。这通常是中间链路质量问题比如高丢包、拥塞、CRC错误导致心跳报文在途中丢了。这类的核心不是调大Hold Time而是找到丢包点。沿链路逐段看接口错包计数或抓包看KEEPALIVE是否到达对端能定位到底丢在哪一段。另一种常见原因是触发策略导致的主动断开。比如max-prefix设了最大前缀数对端通告的路由数量超过限制会触发NOTIFICATION并断开会话。再比如入方向路由策略突然变更拒绝了对方所有的路由也会导致对端发NOTIFICATION。这些故障都会在日志里留下错误记录看日志比瞎猜有效得多。4.4 一个可以直接对照的故障速查表故障现象最可能的原因优先排查动作Idle与Active循环TCP连接建立失败源地址/ACL/TTL有问题ping、telnet 179端口、查看TCP状态长期停在OpenSentOPEN报文协商失败AS号不匹配、Hold Time非法、Router-ID冲突抓包对比OPEN报文与本地配置停在OpenConfirm等待KEEPALIVE心跳丢失或间隔异常查看Hold Time协商结果、两端KeepAlive配置Established反复跌落Hold Time超时、中间链路丢包、max-prefix触发、认证失效查NOTIFICATION错误码、查日志、查链路丢包单边永远Active对端未配置邻居或AS配置不对称核对两端配置的邻居关系与AS号这张表是我实际排障时一直挂在手边的速查逻辑它把状态现象、原因、动作串成了一条线。遇到问题先对号入座能省掉大量试错时间。5. 从零配置到状态观察一整套可复用的实操流程5.1 最小化邻居配置示例纸上谈兵没意思直接给一个最简配置作为起步帧。以下示例为A设备和B设备建立eBGP邻居A设备AS号为65001B设备AS号为65002双方通过Loopback接口建立会话。A设备配置bgp 65001 router-id 10.0.0.1 peer 10.0.0.2 as-number 65002 peer 10.0.0.2 update-source 10.0.0.1 peer 10.0.0.2 ebgp-multihop 2B设备配置bgp 65002 router-id 10.0.0.2 peer 10.0.0.1 as-number 65001 peer 10.0.0.1 update-source 10.0.0.2 peer 10.0.0.1 ebgp-multihop 2这里每一条配置都有目的。router-id是BGP的身份证必须唯一peer命令指定对端地址和AS号update-source确保用Loopback地址作为TCP源地址避免源地址随机ebgp-multihop则是允许eBGP跨多跳建立连接。不同产品族的命令写法可能略有差异但参数含义是通用的抓住这四件事基础就稳了。5.2 状态观察与常用调试命令配置完成后第一件事不是看路由表而是确认邻居状态。不同设备族查看命令不一样常见两类# A类设备风格 show bgp neighbors show tcp brief # B类设备风格 display bgp peer display tcp status关键看State字段是Established还是卡在别的状态。同时查看Hold Time、KeepAlive的实际生效值以及对端通告的Router-ID这些信息在排障时非常有用。如果需要看更底层的信息抓包最直接。在设备上或旁路交换机上抓179端口的流量重点看三样东西TCP三次握手是否正常完成、OPEN报文里的字段和本端配置是否匹配、KEEPALIVE报文是否按照协商的间隔稳定发送。抓包数据比任何抽象的状态描述都有说服力一次抓包能顶十次猜测。调试日志命令建议慎用。BGP的调试输出在某些负载高的设备上会放大CPU开销生产环境尤其要克制。更好的做法是先看静态信息比如show命令和日志定位到具体阶段再去抓包不要一上来就开debug。5.3 常规文档不会写的实战建议最后聊几个实操中积攒下来的习惯这些在标准文档里通常看不到但对日常维护特别有用。第一改配置之前先记录当前基线。每次变更BGP配置前先截图或记录下邻居状态、Hold Time、对端Router-ID、已收到的路由数量。这样一旦变更出了岔子能立刻对比出“什么变了”。第二不要只盯着BGP配置本身。很多BGP会话长期建不起来最后查出来是防火墙策略挡了179端口或者中间设备的安全策略拦了TCP SYN。BGP排障要先分TCP层和协议层TCP不通就在网络路径上找原因别在BGP参数里原地打转。第三能软重置就不要硬重置。BGP支持软重置的时候优先用路由刷新机制重新通告路由避免对整个会话做硬重置。硬重置意味着状态机直接回到Idle正在经过该邻居的流量会全部中断生产环境下这是伤筋动骨的操作。第四维护一份“正常状态记录表”。每一对重要邻居记下它正常时的状态、Hold Time协商值、KeepAlive实际间隔、UPDATE报文频率。这些数据是日后排障的对照基准。我自己的习惯是每次BGP排障结束都会把现象、根因、处理动作记成一条短记录久而久之很多所谓疑难杂症其实都是见过的老问题。BGP这套东西状态机部分是基础中的基础也是最能体现网络工程师排障功底的地方。状态机并不难难的是把每个状态放到真实的TCP连接和报文协商背景下去理解。搞懂了状态机BGP在你眼里就不再是一堆需要背的术语而是一台能看透的机器哪里卡住就修哪里。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑