MPLS LDP工作原理与LDP ID传输地址选举机制详解
1. 从一个让人抓狂的故障说起为什么LDP邻居死活起不来刚接手某运营商城域网扩容项目那会儿我遇到过一个至今印象深刻的故障。两台核心路由器之间直连链路物理层完全正常OSPF邻居也稳稳地Full了但LDP会话就是卡在Initialized状态反复震荡标签分发完全瘫痪整条MPLS转发路径上的业务全部中断。当时排查了整整一个下午最后发现问题出在LDP ID的传输地址选择上——两台设备的Loopback接口虽然都通告进了IGP但其中一台的LDP传输地址被手动指定成了一个对端路由表里压根不存在的地址。这个坑让我意识到很多人学MPLS的时候把注意力全放在标签栈怎么压怎么弹、LFIB怎么查表转发上却忽略了LDP这个标签分发协议本身的握手逻辑和ID协商机制。而恰恰是这些底层细节决定了整个MPLS网络能不能正常运转起来。这篇内容就是围绕MPLS LDP的基本工作机制和LDP ID这两个核心点展开的。我会从LDP会话建立的完整流程讲起把Discovery、Session Establishment、Label Distribution三个阶段拆开揉碎重点说清楚LDP ID的组成结构、传输地址的选举逻辑以及在实际组网中怎么避坑。适合已经了解MPLS基础概念、正在做网络部署或准备认证考试的网络工程师阅读也适合那些被LDP邻居震荡折磨过的同行参考。2. LDP协议在MPLS体系中的定位它到底解决了什么问题2.1 没有LDP的时候MPLS网络是什么样子要理解LDP的价值得先知道它不在的时候网络怎么跑。MPLS的转发依赖标签交换每台LSR标签交换路由器需要知道去往某个FEC转发等价类的报文应该打上什么入标签、从哪个接口发出去、对端期望收到什么出标签。这些映射关系如果全靠手工配置在一个几十台设备的中型网络里就是灾难——任何一条链路或节点的增减都意味着大量静态标签映射需要人工同步修改。早期确实有静态LSP的部署方式我在一些对稳定性要求极高、拓扑极其固定的专线场景里也用过。静态LSP的优点是可控性强、不依赖动态协议但缺点同样明显无法自动适应拓扑变化扩展性几乎为零。一个省级网络动辄上百台设备、上千条LSP靠手工维护根本不现实。LDP的出现就是为了解决这个自动化问题。它让LSR之间能够动态地交换FEC到标签的映射信息拓扑变化时自动重新收敛不需要人工干预。你可以把LDP理解成标签世界的路由协议——OSPF和IS-IS负责计算去往某个网段走哪条路LDP负责告诉沿途每台设备这条路对应的标签该怎么分配。2.2 LDP与IGP的分工边界这里有个初学者容易混淆的点LDP本身不做路由计算。它不关心网络拓扑长什么样也不参与最短路径的计算。LDP做的事情是跟随IGP——IGP算出有哪些可达的前缀LDP就为这些前缀分配标签并通告给邻居。具体来说当IGP比如OSPF在路由表中生成了一条去往10.1.1.0/24的路由LDP会感知到这个前缀然后为它分配一个本地标签并通过LDP会话把这个前缀标签的绑定关系告诉所有LDP邻居。邻居收到后把这条映射关系存进LIB标签信息库再结合路由表的下一跳信息生成LFIB标签转发信息库表项用于实际的数据转发。这个分工意味着LDP会话的建立不依赖IGP但LDP标签映射的有效性依赖IGP。两台设备之间的LDP会话可以正常建立但如果IGP路由不可达对应的标签映射就不会被优选进LFIB。反过来如果IGP正常但LDP会话断了标签转发同样会中断。两者是互补关系缺一不可。2.3 LDP的四种消息类型LDP协议定义了四类消息理解这四类消息是搞懂工作流程的基础消息类型英文名称作用传输方式发现消息Discovery Message宣告LSR的存在发现邻居UDP 646端口组播/单播会话消息Session Message建立、维护、终止LDP会话TCP 646端口通告消息Advertisement Message通告标签映射关系TCP 646端口通知消息Notification Message报告错误和状态信息TCP 646端口发现阶段用UDP是因为此时还没有建立TCP连接需要一种轻量级的方式让设备互相打招呼。一旦发现邻居后续的会话建立和标签交换全部走TCP保证可靠性。这个设计思路和很多协议一样——先用无连接的方式探路确认对方存在后再建立可靠连接做正经事。3. LDP ID的组成结构与传输地址的选举逻辑3.1 LDP ID到底是什么LDP ID是LDP协议中用于唯一标识一台LSR的标识符格式固定为4字节路由器ID 2字节标签空间ID总共6字节。路由器ID部分通常是一个32位的值一般用设备的Loopback接口地址来充当。标签空间ID则用来区分不同的标签空间——如果一台设备只有一个标签空间绝大多数情况这个值就是0。所以你在设备上看到的LDP ID通常长这样10.0.0.1:0冒号前面是路由器ID冒号后面是标签空间ID。这里要特别注意一个容易搞混的概念LDP ID不等于传输地址。LDP ID是标识我是谁传输地址是告诉对方你要跟我建立TCP会话的话连哪个IP。两者可以相同也可以不同取决于配置。3.2 传输地址的选举规则传输地址的选择有一套明确的优先级规则从高到低依次是手动配置的传输地址如果管理员显式指定了ldp transport-address那就用这个地址优先级最高。LSR ID对应的地址如果没有手动配置设备会尝试使用LSR ID通常是Loopback地址作为传输地址。接口地址如果前两者都不可用才会使用物理接口地址。为什么默认优先用Loopback地址因为Loopback接口只要设备不关机就永远UP不会因为某条物理链路故障而消失。LDP会话建立在TCP之上如果传输地址对应的接口Down了TCP连接就会断开LDP会话随之中断。用Loopback地址可以保证只要设备活着、路由可达LDP会话就能维持。我在实际项目里踩过的坑就是某台设备的Loopback地址虽然配置了但没有通告进IGP导致对端无法路由到LDP ID中的地址TCP握手直接失败。所以配置LDP之前一定要确认LDP ID和传输地址在IGP中可达这是最基本的检查项。3.3 标签空间ID的两种模式标签空间ID涉及一个重要的概念区分每平台标签空间和每接口标签空间。每平台标签空间Per-Platform Label Space整台设备共用一个标签空间所有接口收到的标签都从同一个池子里分配。标签空间ID固定为0。这是目前绝大多数部署场景使用的模式。每接口标签空间Per-Interface Label Space每个接口有独立的标签空间标签空间ID不为0。这种模式主要用于帧中继、ATM等传统WAN技术现在基本见不到了。对于以太网和POS接口默认都是每平台标签空间。你在排查LDP问题时如果看到标签空间ID不是0那就要确认一下接口类型和配置是否匹配预期。4. LDP会话建立的完整流程拆解4.1 发现阶段Hello消息如何找到邻居LDP的发现机制分两种基本发现机制和扩展发现机制。基本发现机制用于直接相连的邻居。设备会周期性地向组播地址224.0.0.2的UDP 646端口发送LDP Hello消息。Hello消息里携带了发送方的LDP ID、传输地址、保持时间等参数。收到Hello的设备如果发现对方是潜在邻居就会记录下来进入下一步。扩展发现机制用于非直连的邻居比如跨越多跳的LDP会话。这时Hello消息是单播发送的目标地址由管理员手动指定。扩展发现机制在实际中用得不多但在某些特定场景比如跨域MPLS下会用到。Hello消息的默认发送间隔是5秒保持时间是15秒。也就是说如果连续3个Hello周期15秒没收到对方的Hello就会认为邻居失效拆除会话。这个参数可以调整但一般不建议改——改大了故障感知慢改小了容易因为网络抖动误判。注意Hello消息的源地址和目的地址都是接口地址不是Loopback地址。这一点在排查发现阶段问题时很关键——如果接口地址之间因为ACL或其他原因不通Hello就发不出去邻居根本发现不了。4.2 会话建立阶段TCP握手与参数协商当两台设备通过Hello互相发现后会进入会话建立阶段。这个阶段的核心是确定谁主动发起TCP连接。规则是这样的比较双方的传输地址传输地址较大的一方主动发起TCP连接。比如A的传输地址是10.0.0.1B的传输地址是10.0.0.2那么B会主动向A的646端口发起TCP连接。这个规则保证了不会出现双方同时发起连接导致冲突的情况。TCP连接建立后双方会交换Initialization消息协商一系列参数LDP协议版本目前都是版本1。标签分发方式分为DoDDownstream on Demand下游按需和DUDownstream Unsolicited下游自主。DU模式下LSR会主动向邻居通告标签映射不需要邻居请求DoD模式下只有收到邻居的请求才通告。实际部署中绝大多数用DU模式。标签保留方式分为保守模式和自由模式。保守模式下只保留来自下一跳的标签映射自由模式下保留所有收到的标签映射。自由模式收敛更快但占用更多内存。环路检测可选功能用于检测LSP环路。这些参数必须双方协商一致否则会话建立会失败。我在实际中遇到过因为两端标签分发方式配置不一致导致会话卡在Initialized状态的案例——一端配了DU另一端配了DoDInitialization消息里的参数对不上会话就建不起来。4.3 标签分发与通告阶段会话建立完成后进入标签分发阶段。以DU模式为例流程是这样的每台LSR为本地路由表中的每条IGP前缀分配一个本地标签。LSR通过Label Mapping消息把前缀标签的绑定关系通告给所有LDP邻居。邻居收到Label Mapping消息后把映射关系存入LIB。当LIB中的某个映射关系对应的下一跳与路由表的下一跳一致时这条映射被优选生成LFIB表项。这里有个关键点LDP通告的是我为这个前缀分配的本地标签而不是我希望你用什么标签。标签分配是本地行为每台设备独立决定。下游设备分配了标签后通告给上游上游收到后把这个标签作为出标签使用。这就是所谓的下游分配上游使用。举个例子数据流从R1流向R3经过R2。R3为前缀10.1.1.0/24分配了标签100通告给R2。R2收到后知道去往10.1.1.0/24的报文从R2发往R3时应该打标签100。同时R2自己也分配一个标签200通告给R1。R1收到后知道去往10.1.1.0/24的报文从R1发往R2时应该打标签200。数据包到达R2时R2查LFIB把标签200换成100从去往R3的接口发出去。4.4 会话维护与拆除LDP会话建立后通过两种机制维护Hello消息继续周期性发送用于检测邻居是否存活。如果15秒内没收到Hello认为邻居失效。Keepalive消息通过TCP连接周期性发送默认间隔60秒保持时间180秒。用于检测TCP连接是否正常。如果Hello超时会话会被拆除但TCP连接可能还保留着。如果Keepalive超时TCP连接会被关闭会话彻底拆除。两种机制的检测粒度不同Hello检测的是链路/邻居级别的故障Keepalive检测的是TCP会话级别的故障。5. 实际组网中LDP配置的关键参数与避坑要点5.1 传输地址配置的三种典型场景在实际项目中传输地址的配置策略直接影响LDP的稳定性。我总结了三类典型场景场景一纯Loopback环境。所有设备的LDP ID和传输地址都用Loopback地址且Loopback地址全部通告进IGP。这是最推荐的做法稳定性最好。配置上只需要在LDP视图下确保transport-address使用LSR ID即可大多数厂商设备默认就是这个行为。场景二Loopback不可达的尴尬。有些网络设计里Loopback地址没有通告进IGP或者被路由策略过滤掉了。这时如果还用Loopback作为传输地址TCP连接就建不起来。解决办法要么是把Loopback通告进IGP要么手动指定传输地址为某个物理接口地址。但物理接口地址的稳定性不如Loopback接口一Down会话就断。场景三多路径环境下的传输地址选择。如果两台设备之间有多条等价路径传输地址的选择会影响TCP连接走哪条路。这种情况下建议用Loopback地址让IGP去决定路径LDP不参与路径选择。5.2 标签分发方式的选型对比对比维度DU下游自主DoD下游按需通告触发主动通告无需请求收到请求才通告收敛速度快慢标签资源占用较多较少配置复杂度低高适用场景绝大多数以太网环境传统WAN、标签资源紧张场景实际部署中99%的场景用DU模式。DoD模式主要出现在一些老旧的帧中继或ATM网络里现在新建网络基本不会用到。配置时两端必须一致否则会话建立失败。5.3 标签保留模式的取舍自由模式Liberal Retention和保守模式Conservative Retention的选择本质上是在内存和收敛速度之间做权衡。自由模式下LSR保留所有邻居发来的标签映射不管这个邻居是不是去往该前缀的最优下一跳。当最优下一跳故障时如果备用下一跳的标签映射已经在LIB里了可以立即切换收敛非常快。代价是LIB表项多内存占用大。保守模式下只保留最优下一跳发来的标签映射。内存省了但收敛慢——备用路径的标签映射需要重新请求和通告。在内存充足的现代设备上我一般建议用自由模式换取更快的收敛速度。但在一些低端设备或大规模网络里保守模式也有其价值。5.4 一个真实的LDP震荡排查案例回到开头提到的那个故障。两台设备LDP会话反复震荡我按照以下链路逐步排查第一步确认Hello是否正常。查看LDP邻居发现状态发现邻居能发现说明Hello消息收发正常UDP 646端口和组播通信没问题。第二步确认TCP连接是否建立。查看TCP连接状态发现TCP连接时断时续。进一步查看日志发现TCP连接建立后很快被RST。第三步检查传输地址可达性。在两端分别ping对方的传输地址发现A能ping通B的传输地址但B ping不通A的传输地址。问题定位到了。第四步检查路由表。查看B的路由表发现A的传输地址对应的网段确实不在路由表里。再查A的配置发现A的Loopback地址虽然配置了但被一条路由策略过滤掉了没有通告进IGP。第五步修复。修改A的路由策略把Loopback地址放行重新通告进IGP。B的路由表里出现了A的Loopback路由TCP连接稳定建立LDP会话恢复正常。这个案例的教训是LDP会话建立的前提是传输地址双向可达。单向可达的情况下Hello能通因为Hello用的是接口地址但TCP建不起来因为TCP用的是传输地址。排查时要区分这两种地址的不同作用。6. LDP与相关协议的协同关系及进阶话题6.1 LDP与IGP的联动机制LDP本身不感知IGP的具体实现它通过路由表这个中间层与IGP联动。当IGP在路由表中添加、删除或修改一条路由时LDP会收到通知相应地更新标签映射。这个联动有一个重要的时间差问题IGP收敛需要时间LDP标签映射的更新也需要时间。在IGP收敛完成但LDP还没更新完的窗口期内数据转发可能出现短暂的黑洞。为了减少这个窗口期的影响一些厂商实现了LDP与IGP的同步机制——在IGP收敛完成后延迟一段时间再撤销旧的标签映射给LDP留出更新时间。这个同步机制在不同厂商的设备上叫法不同配置方式也不同。在实际组网中如果对收敛速度要求高建议开启这个功能。6.2 LDP会话的保护机制LDP会话建立在TCP之上TCP本身有重传和超时机制。但在网络震荡时TCP连接可能频繁断开重连导致LDP会话不稳定。为了提高稳定性可以配置LDP会话保护功能会话保持时间在TCP连接断开后保持LDP会话状态一段时间等待TCP重连。如果在这段时间内TCP重连成功会话继续不需要重新交换标签映射。优雅重启设备重启时通过协议扩展通知邻居我要重启了请保留我的标签映射一段时间重启完成后重新同步避免转发中断。这些机制在核心网中非常重要配置时要注意两端设备的兼容性。6.3 LDP在实际网络中的部署建议根据我这些年的部署经验LDP的配置有几个原则值得遵循原则一传输地址统一用Loopback。除非有特殊需求否则LDP ID和传输地址都用Loopback地址且确保Loopback地址在IGP中可达。这是最简单也最稳定的做法。原则二标签分发方式统一用DU。除非对接的是老旧设备否则一律用DU模式。配置简单收敛快。原则三开启会话保护。在核心和汇聚层设备上开启LDP会话保护减少网络震荡对LDP会话的影响。原则四监控LDP会话状态。通过SNMP或Telemetry监控LDP会话的状态变化一旦发现震荡立即告警。LDP会话震荡往往是底层网络问题的表象早发现早处理。原则五定期检查标签空间使用情况。虽然标签空间通常很大每平台模式下有上百万个标签可用但在大规模网络中还是要关注标签分配情况避免耗尽。6.4 从LDP到SR-MPLS的演进思考这几年Segment RoutingSR技术逐渐成熟SR-MPLS用IGP直接扩展来分发标签不再需要LDP这个独立协议。从架构上看SR-MPLS简化了协议栈减少了协议间的同步问题。但LDP并不会立刻消失。大量现网设备还在运行LDP很多业务系统也依赖LDP建立的LSP。从LDP向SR-MPLS的迁移是一个渐进过程在过渡期两者会共存。理解LDP的工作机制对于维护现有网络和规划未来演进都有实际意义。我在一些新建网络中已经开始用SR-MPLS替代LDP但在存量网络中LDP仍然是主力。掌握LDP的底层原理在排查故障和优化网络时能派上大用场。7. 几个容易被忽略的LDP细节与实操心得7.1 LDP ID冲突的检测与处理如果两台设备的LDP ID相同LDP会话无法正常建立。协议本身有检测机制——当设备收到一个与自己LDP ID相同的Hello消息时会记录冲突并告警。但在实际中这种冲突往往是因为配置疏忽导致的比如两台设备误用了同一个Loopback地址。处理方法是修改其中一台设备的LDP ID通常是修改Loopback地址或手动指定LSR ID然后重启LDP进程。修改后要确认全网路由收敛正常避免因为地址变更导致其他协议也受影响。7.2 标签映射的撤销与回收当一条路由失效时LDP会发送Label Withdraw消息通知邻居撤销对应的标签映射。邻居收到后从LIB中删除该映射并回复Label Release消息确认。这个过程叫标签回收。如果Label Withdraw消息丢失邻居可能继续保留无效的标签映射导致转发黑洞。TCP的可靠性机制可以很大程度上避免消息丢失但在极端情况下比如TCP连接中断还是可能出现不一致。LDP会话重建后双方会重新交换所有标签映射最终达到一致状态。7.3 实操中常用的排查命令不同厂商的命令行语法不同但排查思路是一致的。以下是我常用的排查维度查看LDP邻居状态确认邻居是否发现、会话是否建立。查看LDP会话详细信息确认协商参数是否一致、传输地址是否正确。查看LIB表确认标签映射是否正常学习到。查看LFIB表确认标签转发条目是否正常生成。查看LDP统计信息确认消息收发是否正常有无异常丢弃。抓包分析在极端情况下通过抓包分析LDP消息的交互过程定位问题所在。提示排查LDP问题时建议按照发现→会话→通告→转发的顺序逐层排查不要跳步。每一层都有对应的状态和命令逐层确认可以快速定位问题所在的层次。7.4 一个关于标签空间的小实验如果你想直观理解标签空间的分配逻辑可以在实验环境中做一个小实验配置两台设备建立LDP会话然后分别查看它们为同一个前缀分配的标签。你会发现两台设备分配的标签值是不同的——这验证了标签分配是本地行为这个结论。再进一步你可以修改其中一台设备的标签分配范围观察标签值的变化。这个实验能帮你建立对标签空间管理的直观认识比单纯看文档要深刻得多。8. 写在最后LDP排障中那些文档不会告诉你的经验LDP这个协议看文档觉得很简单——不就是发现邻居、建会话、发标签三步走吗但真正在现网里排障的时候你会发现问题的表现形式千奇百怪而根因往往藏在一些不起眼的细节里。我个人的经验是LDP的问题九成以上出在传输地址和IGP可达性上。会话起不来先查传输地址能不能ping通会话震荡先查传输地址对应的接口或路由是否稳定标签映射学不到先查IGP路由是否正常。把这三个先查养成习惯能省下大量排查时间。另一个心得是不要孤立地看LDP。LDP是MPLS转发体系中的一环它和IGP、路由策略、接口状态都有关联。排查LDP问题时要把视野放宽到整个控制平面和转发平面从全局角度分析问题。很多时候LDP会话中断只是表象真正的问题在IGP或者底层链路上。最后说一个实操中的小技巧在设备上开启LDP的日志功能把会话状态变化、标签映射更新等事件记录下来。这些日志在事后分析问题时非常有用能帮你还原故障发生的时间线和事件序列。日志级别不要开太高否则信息量太大反而干扰判断一般开到informational级别就够了。