⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bgp_fsm.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 3 页
字号:
/* BGP-4 Finite State Machine      From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]   Copyright (C) 1996, 97, 98 Kunihiro IshiguroThis file is part of GNU Zebra.GNU Zebra is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.GNU Zebra is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Zebra; see the file COPYING.  If not, write to the FreeSoftware Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.  */#include <zebra.h>#include "linklist.h"#include "prefix.h"#include "vty.h"#include "sockunion.h"#include "thread.h"#include "log.h"#include "stream.h"#include "memory.h"#include "plist.h"#include "bgpd/bgpd.h"#include "bgpd/bgp_attr.h"#include "bgpd/bgp_debug.h"#include "bgpd/bgp_fsm.h"#include "bgpd/bgp_packet.h"#include "bgpd/bgp_network.h"#include "bgpd/bgp_route.h"#include "bgpd/bgp_dump.h"#include "bgpd/bgp_open.h"#ifdef HAVE_SNMP#include "bgpd/bgp_snmp.h"#endif /* HAVE_SNMP *//* BGP FSM (finite state machine) has three types of functions.  Type   one is thread functions.  Type two is event functions.  Type three   is FSM functions.  Timer functions are set by bgp_timer_set   function. *//* BGP event function. */int bgp_event (struct thread *);/* BGP thread functions. */static int bgp_start_timer (struct thread *);static int bgp_connect_timer (struct thread *);static int bgp_holdtime_timer (struct thread *);static int bgp_keepalive_timer (struct thread *);/* BGP FSM functions. */static int bgp_start (struct peer *);/* BGP active delay jitter. */intbgp_active_delay_jitter (int time){  return ((rand () % (time + 1)) - (time / 2));}/* Hook function called after bgp event is occered.  And vty's   neighbor command invoke this function after making neighbor   structure. */voidbgp_timer_set (struct peer *peer){  afi_t afi;  safi_t safi;  int active_delay = 0;  switch (peer->status)    {    case Idle:      /* First entry point of peer's finite state machine.  In Idle	 status start timer is on unless peer is shutdown or peer is	 inactive.  All other timer must be turned off */      if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)	  || CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)	  || ! peer_active (peer))	{	  BGP_TIMER_OFF (peer->t_start);	}      else	{	  if (CHECK_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT))	    {	      BGP_TIMER_ON (peer->t_start, bgp_start_timer, BGP_PEER_FIRST_CREATE_TIMER);	    }	  else	    {	      BGP_TIMER_ON (peer->t_start, bgp_start_timer, peer->v_start);	    }	}      BGP_TIMER_OFF (peer->t_connect);      BGP_TIMER_OFF (peer->t_holdtime);      BGP_TIMER_OFF (peer->t_keepalive);      BGP_TIMER_OFF (peer->t_asorig);      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)	for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)	  BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);      break;    case Connect:      /* After start timer is expired, the peer moves to Connnect         status.  Make sure start timer is off and connect timer is         on. */      BGP_TIMER_OFF (peer->t_start);      BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);      BGP_TIMER_OFF (peer->t_holdtime);      BGP_TIMER_OFF (peer->t_keepalive);      BGP_TIMER_OFF (peer->t_asorig);      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)	for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)	  BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);      break;    case Active:      /* Active is waiting connection from remote peer.  And if         connect timer is expired, change status to Connect. */      BGP_TIMER_OFF (peer->t_start);      /* If peer is passive mode, do not set connect timer. */      if (CHECK_FLAG (peer->flags, PEER_FLAG_CONNECT_MODE_PASSIVE))	{	  if (BGP_DEBUG (normal, NORMAL))	    zlog_info ("%s active open failed - TCP session must be opened passively", peer->host);	  BGP_TIMER_OFF (peer->t_connect);	}      else	{	  if (peer->ostatus == Idle	      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))	    {	      active_delay = peer->v_active_delay;	      active_delay += bgp_active_delay_jitter (BGP_ACTIVE_DELAY_TIMER);	      if (BGP_DEBUG (normal, NORMAL))		zlog_info ("%s open active, delay %d sec", peer->host, active_delay);	      BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, active_delay);	    }	  else	    {	      BGP_TIMER_ON (peer->t_connect, bgp_connect_timer,			    peer->v_connect);	    }	}      BGP_TIMER_OFF (peer->t_holdtime);      BGP_TIMER_OFF (peer->t_keepalive);      BGP_TIMER_OFF (peer->t_asorig);      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)	for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)	  BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);      break;    case OpenSent:      /* OpenSent status. */      BGP_TIMER_OFF (peer->t_start);      BGP_TIMER_OFF (peer->t_connect);      if (peer->v_holdtime != 0)	{	  BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer, 			peer->v_holdtime);	}      else	{	  BGP_TIMER_OFF (peer->t_holdtime);	}      BGP_TIMER_OFF (peer->t_keepalive);      BGP_TIMER_OFF (peer->t_asorig);      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)	for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)	  BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);      break;    case OpenConfirm:      /* OpenConfirm status. */      BGP_TIMER_OFF (peer->t_start);      BGP_TIMER_OFF (peer->t_connect);      /* If the negotiated Hold Time value is zero, then the Hold Time         timer and KeepAlive timers are not started. */      if (peer->v_holdtime == 0)	{	  BGP_TIMER_OFF (peer->t_holdtime);	  BGP_TIMER_OFF (peer->t_keepalive);	}      else	{	  BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,			peer->v_holdtime);	  BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer, 			peer->v_keepalive);	}      BGP_TIMER_OFF (peer->t_asorig);      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)	for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)	  BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);      break;    case Established:      /* In Established status start and connect timer is turned         off. */      BGP_TIMER_OFF (peer->t_start);      BGP_TIMER_OFF (peer->t_connect);      /* Same as OpenConfirm, if holdtime is zero then both holdtime         and keepalive must be turned off. */      if (peer->v_holdtime == 0)	{	  BGP_TIMER_OFF (peer->t_holdtime);	  BGP_TIMER_OFF (peer->t_keepalive);	}      else	{	  BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,			peer->v_holdtime);	  BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,			peer->v_keepalive);	}      BGP_TIMER_OFF (peer->t_asorig);      break;    }}/* BGP start timer.  This function set BGP_Start event to thread value   and process event. */static intbgp_start_timer (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_start = NULL;  UNSET_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT);  if (BGP_DEBUG (fsm, FSM))    zlog (peer->log, LOG_DEBUG,	  "%s [FSM] Timer (start timer expire).", peer->host);  THREAD_VAL (thread) = BGP_Start;  bgp_event (thread);  return 0;}/* BGP connect retry timer. */static intbgp_connect_timer (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_connect = NULL;  if (BGP_DEBUG (fsm, FSM))    zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",	  peer->host);  THREAD_VAL (thread) = ConnectRetry_timer_expired;  bgp_event (thread);  return 0;}/* BGP holdtime timer. */static intbgp_holdtime_timer (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_holdtime = NULL;  if (BGP_DEBUG (fsm, FSM))    zlog (peer->log, LOG_DEBUG,	  "%s [FSM] Timer (holdtime timer expire)",	  peer->host);  THREAD_VAL (thread) = Hold_Timer_expired;  bgp_event (thread);  return 0;}/* BGP keepalive fire ! */static intbgp_keepalive_timer (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_keepalive = NULL;  if (BGP_DEBUG (fsm, FSM))    zlog (peer->log, LOG_DEBUG,	  "%s [FSM] Timer (keepalive timer expire)",	  peer->host);  THREAD_VAL (thread) = KeepAlive_timer_expired;  bgp_event (thread);  return 0;}intbgp_routeadv_timer_ipv4_unicast (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_routeadv[AFI_IP][SAFI_UNICAST] = NULL;  if (BGP_DEBUG (events, EVENTS))    zlog_info ("%s routeadv timer expired for IPv4 Unicast", peer->host);  peer->synctime[AFI_IP][SAFI_UNICAST] = time (NULL);  BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);  BGP_TIMER_ON (peer->t_routeadv[AFI_IP][SAFI_UNICAST], bgp_routeadv_timer_ipv4_unicast,		peer->v_routeadv);  return 0;}intbgp_routeadv_timer_ipv4_multicast (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_routeadv[AFI_IP][SAFI_MULTICAST] = NULL;  if (BGP_DEBUG (events, EVENTS))    zlog_info ("%s routeadv timer expired for IPv4 Multicast", peer->host);  peer->synctime[AFI_IP][SAFI_MULTICAST] = time (NULL);  BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);  BGP_TIMER_ON (peer->t_routeadv[AFI_IP][SAFI_MULTICAST], bgp_routeadv_timer_ipv4_multicast,		peer->v_routeadv);  return 0;}intbgp_routeadv_timer_ipv6_unicast (struct thread *thread){  struct peer *peer;  peer = THREAD_ARG (thread);  peer->t_routeadv[AFI_IP6][SAFI_UNICAST] = NULL;  if (BGP_DEBUG (events, EVENTS))    zlog_info ("%s routeadv timer expired for IPv6 Unicast", peer->host);  peer->synctime[AFI_IP6][SAFI_UNICAST] = time (NULL);  BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);  BGP_TIMER_ON (peer->t_routeadv[AFI_IP6][SAFI_UNICAST], bgp_routeadv_timer_ipv6_unicast,		peer->v_routeadv);  return 0;}intbgp_routeadv_timer_vpnv4_unicast (struct thread *thread)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -