diff options
-rw-r--r-- | bgpd/bgp_connection.c | 34 | ||||
-rw-r--r-- | bgpd/bgp_connection.h | 10 | ||||
-rw-r--r-- | bgpd/bgp_session.c | 116 | ||||
-rw-r--r-- | bgpd/bgp_session.h | 6 | ||||
-rw-r--r-- | lib/mqueue.c | 15 | ||||
-rw-r--r-- | lib/mqueue.h | 3 |
6 files changed, 91 insertions, 93 deletions
diff --git a/bgpd/bgp_connection.c b/bgpd/bgp_connection.c index ba75a509..665d5557 100644 --- a/bgpd/bgp_connection.c +++ b/bgpd/bgp_connection.c @@ -461,7 +461,7 @@ bgp_connection_queue_process(void) } ; /* Process next item on connection's pending queue */ - mqb = mqueue_local_head(&connection->pending_queue) ; + mqb = mqueue_local_dequeue(&connection->pending_queue) ; if (mqb != NULL) /* The action will either remove the mqb from the pending queue, * or remove the connection from the connection queue. @@ -472,12 +472,40 @@ bgp_connection_queue_process(void) && (connection == session->connections[bgp_connection_primary]) ) ; mqb_dispatch_action(mqb) ; - } - else + } ; + + /* If head is unchanged, then no more to do now. */ + if (mqb == mqueue_local_head(&connection->pending_queue)) bgp_connection_queue_del(connection) ; } ; } ; +/*------------------------------------------------------------------------------ + * Add given message block to the given connection's pending queue + * + * If mqb is not already pending, add it at the tail and mark it pending. + * + * If is already pending, then is being put back onto the queue, so put it + * at the head, and remove the connection from the connection queue -- there + * is nothing more to be done for the connection for the time being. + */ +extern void +bgp_connection_add_pending(bgp_connection connection, mqueue_block mqb, + bgp_connection* is_pending) +{ + if (*is_pending == NULL) + { + mqueue_local_enqueue(&connection->pending_queue, mqb) ; + *is_pending = connection ; + } + else + { + dassert(*is_pending == connection) ; + mqueue_local_enqueue_head(&connection->pending_queue, mqb) ; + bgp_connection_queue_del(connection) ; + } ; +} ; + /*============================================================================== * Opening and closing Connections */ diff --git a/bgpd/bgp_connection.h b/bgpd/bgp_connection.h index e4c183b8..c620de55 100644 --- a/bgpd/bgp_connection.h +++ b/bgpd/bgp_connection.h @@ -234,6 +234,16 @@ bgp_connection_queue_del(bgp_connection connection) ; extern void bgp_connection_queue_process(void) ; +Inline int +bgp_connection_no_pending(bgp_connection connection, bgp_connection* is_pending) +{ + return ( (mqueue_local_head(&connection->pending_queue) == NULL) + || (*is_pending != NULL) ) ; +} ; + +extern void +bgp_connection_add_pending(bgp_connection connection, mqueue_block mqb, + bgp_connection* is_pending) ; /*------------------------------------------------------------------------------ * See if have enough room for what want to write PLUS 1. diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c index 56d6c7f8..e0c3972e 100644 --- a/bgpd/bgp_session.c +++ b/bgpd/bgp_session.c @@ -323,6 +323,7 @@ bgp_session_enable(bgp_peer peer) confirm(sizeof(struct bgp_session_enable_args) == 0) ; + session->state = bgp_session_sEnabled; bgp_to_bgp_engine(mqb) ; } ; @@ -340,7 +341,6 @@ bgp_session_do_enable(mqueue_block mqb, mqb_flag_t flag) session->active = 1 ; bgp_fsm_enable_session(session) ; - session->state = bgp_session_sEnabled; BGP_SESSION_UNLOCK(session) ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ } ; @@ -487,8 +487,8 @@ bgp_session_update_send(bgp_session session, struct stream* upd) mqb = mqb_init_new(NULL, bgp_session_do_update_send, session) ; args = mqb_get_args(mqb) ; - args->buf = stream_dup(upd) ; - args->pending = NULL ; + args->buf = stream_dup(upd) ; + args->is_pending = NULL ; BGP_SESSION_LOCK(session) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ session->flow_control++; /* count them in ... */ @@ -544,33 +544,22 @@ bgp_session_do_update_send(mqueue_block mqb, mqb_flag_t flag) bgp_connection connection = session->connections[bgp_connection_primary] ; assert(connection != NULL) ; - mqueue_block head = mqueue_local_head(&connection->pending_queue) ; - - int is_pending = (args->pending != NULL) ; - if (is_pending) - assert( (args->pending == connection) && (mqb == head) ) ; - /* If established, try and send. */ if (connection->state == bgp_fsm_sEstablished) { - int ret = 0 ; + int ret = bgp_connection_no_pending(connection, &args->is_pending) ; - if ((head == NULL) || is_pending) + if (ret != 0) ret = bgp_msg_send_update(connection, args->buf) ; if (ret == 0) { - /* Did not fail, but could not write the message. */ - if (!is_pending) - { - mqueue_local_enqueue(&connection->pending_queue, mqb) ; - args->pending = connection ; - } - else - bgp_connection_queue_del(connection) ; - - return ; /* **** Quit now, with message intact. */ - + /* Either there is already a pending queue, or the message + * could not be sent (and has not failed) -- so add to the + * pending queue. + */ + bgp_connection_add_pending(connection, mqb, &args->is_pending) ; + return ; /* Quit now, with message intact. */ } else if (ret > 0) { @@ -584,10 +573,6 @@ bgp_session_do_update_send(mqueue_block mqb, mqb_flag_t flag) bgp_session_XON(session); } ; } ; - - /* Have dealt with the message -- if was pending, it's done. */ - if (is_pending) - mqueue_local_dequeue(&connection->pending_queue) ; } ; stream_free(args->buf) ; @@ -641,8 +626,8 @@ bgp_session_route_refresh_send(bgp_session session, bgp_route_refresh rr) mqb = mqb_init_new(NULL, bgp_session_do_route_refresh_send, session) ; args = mqb_get_args(mqb) ; - args->rr = rr ; - args->pending = NULL ; + args->rr = rr ; + args->is_pending = NULL ; bgp_to_bgp_engine(mqb) ; } ; @@ -664,45 +649,24 @@ bgp_session_do_route_refresh_send(mqueue_block mqb, mqb_flag_t flag) bgp_connection connection = session->connections[bgp_connection_primary] ; assert(connection != NULL) ; - mqueue_block head = mqueue_local_head(&connection->pending_queue) ; - - int is_pending = (args->pending != NULL) ; - if (is_pending) - assert( (args->pending == connection) && (mqb == head) ) ; - /* If established, try and send. */ if (connection->state == bgp_fsm_sEstablished) { - int ret = 0 ; + int ret = bgp_connection_no_pending(connection, &args->is_pending) ; - if ((head == NULL) || is_pending) + if (ret != 0) ret = bgp_msg_send_route_refresh(connection, args->rr) ; if (ret == 0) { - /* Did not fail, but could not write everything. - * - * If this is not on the connection's pending queue, put it there. - * - * Otherwise leave it there, and take the connection off the - * connection queue -- nothing further can be done for this - * connection. + /* Either there is already a pending queue, or the message + * could not be sent (and has not failed) -- so add to the + * pending queue. */ - if (!is_pending) - { - mqueue_local_enqueue(&connection->pending_queue, mqb) ; - args->pending = connection ; - } - else - bgp_connection_queue_del(connection) ; - + bgp_connection_add_pending(connection, mqb, &args->is_pending) ; return ; /* Quit now, with message intact. */ } ; } ; - - /* Have dealt with the message -- if was pending, it's done. */ - if (is_pending) - mqueue_local_dequeue(&connection->pending_queue) ; } ; bgp_route_refresh_free(args->rr) ; @@ -724,9 +688,9 @@ bgp_session_end_of_rib_send(bgp_session session, qAFI_t afi, qSAFI_t safi) mqb = mqb_init_new(NULL, bgp_session_do_end_of_rib_send, session) ; args = mqb_get_args(mqb) ; - args->afi = get_iAFI(qafx) ; - args->safi = get_iSAFI(qafx) ; - args->pending = NULL ; + args->afi = get_iAFI(qafx) ; + args->safi = get_iSAFI(qafx) ; + args->is_pending = NULL ; bgp_to_bgp_engine(mqb) ; } ; @@ -748,45 +712,25 @@ bgp_session_do_end_of_rib_send(mqueue_block mqb, mqb_flag_t flag) bgp_connection connection = session->connections[bgp_connection_primary] ; assert(connection != NULL) ; - mqueue_block head = mqueue_local_head(&connection->pending_queue) ; - - int is_pending = (args->pending != NULL) ; - if (is_pending) - assert( (args->pending == connection) && (mqb == head) ) ; - /* If established, try and send. */ if (connection->state == bgp_fsm_sEstablished) { - int ret = 0 ; + int ret = bgp_connection_no_pending(connection, &args->is_pending) ; - if ((head == NULL) || is_pending) + if (ret != 0) ret = bgp_msg_send_end_of_rib(connection, args->afi, args->safi) ; if (ret == 0) { - /* Did not fail, but could not write everything. - * - * If this is not on the connection's pending queue, put it there. - * - * Otherwise leave it there, and take the connection off the - * connection queue -- nothing further can be done for this - * connection. + /* Either there is already a pending queue, or the message + * could not be sent (and has not failed) -- so add to the + * pending queue. */ - if (!is_pending) - { - mqueue_local_enqueue(&connection->pending_queue, mqb) ; - args->pending = connection ; - } - else - bgp_connection_queue_del(connection) ; + bgp_connection_add_pending(connection, mqb, &args->is_pending) ; return ; /* Quit now, with message intact. */ } ; } ; - - /* Have dealt with the message -- if was pending, it's done. */ - if (is_pending) - mqueue_local_dequeue(&connection->pending_queue) ; } ; mqb_free(mqb) ; @@ -853,8 +797,8 @@ bgp_session_route_refresh_recv(bgp_session session, bgp_route_refresh rr) mqb = mqb_init_new(NULL, bgp_session_do_route_refresh_recv, session) ; args = mqb_get_args(mqb) ; - args->rr = rr ; - args->pending = NULL ; + args->rr = rr ; + args->is_pending = NULL ; bgp_to_peering_engine(mqb) ; } ; diff --git a/bgpd/bgp_session.h b/bgpd/bgp_session.h index 06d2846d..967286ef 100644 --- a/bgpd/bgp_session.h +++ b/bgpd/bgp_session.h @@ -244,7 +244,7 @@ struct bgp_session_update_args /* to and from BGP Engine */ struct stream* buf ; bgp_size_t size ; - bgp_connection pending ; /* used inside the BGP Engine */ + bgp_connection is_pending ; /* used inside the BGP Engine */ /* set NULL on message creation */ } ; MQB_ARGS_SIZE_OK(bgp_session_update_args) ; @@ -253,7 +253,7 @@ struct bgp_session_route_refresh_args /* to and from BGP Engine */ { bgp_route_refresh rr ; - bgp_connection pending ; /* used inside the BGP Engine */ + bgp_connection is_pending ; /* used inside the BGP Engine */ /* set NULL on message creation */ } ; MQB_ARGS_SIZE_OK(bgp_session_route_refresh_args) ; @@ -263,7 +263,7 @@ struct bgp_session_end_of_rib_args /* to and from BGP Engine */ iAFI_t afi ; iSAFI_t safi ; - bgp_connection pending ; /* used inside the BGP Engine */ + bgp_connection is_pending ; /* used inside the BGP Engine */ /* set NULL on message creation */ } ; MQB_ARGS_SIZE_OK(bgp_session_end_of_rib_args) ; diff --git a/lib/mqueue.c b/lib/mqueue.c index 7156e31e..de1d654c 100644 --- a/lib/mqueue.c +++ b/lib/mqueue.c @@ -708,7 +708,7 @@ mqueue_done_waiting(mqueue_queue mq, mqueue_thread_signal mtsig) } ; /*------------------------------------------------------------------------------ - * Enqueue message on local queue + * Enqueue message on local queue -- at tail */ extern void mqueue_local_enqueue(mqueue_local_queue lmq, mqueue_block mqb) @@ -722,6 +722,19 @@ mqueue_local_enqueue(mqueue_local_queue lmq, mqueue_block mqb) } ; /*------------------------------------------------------------------------------ + * Enqueue message on local queue -- at head + */ +extern void +mqueue_local_enqueue_head(mqueue_local_queue lmq, mqueue_block mqb) +{ + if (lmq->head == NULL) + lmq->tail = mqb ; + + mqb->next = lmq->head ; + lmq->head = mqb ; +} ; + +/*------------------------------------------------------------------------------ * Dequeue message from local queue -- returns NULL if empty */ extern mqueue_block diff --git a/lib/mqueue.h b/lib/mqueue.h index a6edb4d7..2bd96896 100644 --- a/lib/mqueue.h +++ b/lib/mqueue.h @@ -234,6 +234,9 @@ mqueue_done_waiting(mqueue_queue mq, mqueue_thread_signal mtsig) ; extern void mqueue_local_enqueue(mqueue_local_queue lmq, mqueue_block mqb) ; +extern void +mqueue_local_enqueue_head(mqueue_local_queue lmq, mqueue_block mqb) ; + Inline mqueue_block mqueue_local_head(mqueue_local_queue lmq) ; |