Download raw body.
bgpd: allow quick open on startup
With the change to the IdleHoldTimer I did a few days ago the regress
tests starterd to blow up. I remember I tested them but I probably screwed
up something on my side.
The problem is that on startup we keep seesion in Idle for
SESSION_CLEAR_DELAY seconds. In that state no connection is accepted.
So this applies the same logic and moves the peer directly to Active
and adds an extra hack into the bgp_fsm EVNT_START handling to reduce
the Timer_ConnectRetry to SESSION_CLEAR_DELAY.
In init_peer() instead of passing via the timer just call the bgp_fsm().
Also there is no need to stop a timer that is not running.
The initial delay I added here was to ensure that the async bits of the
initial config load have finished in the RDE. This just prevents extra
work on startup for setups with big configs and many peers. Maybe the RDE
should signal the SE when finished so we could use that signal to start all
sessions on startup.
With the diff below regress is passing again.
--
:wq Claudio
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
diff -u -p -r1.538 session.c
--- session.c 21 Jul 2026 08:23:44 -0000 1.538
+++ session.c 23 Jul 2026 09:14:32 -0000
@@ -593,10 +593,8 @@ init_peer(struct peer *p, struct bgpd_co
peer_cnt++;
change_state(p, STATE_IDLE, EVNT_NONE);
- if (p->conf.down)
- timer_stop(&p->timers, Timer_IdleHold); /* no autostart */
- else
- timer_set(&p->timers, Timer_IdleHold, SESSION_CLEAR_DELAY);
+ if (!p->conf.down)
+ bgp_fsm(p, EVNT_START, NULL);
p->stats.last_updown = getmonotime();
Index: session_bgp.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session_bgp.c,v
diff -u -p -r1.11 session_bgp.c
--- session_bgp.c 21 Jul 2026 08:23:44 -0000 1.11
+++ session_bgp.c 23 Jul 2026 09:10:01 -0000
@@ -1554,16 +1554,19 @@ bgp_fsm(struct peer *peer, enum session_
timer_stop(&peer->timers, Timer_Keepalive);
timer_stop(&peer->timers, Timer_IdleHold);
- if (!peer->depend_ok)
+ if (!peer->depend_ok) {
timer_stop(&peer->timers, Timer_ConnectRetry);
- else if (peer->conf.passive || peer->conf.template) {
+ } else if (peer->conf.passive || peer->conf.template) {
change_state(peer, STATE_ACTIVE, event);
timer_stop(&peer->timers, Timer_ConnectRetry);
- } else if (peer->IdleHoldTime ==
- INTERVAL_IDLE_HOLD_INITIAL) {
+ } else if (peer->prev_state == STATE_NONE ||
+ peer->IdleHoldTime == INTERVAL_IDLE_HOLD_INITIAL) {
+ u_int holdtime = INTERVAL_IDLE_HOLD_INITIAL;
+ if (peer->prev_state == STATE_NONE)
+ holdtime = SESSION_CLEAR_DELAY;
change_state(peer, STATE_ACTIVE, event);
timer_set(&peer->timers, Timer_ConnectRetry,
- INTERVAL_IDLE_HOLD_INITIAL);
+ holdtime);
} else {
change_state(peer, STATE_CONNECT, event);
timer_set(&peer->timers, Timer_ConnectRetry,
bgpd: allow quick open on startup