summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_fsm.c')
-rw-r--r--bgpd/bgp_fsm.c105
1 files changed, 43 insertions, 62 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 8a8be52d..77afa12f 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -57,7 +57,7 @@
*
* In general the FSM manages connections, but there is some interaction with
* the session. In particular, exceptions are expressed as session_eXXX
- * values -- which are passed to the Peering Engine as session events. The
+ * values -- which are passed to the Routing Engine as session events. The
* handling of FSM events is depends mostly on the FSM state, but any
* exception influences that too.
*
@@ -273,7 +273,7 @@
* notification -- any NOTIFICATION message
* err -- any I/O or other error
*
- * on exit from the FSM this information is passed to the Peering Engine.
+ * on exit from the FSM this information is passed to the Routing Engine.
*
* Can throw exceptions within the FSM, as discussed above.
*
@@ -446,7 +446,7 @@ bgp_fsm_enable_session(bgp_session session)
*
*/
static void
-bgp_fsm_throw(bgp_connection connection, bgp_session_event_t except,
+bgp_fsm_throw(bgp_connection connection, bgp_session_event_t exception,
bgp_notify notification, int err, bgp_fsm_event_t event) ;
static bgp_fsm_state_t
@@ -548,10 +548,10 @@ bgp_fsm_disable_session(bgp_session session, bgp_notify notification)
* fsm_active/follow_on mechanism looks after this.
*/
extern void
-bgp_fsm_exception(bgp_connection connection, bgp_session_event_t except,
+bgp_fsm_exception(bgp_connection connection, bgp_session_event_t exception,
bgp_notify notification)
{
- bgp_fsm_throw(connection, except, notification, 0, bgp_fsm_eBGP_Stop) ;
+ bgp_fsm_throw(connection, exception, notification, 0, bgp_fsm_eBGP_Stop) ;
} ;
/*------------------------------------------------------------------------------
@@ -559,7 +559,7 @@ bgp_fsm_exception(bgp_connection connection, bgp_session_event_t except,
*
* A connection will discard any sibling if:
*
- * * the session is being disabled (by the Peering Engine)
+ * * the session is being disabled (by the Routing Engine)
*
* * an invalid event is bringing down the session
*
@@ -655,7 +655,7 @@ bgp_fsm_io_error(bgp_connection connection, int err)
* This is used by the connect() and accept() qpselect actions. It is also
* used if a connect() attempt fails immediately.
*
- * If err == 0, then all is well: copy the local and remote sockunions
+ * If err == 0, then all is well: start the connection (can now write to it)
* and generate TCP_connection_open event
*
* If err is one of:
@@ -666,6 +666,9 @@ bgp_fsm_io_error(bgp_connection connection, int err)
* these errors.)
*
* Other errors are reported as TCP_fatal_error.
+ *
+ * NB: in any case on entry to this function the file is *disabled* in all
+ * modes.
*/
extern void
bgp_fsm_connect_completed(bgp_connection connection, int err,
@@ -674,12 +677,8 @@ bgp_fsm_connect_completed(bgp_connection connection, int err,
{
if (err == 0)
{
+ bgp_connection_start(connection, su_local, su_remote) ;
bgp_fsm_event(connection, bgp_fsm_eTCP_connection_open) ;
-
- sockunion_set_dup(&connection->su_local, su_local) ;
- sockunion_set_dup(&connection->su_remote, su_remote) ;
-
- connection->paf = sockunion_family(connection->su_local) ;
}
else if ( (err == ECONNREFUSED)
|| (err == ECONNRESET)
@@ -697,12 +696,12 @@ bgp_fsm_connect_completed(bgp_connection connection, int err,
* NB: takes responsibility for the notification structure.
*/
static void
-bgp_fsm_throw(bgp_connection connection, bgp_session_event_t except,
+bgp_fsm_throw(bgp_connection connection, bgp_session_event_t exception,
bgp_notify notification, int err, bgp_fsm_event_t event)
{
- connection->except = except ;
+ connection->exception = exception ;
bgp_notify_set(&connection->notification, notification) ;
- connection->err = err ;
+ connection->err = err ;
bgp_fsm_event(connection, event) ;
} ;
@@ -721,10 +720,10 @@ bgp_fsm_throw(bgp_connection connection, bgp_session_event_t except,
* NB: takes responsibility for the notification structure.
*/
static bgp_fsm_state_t
-bgp_fsm_throw_stop(bgp_connection connection, bgp_session_event_t except,
+bgp_fsm_throw_stop(bgp_connection connection, bgp_session_event_t exception,
bgp_notify notification)
{
- bgp_fsm_throw(connection, except, notification, 0, bgp_fsm_eBGP_Stop) ;
+ bgp_fsm_throw(connection, exception, notification, 0, bgp_fsm_eBGP_Stop) ;
return connection->state ;
} ;
@@ -1477,7 +1476,7 @@ bgp_fsm_event(bgp_connection connection, bgp_fsm_event_t event)
} while (--connection->fsm_active != 0) ;
/* If required, post session event. */
- if (connection->except != bgp_session_null_event)
+ if (connection->exception != bgp_session_null_event)
{
int stopped = (connection->state == bgp_fsm_sStopping) ;
int has_session = (connection->session != NULL) ;
@@ -1488,16 +1487,16 @@ bgp_fsm_event(bgp_connection connection, bgp_fsm_event_t event)
* connection->state will be Stopping is when the session is being
* stopped. (eDiscard and eCollision go quietly to Stopping !)
*/
- if ((connection->except <= bgp_session_max_event) && has_session)
- bgp_session_event(connection->session, connection->except,
+ if ((connection->exception <= bgp_session_max_event) && has_session)
+ bgp_session_event(connection->session, connection->exception,
bgp_notify_take(&connection->notification),
connection->err,
connection->ordinal,
stopped) ;
/* Tidy up -- notification already cleared */
- connection->except = bgp_session_null_event ;
- connection->err = 0 ;
+ connection->exception = bgp_session_null_event ;
+ connection->err = 0 ;
bgp_notify_unset(&connection->notification) ; /* if any */
if (stopped && has_session)
@@ -1552,12 +1551,12 @@ static bgp_fsm_action(bgp_fsm_enter)
*/
static bgp_fsm_action(bgp_fsm_stop)
{
- if (connection->except == bgp_session_null_event)
+ if (connection->exception == bgp_session_null_event)
return bgp_fsm_invalid(connection, bgp_fsm_sStopping, event) ;
- if ( (connection->except == bgp_session_eDisabled)
- || (connection->except == bgp_session_eDiscard)
- || (connection->except == bgp_session_eInvalid) )
+ if ( (connection->exception == bgp_session_eDisabled)
+ || (connection->exception == bgp_session_eDiscard)
+ || (connection->exception == bgp_session_eInvalid) )
next_state = bgp_fsm_sStopping ;
return bgp_fsm_catch(connection, next_state) ;
@@ -1590,7 +1589,7 @@ static bgp_fsm_action(bgp_fsm_invalid)
*
* Enters either sConnect or sActive, depending on primary/secondary.
*
- * Throws a session_eStart exception so the Peering Engine gets to see this,
+ * Throws a session_eStart exception so the Routing Engine gets to see this,
* and a follow-on fsm_eBGP_Start event to kick the connect() or accept() into
* life.
*
@@ -2029,12 +2028,12 @@ bgp_fsm_catch(bgp_connection connection, bgp_fsm_state_t next_state)
{
bgp_notify send_notification ;
- assert(connection->except != bgp_session_null_event) ;
+ assert(connection->exception != bgp_session_null_event) ;
/* Have a notification to send iff not just received one, and is in a
* suitable state to send one at all.
*/
- if (connection->except == bgp_session_eNOM_recv)
+ if (connection->exception == bgp_session_eNOM_recv)
send_notification = NULL ;
else
{
@@ -2046,54 +2045,36 @@ bgp_fsm_catch(bgp_connection connection, bgp_fsm_state_t next_state)
send_notification = connection->notification ;
} ;
- /* If there is a NOTIFICATION to send, now is the time to do that.
+ /* If there is a NOTIFICATION to send, send it if possible.
* Otherwise, close the connection but leave the timers.
*
* The state transition stuff looks after timers. In particular an error
* in Connect/Active states leaves the ConnectRetryTimer running.
*/
- if (send_notification != NULL)
+ if ((send_notification != NULL) && bgp_connection_part_close(connection))
{
- int ret ;
-
/* If not changing to stopping, we hold in the current state until
* the NOTIFICATION process is complete.
*/
if (next_state != bgp_fsm_sStopping)
next_state = connection->state ;
- /* Close for reading and flush write buffers. */
- bgp_connection_part_close(connection) ;
-
+ /* Make sure that cannot pop out a Keepalive ! */
qtimer_unset(&connection->keepalive_timer) ;
- /* Write the message
+ /* Write the message */
+ bgp_msg_write_notification(connection, send_notification) ;
+
+ /* notification is sitting in the write buffer
+ *
+ * notification_pending is set, so write action will raise the required
+ * event in due course.
*
- * If the write fails it raises a suitable event, which will now be
- * sitting waiting to be processed on the way out of the FSM.
+ * Set the HoldTimer to something suitable. Don't really expect this
+ * to happen in anything except sEstablished state -- but copes. (Is
+ * ready to wait 20 seconds in sStopping state and 5 otherwise.)
*/
- ret = bgp_msg_write_notification(connection, send_notification) ;
-
- connection->notification_pending = (ret >= 0) ;
- /* is pending if not failed */
- if (ret > 0)
- /* notification reached the TCP buffers instantly
- *
- * Send ourselves the good news !
- */
- bgp_fsm_notification_sent(connection) ;
-
- else if (ret == 0)
- /* notification is sitting in the write buffer
- *
- * notification_pending is set, so write action will raise the required
- * event in due course.
- *
- * Set the HoldTimer to something suitable. Don't really expect this
- * to happen in anything except sEstablished state -- but copes. (Is
- * ready to wait 20 seconds in sStopping state and 5 otherwise.)
- */
- bgp_hold_timer_set(connection,
+ bgp_hold_timer_set(connection,
(next_state == bgp_fsm_sStopping) ? 20 : 5) ;
}
else
@@ -2106,7 +2087,7 @@ bgp_fsm_catch(bgp_connection connection, bgp_fsm_state_t next_state)
/* If sStopping and not eDiscard, do in any sibling */
if ( (next_state == bgp_fsm_sStopping)
- && (connection->except != bgp_session_eDiscard) )
+ && (connection->exception != bgp_session_eDiscard) )
{
bgp_connection sibling ;