Download raw body.
bgpd: better monotime handling
I wanted to increase the resolution of getmonotime to milliseconds as a
quick way to get a but higher resolution. tb@ convinced me to make this
better so that times are not easily confused.
So here is that diff. monotime_t is now a new type (wrapped into a struct
to prevent integer promotion). The resolution is now actually microseconds
which should be good enough.
This adds enough helper functions to work with monotime_t which was
inspired by things like timeradd(3).
Regress still passes and also my limited testing showed no issues.
--
:wq Claudio
Index: bgpctl/Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/Makefile,v
diff -u -p -r1.19 Makefile
--- bgpctl/Makefile 20 Apr 2023 14:01:50 -0000 1.19
+++ bgpctl/Makefile 13 Feb 2025 15:29:22 -0000
@@ -5,7 +5,7 @@
PROG= bgpctl
SRCS= bgpctl.c output.c output_json.c output_ometric.c parser.c \
mrtparser.c json.c ometric.c
-SRCS+= util.c flowspec.c
+SRCS+= util.c flowspec.c monotime.c
CFLAGS+= -Wall
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+= -Wmissing-declarations
Index: bgpctl/bgpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
diff -u -p -r1.315 bgpctl.c
--- bgpctl/bgpctl.c 31 Jan 2025 20:07:53 -0000 1.315
+++ bgpctl/bgpctl.c 17 Feb 2025 13:56:15 -0000
@@ -588,17 +588,14 @@ show(struct imsg *imsg, struct parse_res
}
time_t
-get_monotime(time_t t)
+get_rel_monotime(monotime_t t)
{
- struct timespec ts;
+ monotime_t now;
- if (t == 0)
- return -1;
- 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 (ts.tv_sec - t);
+ if (!monotime_valid(t))
+ return 0;
+ now = getmonotime();
+ return monotime_to_sec(monotime_sub(now, t));
}
char *
@@ -649,15 +646,18 @@ fmt_auth_method(enum auth_method method)
#define TF_LEN 16
-const char *
+static const char *
fmt_timeframe(time_t t)
{
- static char buf[TF_LEN];
- unsigned int sec, min, hrs, day;
- unsigned long long week;
-
- if (t < 0)
- t = 0;
+ static char buf[TF_LEN];
+ unsigned long long week;
+ unsigned int sec, min, hrs, day;
+ const char *due = "";
+
+ if (t < 0) {
+ due = "due in ";
+ t = -t;
+ }
week = t;
sec = week % 60;
@@ -670,25 +670,29 @@ fmt_timeframe(time_t t)
week /= 7;
if (week >= 1000)
- snprintf(buf, TF_LEN, "%02lluw", week);
+ snprintf(buf, sizeof(buf), "%s%02lluw", due, week);
else if (week > 0)
- snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs);
+ snprintf(buf, sizeof(buf), "%s%02lluw%01ud%02uh",
+ due, week, day, hrs);
else if (day > 0)
- snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
+ snprintf(buf, sizeof(buf), "%s%01ud%02uh%02um",
+ due, day, hrs, min);
else
- snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
+ snprintf(buf, sizeof(buf), "%s%02u:%02u:%02u",
+ due, hrs, min, sec);
return (buf);
}
const char *
-fmt_monotime(time_t t)
+fmt_monotime(monotime_t mt)
{
- t = get_monotime(t);
+ time_t t;
- if (t == -1)
+ if (!monotime_valid(mt))
return ("Never");
+ t = get_rel_monotime(mt);
return (fmt_timeframe(t));
}
@@ -1229,20 +1233,17 @@ show_mrt_dump(struct mrt_rib *mr, struct
struct ctl_show_rib_request *req = arg;
struct mrt_rib_entry *mre;
struct ibuf ibuf;
- time_t now;
uint16_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];
memset(&ctl, 0, sizeof(ctl));
ctl.prefix = mr->prefix;
ctl.prefixlen = mr->prefixlen;
- if (mre->originated <= now)
- ctl.age = now - mre->originated;
+ ctl.lastchange = time_to_monotime(mre->originated);
ctl.true_nexthop = mre->nexthop;
ctl.exit_nexthop = mre->nexthop;
ctl.origin = mre->origin;
@@ -1314,21 +1315,18 @@ 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;
uint16_t i, j;
/* can't announce more than one path so ignore add-path */
if (mr->add_path)
return;
- now = time(NULL);
for (i = 0; i < mr->nentries; i++) {
mre = &mr->entries[i];
memset(&ctl, 0, sizeof(ctl));
ctl.prefix = mr->prefix;
ctl.prefixlen = mr->prefixlen;
- if (mre->originated <= now)
- ctl.age = now - mre->originated;
+ ctl.lastchange = time_to_monotime(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
diff -u -p -r1.24 bgpctl.h
--- bgpctl/bgpctl.h 31 Jan 2024 11:23:20 -0000 1.24
+++ bgpctl/bgpctl.h 13 Feb 2025 15:30:17 -0000
@@ -42,10 +42,9 @@ extern const struct output show_output,
#define EOL0(flag) ((flag & F_CTL_SSV) ? ';' : '\n')
-time_t get_monotime(time_t);
+time_t get_rel_monotime(monotime_t);
char *fmt_peer(const char *, const struct bgpd_addr *, int);
-const char *fmt_timeframe(time_t);
-const char *fmt_monotime(time_t);
+const char *fmt_monotime(monotime_t);
const char *fmt_fib_flags(uint16_t);
const char *fmt_origin(uint8_t, int);
const char *fmt_flags(uint32_t, int);
Index: bgpctl/output.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v
diff -u -p -r1.59 output.c
--- bgpctl/output.c 29 Jan 2025 13:14:41 -0000 1.59
+++ bgpctl/output.c 13 Feb 2025 16:20:20 -0000
@@ -314,7 +314,7 @@ show_neighbor_full(struct peer *p, struc
printf(" with shutdown reason \"%s\"",
log_reason(p->conf.reason));
}
- if (p->stats.last_updown != 0)
+ if (monotime_valid(p->stats.last_updown))
printf(", %s for %s",
p->state == STATE_ESTABLISHED ? "up" : "down",
fmt_monotime(p->stats.last_updown));
@@ -467,10 +467,10 @@ show_timer(struct ctl_timer *t)
{
printf(" %-20s ", timernames[t->type]);
- if (t->val <= 0)
- printf("%-20s\n", "due");
+ if (get_rel_monotime(t->val) >= 0)
+ printf("%s\n", "due");
else
- printf("due in %-13s\n", fmt_timeframe(t->val));
+ printf("%s\n", fmt_monotime(t->val));
}
static void
@@ -1033,7 +1033,7 @@ show_rib_detail(struct ctl_show_rib *r,
fmt_flags(r->flags, 0));
printf("%c Last update: %s ago%c", EOL0(flag0),
- fmt_timeframe(r->age), EOL0(flag0));
+ fmt_monotime(r->lastchange), EOL0(flag0));
}
static void
@@ -1113,7 +1113,7 @@ show_rib_set(struct ctl_show_set *set)
snprintf(buf, sizeof(buf), "%7zu %7zu %6s",
set->v4_cnt, set->v6_cnt, "-");
- printf("%-6s %-34s %s %11s\n", fmt_set_type(set), set->name,
+ printf("%-6s %-34s %s %12s\n", fmt_set_type(set), set->name,
buf, fmt_monotime(set->lastchange));
}
Index: bgpctl/output_json.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/output_json.c,v
diff -u -p -r1.50 output_json.c
--- bgpctl/output_json.c 13 Dec 2024 19:22:01 -0000 1.50
+++ bgpctl/output_json.c 13 Feb 2025 16:06:03 -0000
@@ -140,9 +140,9 @@ json_neighbor_stats(struct peer *p)
{
json_do_object("stats", 0);
json_do_string("last_read", fmt_monotime(p->stats.last_read));
- json_do_int("last_read_sec", get_monotime(p->stats.last_read));
+ json_do_int("last_read_sec", get_rel_monotime(p->stats.last_read));
json_do_string("last_write", fmt_monotime(p->stats.last_write));
- json_do_int("last_write_sec", get_monotime(p->stats.last_write));
+ json_do_int("last_write_sec", get_rel_monotime(p->stats.last_write));
json_do_object("prefixes", 1);
json_do_uint("sent", p->stats.prefix_out_cnt);
@@ -332,7 +332,7 @@ json_neighbor(struct peer *p, struct par
}
json_do_string("state", statenames[p->state]);
json_do_string("last_updown", fmt_monotime(p->stats.last_updown));
- json_do_int("last_updown_sec", get_monotime(p->stats.last_updown));
+ json_do_int("last_updown_sec", get_rel_monotime(p->stats.last_updown));
switch (res->action) {
case SHOW:
@@ -359,7 +359,7 @@ json_timer(struct ctl_timer *t)
json_do_object("timer", 1);
json_do_string("name", timernames[t->type]);
- json_do_int("due", t->val);
+ json_do_int("due", -get_rel_monotime(t->val));
json_do_end();
}
@@ -862,8 +862,8 @@ json_rib(struct ctl_show_rib *r, struct
json_do_uint("localpref", r->local_pref);
json_do_uint("weight", r->weight);
json_do_int("dmetric", r->dmetric);
- json_do_string("last_update", fmt_timeframe(r->age));
- json_do_int("last_update_sec", r->age);
+ json_do_string("last_update", fmt_monotime(r->lastchange));
+ json_do_int("last_update_sec", get_rel_monotime(r->lastchange));
/* keep the object open for communities and attributes */
}
@@ -942,7 +942,7 @@ json_rib_set(struct ctl_show_set *set)
json_do_string("name", set->name);
json_do_string("type", fmt_set_type(set));
json_do_string("last_change", fmt_monotime(set->lastchange));
- json_do_int("last_change_sec", get_monotime(set->lastchange));
+ json_do_int("last_change_sec", get_rel_monotime(set->lastchange));
if (set->type == ASNUM_SET || set->type == ASPA_SET) {
json_do_uint("num_ASnum", set->as_cnt);
} else {
Index: bgpctl/output_ometric.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/output_ometric.c,v
diff -u -p -r1.13 output_ometric.c
--- bgpctl/output_ometric.c 23 Jan 2024 15:55:20 -0000 1.13
+++ bgpctl/output_ometric.c 13 Feb 2025 15:41:17 -0000
@@ -193,14 +193,14 @@ ometric_neighbor_stats(struct peer *p, s
ometric_set_state(peer_state, statenames[p->state], ol);
ometric_set_int(peer_state_raw, p->state, ol);
- ometric_set_int(peer_last_change, get_monotime(p->stats.last_updown),
- ol);
+ ometric_set_int(peer_last_change,
+ get_rel_monotime(p->stats.last_updown), ol);
if (p->state == STATE_ESTABLISHED) {
ometric_set_int(peer_last_read,
- get_monotime(p->stats.last_read), ol);
+ get_rel_monotime(p->stats.last_read), ol);
ometric_set_int(peer_last_write,
- get_monotime(p->stats.last_write), ol);
+ get_rel_monotime(p->stats.last_write), ol);
}
ometric_set_int(peer_prefixes_transmit, p->stats.prefix_out_cnt, ol);
Index: bgpd/Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/Makefile,v
diff -u -p -r1.39 Makefile
--- bgpd/Makefile 17 Apr 2023 08:02:21 -0000 1.39
+++ bgpd/Makefile 13 Feb 2025 15:25:00 -0000
@@ -1,7 +1,7 @@
# $OpenBSD: Makefile,v 1.39 2023/04/17 08:02:21 claudio Exp $
PROG= bgpd
-SRCS= bgpd.c session.c log.c logmsg.c parse.y config.c \
+SRCS= bgpd.c session.c log.c logmsg.c parse.y config.c monotime.c \
rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c control.c \
pfkey.c rde_update.c rde_attr.c rde_community.c printconf.c \
rde_filter.c rde_sets.c rde_aspa.c rde_trie.c pftable.c name2id.c \
Index: bgpd/bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
diff -u -p -r1.281 bgpd.c
--- bgpd/bgpd.c 12 Feb 2025 19:33:20 -0000 1.281
+++ bgpd/bgpd.c 13 Feb 2025 16:35:07 -0000
@@ -118,7 +118,7 @@ usage(void)
#define PFD_SOCK_ROUTE 3
#define PFD_SOCK_PFKEY 4
#define PFD_CONNECT_START 5
-#define MAX_TIMEOUT 3600
+#define MAX_TIMEOUT (3600 * 1000)
int cmd_opts;
@@ -359,7 +359,7 @@ BROKEN if (pledge("stdio rpath wpath cpa
if (timeout < 0 || timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT;
- if (poll(pfd, npfd, timeout * 1000) == -1) {
+ if (poll(pfd, npfd, timeout) == -1) {
if (errno != EINTR) {
log_warn("poll error");
quit = 1;
Index: bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
diff -u -p -r1.514 bgpd.h
--- bgpd/bgpd.h 12 Feb 2025 19:33:20 -0000 1.514
+++ bgpd/bgpd.h 17 Feb 2025 13:57:18 -0000
@@ -30,9 +30,10 @@
#include <poll.h>
#include <stdarg.h>
#include <stdint.h>
-
#include <imsg.h>
+#include "monotime.h"
+
#define BGP_VERSION 4
#define RTR_MAX_VERSION 2
#define RTR_DEFAULT_VERSION 1
@@ -281,7 +282,7 @@ struct rde_prefixset {
char name[SET_NAME_LEN];
struct trie_head th;
SIMPLEQ_ENTRY(rde_prefixset) entry;
- time_t lastchange;
+ monotime_t lastchange;
int dirty;
};
SIMPLEQ_HEAD(rde_prefixset_head, rde_prefixset);
@@ -896,7 +897,7 @@ struct ctl_show_nexthop {
struct ctl_show_set {
char name[SET_NAME_LEN];
- time_t lastchange;
+ monotime_t lastchange;
size_t v4_cnt;
size_t v6_cnt;
size_t as_cnt;
@@ -935,7 +936,7 @@ struct ctl_show_rib {
struct bgpd_addr prefix;
struct bgpd_addr remote_addr;
char descr[PEER_DESCR_LEN];
- time_t age;
+ monotime_t lastchange;
uint32_t remote_id;
uint32_t path_id;
uint32_t local_pref;
@@ -1331,7 +1332,7 @@ struct as_set {
char name[SET_NAME_LEN];
SIMPLEQ_ENTRY(as_set) entry;
struct set_table *set;
- time_t lastchange;
+ monotime_t lastchange;
int dirty;
};
@@ -1590,9 +1591,6 @@ int trie_roa_check(struct trie_head *, s
uint32_t);
void trie_dump(struct trie_head *);
int trie_equal(struct trie_head *, struct trie_head *);
-
-/* timer.c */
-time_t getmonotime(void);
/* util.c */
char *ibuf_get_string(struct ibuf *, size_t);
Index: bgpd/control.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/control.c,v
diff -u -p -r1.133 control.c
--- bgpd/control.c 12 Feb 2025 13:10:13 -0000 1.133
+++ bgpd/control.c 13 Feb 2025 12:28:46 -0000
@@ -232,7 +232,7 @@ control_close(struct ctl_conn *c)
close(c->imsgbuf.fd);
free(c);
- pauseaccept = 0;
+ pauseaccept = monotime_clear();
return (1);
}
@@ -340,7 +340,7 @@ control_dispatch_msg(struct pollfd *pfd,
p->conf.id, pid);
} else {
u_int i;
- time_t d;
+ monotime_t d;
struct ctl_timer ct;
imsg_compose(&c->imsgbuf,
Index: bgpd/monotime.c
===================================================================
RCS file: bgpd/monotime.c
diff -N bgpd/monotime.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ bgpd/monotime.c 19 Feb 2025 16:13:01 -0000
@@ -0,0 +1,58 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2025 Claudio Jeker <claudio@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <time.h>
+
+#include "monotime.h"
+
+static inline monotime_t
+monotime_from_ts(struct timespec *ts)
+{
+ monotime_t mt;
+
+ mt = monotime_from_sec(ts->tv_sec);
+ mt.monotime += ts->tv_nsec / (1000 * 1000 * 1000LL / MONOTIME_RES);
+ return mt;
+}
+
+monotime_t
+getmonotime(void)
+{
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+ return monotime_clear();
+ return monotime_from_ts(&ts);
+}
+
+time_t
+monotime_to_time(monotime_t mt)
+{
+ mt = monotime_sub(getmonotime(), mt);
+ return time(NULL) - monotime_to_sec(mt);
+}
+
+monotime_t
+time_to_monotime(time_t t)
+{
+ time_t now = time(NULL);
+
+ if (now < t)
+ return monotime_clear();
+ t = now - t;
+ return monotime_sub(getmonotime(), monotime_from_sec(t));
+}
Index: bgpd/monotime.h
===================================================================
RCS file: bgpd/monotime.h
diff -N bgpd/monotime.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ bgpd/monotime.h 20 Feb 2025 12:12:28 -0000
@@ -0,0 +1,93 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2025 Claudio Jeker <claudio@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <time.h>
+
+/*
+ * bgpd uses an internal microsecond time format.
+ * To reduce errors this is wrapped into a struct and comes
+ * with a bunch of helper functions.
+ */
+#define MONOTIME_RES (1000 * 1000LL)
+
+typedef struct monotime {
+ long long monotime;
+} monotime_t;
+
+monotime_t getmonotime(void);
+time_t monotime_to_time(monotime_t);
+monotime_t time_to_monotime(time_t);
+
+static inline monotime_t
+monotime_clear(void)
+{
+ monotime_t mt = { 0 };
+ return mt;
+}
+
+static inline int
+monotime_valid(monotime_t mt)
+{
+ return mt.monotime > 0;
+}
+
+static inline int
+monotime_cmp(monotime_t a, monotime_t b)
+{
+ if (a.monotime > b.monotime)
+ return 1;
+ if (a.monotime < b.monotime)
+ return -1;
+ return 0;
+}
+
+static inline monotime_t
+monotime_add(monotime_t add1, monotime_t add2)
+{
+ monotime_t sum;
+ sum.monotime = add1.monotime + add2.monotime;
+ return sum;
+}
+
+static inline monotime_t
+monotime_sub(monotime_t minu, monotime_t subt)
+{
+ monotime_t dif;
+ dif.monotime = minu.monotime - subt.monotime;
+ return dif;
+}
+
+static inline long long
+monotime_to_msec(monotime_t mt)
+{
+ return mt.monotime / (MONOTIME_RES / 1000);
+}
+
+static inline long long
+monotime_to_sec(monotime_t mt)
+{
+ return mt.monotime / MONOTIME_RES;
+}
+
+static inline monotime_t
+monotime_from_sec(time_t sec)
+{
+ monotime_t mt;
+ mt.monotime = sec;
+ mt.monotime *= MONOTIME_RES;
+ return mt;
+}
Index: bgpd/mrt.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/mrt.c,v
diff -u -p -r1.125 mrt.c
--- bgpd/mrt.c 12 Feb 2025 16:49:56 -0000 1.125
+++ bgpd/mrt.c 13 Feb 2025 12:24:45 -0000
@@ -415,8 +415,7 @@ mrt_dump_entry_mp(struct mrt *mrt, struc
if (ibuf_add_n16(h2buf, 1) == -1) /* status */
goto fail;
/* originated timestamp */
- if (ibuf_add_n32(h2buf, time(NULL) - (getmonotime() -
- p->lastchange)) == -1)
+ if (ibuf_add_n32(h2buf, monotime_to_time(p->lastchange)) == -1)
goto fail;
n = prefix_nexthop(p);
@@ -577,8 +576,7 @@ mrt_dump_entry(struct mrt *mrt, struct p
if (ibuf_add_n8(hbuf, 1) == -1) /* state */
goto fail;
/* originated timestamp */
- if (ibuf_add_n32(hbuf, time(NULL) - (getmonotime() -
- p->lastchange)) == -1)
+ if (ibuf_add_n32(hbuf, monotime_to_time(p->lastchange)) == -1)
goto fail;
switch (p->pt->aid) {
case AID_INET:
@@ -653,8 +651,7 @@ mrt_dump_entry_v2_rib(struct rib_entry *
if (ibuf_add_n16(buf, prefix_peer(p)->mrt_idx) == -1)
goto fail;
/* originated timestamp */
- if (ibuf_add_n32(buf, time(NULL) - (getmonotime() -
- p->lastchange)) == -1)
+ if (ibuf_add_n32(buf, monotime_to_time(p->lastchange)) == -1)
goto fail;
/* RFC8050: path-id if add-path is used */
@@ -976,7 +973,7 @@ mrt_dump_hdr_se(struct ibuf ** bp, struc
if (ibuf_add_n32(*bp, len) == -1)
goto fail;
- /* millisecond field use by the _ET format */
+ /* microsecond field use by the _ET format */
if (ibuf_add_n32(*bp, time.tv_nsec / 1000) == -1)
goto fail;
Index: bgpd/rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
diff -u -p -r1.652 rde.c
--- bgpd/rde.c 12 Feb 2025 16:49:56 -0000 1.652
+++ bgpd/rde.c 13 Feb 2025 14:28:12 -0000
@@ -467,7 +467,7 @@ rde_dispatch_imsg_session(struct imsgbuf
peer_flush(peer, aid, peer->staletime[aid]);
break;
case IMSG_SESSION_RESTARTED:
- if (peer->staletime[aid])
+ if (monotime_valid(peer->staletime[aid]))
peer_flush(peer, aid,
peer->staletime[aid]);
break;
@@ -1369,7 +1369,7 @@ rde_dispatch_imsg_peer(struct rde_peer *
break;
case ROUTE_REFRESH_END_RR:
if ((peer->recv_eor & (1 << rr.aid)) != 0 &&
- peer->staletime[rr.aid])
+ monotime_valid(peer->staletime[rr.aid]))
peer_flush(peer, rr.aid,
peer->staletime[rr.aid]);
else
@@ -2822,14 +2822,14 @@ rde_dump_rib_as(struct prefix *p, struct
struct rib_entry *re;
struct prefix *xp;
struct rde_peer *peer;
- time_t staletime;
+ monotime_t staletime;
size_t aslen;
uint8_t l;
nexthop = prefix_nexthop(p);
peer = prefix_peer(p);
memset(&rib, 0, sizeof(rib));
- rib.age = getmonotime() - p->lastchange;
+ rib.lastchange = p->lastchange;
rib.local_pref = asp->lpref;
rib.med = asp->med;
rib.weight = asp->weight;
@@ -2890,7 +2890,8 @@ rde_dump_rib_as(struct prefix *p, struct
else if (asp->flags & F_ATTR_PARSE_ERR)
rib.flags |= F_PREF_INVALID;
staletime = peer->staletime[p->pt->aid];
- if (staletime && p->lastchange <= staletime)
+ if (monotime_valid(staletime) &&
+ monotime_cmp(p->lastchange, staletime) <= 0)
rib.flags |= F_PREF_STALE;
if (!adjout) {
if (peer_has_add_path(peer, p->pt->aid, CAPA_AP_RECV)) {
Index: bgpd/rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
diff -u -p -r1.313 rde.h
--- bgpd/rde.h 27 Jan 2025 15:22:11 -0000 1.313
+++ bgpd/rde.h 13 Feb 2025 10:42:46 -0000
@@ -89,7 +89,7 @@ struct rde_peer {
struct prefix_tree updates[AID_MAX];
struct prefix_tree withdraws[AID_MAX];
struct filter_head *out_rules;
- time_t staletime[AID_MAX];
+ monotime_t staletime[AID_MAX];
uint32_t remote_bgpid;
uint32_t path_id_tx;
unsigned int local_if_scope;
@@ -279,7 +279,7 @@ struct prefix {
struct rde_community *communities;
struct rde_peer *peer;
struct nexthop *nexthop; /* may be NULL */
- time_t lastchange;
+ monotime_t lastchange;
uint32_t path_id;
uint32_t path_id_tx;
uint16_t flags;
@@ -373,7 +373,7 @@ void rde_generate_updates(struct rib_e
void peer_up(struct rde_peer *, struct session_up *);
void peer_down(struct rde_peer *);
void peer_delete(struct rde_peer *);
-void peer_flush(struct rde_peer *, uint8_t, time_t);
+void peer_flush(struct rde_peer *, uint8_t, monotime_t);
void peer_stale(struct rde_peer *, uint8_t, int);
void peer_blast(struct rde_peer *, uint8_t);
void peer_dump(struct rde_peer *, uint8_t);
Index: bgpd/rde_aspa.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_aspa.c,v
diff -u -p -r1.5 rde_aspa.c
--- bgpd/rde_aspa.c 16 Aug 2023 08:26:35 -0000 1.5
+++ bgpd/rde_aspa.c 13 Feb 2025 10:45:25 -0000
@@ -51,7 +51,7 @@ struct rde_aspa {
size_t maxdata;
size_t curdata;
uint32_t curset;
- time_t lastchange;
+ monotime_t lastchange;
};
struct aspa_state {
Index: bgpd/rde_decide.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_decide.c,v
diff -u -p -r1.103 rde_decide.c
--- bgpd/rde_decide.c 14 Aug 2024 19:09:51 -0000 1.103
+++ bgpd/rde_decide.c 13 Feb 2025 13:10:50 -0000
@@ -232,10 +232,12 @@ prefix_cmp(struct prefix *p1, struct pre
* evaluation is enabled.
*/
if (rde_decisionflags() & BGPD_FLAG_DECISION_ROUTEAGE) {
- if (p1->lastchange < p2->lastchange) /* p1 is older */
+ switch (monotime_cmp(p1->lastchange, p2->lastchange)) {
+ case -1: /* p1 is older */
return rv;
- if (p1->lastchange > p2->lastchange)
+ case 1: /* p2 is older */
return -rv;
+ }
}
/* 10. lowest BGP Id wins, use ORIGINATOR_ID if present */
Index: bgpd/rde_peer.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v
diff -u -p -r1.46 rde_peer.c
--- bgpd/rde_peer.c 27 Jan 2025 15:22:11 -0000 1.46
+++ bgpd/rde_peer.c 13 Feb 2025 13:14:08 -0000
@@ -303,7 +303,7 @@ rde_generate_updates(struct rib_entry *r
*/
struct peer_flush {
struct rde_peer *peer;
- time_t staletime;
+ monotime_t staletime;
};
static void
@@ -313,7 +313,7 @@ peer_flush_upcall(struct rib_entry *re,
struct rde_aspath *asp;
struct bgpd_addr addr;
struct prefix *p, *np, *rp;
- time_t staletime = ((struct peer_flush *)arg)->staletime;
+ monotime_t staletime = ((struct peer_flush *)arg)->staletime;
uint32_t i;
uint8_t prefixlen;
@@ -322,7 +322,8 @@ peer_flush_upcall(struct rib_entry *re,
TAILQ_FOREACH_SAFE(p, &re->prefix_h, entry.list.rib, np) {
if (peer != prefix_peer(p))
continue;
- if (staletime && p->lastchange > staletime)
+ if (monotime_valid(staletime) &&
+ monotime_cmp(p->lastchange, staletime) > 0)
continue;
for (i = RIB_LOC_START; i < rib_size; i++) {
@@ -363,7 +364,7 @@ peer_up(struct rde_peer *peer, struct se
*/
rib_dump_terminate(peer);
peer_imsg_flush(peer);
- peer_flush(peer, AID_UNSPEC, 0);
+ peer_flush(peer, AID_UNSPEC, monotime_clear());
peer->stats.prefix_cnt = 0;
peer->state = PEER_DOWN;
}
@@ -433,7 +434,7 @@ peer_down(struct rde_peer *peer)
peer_imsg_flush(peer);
/* flush Adj-RIB-In */
- peer_flush(peer, AID_UNSPEC, 0);
+ peer_flush(peer, AID_UNSPEC, monotime_clear());
peer->stats.prefix_cnt = 0;
}
@@ -461,7 +462,7 @@ peer_delete(struct rde_peer *peer)
* be flushed.
*/
void
-peer_flush(struct rde_peer *peer, uint8_t aid, time_t staletime)
+peer_flush(struct rde_peer *peer, uint8_t aid, monotime_t staletime)
{
struct peer_flush pf = { peer, staletime };
@@ -474,9 +475,9 @@ peer_flush(struct rde_peer *peer, uint8_
if (aid == AID_UNSPEC) {
uint8_t i;
for (i = AID_MIN; i < AID_MAX; i++)
- peer->staletime[i] = 0;
+ peer->staletime[i] = monotime_clear();
} else {
- peer->staletime[aid] = 0;
+ peer->staletime[aid] = monotime_clear();
}
}
@@ -488,10 +489,10 @@ peer_flush(struct rde_peer *peer, uint8_
void
peer_stale(struct rde_peer *peer, uint8_t aid, int flushall)
{
- time_t now;
+ monotime_t now;
/* flush the now even staler routes out */
- if (peer->staletime[aid])
+ if (monotime_valid(peer->staletime[aid]))
peer_flush(peer, aid, peer->staletime[aid]);
peer->staletime[aid] = now = getmonotime();
@@ -506,11 +507,13 @@ peer_stale(struct rde_peer *peer, uint8_
peer_imsg_flush(peer);
if (flushall)
- peer_flush(peer, aid, 0);
+ peer_flush(peer, aid, monotime_clear());
/* make sure new prefixes start on a higher timestamp */
- while (now >= getmonotime())
- sleep(1);
+ while (monotime_cmp(now, getmonotime()) >= 0) {
+ struct timespec ts = { .tv_nsec = 1000 * 1000 };
+ nanosleep(&ts, NULL);
+ }
}
/*
@@ -619,17 +622,19 @@ peer_dump(struct rde_peer *peer, uint8_t
void
peer_begin_rrefresh(struct rde_peer *peer, uint8_t aid)
{
- time_t now;
+ monotime_t now;
/* flush the now even staler routes out */
- if (peer->staletime[aid])
+ if (monotime_valid(peer->staletime[aid]))
peer_flush(peer, aid, peer->staletime[aid]);
peer->staletime[aid] = now = getmonotime();
/* make sure new prefixes start on a higher timestamp */
- while (now >= getmonotime())
- sleep(1);
+ while (monotime_cmp(now, getmonotime()) >= 0) {
+ struct timespec ts = { .tv_nsec = 1000 * 1000 };
+ nanosleep(&ts, NULL);
+ }
}
void
Index: bgpd/rtr.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rtr.c,v
diff -u -p -r1.29 rtr.c
--- bgpd/rtr.c 2 Dec 2024 15:13:57 -0000 1.29
+++ bgpd/rtr.c 13 Feb 2025 13:53:57 -0000
@@ -185,7 +185,7 @@ rtr_main(int debug, int verbose)
struct pollfd *pfd = NULL;
void *newp;
size_t pfd_elms = 0, i;
- time_t timeout;
+ monotime_t timeout;
log_init(debug, LOG_DAEMON);
log_setverbose(verbose);
@@ -242,9 +242,10 @@ rtr_main(int debug, int verbose)
}
/* run the expire timeout every EXPIRE_TIMEOUT seconds */
- timeout = timer_nextduein(&expire_timer, getmonotime());
- if (timeout == -1)
+ timeout = timer_nextduein(&expire_timer);
+ if (!monotime_valid(timeout))
fatalx("roa-set expire timer no longer running");
+ timeout = monotime_sub(timeout, getmonotime());
memset(pfd, 0, sizeof(struct pollfd) * pfd_elms);
@@ -254,7 +255,7 @@ rtr_main(int debug, int verbose)
i = PFD_PIPE_COUNT;
i += rtr_poll_events(pfd + i, pfd_elms - i, &timeout);
- if (poll(pfd, i, timeout * 1000) == -1) {
+ if (poll(pfd, i, monotime_to_msec(timeout)) == -1) {
if (errno == EINTR)
continue;
fatal("poll error");
Index: bgpd/rtr_proto.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rtr_proto.c,v
diff -u -p -r1.50 rtr_proto.c
--- bgpd/rtr_proto.c 10 Feb 2025 14:42:13 -0000 1.50
+++ bgpd/rtr_proto.c 13 Feb 2025 13:58:10 -0000
@@ -1310,7 +1310,7 @@ rtr_check_events(struct pollfd *pfds, si
{
struct rtr_session *rs;
struct timer *t;
- time_t now;
+ monotime_t now;
size_t i = 0;
for (i = 0; i < npfds; i++) {
@@ -1362,22 +1362,25 @@ rtr_count(void)
}
size_t
-rtr_poll_events(struct pollfd *pfds, size_t npfds, time_t *timeout)
+rtr_poll_events(struct pollfd *pfds, size_t npfds, monotime_t *timeout)
{
struct rtr_session *rs;
- time_t now = getmonotime();
+ monotime_t now = getmonotime();
size_t i = 0;
TAILQ_FOREACH(rs, &rtrs, entry) {
- time_t nextaction;
+ monotime_t nextaction;
struct pollfd *pfd = pfds + i++;
if (i > npfds)
fatalx("%s: too many sessions for pollfd", __func__);
- if ((nextaction = timer_nextduein(&rs->timers, now)) != -1 &&
- nextaction < *timeout)
- *timeout = nextaction;
+ nextaction = timer_nextduein(&rs->timers);
+ if (monotime_valid(nextaction)) {
+ monotime_sub(nextaction, now);
+ if (monotime_cmp(nextaction, *timeout) < 0)
+ *timeout = nextaction;
+ }
if (rs->state == RTR_STATE_CLOSED) {
pfd->fd = -1;
@@ -1546,7 +1549,7 @@ rtr_show(struct rtr_session *rs, pid_t p
struct ctl_show_rtr msg;
struct ctl_timer ct;
u_int i;
- time_t d;
+ monotime_t d;
memset(&msg, 0, sizeof(msg));
Index: bgpd/session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
diff -u -p -r1.517 session.c
--- bgpd/session.c 18 Feb 2025 16:02:20 -0000 1.517
+++ bgpd/session.c 19 Feb 2025 16:10:07 -0000
@@ -54,6 +54,9 @@
#define PFD_SOCK_RCTL 4
#define PFD_LISTENERS_START 5
+#define MAX_TIMEOUT 240
+#define PAUSEACCEPT_TIMEOUT 1
+
void session_sighdlr(int);
int setup_listeners(u_int *);
void init_peer(struct peer *, struct bgpd_config *);
@@ -111,7 +114,7 @@ int csock = -1, rcsock = -1;
u_int peer_cnt;
struct mrt_head mrthead;
-time_t pauseaccept;
+monotime_t pauseaccept;
static const uint8_t marker[MSGSIZE_HEADER_MARKER] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -192,7 +195,6 @@ setup_listeners(u_int *la_cnt)
void
session_main(int debug, int verbose)
{
- int timeout;
unsigned int i, j, idx_peers, idx_listeners, idx_mrts;
u_int pfd_elms = 0, peer_l_elms = 0, mrt_l_elms = 0;
u_int listener_cnt, ctl_cnt, mrt_cnt;
@@ -203,7 +205,7 @@ session_main(int debug, int verbose)
struct pollfd *pfd = NULL;
struct listen_addr *la;
void *newp;
- time_t now;
+ monotime_t now, timeout;
short events;
log_init(debug, LOG_DAEMON);
@@ -338,7 +340,7 @@ session_main(int debug, int verbose)
set_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde);
set_pollfd(&pfd[PFD_PIPE_ROUTE_CTL], ibuf_rde_ctl);
- if (pauseaccept == 0) {
+ if (!monotime_valid(pauseaccept)) {
pfd[PFD_SOCK_CTL].fd = csock;
pfd[PFD_SOCK_CTL].events = POLLIN;
pfd[PFD_SOCK_RCTL].fd = rcsock;
@@ -350,7 +352,7 @@ session_main(int debug, int verbose)
i = PFD_LISTENERS_START;
TAILQ_FOREACH(la, conf->listen_addrs, entry) {
- if (pauseaccept == 0) {
+ if (!monotime_valid(pauseaccept)) {
pfd[i].fd = la->fd;
pfd[i].events = POLLIN;
} else
@@ -358,11 +360,11 @@ session_main(int debug, int verbose)
i++;
}
idx_listeners = i;
- timeout = 240; /* loop every 240s at least */
+ timeout = monotime_from_sec(MAX_TIMEOUT);
now = getmonotime();
RB_FOREACH(p, peer_head, &conf->peers) {
- time_t nextaction;
+ monotime_t nextaction;
struct timer *pt;
/* check timers */
@@ -420,9 +422,12 @@ session_main(int debug, int verbose)
fatalx("King Bula lost in time");
}
}
- if ((nextaction = timer_nextduein(&p->timers,
- now)) != -1 && nextaction < timeout)
- timeout = nextaction;
+ nextaction = timer_nextduein(&p->timers);
+ if (monotime_valid(nextaction)) {
+ nextaction = monotime_sub(nextaction, now);
+ if (monotime_cmp(nextaction, timeout) < 0)
+ timeout = nextaction;
+ }
/* are we waiting for a write? */
events = POLLIN;
@@ -431,7 +436,7 @@ session_main(int debug, int verbose)
events |= POLLOUT;
/* is there still work to do? */
if (p->rpending)
- timeout = 0;
+ timeout = monotime_clear();
/* poll events */
if (p->fd != -1 && events != 0) {
@@ -459,11 +464,12 @@ session_main(int debug, int verbose)
if (i > pfd_elms)
fatalx("poll pfd overflow");
- if (pauseaccept && timeout > 1)
- timeout = 1;
- if (timeout < 0)
- timeout = 0;
- if (poll(pfd, i, timeout * 1000) == -1) {
+ if (monotime_valid(pauseaccept) && monotime_cmp(timeout,
+ monotime_from_sec(PAUSEACCEPT_TIMEOUT)) > 0)
+ timeout = monotime_from_sec(PAUSEACCEPT_TIMEOUT);
+ if (!monotime_valid(timeout))
+ timeout = monotime_clear();
+ if (poll(pfd, i, monotime_to_msec(timeout)) == -1) {
if (errno == EINTR)
continue;
fatal("poll error");
@@ -473,8 +479,10 @@ session_main(int debug, int verbose)
* If we previously saw fd exhaustion, we stop accept()
* for 1 second to throttle the accept() loop.
*/
- if (pauseaccept && getmonotime() > pauseaccept + 1)
- pauseaccept = 0;
+ if (monotime_valid(pauseaccept) &&
+ monotime_cmp(getmonotime(), monotime_add(pauseaccept,
+ monotime_from_sec(PAUSEACCEPT_TIMEOUT))) > 0)
+ pauseaccept = monotime_clear();
if (handle_pollfd(&pfd[PFD_PIPE_MAIN], ibuf_main) == -1) {
log_warnx("SE: Lost connection to parent");
@@ -876,7 +884,7 @@ session_close_connection(struct peer *pe
{
if (peer->fd != -1) {
close(peer->fd);
- pauseaccept = 0;
+ pauseaccept = monotime_clear();
}
peer->fd = -1;
}
Index: bgpd/session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
diff -u -p -r1.186 session.h
--- bgpd/session.h 18 Feb 2025 16:02:20 -0000 1.186
+++ bgpd/session.h 19 Feb 2025 16:10:07 -0000
@@ -144,9 +144,9 @@ struct peer_stats {
unsigned long long prefix_sent_update;
unsigned long long prefix_sent_withdraw;
unsigned long long prefix_sent_eor;
- time_t last_updown;
- time_t last_read;
- time_t last_write;
+ monotime_t last_updown;
+ monotime_t last_read;
+ monotime_t last_write;
uint32_t msg_queue_len;
uint32_t prefix_cnt;
uint32_t prefix_out_cnt;
@@ -189,7 +189,7 @@ enum Timer {
struct timer {
TAILQ_ENTRY(timer) entry;
enum Timer type;
- time_t val;
+ monotime_t val;
};
TAILQ_HEAD(timer_head, timer);
@@ -233,11 +233,11 @@ struct peer {
uint8_t rdesession;
};
-extern time_t pauseaccept;
+extern monotime_t pauseaccept;
struct ctl_timer {
enum Timer type;
- time_t val;
+ monotime_t val;
};
/* carp.c */
@@ -301,7 +301,7 @@ void rde_main(int, int);
struct rtr_session;
size_t rtr_count(void);
void rtr_check_events(struct pollfd *, size_t);
-size_t rtr_poll_events(struct pollfd *, size_t, time_t *);
+size_t rtr_poll_events(struct pollfd *, size_t, monotime_t *);
struct rtr_session *rtr_new(uint32_t, struct rtr_config_msg *);
struct rtr_session *rtr_get(uint32_t);
void rtr_free(struct rtr_session *);
@@ -346,9 +346,9 @@ struct bgpd_addr *session_localaddr(stru
/* timer.c */
struct timer *timer_get(struct timer_head *, enum Timer);
-struct timer *timer_nextisdue(struct timer_head *, time_t);
-time_t timer_nextduein(struct timer_head *, time_t);
-int timer_running(struct timer_head *, enum Timer, time_t *);
+struct timer *timer_nextisdue(struct timer_head *, monotime_t);
+monotime_t timer_nextduein(struct timer_head *);
+int timer_running(struct timer_head *, enum Timer, monotime_t *);
void timer_set(struct timer_head *, enum Timer, u_int);
void timer_stop(struct timer_head *, enum Timer);
void timer_remove(struct timer_head *, enum Timer);
Index: bgpd/timer.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/timer.c,v
diff -u -p -r1.19 timer.c
--- bgpd/timer.c 11 Dec 2020 12:00:01 -0000 1.19
+++ bgpd/timer.c 13 Feb 2025 15:50:51 -0000
@@ -23,19 +23,6 @@
#include "session.h"
#include "log.h"
-#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
-
-time_t
-getmonotime(void)
-{
- struct timespec ts;
-
- if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
- fatal("clock_gettime");
-
- return (ts.tv_sec);
-}
-
struct timer *
timer_get(struct timer_head *th, enum Timer timer)
{
@@ -49,34 +36,35 @@ timer_get(struct timer_head *th, enum Ti
}
struct timer *
-timer_nextisdue(struct timer_head *th, time_t now)
+timer_nextisdue(struct timer_head *th, monotime_t now)
{
struct timer *t;
t = TAILQ_FIRST(th);
- if (t != NULL && t->val > 0 && t->val <= now)
+ if (t != NULL && monotime_valid(t->val) &&
+ monotime_cmp(t->val, now) <= 0)
return (t);
return (NULL);
}
-time_t
-timer_nextduein(struct timer_head *th, time_t now)
+monotime_t
+timer_nextduein(struct timer_head *th)
{
struct timer *t;
- if ((t = TAILQ_FIRST(th)) != NULL && t->val > 0)
- return (MAXIMUM(t->val - now, 0));
- return (-1);
+ if ((t = TAILQ_FIRST(th)) != NULL && monotime_valid(t->val))
+ return t->val;
+ return monotime_clear();
}
int
-timer_running(struct timer_head *th, enum Timer timer, time_t *left)
+timer_running(struct timer_head *th, enum Timer timer, monotime_t *due)
{
struct timer *t = timer_get(th, timer);
- if (t != NULL && t->val > 0) {
- if (left != NULL)
- *left = t->val - getmonotime();
+ if (t != NULL && monotime_valid(t->val)) {
+ if (due != NULL)
+ *due = t->val;
return (1);
}
return (0);
@@ -87,21 +75,26 @@ timer_set(struct timer_head *th, enum Ti
{
struct timer *t = timer_get(th, timer);
struct timer *next;
+ monotime_t ms;
+
+ ms = monotime_from_sec(offset);
+ ms = monotime_add(ms, getmonotime());
if (t == NULL) { /* have to create */
if ((t = malloc(sizeof(*t))) == NULL)
fatal("timer_set");
t->type = timer;
} else {
- if (t->val == getmonotime() + (time_t)offset)
+ if (monotime_cmp(t->val, ms) == 0)
return;
TAILQ_REMOVE(th, t, entry);
}
- t->val = getmonotime() + offset;
+ t->val = ms;
TAILQ_FOREACH(next, th, entry)
- if (next->val == 0 || next->val > t->val)
+ if (!monotime_valid(next->val) ||
+ monotime_cmp(next->val, t->val) > 0)
break;
if (next != NULL)
TAILQ_INSERT_BEFORE(next, t, entry);
@@ -115,7 +108,7 @@ timer_stop(struct timer_head *th, enum T
struct timer *t = timer_get(th, timer);
if (t != NULL) {
- t->val = 0;
+ t->val = monotime_clear();
TAILQ_REMOVE(th, t, entry);
TAILQ_INSERT_TAIL(th, t, entry);
}
bgpd: better monotime handling