📄 bgp_fsm.c
字号:
{ struct peer *peer; peer = THREAD_ARG (thread); peer->t_routeadv[AFI_IP][SAFI_MPLS_VPN] = NULL; if (BGP_DEBUG (events, EVENTS)) zlog_info ("%s routeadv timer expired for VPNv4 unicast", peer->host); peer->synctime[AFI_IP][SAFI_MPLS_VPN] = time (NULL); BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); BGP_TIMER_ON (peer->t_routeadv[AFI_IP][SAFI_MPLS_VPN], bgp_routeadv_timer_vpnv4_unicast, peer->v_routeadv); return 0;}voidbgp_routeadv_timer (struct peer *peer, afi_t afi, safi_t safi){ if (afi == AFI_IP && safi == SAFI_UNICAST) BGP_TIMER_ON (peer->t_routeadv[afi][safi], bgp_routeadv_timer_ipv4_unicast, 1); else if (afi == AFI_IP && safi == SAFI_MULTICAST) BGP_TIMER_ON (peer->t_routeadv[afi][safi], bgp_routeadv_timer_ipv4_multicast, 1); else if (afi == AFI_IP6 && safi == SAFI_UNICAST) BGP_TIMER_ON (peer->t_routeadv[afi][safi], bgp_routeadv_timer_ipv6_unicast, 1); else if (afi == AFI_IP && safi == SAFI_MPLS_VPN) BGP_TIMER_ON (peer->t_routeadv[afi][safi], bgp_routeadv_timer_vpnv4_unicast, 1);}/* Reset bgp update timer */static voidbgp_uptime_reset (struct peer *peer){ peer->uptime = time (NULL);}/* BGP Peer Down Cause */char *peer_down_str[] ={ "", "Router ID changed", "Remote AS changed", "Local AS change", "Cluster ID changed", "Confederation identifier changed", "Confederation peer changed", "RR client config change", "RS client config change", "Update source change", "Address family activated", "Admin. shutdown", "User reset", "BGP Notification received", "BGP Notification send", "Peer closed the session", "Neighbor deleted", "Peer-group add member", "Peer-group delete member", "Capability changed", "Multihop config change", "Password change", "NSF peer closed the session"};intbgp_graceful_restart_timer_expire (struct thread *thread){ struct peer *peer; afi_t afi; safi_t safi; peer = THREAD_ARG (thread); peer->t_gr_restart = NULL; /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT); BGP_TIMER_OFF (peer->t_gr_stale); if (BGP_DEBUG (events, EVENTS)) { zlog_info ("%s graceful restart timer expired", peer->host); zlog_info ("%s graceful restart stalepath timer stopped", peer->host); } return 0;}intbgp_graceful_stale_timer_expire (struct thread *thread){ struct peer *peer; afi_t afi; safi_t safi; peer = THREAD_ARG (thread); peer->t_gr_stale = NULL; if (BGP_DEBUG (events, EVENTS)) zlog_info ("%s graceful restart stalepath timer expired", peer->host); /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); return 0;}/* Administrative BGP peer stop event. */intbgp_stop (struct peer *peer){ afi_t afi; safi_t safi; char orf_name[BUFSIZ]; if (CHECK_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT)) return 0; /* Increment Dropped count. */ if (peer->status == Established) { bgp_fsm_change_status (peer, Idle); peer->dropped++; /* bgp log-neighbor-changes of neighbor Down */ if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host, peer_down_str [(int) peer->last_reset]); /* graceful restart */ 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 (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)) { if (BGP_DEBUG (events, EVENTS)) { zlog_info ("%s graceful restart timer started for %d sec", peer->host, peer->v_gr_restart); zlog_info ("%s graceful restart stalepath timer started for %d sec", peer->host, peer->bgp->stalepath_time); } BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire, peer->v_gr_restart); BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire, peer->bgp->stalepath_time); } else { UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) peer->nsf[afi][safi] = 0; } /* set last reset time */ peer->resettime = time (NULL);#ifdef HAVE_SNMP bgpTrapBackwardTransition (peer);#endif /* HAVE_SNMP */ /* Reset uptime. */ bgp_uptime_reset (peer); /* Need of clear of peer. */ bgp_clear_route_all (peer); /* Reset peer synctime */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) peer->synctime[afi][safi] = 0; } /* Stop read and write threads when exists. */ BGP_READ_OFF (peer->t_read); BGP_WRITE_OFF (peer->t_write); /* Stop all timers. */ BGP_TIMER_OFF (peer->t_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]); /* Delete all existing events of the peer. */ BGP_EVENT_DELETE (peer); /* Stream reset. */ peer->packet_size = 0; /* Clear input and output buffer. */ if (peer->ibuf) stream_reset (peer->ibuf); if (peer->work) stream_reset (peer->work); stream_fifo_clean (peer->obuf); /* Close of file descriptor. */ if (peer->fd >= 0) { close (peer->fd); peer->fd = -1; } /* Connection information. */ if (peer->su_local) { XFREE (MTYPE_SOCKUNION, peer->su_local); peer->su_local = NULL; } if (peer->su_remote) { XFREE (MTYPE_SOCKUNION, peer->su_remote); peer->su_remote = NULL; } /* Clear remote router-id. */ peer->remote_id.s_addr = 0; /* Clear peer capability flag. */ peer->cap = 0; for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) { /* Reset all negotiated variables */ peer->afc_nego[afi][safi] = 0; peer->afc_adv[afi][safi] = 0; peer->afc_recv[afi][safi] = 0; /* peer address family capability flags*/ peer->af_cap[afi][safi] = 0; /* peer address family status flags*/ peer->af_sflags[afi][safi] = 0; /* Received ORF prefix-filter */ peer->orf_plist[afi][safi] = NULL; /* 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_active_delay *= 2; /* Overflow check. */ if (peer->v_active_delay > BGP_DEFAULT_CONNECT_RETRY) peer->v_active_delay = BGP_DEFAULT_CONNECT_RETRY; 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){ char buf1[BUFSIZ]; 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); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) bgp_getsockname (peer); if (BGP_DEBUG (normal, NORMAL)) { if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) zlog_info ("%s open active, local address %s", peer->host, sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN)); else zlog_info ("%s passive open", peer->host); } 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; 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",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -