HCNP Routing&Switching之BGP报文结构、类型和状态
前文我们了解了BGP的邻居建立条件、优化以及BGP认证相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15395723.html;今天我们来聊一聊BGP报文结构、类型和状态相关话题;
BGP报文结构和类型
提示:BGP工作在应用层,其端口号为179;报文结构是7层封装,BGP报文主要由两种报文头部组成,公共头部和类型头部;公共头部主要用来描述bgp AS号,包头长度,报文类型,版本信息等等信息,类型头部主要用来描述不同类型的BGP报文相关属性;BGP报文类型有5种,分别是open包、update包、Notification包、keepalive和route-refresh;其中open包主要用来建立邻居使用,在邻居建立以后相互发送一次,后续不再发送;keepalive包主要作用是维护邻居关系,默认情况下bgp是每60秒发送一次keepalive包向邻居通告自己还“活”着;如果连续三个周期没有收到邻居的keepalive包,此时本端会认为邻居挂掉;update包主要用来路由更新,其包里的内容主要是用来描述更新的路由信息和属性;只要有路由更新对应都会向邻居发送更新;notification包主要用来发送当检测到错误,发送后关闭BGP连接的信息;Route-refresh包主要用来触发请求邻居重新通告路由;
BGP邻居状态
提示:BGP邻居状态有6种,分别是idle,connect,active,open-sent,open-confirm,established,其中idel状态是最开始状态,表示邻居为空,没有邻居;当配置好邻居信息以后,如果在对应路由表中找到去往邻居的路由,此时邻居关系会从idel转变为connect;如果没有路由,则还是原来的idle状态,即没有发送tcp三次握手请求报文的状态;connect状态表示发起TCP连接,等待tcp连接完成,即本端发送TCP三次握手请求,等待对端回复完成tcp三次握手的状态,该状态会有一个超时时长,如果在规定的时间内还是没有建立tcp连接,该状态会超时重试,即没有邻居回复本端的三次握手请求的状态;active状态表示tcp建立失败,继续尝试tcp连接,即tcp三次握手的报文已经发送,但是由于某些错误导致tcp三次握手没能正常建立的状态,该状态会有一个尝试时间,如果尝试tcp连接还是失败则该状态保持,如果tcp建立超时,则会从active状态转变为idle状态,如果tcp建立成功则会从active状态转变为open-sent状态表示tcp连接成功,并已发送一次open包后的状态;即本端三次握手成功建立,发送open包以后的状态;open-confirm表示对端收到本端发送的open包后的状态,如果没有收到对端的open包,此时会从open-sent状态进入active状态,表示tcp连接失败,或者错误的TCP连接,或者对端不认可和本端建立邻居;established表示邻居建立完成的状态;即收到对端的发送到keepalive包以后的状态;open-sent/open-confirm/established这三种状态一旦发生错误都会返回到idle状态;
BGP邻居建立过程和状态转换
提示:idle和connect状态主要发生在邻居建立初期,tcp三次握手阶段,如果三次握手正常交互,对应状态会从idle转变为connect状态,表示发送了tcp三次握手请求,等待完成tcp三次握手;三次握手成功以后,如果发送了open包,对应状态会从connect状态转变为open-sent状态,如果正确接收到对端的open包以后,对应状态会从open-sent状态转变为open-confirm状态,并向对端发送keepalive包,通告本端的存活状态;如果对端收到本端发送的keepalive包以后,对应状态会从open-confirm状态转变为established状态;以上是bgp邻居建立过程中几种状态切换过程;在established状态下,BGP路由器可以和邻居交换update、keepalive、Route-refresh报文和notification报文;
实验:如下拓扑,配置BGP
R1的配置
sys sys R1 int g0/0/0 ip add 12.0.0.1 24 bgp 12 router-id 1.1.1.1 peer 12.0.0.2 as 12
R2的配置
sys sys R2 int g0/0/0 ip add 12.0.0.2 bgp 12 router-id 2.2.2.2 peer 12.0.0.1 as 12
只配置了R1未配置R2时,R1bgp邻居状态验证
提示:此时R1并未发送tcp三次握手请求,所以对应邻居状态还是idle状态;表示正在查找路由表去往邻居的路由;
在R1查找到对应去往邻居的路由以后,发送TCP三次握手请求后,对应邻居状态
提示:R1发送三次握手请求后,对应邻居从idle状态转变为connect状态,表示发送了三次握手请求,等待三次握手完成;
在R1上抓包
提示:在R1上抓包只有arp包,其原因是R2没有配置,R1找不到R2的mac地址,所以一直发送广播请求R2的mac地址;
配置R2接口地址
验证:在R1上查看bgp邻居状态,看看有什么变化没有?
提示:可以看到对应邻居状态一直处于connect状态;
在R1上抓包,查看对应tcp三次握手的情况
提示:可以看到R1向R2的179端口发起三次握手请求,对端R2一直发送重试;其原因是R2没有配置bgp,当然179端口并不会处于监听状态;所以R1请求R2的179端口,对应R2回复重试;
配置好R2 bgp邻居信息
在R1上查看邻居关系
提示:可以看到对应R1的邻居关系为established,这个过程相对较快,中间的状态我们看不到,但从上面的提示可以看到对应established的前面一个状态为openconfirm状态;
查看R1上的抓包过程
提示:可以看到R1向R2发起三次握手请求,对应R2响应确认并向R1发起建立连接请求,对应R1确认,对应发送open包,再后续发送keepalive包;
在R1上配置邻居2.2.2.2 对应as号为12
查看邻居状态
提示:可以看到我们配置的2.2.2.2,对应邻居状态为idle,表示没有发送tcp三次握手请求;其原因是本地没有去往2.2.2.2的路由,所以对应邻居会一直处于idle状态;
验证:在R1上添加静态路由去往2.2.2.2,看看对应邻居状态是否发生变化?
提示:可以看到在R1上添加静态路由以后,对应bgp邻居状态从idle状态变为了connect状态;说明R1通过查找路由表,已经向2.2.2.2发起tcp三次握手请求;
验证:查看R1的抓包,看看R1是否向2.2.2.2发起tcp三次握手?
提示:可以看到对应R1的确在向2.2.2.2发送tcp三次握手请求;
在R2上新建lo接口并配置接口地址为2.2.2.2/32
再次验证R1上2.2.2.2的邻居状态是否发生变化?
提示:可以看到R1上2.2.2.2邻居状态从connect状态转变为active状态,这是为什么呢?我们知道active状态是tcp三次握手失败,对应状态;
在R1抓包查看tcp三次握手情况
提示:可以看到R1向2.2.2.2发起三次握手请求,对应2.2.2.2也回复并建立起tcp连接,对应R1向2.2.2.2发送了open包以后,对应2.2.2.2又给R1发送了断开连接请求;说明R1和2.2.2.2并没有建立起TCP连接,即tcp连接建立失败,所以从connect转态转变为active状态;其实这里的原因是R2回复R1的包其源地址为12.0.0.2和R1配置的邻居2.2.2.2地址不匹配导致的;
验证:在R2上更改更新源为lo2接口地址,看看邻居状态的变化
提示:在R2上更改更新源以后,对应和12.0.0.1邻居状态从established变为了idle,这是因为更新源发生变化导致tcp连接错误;所以从established状态转变为idle状态;
在R1上验证邻居状态
提示:可以看到此时R1上和2.2.2.2建立起邻居,但是对应和12.0.0.2的邻居状态变为了active,这是因为从R2过来的包,其源地址为2.2.2.2,和本端配置的邻居12.0.0.2不匹配,所以导致tcp连接建立失败,所以在R1上看到和2.2.2.2正常建立tcp连接,邻居正常,和12.0.0.2建立不起来TCP连接,邻居状态处于active状态;
总结:指向bgp数据包源ip地址的路由不存在,即没有邻居路由,对应邻居关系为idle;邻居与错误地址建立对等关系,即源地址不匹配,导致邻居状态为active状态;不存在该路由器的邻居声明,即对端未配置本端为邻居,邻居状态会卡在active(如果对端未配置bgp会卡在connect状态);as号配置错误会导致对应邻居状态为active;以上原因都可能导致邻居状态在idle/active状态循环;