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 -0000      1.255
> +++ bgpctl/bgpctl.c   31 Dec 2019 15:31:39 -0000
> @@ -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, &ts) != 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_t                        i, j;
>  
>       memset(&res, 0, sizeof(res));
>       res.flags = req->flags;
> +     now = time(NULL);
>  
>       for (i = 0; i < mr->nentries; i++) {
>               mre = &mr->entries[i];
>               bzero(&ctl, 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_t                        i, j;
>  
> +     now = time(NULL);
>       for (i = 0; i < mr->nentries; i++) {
>               mre = &mr->entries[i];
>               bzero(&ctl, 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 -0000      1.2
> +++ bgpctl/bgpctl.h   31 Dec 2019 15:31:39 -0000
> @@ -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 -0000      1.2
> +++ bgpctl/output.c   31 Dec 2019 15:31:39 -0000
> @@ -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
>       if (p->stats.last_updown != 0)
>               printf(", %s for %s",
>                   p->state == STATE_ESTABLISHED ? "up" : "down",
> -                 fmt_timeframe(p->stats.last_updown));
> +                 fmt_monotime(p->stats.last_updown));
>       printf("\n");
>       printf("  Last read %s, holdtime %us, keepalive interval %us\n",
> -         fmt_timeframe(p->stats.last_read),
> +         fmt_monotime(p->stats.last_read),
>           p->holdtime, p->holdtime/3);
> +     printf("  Last write %s\n", fmt_monotime(p->stats.last_write));
>       for (i = 0; i < AID_MAX; i++)
>               if (p->capa.peer.mp[i])
>                       hascapamp = 1;
> @@ -288,7 +289,7 @@ show_timer(struct ctl_timer *t)
>       if (t->val <= 0)
>               printf("%-20s\n", "due");
>       else
> -             printf("due in %-13s\n", fmt_timeframe(time(NULL) - t->val));
> +             printf("due in %-13s\n", fmt_timeframe(t->val));
>  }
>  
>  void
> @@ -432,7 +433,7 @@ show_rib_detail(struct ctl_show_rib *r, 
>       print_flags(r->flags, 0);
>  
>       printf("%c    Last update: %s ago%c", EOL0(flag0),
> -         fmt_timeframe(r->lastchange), EOL0(flag0));
> +         fmt_timeframe(r->age), EOL0(flag0));
>  }
>  
>  void
> Index: bgpd/bgpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.395
> diff -u -p -r1.395 bgpd.h
> --- bgpd/bgpd.h       27 Nov 2019 01:21:54 -0000      1.395
> +++ bgpd/bgpd.h       31 Dec 2019 15:31:40 -0000
> @@ -711,7 +711,7 @@ struct ctl_show_rib {
>       struct bgpd_addr        prefix;
>       struct bgpd_addr        remote_addr;
>       char                    descr[PEER_DESCR_LEN];
> -     time_t                  lastchange;
> +     time_t                  age;
>       u_int32_t               remote_id;
>       u_int32_t               local_pref;
>       u_int32_t               med;
> @@ -1290,6 +1290,9 @@ int     trie_roa_check(struct trie_head *, s
>           u_int32_t);
>  void trie_dump(struct trie_head *);
>  int  trie_equal(struct trie_head *, struct trie_head *);
> +
> +/* timer.c */
> +time_t                        getmonotime(void);
>  
>  /* util.c */
>  const char   *log_addr(const struct bgpd_addr *);
> Index: bgpd/mrt.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/mrt.c,v
> retrieving revision 1.101
> diff -u -p -r1.101 mrt.c
> --- bgpd/mrt.c        31 Dec 2019 12:02:47 -0000      1.101
> +++ bgpd/mrt.c        31 Dec 2019 15:31:40 -0000
> @@ -323,7 +323,8 @@ mrt_dump_entry_mp(struct mrt *mrt, struc
>  
>       DUMP_SHORT(h2buf, 0);           /* view */
>       DUMP_SHORT(h2buf, 1);           /* status */
> -     DUMP_LONG(h2buf, p->lastchange);        /* originated */
> +     /* originated timestamp */
> +     DUMP_LONG(h2buf, time(NULL) - (getmonotime() - p->lastchange));
>  
>       pt_getaddr(p->pt, &addr);
>  
> @@ -459,7 +460,8 @@ mrt_dump_entry(struct mrt *mrt, struct p
>       DUMP_BYTE(hbuf, p->pt->prefixlen);
>  
>       DUMP_BYTE(hbuf, 1);             /* state */
> -     DUMP_LONG(hbuf, p->lastchange); /* originated */
> +     /* originated timestamp */
> +     DUMP_LONG(hbuf, time(NULL) - (getmonotime() - p->lastchange));
>       switch (p->pt->aid) {
>       case AID_INET:
>               DUMP_NLONG(hbuf, peer->remote_addr.v4.s_addr);
> @@ -547,7 +549,8 @@ mrt_dump_entry_v2(struct mrt *mrt, struc
>                       nh = &nexthop->exit_nexthop;
>  
>               DUMP_SHORT(buf, prefix_peer(p)->mrt_idx);
> -             DUMP_LONG(buf, p->lastchange); /* originated */
> +             /* originated timestamp */
> +             DUMP_LONG(buf, time(NULL) - (getmonotime() - p->lastchange));
>  
>               if ((tbuf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) {
>                       log_warn("%s: ibuf_dynamic", __func__);
> Index: bgpd/rde.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.494
> diff -u -p -r1.494 rde.c
> --- bgpd/rde.c        31 Dec 2019 11:53:46 -0000      1.494
> +++ bgpd/rde.c        31 Dec 2019 15:31:41 -0000
> @@ -2222,7 +2222,7 @@ rde_dump_rib_as(struct prefix *p, struct
>  
>       nexthop = prefix_nexthop(p);
>       bzero(&rib, sizeof(rib));
> -     rib.lastchange = p->lastchange;
> +     rib.age = getmonotime() - p->lastchange;
>       rib.local_pref = asp->lpref;
>       rib.med = asp->med;
>       rib.weight = asp->weight;
> @@ -3875,7 +3875,7 @@ peer_stale(struct rde_peer *peer, u_int8
>       if (peer->staletime[aid])
>               peer_flush(peer, aid, peer->staletime[aid]);
>  
> -     peer->staletime[aid] = now = time(NULL);
> +     peer->staletime[aid] = now = getmonotime();
>       peer->state = PEER_DOWN;
>  
>       /* mark Adj-RIB-Out stale for this peer */
> @@ -3884,7 +3884,7 @@ peer_stale(struct rde_peer *peer, u_int8
>               fatal("%s: prefix_dump_new", __func__);
>  
>       /* make sure new prefixes start on a higher timestamp */
> -     while (now >= time(NULL))
> +     while (now >= getmonotime())
>               sleep(1);
>  }
>  
> Index: bgpd/rde_rib.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
> retrieving revision 1.210
> diff -u -p -r1.210 rde_rib.c
> --- bgpd/rde_rib.c    30 Oct 2019 05:27:50 -0000      1.210
> +++ bgpd/rde_rib.c    31 Dec 2019 15:31:41 -0000
> @@ -983,7 +983,7 @@ prefix_update(struct rib *rib, struct rd
>                   communities_equal(ncomm, prefix_communities(p)) &&
>                   path_compare(nasp, prefix_aspath(p)) == 0) {
>                       /* no change, update last change */
> -                     p->lastchange = time(NULL);
> +                     p->lastchange = getmonotime();
>                       p->validation_state = vstate;
>                       return (0);
>               }
> @@ -1058,7 +1058,7 @@ prefix_move(struct prefix *p, struct rde
>       np->nhflags = nhflags;
>       np->nexthop = nexthop_ref(nexthop);
>       nexthop_link(np);
> -     np->lastchange = time(NULL);
> +     np->lastchange = getmonotime();
>  
>       /*
>        * no need to update the peer prefix count because we are only moving
> @@ -1168,7 +1168,7 @@ prefix_adjout_update(struct rde_peer *pe
>                           0) {
>                               /* nothing changed */
>                               p->validation_state = vstate;
> -                             p->lastchange = time(NULL);
> +                             p->lastchange = getmonotime();
>                               p->flags &= ~PREFIX_FLAG_STALE;
>                               return 0;
>                       }
> @@ -1217,7 +1217,7 @@ prefix_adjout_update(struct rde_peer *pe
>       p->nhflags = state->nhflags;
>  
>       p->validation_state = vstate;
> -     p->lastchange = time(NULL);
> +     p->lastchange = getmonotime();
>  
>       if (p->flags & PREFIX_FLAG_MASK)
>               fatalx("%s: bad flags %x", __func__, p->flags);
> @@ -1244,7 +1244,7 @@ prefix_adjout_withdraw(struct rde_peer *
>  
>       /* already a withdraw, shortcut */
>       if (p->flags & PREFIX_FLAG_WITHDRAW) {
> -             p->lastchange = time(NULL);
> +             p->lastchange = getmonotime();
>               p->flags &= ~PREFIX_FLAG_STALE;
>               return (0);
>       }
> @@ -1271,7 +1271,7 @@ prefix_adjout_withdraw(struct rde_peer *
>       p->aspath = NULL;
>       /* re already NULL */
>  
> -     p->lastchange = time(NULL);
> +     p->lastchange = getmonotime();
>  
>       p->flags |= PREFIX_FLAG_WITHDRAW;
>       if (RB_INSERT(prefix_tree, &peer->withdraws[prefix->aid], p) != NULL)
> @@ -1599,7 +1599,7 @@ prefix_link(struct prefix *p, struct rib
>       p->nhflags = nhflags;
>       p->nexthop = nexthop_ref(nexthop);
>       nexthop_link(p);
> -     p->lastchange = time(NULL);
> +     p->lastchange = getmonotime();
>  
>       /* make route decision */
>       prefix_evaluate(p, re);
> Index: bgpd/session.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
> retrieving revision 1.395
> diff -u -p -r1.395 session.c
> --- bgpd/session.c    2 Oct 2019 08:57:00 -0000       1.395
> +++ bgpd/session.c    31 Dec 2019 15:31:42 -0000
> @@ -252,7 +252,7 @@ session_main(int debug, int verbose)
>                               /* cloned peer that idled out? */
>                               if (p->template && (p->state == STATE_IDLE ||
>                                   p->state == STATE_ACTIVE) &&
> -                                 time(NULL) - p->stats.last_updown >=
> +                                 getmonotime() - p->stats.last_updown >=
>                                   INTERVAL_HOLD_CLONED)
>                                       p->reconf_action = RECONF_DELETE;
>  
> @@ -1701,6 +1701,7 @@ session_dispatch_msg(struct pollfd *pfd,
>                       bgp_fsm(p, EVNT_CON_FATAL);
>                       return (1);
>               }
> +             p->stats.last_write = getmonotime();
>               if (p->throttled && p->wbuf.queued < SESS_MSG_LOW_MARK) {
>                       if (imsg_rde(IMSG_XON, p->conf.id, NULL, 0) == -1)
>                               log_peer_warn(&p->conf, "imsg_compose XON");
> @@ -1726,7 +1727,7 @@ session_dispatch_msg(struct pollfd *pfd,
>               }
>  
>               p->rbuf->wpos += n;
> -             p->stats.last_read = time(NULL);
> +             p->stats.last_read = getmonotime();
>               return (1);
>       }
>       return (0);
> @@ -3048,7 +3049,7 @@ void
>  session_down(struct peer *peer)
>  {
>       bzero(&peer->capa.neg, sizeof(peer->capa.neg));
> -     peer->stats.last_updown = time(NULL);
> +     peer->stats.last_updown = getmonotime();
>       /*
>        * session_down is called in the exit code path so check
>        * if the RDE is still around, if not there is no need to
> @@ -3075,7 +3076,7 @@ session_up(struct peer *p)
>       sup.remote_bgpid = p->remote_bgpid;
>       sup.short_as = p->short_as;
>       memcpy(&sup.capa, &p->capa.neg, sizeof(sup.capa));
> -     p->stats.last_updown = time(NULL);
> +     p->stats.last_updown = getmonotime();
>       if (imsg_rde(IMSG_SESSION_UP, p->conf.id, &sup, sizeof(sup)) == -1)
>               fatalx("imsg_compose error");
>  }
> Index: bgpd/session.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
> retrieving revision 1.141
> diff -u -p -r1.141 session.h
> --- bgpd/session.h    1 Oct 2019 11:05:30 -0000       1.141
> +++ bgpd/session.h    31 Dec 2019 15:31:42 -0000
> @@ -167,6 +167,7 @@ struct peer_stats {
>       unsigned long long       prefix_sent_eor;
>       time_t                   last_updown;
>       time_t                   last_read;
> +     time_t                   last_write;
>       u_int32_t                prefix_cnt;
>       u_int8_t                 last_sent_errcode;
>       u_int8_t                 last_sent_suberr;
> @@ -310,7 +311,6 @@ int                imsg_ctl_rde(int, pid_t, void *, u
>  void          session_stop(struct peer *, u_int8_t);
>  
>  /* timer.c */
> -time_t                        getmonotime(void);
>  struct peer_timer    *timer_get(struct peer *, enum Timer);
>  struct peer_timer    *timer_nextisdue(struct peer *, time_t);
>  time_t                        timer_nextduein(struct peer *, time_t);
> 

Reply via email to