bgpd does not really synchronize the start of sessions with the config reload of the RDE. This is fine but there is one gotcha. When loading big configs including RTR tables the delay between the SE finishing the config reload (RECONF_DONE) and the RDE finally getting RECONF_DONE is so long that on startup many sessions come up manage to feed data to the RDE before the initial config gets active. This is not great.
So this diff tries to reduce this window a bit by a) issue RECONF_DONE for the RTR and RDE together (there is no dependecy between the two and the ROA/ASPA reloads can happen on the side). b) introduce a small timeout before bringing new sessions up. For the second diff I had to fix a bug in the neighbor state handler which has been there for a long time. The "reinit due?" case only triggers when init_peer() also triggers and so this code makes no sense and can simply be removed. We should never restart a session because of a config reload. -- :wq Claudio Index: bgpd.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v retrieving revision 1.256 diff -u -p -r1.256 bgpd.c --- bgpd.c 20 Jan 2023 10:30:41 -0000 1.256 +++ bgpd.c 14 Feb 2023 10:57:15 -0000 @@ -984,9 +984,9 @@ dispatch_imsg(struct imsgbuf *ibuf, int break; } if (idx == PFD_PIPE_SESSION) { + /* RDE and RTR engine can reload concurrently */ imsg_compose(ibuf_rtr, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0); - } else if (idx == PFD_PIPE_RTR) { imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0); Index: session.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.c,v retrieving revision 1.440 diff -u -p -r1.440 session.c --- session.c 9 Feb 2023 13:43:23 -0000 1.440 +++ session.c 14 Feb 2023 11:36:38 -0000 @@ -259,14 +259,6 @@ session_main(int debug, int verbose) if (p->state == STATE_NONE) init_peer(p); - /* reinit due? */ - if (p->reconf_action == RECONF_REINIT) { - session_stop(p, ERR_CEASE_ADMIN_RESET); - if (!p->conf.down) - timer_set(&p->timers, - Timer_IdleHold, 0); - } - /* deletion due? */ if (p->reconf_action == RECONF_DELETE) { if (p->demoted) @@ -580,7 +572,7 @@ init_peer(struct peer *p) if (p->conf.down) timer_stop(&p->timers, Timer_IdleHold); /* no autostart */ else - timer_set(&p->timers, Timer_IdleHold, 0); /* start ASAP */ + timer_set(&p->timers, Timer_IdleHold, SESSION_CLEAR_DELAY); p->stats.last_updown = getmonotime();