From: Theo Buehler Subject: Re: bgpctl: print absolute timestamps for mrt dumps To: tech@openbsd.org Date: Thu, 21 May 2026 16:11:22 +0200 On Thu, May 21, 2026 at 03:22:24PM +0200, Claudio Jeker wrote: > bgpctl show mrt detail currently show entries with > Last update: Never ago > > This comes from the fact that most mrt dumps come from the past and bgpctl > tries to print the Last update as a relative timeframe based on the > monotonic clock. > > So for 'show mrt' switch fmt_monotime() to absolute timestamps. > Remove the 'ago' from the Last update line and print the timestamp using > monotime_to_time, gmtime and strftime("%FT%TZ") to get a ISO format > timestamp string. > > While there also adjust get_rel_monotime() to be more like > monotime_to_time() and stop treating negative numbers as error. > In fmt_monotime() instead compare the time against 0 to print Never. > > With this the mrt dump I have now shows this: > Last update: 2019-05-08T20:03:06Z ok tb > > -- > :wq Claudio > > Index: bgpctl.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v > diff -u -p -r1.321 bgpctl.c > --- bgpctl.c 18 May 2026 18:37:22 -0000 1.321 > +++ bgpctl.c 21 May 2026 13:12:58 -0000 > @@ -66,6 +66,7 @@ struct mrt_parser net_mrt = { network_mr > const struct output *output = &show_output; > int tableid; > int nodescr; > +int abs_time; > > __dead void > usage(void) > @@ -134,6 +135,7 @@ main(int argc, char *argv[]) > if (pledge("stdio", NULL) == -1) > err(1, "pledge"); > > + abs_time = 1; > memset(&ribreq, 0, sizeof(ribreq)); > if (res->as.type != AS_UNDEF) > ribreq.as = res->as; > @@ -588,14 +590,10 @@ show(struct imsg *imsg, struct parse_res > } > > time_t > -get_rel_monotime(monotime_t t) > +get_rel_monotime(monotime_t mt) > { > - monotime_t now; > - > - if (!monotime_valid(t)) > - return 0; > - now = getmonotime(); > - return monotime_to_sec(monotime_sub(now, t)); > + mt = monotime_sub(getmonotime(), mt); > + return monotime_to_sec(mt); > } > > char * > @@ -644,7 +642,7 @@ fmt_auth_method(enum auth_method method) > } > } > > -#define TF_LEN 16 > +#define TF_LEN 64 > > static const char * > fmt_timeframe(time_t t) > @@ -670,7 +668,7 @@ fmt_timeframe(time_t t) > week /= 7; > > if (week >= 1000) > - snprintf(buf, sizeof(buf), "%s%02lluw", due, week); > + snprintf(buf, sizeof(buf), "%s%lluw", due, week); > else if (week > 0) > snprintf(buf, sizeof(buf), "%s%02lluw%01ud%02uh", > due, week, day, hrs); > @@ -688,12 +686,23 @@ const char * > fmt_monotime(monotime_t mt) > { > time_t t; > + monotime_t z = monotime_clear(); > > - if (!monotime_valid(mt)) > - return ("Never"); > - > - t = get_rel_monotime(mt); > - return (fmt_timeframe(t)); > + if (abs_time) { > + struct tm *tm; > + static char buf[TF_LEN]; > + > + t = monotime_to_time(mt); > + if ((tm = gmtime(&t)) == NULL) > + return "invalid"; > + strftime(buf, sizeof(buf), "%FT%TZ", tm); > + return (buf); > + } else { > + if (monotime_cmp(mt, z) == 0) > + return ("Never"); > + t = get_rel_monotime(mt); > + return (fmt_timeframe(t)); > + } > } > > const char * > Index: output.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v > diff -u -p -r1.76 output.c > --- output.c 18 May 2026 09:22:09 -0000 1.76 > +++ output.c 21 May 2026 12:49:51 -0000 > @@ -1045,7 +1045,7 @@ show_rib_detail(struct ctl_show_rib *r, > printf("avs %s, %s", fmt_avs(r->aspa_validation_state, 0), > fmt_flags(r->flags, 0)); > > - printf("%c Last update: %s ago%c", EOL0(flag0), > + printf("%c Last update: %s%c", EOL0(flag0), > fmt_monotime(r->lastchange), EOL0(flag0)); > } > >