Download raw body.
bgpd: trigger session down timer during graceful restart
On Thu, May 07, 2026 at 04:19:25PM +0200, Claudio Jeker wrote:
> When a peer goes down it can either call session_down() or go into
> session_graceful_restart() to do a graceful reload.
>
> In session_down the Timer_SessionDown timer is armed and will fire in 1h.
> In the GR case this is not done. If the session fails to recover the
> RDE will keep on syncing its Adj-RIB-Out which is not helpful. Also
> templated peers are no longer cleaned up.
>
> Now the maximum GR timeout is 4095 (since it is a 12bit field) and that is
> longer than INTERVAL_SESSION_DOWN. So do a quick check to either use
> INTERVAL_SESSION_DOWN or staletime + INTERVAL_SESSION_DOWN depending on
> which one is bigger.
I think you mean "INTERVAL_SESSION_DOWN or staletime + INTERVAL_STALE"
... (see below)
>
> While there also update last_updown in the stats struct since the peer
> either lost or flapped the session.
>
> I switch the grestart.timeout in struct capabilities to uint16_t to
> silence another signed vs unsigned warnings.
> --
> :wq Claudio
>
> Index: bgpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> diff -u -p -r1.540 bgpd.h
> --- bgpd.h 5 May 2026 09:12:04 -0000 1.540
> +++ bgpd.h 7 May 2026 13:31:04 -0000
> @@ -437,10 +437,10 @@ struct auth_config {
>
> struct capabilities {
> struct {
> - int16_t timeout; /* graceful restart timeout */
> - int8_t flags[AID_MAX]; /* graceful restart per AID flags */
> - int8_t restart; /* graceful restart, RFC 4724 */
> - int8_t grnotification; /* graceful notification, RFC 8538 */
> + uint16_t timeout; /* gr restart timeout */
> + int8_t flags[AID_MAX]; /* gr restart per AID flags */
> + int8_t restart; /* gr restart, RFC 4724 */
> + int8_t grnotification; /* gr notification, RFC 8538 */
> } grestart;
> int8_t mp[AID_MAX]; /* multiprotocol extensions, RFC 4760 */
> int8_t add_path[AID_MAX]; /* ADD_PATH, RFC 7911 */
> Index: parse.y
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
> diff -u -p -r1.488 parse.y
> --- parse.y 2 Mar 2026 09:51:48 -0000 1.488
> +++ parse.y 7 May 2026 13:28:57 -0000
> @@ -772,9 +772,9 @@ conf_main : AS as4number {
> conf->min_holdtime = $3;
> }
> | STALETIME NUMBER {
> - if ($2 < MIN_HOLDTIME || $2 > USHRT_MAX) {
> + if ($2 < MIN_HOLDTIME || $2 > CAPA_GR_TIMEMASK) {
> yyerror("staletime must be between %u and %u",
> - MIN_HOLDTIME, USHRT_MAX);
> + MIN_HOLDTIME, CAPA_GR_TIMEMASK);
> YYERROR;
> }
> conf->staletime = $2;
> @@ -1937,9 +1937,9 @@ peeropts : REMOTEAS as4number {
> curpeer->conf.min_holdtime = $3;
> }
> | STALETIME NUMBER {
> - if ($2 < MIN_HOLDTIME || $2 > USHRT_MAX) {
> + if ($2 < MIN_HOLDTIME || $2 > CAPA_GR_TIMEMASK) {
> yyerror("staletime must be between %u and %u",
> - MIN_HOLDTIME, USHRT_MAX);
> + MIN_HOLDTIME, CAPA_GR_TIMEMASK);
> YYERROR;
> }
> curpeer->conf.staletime = $2;
> Index: session.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
> diff -u -p -r1.531 session.c
> --- session.c 7 May 2026 09:17:27 -0000 1.531
> +++ session.c 7 May 2026 13:34:11 -0000
> @@ -1048,7 +1048,7 @@ void
> session_graceful_restart(struct peer *p)
> {
> uint8_t i;
> - uint16_t staletime = conf->staletime;
> + u_int staletime = conf->staletime;
>
> if (p->conf.staletime)
> staletime = p->conf.staletime;
> @@ -1057,6 +1057,14 @@ session_graceful_restart(struct peer *p)
> if (staletime > p->capa.neg.grestart.timeout)
> staletime = p->capa.neg.grestart.timeout;
> timer_set(&p->timers, Timer_RestartTimeout, staletime);
> +
> + if (staletime < INTERVAL_SESSION_DOWN - INTERVAL_STALE)
> + staletime = INTERVAL_SESSION_DOWN - INTERVAL_STALE;
> +
> + /* bits from session_down that are also needed here */
> + p->stats.last_updown = getmonotime();
> + timer_set(&p->timers, Timer_SessionDown,
> + staletime + INTERVAL_SESSION_DOWN);
... and this should be:
staletime + INTERVAL_STALE);
then it's ok
>
> for (i = AID_MIN; i < AID_MAX; i++) {
> if (p->capa.neg.grestart.flags[i] & CAPA_GR_PRESENT) {
>
bgpd: trigger session down timer during graceful restart