From: Quentin Young Date: Thu, 6 Apr 2017 01:09:33 +0000 (+0000) Subject: bgpd: transfer packets from peer stub to actual peer X-Git-Tag: frr-4.0-dev~120^2~52 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=727c4f870b0e6079b761afc525f6a1f5262bcf9f;p=mirror%2Ffrr.git bgpd: transfer packets from peer stub to actual peer During transition from OpenConfirm -> Established, we wipe the peer stub's output buffer. Because thread.c prioritizes I/O operations over regular background threads and events, in a single threaded environment this ordering meant that the output buffer would be happily empty at wipe time. In MT-land, this convenient coincidence is no longer true; thus we need to make sure that any packets remaining on the peer stub get transferred over to the peer proper. Also removes misleading comment indicating that bgp_establish() sends a keepalive packet. It does not. Signed-off-by: Quentin Young --- diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index aa883f7364..3344bf3126 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -138,17 +138,22 @@ static struct peer *peer_xfer_conn(struct peer *from_peer) from_peer->fd = fd; stream_reset(peer->ibuf); + // At this point in time, it is possible that there are packets pending + // on + // from_peer->obuf. These need to be transferred to the new peer struct. pthread_mutex_lock(&peer->obuf_mtx); + pthread_mutex_lock(&from_peer->obuf_mtx); { + // wipe new peer's packet queue stream_fifo_clean(peer->obuf); - } - pthread_mutex_unlock(&peer->obuf_mtx); - pthread_mutex_lock(&from_peer->obuf_mtx); - { - stream_fifo_clean(from_peer->obuf); + // copy each packet from old peer's queue to new peer's queue + while (from_peer->obuf->head) + stream_fifo_push(peer->obuf, + stream_fifo_pop(from_peer->obuf)); } pthread_mutex_unlock(&from_peer->obuf_mtx); + pthread_mutex_unlock(&peer->obuf_mtx); peer->as = from_peer->as; peer->v_holdtime = from_peer->v_holdtime; @@ -1398,8 +1403,12 @@ static int bgp_fsm_holdtime_expire(struct peer *peer) return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0); } -/* Status goes to Established. Send keepalive packet then make first - update information. */ +/** + * Transition to Established state. + * + * Convert peer from stub to full fledged peer, set some timers, and generate + * initial updates. + */ static int bgp_establish(struct peer *peer) { afi_t afi;