Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
bgpd: allow quick open on startup
To:
tech@openbsd.org
Date:
Thu, 23 Jul 2026 12:07:24 +0200

Download raw body.

Thread
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,