From: Claudio Jeker Subject: bgpd: introduce SessionDown timer To: tech@openbsd.org Date: Tue, 10 Dec 2024 15:02:56 +0100 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,