Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
bgpd: introduce SessionDown timer
To:
tech@openbsd.org
Date:
Tue, 10 Dec 2024 15:02:56 +0100

Download raw body.

Thread
Introduce a SessionDown timer which is started when a session goes down
and stopped when the session comes up (ESTABLISHED state).

Use this timer to implement the automatic removal of cloned peers.
For this to work in any case we start the timer when a template is cloned.
This way a cloned session that never makes it up will be removed after a
1h of trying.

Soon this will also be used to implement the timeout for the Adj-RIB-Out
cache.
-- 
:wq Claudio

Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
diff -u -p -r1.502 bgpd.h
--- bgpd.h	9 Dec 2024 10:51:46 -0000	1.502
+++ bgpd.h	10 Dec 2024 13:58:12 -0000
@@ -1761,6 +1761,7 @@ static const char * const timernames[] =
 	"IdleHoldResetTimer",
 	"CarpUndemoteTimer",
 	"RestartTimer",
+	"SessionDownTimer",
 	"RTR RefreshTimer",
 	"RTR RetryTimer",
 	"RTR ExpireTimer",
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
diff -u -p -r1.501 session.c
--- session.c	9 Dec 2024 10:51:46 -0000	1.501
+++ session.c	10 Dec 2024 13:57:58 -0000
@@ -257,13 +257,6 @@ session_main(int debug, int verbose)
 		/* check for peers to be initialized or deleted */
 		if (!pending_reconf) {
 			RB_FOREACH_SAFE(p, peer_head, &conf->peers, next) {
-				/* cloned peer that idled out? */
-				if (p->template && (p->state == STATE_IDLE ||
-				    p->state == STATE_ACTIVE) &&
-				    getmonotime() - p->stats.last_updown >=
-				    INTERVAL_HOLD_CLONED)
-					p->reconf_action = RECONF_DELETE;
-
 				/* new peer that needs init? */
 				if (p->state == STATE_NONE)
 					init_peer(p);
@@ -409,6 +402,14 @@ session_main(int debug, int verbose)
 					    Timer_RestartTimeout);
 					session_graceful_stop(p);
 					break;
+				case Timer_SessionDown:
+					timer_stop(&p->timers,
+					    Timer_SessionDown);
+					/* finally delete this cloned peer */
+					if (p->template)
+						p->reconf_action =
+						    RECONF_DELETE;
+					break;
 				default:
 					fatalx("King Bula lost in time");
 				}
@@ -2266,7 +2267,11 @@ parse_open(struct peer *peer, struct ibu
 		return (-1);
 	}
 
-	/* if remote-as is zero and it's a cloned neighbor, accept any */
+	/*
+	 * if remote-as is zero and it's a cloned neighbor, accept any
+	 * but only on the first connect, after that the remote-as needs
+	 * to remain the same.
+	 */
 	if (peer->template && !peer->conf.remote_as && as != AS_TRANS) {
 		peer->conf.remote_as = as;
 		peer->conf.ebgp = (peer->conf.remote_as != peer->conf.local_as);
@@ -3338,6 +3343,9 @@ getpeerbyip(struct bgpd_config *c, struc
 		newpeer->rpending = 0;
 		newpeer->wbuf = NULL;
 		init_peer(newpeer);
+		/* start delete timer, it is stopped when session goes up. */
+		timer_set(&newpeer->timers, Timer_SessionDown,
+		    INTERVAL_SESSION_DOWN);
 		bgp_fsm(newpeer, EVNT_START, NULL);
 		if (RB_INSERT(peer_head, &c->peers, newpeer) != NULL)
 			fatalx("%s: peer tree is corrupt", __func__);
@@ -3426,6 +3434,9 @@ session_down(struct peer *peer)
 {
 	memset(&peer->capa.neg, 0, sizeof(peer->capa.neg));
 	peer->stats.last_updown = getmonotime();
+
+	timer_set(&peer->timers, Timer_SessionDown, INTERVAL_SESSION_DOWN);
+
 	/*
 	 * session_down is called in the exit code path so check
 	 * if the RDE is still around, if not there is no need to
@@ -3448,6 +3459,8 @@ session_up(struct peer *p)
 	p->stats.last_rcvd_errcode = 0;
 	p->stats.last_rcvd_suberr = 0;
 	memset(p->stats.last_reason, 0, sizeof(p->stats.last_reason));
+
+	timer_stop(&p->timers, Timer_SessionDown);
 
 	if (imsg_rde(IMSG_SESSION_ADD, p->conf.id,
 	    &p->conf, sizeof(p->conf)) == -1)
Index: session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
diff -u -p -r1.180 session.h
--- session.h	21 Nov 2024 13:34:30 -0000	1.180
+++ session.h	10 Dec 2024 13:57:28 -0000
@@ -25,8 +25,8 @@
 #define	INTERVAL_HOLD_INITIAL		240
 #define	INTERVAL_HOLD			90
 #define	INTERVAL_IDLE_HOLD_INITIAL	30
-#define	INTERVAL_HOLD_CLONED		3600
 #define	INTERVAL_HOLD_DEMOTED		60
+#define	INTERVAL_SESSION_DOWN		3600
 #define	MAX_IDLE_HOLD			3600
 #define	MSGSIZE_HEADER			19
 #define	MSGSIZE_HEADER_MARKER		16
@@ -176,6 +176,7 @@ enum Timer {
 	Timer_IdleHoldReset,
 	Timer_CarpUndemote,
 	Timer_RestartTimeout,
+	Timer_SessionDown,
 	Timer_Rtr_Refresh,
 	Timer_Rtr_Retry,
 	Timer_Rtr_Expire,