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

📄 bgp_fsm.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* ORF received prefix-filter pnt */        sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);        prefix_bgp_orf_remove_all (orf_name);      }  /* Reset keepalive and holdtime */  if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))    {      peer->v_keepalive = peer->keepalive;      peer->v_holdtime = peer->holdtime;    }  else    {      peer->v_keepalive = peer->bgp->default_keepalive;      peer->v_holdtime = peer->bgp->default_holdtime;    }  peer->update_time = 0;  /* Until we are sure that there is no problem about prefix count     this should be commented out.*/#if 0  /* Reset prefix count */  peer->pcount[AFI_IP][SAFI_UNICAST] = 0;  peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;  peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;  peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;  peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;#endif /* 0 */  return 0;}/* BGP peer is stoped by the error. */intbgp_stop_with_error (struct peer *peer){  /* Double start timer. */  peer->v_start *= 2;  /* Overflow check. */  if (peer->v_start >= (60 * 2))    peer->v_start = (60 * 2);  bgp_stop (peer);  return 0;}/* TCP connection open.  Next we send open message to remote peer. And   add read thread for reading open message. */intbgp_connect_success (struct peer *peer){  if (peer->fd < 0)    {      zlog_err ("bgp_connect_success peer's fd is negative value %d",		peer->fd);      return -1;    }  BGP_READ_ON (peer->t_read, bgp_read, peer->fd);  /* bgp_getsockname (peer); */  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))    bgp_open_send (peer);  return 0;}/* TCP connect fail */intbgp_connect_fail (struct peer *peer){  bgp_stop (peer);  return 0;}/* This function is the first starting point of all BGP connection. It   try to connect to remote peer with non-blocking IO. */intbgp_start (struct peer *peer){  int status;  /* If the peer is passive mode, force to move to Active mode. */  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))    {      BGP_EVENT_ADD (peer, TCP_connection_open_failed);      return 0;    }  status = bgp_connect (peer);  switch (status)    {    case connect_error:      if (BGP_DEBUG (fsm, FSM))	plog_info (peer->log, "%s [FSM] Connect error", peer->host);      BGP_EVENT_ADD (peer, TCP_connection_open_failed);      break;    case connect_success:      if (BGP_DEBUG (fsm, FSM))	plog_info (peer->log, "%s [FSM] Connect immediately success",		   peer->host);      BGP_EVENT_ADD (peer, TCP_connection_open);      break;    case connect_in_progress:      /* To check nonblocking connect, we wait until socket is         readable or writable. */      if (BGP_DEBUG (fsm, FSM))	plog_info (peer->log, "%s [FSM] Non blocking connect waiting result",		   peer->host);      if (peer->fd < 0)	{	  zlog_err ("bgp_start peer's fd is negative value %d",		    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;}/* 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;  /* 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 start timer value to default. */  peer->v_start = BGP_INIT_START_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);#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);  BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);  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_start,  Connect},	/* 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));  if (BGP_DEBUG (normal, NORMAL)      && strcmp (LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)))    zlog_info ("%s went from %s to %s",	       peer->host,	       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 + -