summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_packet.c28
-rw-r--r--bgpd/bgp_packet.h2
-rw-r--r--bgpd/bgp_peer.c52
-rw-r--r--bgpd/bgp_route.c11
-rw-r--r--bgpd/bgpd.c19
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)