It is possible that a session is going down while peer->rpending (the flag indicating that there is more data to process) is set. If that is happening the session engine is spinning until the session comes back up or the neighbor is removed.
Fix is obvious, clear the flag when the read buffer rbuf is set to NULL. Additionally ensure that the timeout is only set to 0 if there is something in the read buffer to process. -- :wq Claudio Index: session.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.c,v retrieving revision 1.386 diff -u -p -r1.386 session.c --- session.c 22 Jun 2019 05:36:40 -0000 1.386 +++ session.c 28 Jun 2019 07:43:11 -0000 @@ -422,7 +422,7 @@ session_main(int debug, int verbose) if (p->wbuf.queued > 0 || p->state == STATE_CONNECT) events |= POLLOUT; /* is there still work to do? */ - if (p->rpending) + if (p->rpending && p->rbuf && p->rbuf->wpos) timeout = 0; /* poll events */ @@ -888,6 +888,7 @@ change_state(struct peer *peer, enum ses msgbuf_clear(&peer->wbuf); free(peer->rbuf); peer->rbuf = NULL; + peer->rpending = 0; bzero(&peer->capa.peer, sizeof(peer->capa.peer)); if (!peer->template) imsg_compose(ibuf_main, IMSG_PFKEY_RELOAD, @@ -2959,6 +2960,7 @@ getpeerbyip(struct bgpd_config *c, struc newpeer->state = newpeer->prev_state = STATE_NONE; newpeer->reconf_action = RECONF_KEEP; newpeer->rbuf = NULL; + newpeer->rpending = 0; init_peer(newpeer); bgp_fsm(newpeer, EVNT_START); if (RB_INSERT(peer_head, &c->peers, newpeer) != NULL)