summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_peer.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_peer.c')
-rw-r--r--bgpd/bgp_peer.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index 2062c527..625e1d99 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -177,7 +177,8 @@
/* prototypes */
static void bgp_session_has_established(bgp_session session);
-static void bgp_session_has_stopped(bgp_session session);
+static void bgp_session_has_stopped(bgp_session session,
+ bgp_notify notification) ;
static void bgp_session_has_disabled(bgp_session session);
static void bgp_uptime_reset (struct peer *peer);
static void bgp_peer_stop (struct peer *peer, bool nsf) ;
@@ -216,9 +217,7 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag)
{
/* Pull stuff into Routing Engine *private* fields in the session */
- session->event = args->event ; /* last event */
- bgp_notify_set(&session->notification, args->notification) ;
- /* if any sent/received */
+ session->event = args->event ; /* last event */
session->err = args->err ; /* errno, if any */
session->ordinal = args->ordinal ; /* primary/secondary connection */
@@ -232,6 +231,8 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag)
* before the BGP Engine had seen the disable message.
*/
case bgp_session_eEstablished:
+ assert(args->notification == NULL) ;
+
if (session->state == bgp_session_sLimping)
break ;
@@ -241,6 +242,10 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag)
/* If now Disabled, then the BGP Engine is acknowledging the a
* session disable, and the session is now disabled.
*
+ * If sent a notification with the disable request, then it is
+ * returned iff the notification was actually sent. Don't really
+ * care one way or the other.
+ *
* BEWARE: this may be the last thing that happens to the session
* and/or the related peer -- which may be deleted inside
* bgp_session_has_disabled().
@@ -259,12 +264,13 @@ bgp_session_do_event(mqueue_block mqb, mqb_flag_t flag)
break ;
if (args->stopped)
- bgp_session_has_stopped(session) ;
+ bgp_session_has_stopped(session,
+ bgp_notify_take(&(args->notification))) ;
break ;
} ;
- }
- else
- bgp_notify_free(args->notification) ;
+ } ;
+
+ bgp_notify_free(args->notification) ; /* Discard any notification. */
mqb_free(mqb) ;
}
@@ -410,11 +416,13 @@ bgp_session_has_established(bgp_session session)
* that is to tell it to disable the session, and then wait in sLimping state
* until the BGP Engine completes the disable request and signals that.
*
+ * NB: takes responsibility for the notification.
+ *
* TODO: session stopped because we stopped it or because the other end did ?
* TODO: restore NSF !!
*/
static void
-bgp_session_has_stopped(bgp_session session)
+bgp_session_has_stopped(bgp_session session, bgp_notify notification)
{
peer_down_t why_down ;
@@ -432,17 +440,17 @@ bgp_session_has_stopped(bgp_session session)
peer->v_start = (60 * 2);
} ;
- if (session->notification == NULL)
+ if (notification == NULL)
why_down = PEER_DOWN_CLOSE_SESSION ;
else
{
- if (session->notification->received)
+ if (notification->received)
why_down = PEER_DOWN_NOTIFY_RECEIVED ;
else
- why_down = bgp_peer_map_notification(session->notification) ;
+ why_down = bgp_peer_map_notification(notification) ;
} ;
- bgp_peer_down_notify(peer, why_down, session->notification) ;
+ bgp_peer_down_notify(peer, why_down, notification) ;
} ;
/*------------------------------------------------------------------------------
@@ -1255,6 +1263,16 @@ bgp_peer_down(bgp_peer peer, peer_down_t why_down)
bgp_peer_down_notify(peer, why_down, NULL) ;
} ;
+/*------------------------------------------------------------------------------
+ * Down Peer for the given reason, with the given notification, if any.
+ *
+ * See bgp_peer_down() above.
+ *
+ * If the notification is NULL and need to send a notification, make one up from
+ * the given reason for downing the peer.
+ *
+ * NB: takes responsibility for the notification.
+ */
static void
bgp_peer_down_notify(bgp_peer peer, peer_down_t why_down,
bgp_notify notification)
@@ -1266,12 +1284,14 @@ bgp_peer_down_notify(bgp_peer peer, peer_down_t why_down,
if (notification == NULL)
notification = bgp_peer_map_peer_down(why_down) ;
- bgp_notify_set_dup(&peer->session->notification, notification) ;
+ bgp_notify_set(&peer->session->notification, notification) ;
- bgp_session_disable(peer, notification) ;
- }
- else
- bgp_notify_free(notification) ; /* Discard unused notification */
+ bgp_session_disable(peer, bgp_notify_dup(notification)) ;
+ /* The copy of the notification will be discarded either by
+ * the BGP_Engine, if the notification is not sent, or when
+ * it is returned in the eDisabled message.
+ */
+ } ;
/* Now worry about the state of the peer */