diff options
Diffstat (limited to 'bgpd/bgp_fsm.c')
-rw-r--r-- | bgpd/bgp_fsm.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 6368ff47..fc7654f0 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -214,7 +214,7 @@ bgp_start_timer (struct thread *thread) "%s [FSM] Timer (start timer expire).", peer->host); THREAD_VAL (thread) = BGP_Start; - bgp_event (thread); + bgp_event (thread); /* bgp_event unlocks peer */ return 0; } @@ -233,7 +233,7 @@ bgp_connect_timer (struct thread *thread) peer->host); THREAD_VAL (thread) = ConnectRetry_timer_expired; - bgp_event (thread); + bgp_event (thread); /* bgp_event unlocks peer */ return 0; } @@ -253,7 +253,7 @@ bgp_holdtime_timer (struct thread *thread) peer->host); THREAD_VAL (thread) = Hold_Timer_expired; - bgp_event (thread); + bgp_event (thread); /* bgp_event unlocks peer */ return 0; } @@ -273,7 +273,7 @@ bgp_keepalive_timer (struct thread *thread) peer->host); THREAD_VAL (thread) = KeepAlive_timer_expired; - bgp_event (thread); + bgp_event (thread); /* bgp_event unlocks peer */ return 0; } @@ -388,12 +388,31 @@ bgp_graceful_stale_timer_expire (struct thread *thread) return 0; } +/* Called after event occured, this function change status and reset + read/write and timer thread. */ +void +bgp_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)) + zlog_debug ("%s went from %s to %s", + peer->host, + LOOKUP (bgp_status_msg, peer->ostatus), + LOOKUP (bgp_status_msg, peer->status)); +} + /* Administrative BGP peer stop event. */ int bgp_stop (struct peer *peer) { afi_t afi; safi_t safi; + unsigned int i; char orf_name[BUFSIZ]; /* Increment Dropped count. */ @@ -468,9 +487,11 @@ bgp_stop (struct peer *peer) BGP_TIMER_OFF (peer->t_asorig); BGP_TIMER_OFF (peer->t_routeadv); - /* Delete all existing events of the peer. */ - BGP_EVENT_DELETE (peer); - + /* Delete all existing events of the peer, + and corresponding peer ref-count */ + for (i = thread_cancel_event (master, peer); i > 0; i--) + peer_unlock (peer); /* thread event reference */ + /* Stream reset. */ peer->packet_size = 0; @@ -479,7 +500,8 @@ bgp_stop (struct peer *peer) stream_reset (peer->ibuf); if (peer->work) stream_reset (peer->work); - stream_fifo_clean (peer->obuf); + if (peer->obuf) + stream_fifo_clean (peer->obuf); /* Close of file descriptor. */ if (peer->fd >= 0) @@ -683,24 +705,6 @@ bgp_fsm_open (struct peer *peer) return 0; } -/* Called after event occured, this function change status and reset - read/write and timer thread. */ -void -bgp_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)) - zlog_debug ("%s went from %s to %s", - peer->host, - LOOKUP (bgp_status_msg, peer->ostatus), - LOOKUP (bgp_status_msg, peer->status)); -} - /* Keepalive send to peer. */ int bgp_fsm_keepalive_expire (struct peer *peer) @@ -1021,15 +1025,16 @@ bgp_event (struct thread *thread) 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); + if (ret >= 0) + { + /* If status is changed. */ + if (next != peer->status) + bgp_fsm_change_status (peer, next); - return 0; + /* Make sure timer is set. */ + bgp_timer_set (peer); + } + + peer_unlock (peer); /* bgp-event peer reference */ + return ret; } |