前文我们了解了MPLS的静态LSP配置相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16937104.html;今天我们来聊一聊标签分发协议LDP相关话题;
我们知道在mpls网络中,只要有了标签,转发就是一件很简单的事;但是如何产生标签,却是MPLS中较难的部分;手动静态配置吧,过于繁琐,且容易出错;为此,MPLS有一个叫LDP的协议出现了;
LDP简介
LDP是Label Distribution Protocol的首字母缩写翻译成中文就是标签分发协议;该协议主要用于动态分配和维护mpls标签;在LSR之间通过建立LDP Session来交换彼此的标签,完成标签的分发;建立了LDP Session的两台设备称为LDP Peers(LDP邻居或者叫对等体);

提示:LDP通过hello信息建立起邻居,随后建立起LDP会话后,就开始在LDP邻居间交换标签和FEC映射,从而完成LSP的建立;
LDP消息类型
LDP封装在UDP或TCP之上,端口号为646;


LDP发现机制

提示:LDP发现机制有两种,第一种是LDP基本发现机制,即发现直连邻居,使用组播;通过周期性的发送LDP Link Hello,建立本地LDP会话;第二种是LDP扩展发现机制,即发现非直连的邻居,使用单播;通过周期性发送LDP Targeted Hello,建立远端LDP会话;

提示:基本发现机制使用组播地址224.0.0.2;基本方式只能用于两个路由器直连,不能跨网段;

提示:扩展发现机制使用单播,所以可以跨路由器,使用各自的单播地址建立会话;前提是这两个单播地址是能够互通的;
LDP邻居发现过程

提示:LDP hello消息中使用UDP封装,发送周期为5秒,使用组播地址224.0.0.2(所有路由器);hello消息中,携带Transport Address字段,该字段默认域设备配置的LSR ID一直,表明与对端建立邻居关系时所使用的ip地址;所以我们配置的LSR ID 需要保证路由可达,同时对应的接口也需要存在;只有保证两个LSR ID路由可达能够互相通信以后,对应双方才会正式通过TCP的三次握手,用自己的LSR ID来建立起邻居;当然这是默认情况;我们也可以根据自己的需求来更改transport address字段信息;
LDP会话建立过程

提示:建立会话阶段由地址大的一方向发送协商参数,协商参数包括LDP协议版本,标签分发方式、Keepalive保持定时器的值、最大PDU长度和标签空间等;如果对端不能接受相关参数,则发送Notification消息来终止LDP会话的建立:如果对端能接受,则对端发送keepalive消息并携带上自己的参数信息,随后本端收到参数后检查是否接受,接受就发送keepalive消息,随后双方都收到了对方的keepalive消息以后,对应会话就建立起了;LDP会话建立成功后,随后就进行fec的创建与标签的分发;

提示:以上是LDP整个活动周期,最初是两个路由器通过发送hello消息寻找建立邻居,随后通过transport address建立tcp三次握手,随后就是发送协商参数进行会话建立;会话建立好以后,对应双方进行fec的创建与标签的分发;最后一个是会话没有能正常建立就会发送Notification消息告知对方会话建立失败,终止LDP会话的建立;
LDP标签的发布和管理
LDP会话建立后,LDP协议开始交换标签映射等消息用于建立LSP;RFC5036本别定义了标签发布方式、标签分配控制方式、标签保持方式来决定LSR如何发布标签和管理标签;
标签发布方式

提示:标签的发布方式有两种,DU(Downstream Unsolicited,下游自主);所谓下游自主是指LSR无需从上游获得标签请求消息即可进行标签的分配与分发;DoD(Distribution on Demand,下游按需);所谓下游按需是指LSR必须从上游获得标签请求消息之后进行标签分配与分发;华为和思科设备默认是采用DU(下游自主),这是因为在网络拓扑发生变化时,采用DU可以快速反应为新的拓扑分发标签,收敛时间相对于DoD较短;
标签分配控制方式

提示:Label Distribution Control Mode,标签分配控制方式;为一条路由前缀分配标签的前提条件;标签由设备自动随机生成;标签分配控制方式也有两种类型;一种是Independent,一种是Ordered;Independent表示独立;所谓独立是指LSR可以主动分配标签,无需灯带下游的标签;Ordered表示有序,有序是指LSR只有收到下游的标签后,才能分配标签;华为设备默认采用Ordered模式,这样是为了避免下游ip分组的标签为分配或收敛时间较长,上游的标签已分配,数据开始转发而造成数据丢失;思科设备默认采用Independent;也就是说Independent追求快速,但不稳定,可能出现数据丢失的情况;Ordered追求稳定,但是相对于Independent要慢;
标签的发布方式和控制方式的组合

标签保持模式
Label Retention Mode,标签保持模式是指如何保留从邻居接收到的标签;
自由模式(Liberal)

提示:所谓自由模式是指保留邻居发送的所有标签,无论邻居是否是自己的下一跳;这种方式的优点是,路由发送变化能够快速建立新的LSP进行数据转发;缺点就是消耗更多的内存和标签空间;
保守模式(Conservative)

提示:保守模式是指只保留来自下一跳邻居的标签;这种模式的优点是节省内存和标签空间;缺点是路由发生变化时必须从新的下一跳那里获得标签后才能数据转发,收敛较慢;通常与DoD方式一起;华为和思科设备默认采用Liberal自由模式;
LDP建立LSP到数据转发过程
LDP建立LSP过程

提示:IGP协议负责实现mpls网络内路由可达,为fec的分组提供路由;LDP协议负责实现对FEC的分类、标签的分配以及LSP的建立和维护等操作;
MPLS数据转发过程

提示:在mpls网络中,数据包在每台路由器上根据已分配的标签进行标签的封装和转发;当数据包到达egress节点时,对应发出的数据包都不会代有标签,因为非mpls网络路由器,它是识别不了mpls标签的;其次在mpls网络中,如果流量很大的情况下,如果让egress节点再处理标签就会额外给egress节点带来负担,所以更妥当的做法是在倒数第二跳节点将标签剥离掉,让egress节点直接用ip路由转发会更为妥善(它不需再查标签转发表,然后再查ip路由表,而是直接查找ip路由表将对应数据包转发出去);

提示:倒数第二跳弹出的具体过程如上图所示;RTC收到RTB发送代有标签1026的报文,查找LFIB(Label Forwarding Information Base,标签转发信息数据库)表,发现分配的出标签为隐式空标签3,于是执行弹出标签的动作,并将ip数据包转发给下游路由器RTD;RTD收到RTC发送ip报文,直接查找自己的FIB表,根据FIB表中的出接口进行ip报文封装并转发出去;

提示:最下游路由器在标签分发时,会给倒数第二跳路由器分发标签为3的标签,表示倒数第二跳发出的数据包,剥离标签,即最后一跳路由器收到不带标签的数据包;
倒数第二跳弹出
PHP(Penultimate Hop Popping);所谓倒数第二跳弹出是指在mpls网络中当携带有标签的数据包到达倒数第二跳路由器时,会将对应的标签剥离,然后将数据包转发给最后一跳;这是因为在最后一跳节点,标签已经没有使用价值;在这种情况下将标签弹出,减少最后一跳的负担;

提示:上图主要描述了在mpls网络中,标签在最后一跳节点都会将所有标签剥离,然后将原始数据包转发至下一个非mpls网络的路由器;

提示:上图描述了倒数第二跳弹出的示意图;在倒数第二跳时间顶层标签剥离,减轻最后一跳的负担;这里说一下,倒数第二跳弹出主要是弹出顶层标签(如果有多层标签的情况下);即路由器查看标签转发表发现转发出去的标签为3,对应就会把原有标签剥离,然后转发给下一跳路由器;对应路由器收到的数据包就不带任何标签;
特殊保留标签

提示:标签3是隐式空标签(Implicit-null),表示通知倒数第二跳路由器移除顶层标签;这里需要注意标签3其实永远不会出现在MPLS报文的标签栈中;即我们抓包是看不到对应标签3的;

提示:标签0显式空标签(explicit-null),表示通知路由器直接弹出标签;在实施QOS时,最后一跳必须携带EXP位,因此标签不能被弹出,需要配置显式空标签,此时分配给特定路由器的标签值为0并转发给LDP邻居;
简单讲,当路由器查看LFIB表发现转发出去的标签为3,对应数据包发出时,对应标签就被剥离掉了;所以到最后一跳的数据包是不带标签;当路由器查看LFIB表发现转发出去的标签为0,对应数据包发出时还是会携带标签0,到达最后一跳,对应数据包是携带标签0;两者区别就是隐式空标签在倒数第二跳转发之前被剥离,显式空标签是在最后一跳数据转发出去之前剥离;
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳