Re: bgpd and time stamps
On Tue, Dec 31, 2019 at 04:32:24PM +0100, Claudio Jeker wrote: > This changes bgpd to only use CLOCK_MONOTONIC via the getmonotime() > function. Additionally it changes the export of RIB entries to report the > last modified time relative to now. Other places also needed some fixup, > like the mrt dump code since the Originated Time field in those messages > is epoch based. > > It would be nice to also send the last_read, last_write, and last_updown in > a relative form to bgpctl but that is more complex. > > In bgpctl fmt_timeframe is now for relative timestamps and fmt_monotime > for those using CLOCK_MONOTONIC. The goal is to remove the latter once > last_read and friends got changed. > > OK? OK denis@ > -- > :wq Claudio > > Index: bgpctl/bgpctl.c > === > RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v > retrieving revision 1.255 > diff -u -p -r1.255 bgpctl.c > --- bgpctl/bgpctl.c 31 Dec 2019 14:09:27 - 1.255 > +++ bgpctl/bgpctl.c 31 Dec 2019 15:31:39 - > @@ -595,8 +595,8 @@ print_neighbor_msgstats(struct peer *p) > #define TF_BUFS 8 > #define TF_LEN 9 > > -static const char * > -fmt_timeframe_core(time_t t) > +const char * > +fmt_timeframe(time_t t) > { > char*buf; > static char tfbuf[TF_BUFS][TF_LEN];/* ring buffer */ > @@ -630,17 +630,18 @@ fmt_timeframe_core(time_t t) > } > > const char * > -fmt_timeframe(time_t t) > +fmt_monotime(time_t t) > { > - time_t now; > + struct timespec ts; > > if (t == 0) > return ("Never"); > > - now = time(NULL); > - if (t > now)/* time in the future is not possible */ > - t = now; > - return (fmt_timeframe_core(now - t)); > + if (clock_gettime(CLOCK_MONOTONIC, ) != 0) > + err(1, "clock_gettime"); > + if (t > ts.tv_sec) /* time in the future is not possible */ > + t = ts.tv_sec; > + return (fmt_timeframe(ts.tv_sec - t)); > } > > void > @@ -1414,17 +1415,20 @@ show_mrt_dump(struct mrt_rib *mr, struct > struct parse_result res; > struct ctl_show_rib_request *req = arg; > struct mrt_rib_entry*mre; > + time_t now; > u_int16_ti, j; > > memset(, 0, sizeof(res)); > res.flags = req->flags; > + now = time(NULL); > > for (i = 0; i < mr->nentries; i++) { > mre = >entries[i]; > bzero(, sizeof(ctl)); > ctl.prefix = mr->prefix; > ctl.prefixlen = mr->prefixlen; > - ctl.lastchange = mre->originated; > + if (mre->originated <= now) > + ctl.age = now - mre->originated; > ctl.true_nexthop = mre->nexthop; > ctl.exit_nexthop = mre->nexthop; > ctl.origin = mre->origin; > @@ -1490,14 +1494,17 @@ network_mrt_dump(struct mrt_rib *mr, str > struct ctl_show_rib_request *req = arg; > struct mrt_rib_entry*mre; > struct ibuf *msg; > + time_t now; > u_int16_ti, j; > > + now = time(NULL); > for (i = 0; i < mr->nentries; i++) { > mre = >entries[i]; > bzero(, sizeof(ctl)); > ctl.prefix = mr->prefix; > ctl.prefixlen = mr->prefixlen; > - ctl.lastchange = mre->originated; > + if (mre->originated <= now) > + ctl.age = now - mre->originated; > ctl.true_nexthop = mre->nexthop; > ctl.exit_nexthop = mre->nexthop; > ctl.origin = mre->origin; > Index: bgpctl/bgpctl.h > === > RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.h,v > retrieving revision 1.2 > diff -u -p -r1.2 bgpctl.h > --- bgpctl/bgpctl.h 31 Dec 2019 14:09:27 - 1.2 > +++ bgpctl/bgpctl.h 31 Dec 2019 15:31:39 - > @@ -44,6 +44,7 @@ const char *print_auth_method(enum auth_ > const char *fmt_mem(long long); > > const char *fmt_timeframe(time_t); > +const char *fmt_monotime(time_t); > char *fmt_peer(const char *, const struct bgpd_addr *, int); > const char *get_errstr(u_int8_t, u_int8_t); > > Index: bgpctl/output.c > === > RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v > retrieving revision 1.2 > diff -u -p -r1.2 output.c > --- bgpctl/output.c 31 Dec 2019 14:09:27 - 1.2 > +++ bgpctl/output.c 31 Dec 2019 15:31:39 - > @@ -111,7 +111,7 @@ show_summary(struct peer *p) > p->stats.msg_sent_update + p->stats.msg_sent_keepalive + > p->stats.msg_sent_rrefresh, > p->wbuf.queued, > - fmt_timeframe(p->stats.last_updown)); > + fmt_monotime(p->stats.last_updown)); >
bgpd and time stamps
This changes bgpd to only use CLOCK_MONOTONIC via the getmonotime() function. Additionally it changes the export of RIB entries to report the last modified time relative to now. Other places also needed some fixup, like the mrt dump code since the Originated Time field in those messages is epoch based. It would be nice to also send the last_read, last_write, and last_updown in a relative form to bgpctl but that is more complex. In bgpctl fmt_timeframe is now for relative timestamps and fmt_monotime for those using CLOCK_MONOTONIC. The goal is to remove the latter once last_read and friends got changed. OK? -- :wq Claudio Index: bgpctl/bgpctl.c === RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v retrieving revision 1.255 diff -u -p -r1.255 bgpctl.c --- bgpctl/bgpctl.c 31 Dec 2019 14:09:27 - 1.255 +++ bgpctl/bgpctl.c 31 Dec 2019 15:31:39 - @@ -595,8 +595,8 @@ print_neighbor_msgstats(struct peer *p) #define TF_BUFS8 #define TF_LEN 9 -static const char * -fmt_timeframe_core(time_t t) +const char * +fmt_timeframe(time_t t) { char*buf; static char tfbuf[TF_BUFS][TF_LEN];/* ring buffer */ @@ -630,17 +630,18 @@ fmt_timeframe_core(time_t t) } const char * -fmt_timeframe(time_t t) +fmt_monotime(time_t t) { - time_t now; + struct timespec ts; if (t == 0) return ("Never"); - now = time(NULL); - if (t > now)/* time in the future is not possible */ - t = now; - return (fmt_timeframe_core(now - t)); + if (clock_gettime(CLOCK_MONOTONIC, ) != 0) + err(1, "clock_gettime"); + if (t > ts.tv_sec) /* time in the future is not possible */ + t = ts.tv_sec; + return (fmt_timeframe(ts.tv_sec - t)); } void @@ -1414,17 +1415,20 @@ show_mrt_dump(struct mrt_rib *mr, struct struct parse_result res; struct ctl_show_rib_request *req = arg; struct mrt_rib_entry*mre; + time_t now; u_int16_ti, j; memset(, 0, sizeof(res)); res.flags = req->flags; + now = time(NULL); for (i = 0; i < mr->nentries; i++) { mre = >entries[i]; bzero(, sizeof(ctl)); ctl.prefix = mr->prefix; ctl.prefixlen = mr->prefixlen; - ctl.lastchange = mre->originated; + if (mre->originated <= now) + ctl.age = now - mre->originated; ctl.true_nexthop = mre->nexthop; ctl.exit_nexthop = mre->nexthop; ctl.origin = mre->origin; @@ -1490,14 +1494,17 @@ network_mrt_dump(struct mrt_rib *mr, str struct ctl_show_rib_request *req = arg; struct mrt_rib_entry*mre; struct ibuf *msg; + time_t now; u_int16_ti, j; + now = time(NULL); for (i = 0; i < mr->nentries; i++) { mre = >entries[i]; bzero(, sizeof(ctl)); ctl.prefix = mr->prefix; ctl.prefixlen = mr->prefixlen; - ctl.lastchange = mre->originated; + if (mre->originated <= now) + ctl.age = now - mre->originated; ctl.true_nexthop = mre->nexthop; ctl.exit_nexthop = mre->nexthop; ctl.origin = mre->origin; Index: bgpctl/bgpctl.h === RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.h,v retrieving revision 1.2 diff -u -p -r1.2 bgpctl.h --- bgpctl/bgpctl.h 31 Dec 2019 14:09:27 - 1.2 +++ bgpctl/bgpctl.h 31 Dec 2019 15:31:39 - @@ -44,6 +44,7 @@ const char*print_auth_method(enum auth_ const char *fmt_mem(long long); const char *fmt_timeframe(time_t); +const char *fmt_monotime(time_t); char *fmt_peer(const char *, const struct bgpd_addr *, int); const char *get_errstr(u_int8_t, u_int8_t); Index: bgpctl/output.c === RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v retrieving revision 1.2 diff -u -p -r1.2 output.c --- bgpctl/output.c 31 Dec 2019 14:09:27 - 1.2 +++ bgpctl/output.c 31 Dec 2019 15:31:39 - @@ -111,7 +111,7 @@ show_summary(struct peer *p) p->stats.msg_sent_update + p->stats.msg_sent_keepalive + p->stats.msg_sent_rrefresh, p->wbuf.queued, - fmt_timeframe(p->stats.last_updown)); + fmt_monotime(p->stats.last_updown)); if (p->state == STATE_ESTABLISHED) { printf("%6u", p->stats.prefix_cnt); if (p->conf.max_prefix != 0) @@ -182,11 +182,12 @@ show_neighbor_full(struct peer *p, struc