diff options
-rw-r--r-- | bgpd/bgp_packet.c | 28 | ||||
-rw-r--r-- | bgpd/bgp_packet.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_peer.c | 52 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 11 | ||||
-rw-r--r-- | bgpd/bgpd.c | 19 |
5 files changed, 42 insertions, 70 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index cd36723d..f8c0f0bb 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -819,10 +819,10 @@ bgp_open_send (struct peer *peer) } #endif -/* Generate notification object */ -static bgp_notify -bgp_notification (struct peer *peer, u_char code, u_char sub_code, - u_char *data, size_t datalen) +/* Send BGP notify packet with data portion. */ +void +bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, + u_char *data, size_t datalen) { bgp_notify notification; notification = bgp_notify_new(code, sub_code, datalen); @@ -833,7 +833,7 @@ bgp_notification (struct peer *peer, u_char code, u_char sub_code, if (BGP_DEBUG (normal, NORMAL)) zlog_debug ("%s send message type %d, length (incl. header) %d", - peer->host, BGP_MSG_NOTIFY, notification->length); + peer->host, BGP_MSG_NOTIFY, notification->length); /* peer reset cause */ if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE) @@ -846,23 +846,7 @@ bgp_notification (struct peer *peer, u_char code, u_char sub_code, peer->last_reset = PEER_DOWN_NOTIFY_SEND; } - return notification; -} - -/* Send BGP notify packet with data portion. Reenable peer*/ -void -bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, - u_char *data, size_t datalen) -{ - bgp_peer_reenable(peer, bgp_notification(peer, code, sub_code, data, datalen)); -} - -/* Send BGP notify packet with data portion. Disable peer*/ -void -bgp_notify_send_with_data_disable (struct peer *peer, u_char code, u_char sub_code, - u_char *data, size_t datalen) -{ - bgp_peer_disable(peer, bgp_notification(peer, code, sub_code, data, datalen)); + bgp_peer_disable(peer, notification); } /* Send BGP notify packet. */ diff --git a/bgpd/bgp_packet.h b/bgpd/bgp_packet.h index 2b50f986..81937522 100644 --- a/bgpd/bgp_packet.h +++ b/bgpd/bgp_packet.h @@ -51,8 +51,6 @@ extern void bgp_open_send (struct peer *); extern void bgp_notify_send (struct peer *, u_int8_t, u_int8_t); extern void bgp_notify_send_with_data (struct peer *, u_int8_t, u_int8_t, u_int8_t *, size_t); -extern void bgp_notify_send_with_data_disable (struct peer *peer, u_char code, u_char sub_code, - u_char *data, size_t datalen); extern void bgp_route_refresh_send (struct peer *, afi_t, safi_t, u_char, u_char, int); extern void bgp_capability_send (struct peer *, afi_t, safi_t, int, int); extern void bgp_default_update_send (struct peer *, struct attr *, diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c index eeb39912..fc5ea7bf 100644 --- a/bgpd/bgp_peer.c +++ b/bgpd/bgp_peer.c @@ -301,7 +301,7 @@ bgp_session_has_stopped(bgp_peer peer) bgp_session session = peer->session ; assert(bgp_session_is_active(session)) ; - bgp_peer_reenable(peer, NULL); + bgp_peer_disable(peer, NULL); /* TODO: needs to deal with NOTIFICATION, if any ?? */ return 0; @@ -325,11 +325,18 @@ bgp_session_has_disabled(bgp_peer peer) mqueue_revoke(routing_nexus->queue, session) ; /* does the session need to be re-enabled? */ - if (session->defer_enable) + if (session->defer_enable || peer->state == bgp_peer_sIdle) { session->defer_enable = 0; bgp_session_enable(peer); } + else if (peer->state == bgp_peer_sEstablished) + { + /* disable the peer */ + bgp_peer_stop(peer); + bgp_clear_route_all(peer); + peer_change_status(peer, bgp_peer_sClearing); + } /* if the program is terminating then see if this was the last session * and if so ... die .... @@ -818,6 +825,7 @@ peer_delete (struct peer *peer) */ peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; bgp_peer_stop (peer); + bgp_clear_route_all (peer); peer_change_status (peer, bgp_peer_sDeleted); /* Password configuration */ @@ -985,22 +993,7 @@ peer_nsf_stop (struct peer *peer) bgp_clear_route_all (peer); } - -/* Disable then enable the peer. Sends notification. */ -void -bgp_peer_reenable(bgp_peer peer, bgp_notify notification) -{ - if (bgp_session_is_active(peer->session)) - { - bgp_peer_disable(peer, notification); - bgp_peer_enable(peer); /* may defer if still stopping */ - } - else - bgp_notify_free(notification) ; -} - /* enable the peer */ - void bgp_peer_enable(bgp_peer peer) { @@ -1009,33 +1002,26 @@ bgp_peer_enable(bgp_peer peer) } /* disable the peer - * sent notification, disable session, stop the peer + * sent notification, disable session */ void bgp_peer_disable(bgp_peer peer, bgp_notify notification) { - /* disable the session */ - bgp_session_disable(peer, notification); - - /* and the peer */ - bgp_peer_stop(peer); - if (peer->state == bgp_peer_sEstablished) - peer_change_status (peer, bgp_peer_sClearing); + if (bgp_session_is_active(peer->session)) + bgp_session_disable(peer, notification); + else + { + bgp_notify_free(notification) ; + bgp_peer_stop(peer); + } } -/* Called after event occurred, this function change status and reset - read/write and timer thread. */ +/* Called after event occurred, this function changes status */ void peer_change_status (bgp_peer peer, int status) { bgp_dump_state (peer, peer->state, status); - /* Transition into Clearing or Deleted must /always/ clear all routes.. - * (and must do so before actually changing into Deleted.. - */ - if (status >= bgp_peer_sClearing) - bgp_clear_route_all (peer); - /* Preserve old status and change into new status. */ peer->ostate = peer->state; peer->state = status; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 1beae6b2..5ca89b06 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1722,7 +1722,7 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); /* Disable the peer, the timer routine will reenable. */ - bgp_notify_send_with_data_disable (peer, BGP_NOTIFY_CEASE, + bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7); } @@ -2728,7 +2728,14 @@ bgp_clear_node_complete (struct work_queue *wq) bgp_peer_stop(peer); BGP_EVENT_FLUSH (peer); if (peer->state == bgp_peer_sClearing) - peer_change_status (peer, bgp_peer_sIdle); + { + peer_change_status (peer, bgp_peer_sIdle); + + /* enable peer if required */ + if (!CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN) && + !CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) + bgp_peer_enable(peer); + } peer_unlock (peer); /* bgp_clear_route */ } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index f05e91f3..5dc34c49 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2001,14 +2001,14 @@ peer_flag_modify_action (struct peer *peer, u_int32_t flag) { BGP_TIMER_OFF (peer->t_pmax_restart); if (BGP_DEBUG (events, EVENTS)) - zlog_debug ("%s Maximum-prefix restart timer canceled", + zlog_debug ("%s Maximum-prefix restart timer cancelled", peer->host); } if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)) peer_nsf_stop (peer); - bgp_notify_send_with_data_disable(peer, BGP_NOTIFY_CEASE, + bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, NULL, 0); } else @@ -4702,7 +4702,6 @@ bgp_terminate (int terminating, int retain_mode) struct peer *peer; struct listnode *node, *nnode; struct listnode *mnode, *mnnode; - bgp_notify notification = NULL; program_terminating = terminating; @@ -4710,16 +4709,14 @@ bgp_terminate (int terminating, int retain_mode) for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) { - notification = (retain_mode) - ? NULL - : bgp_notify_new(BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, 0); - - if (terminating) - bgp_peer_disable(peer, notification); - else + if (retain_mode) + bgp_peer_disable(peer, NULL); + else if (terminating) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); + else + bgp_notify_send(peer, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_ADMIN_RESET); } if (!retain_mode) |