diff options
-rw-r--r-- | bgpd/bgp_msg_read.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 8 | ||||
-rw-r--r-- | bgpd/bgp_peer.c | 26 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_session.c | 23 | ||||
-rw-r--r-- | bgpd/bgp_session.h | 6 | ||||
-rw-r--r-- | bgpd/bgpd.c | 4 | ||||
-rw-r--r-- | lib/log.c | 26 | ||||
-rw-r--r-- | lib/mqueue.c | 12 |
9 files changed, 78 insertions, 31 deletions
diff --git a/bgpd/bgp_msg_read.c b/bgpd/bgp_msg_read.c index 7b7b1130..c134a032 100644 --- a/bgpd/bgp_msg_read.c +++ b/bgpd/bgp_msg_read.c @@ -1354,7 +1354,7 @@ static void bgp_msg_update_receive (bgp_connection connection, bgp_size_t body_size) { /* Must be prepared to receive "update" like messages */ - if (bgp_fsm_pre_update(connection) != 0) ; + if (bgp_fsm_pre_update(connection) != 0) { plog_err(connection->log, "%s [Error] Update message received while in %s State", diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index f54c9f1f..cb696b9c 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -629,7 +629,10 @@ bgp_write (bgp_peer peer) struct stream *s; int free_s ; - while (bgp_session_is_XON(peer)) + if (bgp_session_is_XOFF(peer)) + return 0 ; + + do { free_s = 0 ; @@ -677,7 +680,8 @@ bgp_write (bgp_peer peer) /* OK we sent packet so delete it. */ if (free_s) bgp_packet_delete (peer); - } + + } while (bgp_session_is_XON(peer)) ; return 0; } diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c index f314e17b..60996999 100644 --- a/bgpd/bgp_peer.c +++ b/bgpd/bgp_peer.c @@ -110,13 +110,21 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag) if (flag == mqb_action) { - BGP_SESSION_LOCK(session) ; + BGP_SESSION_LOCK(session) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ switch(args->event) { - /* If now Established, then the BGP Engine has exchanged BGP Open */ - /* messages, and received the KeepAlive that acknowledges our Open. */ + /* If now Established, then the BGP Engine has exchanged BGP Open + * messages, and received the KeepAlive that acknowledges our Open. + * + * Ignore this, however, if the session is sLimping -- which can + * happen when the session has been disabled, but it became established + * before the BGP Engine had seen the disable message. + */ case bgp_session_eEstablished: + if (session->state == bgp_session_sLimping) + break ; + bgp_session_has_established(peer); break ; @@ -127,15 +135,21 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag) break ; default: - /* If now Stopped, then for some reason the BGP Engine has either */ - /* stopped trying to connect, or the session has been stopped. */ + /* If now Stopped, then for some reason the BGP Engine has either + * stopped trying to connect, or the session has been stopped. + * + * Again we ignore this in sLimping. + */ + if (session->state == bgp_session_sLimping) + break ; + if (args->stopped) bgp_session_has_stopped(peer); break ; } - BGP_SESSION_UNLOCK(session) ; + BGP_SESSION_UNLOCK(session) ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ } mqb_free(mqb) ; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 27e28fd3..d592e970 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1411,7 +1411,7 @@ bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected, p = &rn->p; /* Announce route to Established peer. */ - if (peer->state == bgp_peer_sEstablished) + if (peer->state != bgp_peer_sEstablished) return 0; /* Address family configuration check. */ diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c index 936857c0..56d6c7f8 100644 --- a/bgpd/bgp_session.c +++ b/bgpd/bgp_session.c @@ -595,6 +595,22 @@ bgp_session_do_update_send(mqueue_block mqb, mqb_flag_t flag) } ; /*------------------------------------------------------------------------------ + * Peering Engine: are we in XOFF state ? + */ +extern int +bgp_session_is_XOFF(bgp_peer peer) +{ + int result = 0; + bgp_session session = peer->session; + + BGP_SESSION_LOCK(session) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + result = session->flow_control > BGP_XOFF_THRESHOLD ; + BGP_SESSION_UNLOCK(session) ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + + return result; +} ; + +/*------------------------------------------------------------------------------ * Peering Engine: are we in XON state ? */ extern int @@ -805,17 +821,19 @@ bgp_session_update_recv(bgp_session session, struct stream* buf, bgp_size_t size static void bgp_session_do_update_recv(mqueue_block mqb, mqb_flag_t flag) { + bgp_session session = mqb_get_arg0(mqb) ; + struct bgp_session_update_args* args = mqb_get_args(mqb) ; if (flag == mqb_action) { - bgp_session session = mqb_get_arg0(mqb) ; bgp_peer peer = session->peer; - struct bgp_session_update_args* args = mqb_get_args(mqb) ; stream_free(peer->ibuf); peer->ibuf = args->buf; bgp_update_receive (peer, args->size); } + else + stream_free(args->buf) ; mqb_free(mqb) ; } @@ -892,6 +910,7 @@ bgp_session_do_XON(mqueue_block mqb, mqb_flag_t flag) mqb_free(mqb) ; } + /*============================================================================== * Peering Engine: send set ttl message to BGP Engine * diff --git a/bgpd/bgp_session.h b/bgpd/bgp_session.h index 2813b454..06d2846d 100644 --- a/bgpd/bgp_session.h +++ b/bgpd/bgp_session.h @@ -283,7 +283,8 @@ struct bgp_session_XON_args /* to Routeing Engine */ /* no further arguments */ } ; MQB_ARGS_SIZE_OK(bgp_session_XON_args) ; -enum { BGP_XON_THRESHOLD = 7 } ; +enum { BGP_XON_THRESHOLD = 12, + BGP_XOFF_THRESHOLD = 4 } ; struct bgp_session_ttl_args /* to bgp Engine */ { @@ -347,6 +348,9 @@ extern void bgp_session_route_refresh_recv(bgp_session session, bgp_route_refresh rr); extern int +bgp_session_is_XOFF(bgp_peer peer); + +extern int bgp_session_is_XON(bgp_peer peer); extern void diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 56358b97..f62ee4b4 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3841,7 +3841,9 @@ peer_clear (struct peer *peer) zlog_debug ("%s Maximum-prefix restart timer cancelled", peer->host); } - bgp_peer_enable(peer); +/* TODO: worry about why session is already enabled at this point !! */ +// bgp_peer_enable(peer); + bgp_peer_reenable(peer, NULL) ; return 0; } @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * 02111-1307, USA. */ #include <zebra.h> @@ -58,7 +58,7 @@ static int logfile_fd = -1; /* Used in signal handler. */ struct zlog *zlog_default = NULL; -const char *zlog_proto_names[] = +const char *zlog_proto_names[] = { "NONE", "DEFAULT", @@ -178,7 +178,7 @@ time_print(FILE *fp, struct timestamp_control *ctl) } fprintf(fp, "%s ", ctl->buf); } - + /* va_list version of zlog. */ static void vzlog (struct zlog *zl, int priority, const char *format, va_list args) @@ -187,7 +187,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) uvzlog(zl, priority, format, args); UNLOCK } - + /* va_list version of zlog. Unprotected assumes mutex already held*/ static void uvzlog (struct zlog *zl, int priority, const char *format, va_list args) @@ -540,7 +540,7 @@ zlog_backtrace_sigsafe(int priority, void *program_counter) for (i = 0; i < size; i++) { s = buf; - if (bt) + if (bt) s = str_append(LOC, bt[i]); else { s = str_append(LOC,"[bt "); @@ -567,7 +567,7 @@ void zlog_backtrace(int priority) { LOCK - zlog_backtrace(priority); + uzlog_backtrace(priority); UNLOCK } @@ -738,7 +738,7 @@ zlog_abort (const char *mess) abort(); } - + /* Open log stream */ struct zlog * openzlog (const char *progname, zlog_proto_t protocol, @@ -761,7 +761,7 @@ openzlog (const char *progname, zlog_proto_t protocol, zl->default_lvl = LOG_DEBUG; openlog (progname, syslog_flags, zl->facility); - + return zl; } @@ -1187,15 +1187,15 @@ lookup (const struct message *mes, int key) { const struct message *pnt; - for (pnt = mes; pnt->key != 0; pnt++) - if (pnt->key == key) + for (pnt = mes; pnt->key != 0; pnt++) + if (pnt->key == key) return pnt->str; return ""; } /* Older/faster version of message lookup function, but requires caller to pass - * in the array size (instead of relying on a 0 key to terminate the search). + * in the array size (instead of relying on a 0 key to terminate the search). * * The return value is the message string if found, or the 'none' pointer * provided otherwise. @@ -1204,7 +1204,7 @@ const char * mes_lookup (const struct message *meslist, int max, int index, const char *none) { int pos = index - meslist[0].key; - + /* first check for best case: index is in range and matches the key * value in that slot. * NB: key numbering might be offset from 0. E.g. protocol constants @@ -1223,7 +1223,7 @@ mes_lookup (const struct message *meslist, int max, int index, const char *none) if (meslist->key == index) { const char *str = (meslist->str ? meslist->str : none); - + zlog_debug ("message index %d [%s] found in position %d (max is %d)", index, str, i, max); return str; diff --git a/lib/mqueue.c b/lib/mqueue.c index 3031891e..7156e31e 100644 --- a/lib/mqueue.c +++ b/lib/mqueue.c @@ -293,18 +293,22 @@ mqb_init_new(mqueue_block mqb, mqueue_action action, void* arg0) { if (mqb == NULL) { - qpt_mutex_lock(&mqb_mutex) ; + qpt_mutex_lock(&mqb_mutex) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ mqb = mqb_free_list ; if (mqb == NULL) - mqb = XMALLOC(MTYPE_MQUEUE_BLOCK, sizeof(struct mqueue_block)) ; + { + dassert(mqb_free_count == 0) ; + mqb = XMALLOC(MTYPE_MQUEUE_BLOCK, sizeof(struct mqueue_block)) ; + } else { + dassert(mqb_free_count >= 0) ; mqb_free_list = mqb->next ; --mqb_free_count ; } ; - qpt_mutex_unlock(&mqb_mutex) ; + qpt_mutex_unlock(&mqb_mutex) ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ } ; memset(mqb, 0, sizeof(struct mqueue_block)) ; @@ -649,7 +653,7 @@ mqueue_revoke(mqueue_queue mq, void* arg0) else prev->next = mqb->next ; - if (mq->tail == mqb) + if (mqb == mq->tail) mq->tail = prev ; if (mqb == mq->tail_priority) |