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

📄 bgp_fsm.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 3 页
字号:
		    peer->fd);	  return -1;	}      BGP_READ_ON (peer->t_read, bgp_read, peer->fd);      BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);      break;    }  return 0;}/* Connect retry timer is expired when the peer status is Connect. */intbgp_reconnect (struct peer *peer){  bgp_stop (peer);  bgp_start (peer);  return 0;}intbgp_fsm_open (struct peer *peer){  /* Send keepalive and make keepalive timer */  bgp_keepalive_send (peer);  /* Reset holdtimer value. */  BGP_TIMER_OFF (peer->t_holdtime);  return 0;}/* Called after event occured, this function change status and reset   read/write and timer thread. */voidbgp_fsm_change_status (struct peer *peer, int status){  bgp_dump_state (peer, peer->status, status);  /* Preserve old status and change into new status. */  peer->ostatus = peer->status;  peer->status = status;  if (BGP_DEBUG (normal, NORMAL))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))      zlog_info ("%s went from %s to %s", peer->host,		 LOOKUP (bgp_status_msg, peer->ostatus),		 LOOKUP (bgp_status_msg, peer->status));}/* Keepalive send to peer. */intbgp_fsm_keepalive_expire (struct peer *peer){  bgp_keepalive_send (peer);  return 0;}/* Hold timer expire.  This is error of BGP connection. So cut the   peer and change to Idle status. */intbgp_fsm_holdtime_expire (struct peer *peer){  if (BGP_DEBUG (fsm, FSM))    zlog (peer->log, LOG_DEBUG, "%s [FSM] Hold timer expire", peer->host);  /* Send notify to remote peer. */  bgp_notify_send (peer, BGP_NOTIFY_HOLD_ERR, 0);  /* Sweep if it is temporary peer. */  if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))    {      zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);      peer_delete (peer);      return -1;    }  return 0;}/* Status goes to Established.  Send keepalive packet then make first   update information. */intbgp_establish (struct peer *peer){  struct bgp_notify *notify;  afi_t afi;  safi_t safi;  int nsf_af_count = 0;  /* Reset capability open status flag. */  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))    SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);  /* Clear last notification data. */  notify = &peer->notify;  if (notify->data)    XFREE (MTYPE_TMP, notify->data);  memset (notify, 0, sizeof (struct bgp_notify));  /* Clear active delay timer value to default. */  peer->v_active_delay = BGP_ACTIVE_DELAY_TIMER;  /* Increment established count. */  peer->established++;  bgp_fsm_change_status (peer, Established);  /* bgp log-neighbor-changes of neighbor Up */  if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))    zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);  /* graceful restart */  UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)    for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)      {	if (peer->afc_nego[afi][safi]	    && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)	    && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))	  {	    if (peer->nsf[afi][safi]		&& ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))	      bgp_clear_stale_route (peer, afi, safi);	    peer->nsf[afi][safi] = 1;	    nsf_af_count++;	  }	else	  {	    if (peer->nsf[afi][safi])	      bgp_clear_stale_route (peer, afi, safi);	    peer->nsf[afi][safi] = 0;	  }      }  if (nsf_af_count)    SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);  else    {      UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);      if (peer->t_gr_stale)	{	  BGP_TIMER_OFF (peer->t_gr_stale);	  if (BGP_DEBUG (events, EVENTS))	    zlog_info ("%s graceful restart stalepath timer stopped", peer->host);	}    }  if (peer->t_gr_restart)    {      BGP_TIMER_OFF (peer->t_gr_restart);      if (BGP_DEBUG (events, EVENTS))	zlog_info ("%s graceful restart timer stopped", peer->host);    }#ifdef HAVE_SNMP  bgpTrapEstablished (peer);#endif /* HAVE_SNMP */  /* Reset uptime, send keepalive, send current table. */  bgp_uptime_reset (peer);  /* Send route-refresh when ORF is enabled */  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)      if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))	{	  if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))	    bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,				    REFRESH_IMMEDIATE, 0);	  else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))	    bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,				    REFRESH_IMMEDIATE, 0);	}  if (peer->v_keepalive)    bgp_keepalive_send (peer);  /* First update is deferred until ORF or ROUTE-REFRESH is received */  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)      if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))	if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)	    || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))	  SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);  bgp_announce_route_all (peer);  return 0;}/* Keepalive packet is received. */intbgp_fsm_keepalive (struct peer *peer){  /* peer count update */  peer->keepalive_in++;  BGP_TIMER_OFF (peer->t_holdtime);  return 0;}/* Update packet is received. */intbgp_fsm_update (struct peer *peer){  BGP_TIMER_OFF (peer->t_holdtime);  return 0;}/* This is empty event. */intbgp_ignore (struct peer *peer){  if (BGP_DEBUG (fsm, FSM))    zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);  return 0;}/* Finite State Machine structure */struct {  int (*func) ();  int next_state;} FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = {  {    /* Idle state: In Idle state, all events other than BGP_Start is       ignored.  With BGP_Start event, finite state machine calls       bgp_start(). */    {bgp_ignore,  Active},	/* BGP_Start                    */    {bgp_stop,   Idle},		/* BGP_Stop                     */    {bgp_stop,   Idle},		/* TCP_connection_open          */    {bgp_stop,   Idle},		/* TCP_connection_closed        */    {bgp_ignore, Idle},		/* TCP_connection_open_failed   */    {bgp_stop,   Idle},		/* TCP_fatal_error              */    {bgp_ignore, Idle},		/* ConnectRetry_timer_expired   */    {bgp_ignore, Idle},		/* Hold_Timer_expired           */    {bgp_ignore, Idle},		/* KeepAlive_timer_expired      */    {bgp_ignore, Idle},		/* Receive_OPEN_message         */    {bgp_ignore, Idle},		/* Receive_KEEPALIVE_message    */    {bgp_ignore, Idle},		/* Receive_UPDATE_message       */    {bgp_ignore, Idle},		/* Receive_NOTIFICATION_message */  },  {    /* Connect */    {bgp_ignore,  Connect},	/* BGP_Start                    */    {bgp_stop,    Idle},	/* BGP_Stop                     */    {bgp_connect_success, OpenSent}, /* TCP_connection_open          */    {bgp_stop, Idle},		/* TCP_connection_closed        */    {bgp_connect_fail, Active}, /* TCP_connection_open_failed   */    {bgp_connect_fail, Idle},	/* TCP_fatal_error              */    {bgp_reconnect, Connect},	/* ConnectRetry_timer_expired   */    {bgp_ignore,  Idle},	/* Hold_Timer_expired           */    {bgp_ignore,  Idle},	/* KeepAlive_timer_expired      */    {bgp_ignore,  Idle},	/* Receive_OPEN_message         */    {bgp_ignore,  Idle},	/* Receive_KEEPALIVE_message    */    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */    {bgp_stop,    Idle},	/* Receive_NOTIFICATION_message */  },  {    /* Active, */    {bgp_ignore,  Active},	/* BGP_Start                    */    {bgp_stop,    Idle},	/* BGP_Stop                     */    {bgp_connect_success, OpenSent}, /* TCP_connection_open          */    {bgp_stop,    Idle},	/* TCP_connection_closed        */    {bgp_ignore,  Active},	/* TCP_connection_open_failed   */    {bgp_ignore,  Idle},	/* TCP_fatal_error              */    {bgp_start,   Connect},	/* ConnectRetry_timer_expired   */    {bgp_ignore,  Idle},	/* Hold_Timer_expired           */    {bgp_ignore,  Idle},	/* KeepAlive_timer_expired      */    {bgp_ignore,  Idle},	/* Receive_OPEN_message         */    {bgp_ignore,  Idle},	/* Receive_KEEPALIVE_message    */    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */  },  {    /* OpenSent, */    {bgp_ignore,  OpenSent},	/* BGP_Start                    */    {bgp_stop,    Idle},	/* BGP_Stop                     */    {bgp_stop,    Idle},	/* TCP_connection_open          */    {bgp_stop,    Active},	/* TCP_connection_closed        */    {bgp_ignore,  Idle},	/* TCP_connection_open_failed   */    {bgp_stop,    Idle},	/* TCP_fatal_error              */    {bgp_ignore,  Idle},	/* ConnectRetry_timer_expired   */    {bgp_fsm_holdtime_expire, Idle},	/* Hold_Timer_expired           */    {bgp_ignore,  Idle},	/* KeepAlive_timer_expired      */    {bgp_fsm_open,    OpenConfirm},	/* Receive_OPEN_message         */    {bgp_ignore,  Idle},	/* Receive_KEEPALIVE_message    */    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */  },  {    /* OpenConfirm, */    {bgp_ignore,  OpenConfirm},	/* BGP_Start                    */    {bgp_stop,    Idle},	/* BGP_Stop                     */    {bgp_stop,    Idle},	/* TCP_connection_open          */    {bgp_stop,    Idle},	/* TCP_connection_closed        */    {bgp_stop,    Idle},	/* TCP_connection_open_failed   */    {bgp_stop,    Idle},	/* TCP_fatal_error              */    {bgp_ignore,  Idle},	/* ConnectRetry_timer_expired   */    {bgp_fsm_holdtime_expire, Idle},	/* Hold_Timer_expired           */    {bgp_ignore,  OpenConfirm},	/* KeepAlive_timer_expired      */    {bgp_ignore,  Idle},	/* Receive_OPEN_message         */    {bgp_establish, Established}, /* Receive_KEEPALIVE_message    */    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */  },  {    /* Established, */    {bgp_ignore,  Established},	/* BGP_Start                    */    {bgp_stop,    Idle},	/* BGP_Stop                     */    {bgp_stop,    Idle},	/* TCP_connection_open          */    {bgp_stop,    Idle},	/* TCP_connection_closed        */    {bgp_ignore,  Idle},	/* TCP_connection_open_failed   */    {bgp_stop,    Idle},	/* TCP_fatal_error              */    {bgp_ignore,  Idle},	/* ConnectRetry_timer_expired   */    {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired           */    {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired      */    {bgp_stop, Idle},		/* Receive_OPEN_message         */    {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message    */    {bgp_fsm_update,   Established}, /* Receive_UPDATE_message       */    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */  },};static char *bgp_event_str[] ={  NULL,  "BGP_Start",  "BGP_Stop",  "TCP_connection_open",  "TCP_connection_closed",  "TCP_connection_open_failed",  "TCP_fatal_error",  "ConnectRetry_timer_expired",  "Hold_Timer_expired",  "KeepAlive_timer_expired",  "Receive_OPEN_message",  "Receive_KEEPALIVE_message",  "Receive_UPDATE_message",  "Receive_NOTIFICATION_message"};/* Execute event process. */intbgp_event (struct thread *thread){  int ret;  int event;  int next;  struct peer *peer;  peer = THREAD_ARG (thread);  event = THREAD_VAL (thread);  /* Logging this event. */  next = FSM [peer->status -1][event - 1].next_state;  if (BGP_DEBUG (fsm, FSM))    plog_info (peer->log, "%s [FSM] %s (%s->%s)", peer->host, 	       bgp_event_str[event],	       LOOKUP (bgp_status_msg, peer->status),	       LOOKUP (bgp_status_msg, next));  /* Call function. */  ret = (*(FSM [peer->status - 1][event - 1].func))(peer);  /* When function do not want proceed next job return -1. */  if (ret < 0)    return ret;      /* If status is changed. */  if (next != peer->status)    bgp_fsm_change_status (peer, next);  /* Make sure timer is set. */  bgp_timer_set (peer);  return 0;}

⌨️ 快捷键说明

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