[pim] Work-around improper monotonic clock
diff --git a/pimd/Makefile.am b/pimd/Makefile.am
index 4aae637..ef5cffa 100644
--- a/pimd/Makefile.am
+++ b/pimd/Makefile.am
@@ -27,6 +27,8 @@
# PIM_REPORT_RECV_IFINDEX_MISMATCH: Report sock/recv ifindex mismatch
# PIM_ENFORCE_LOOPFREE_MFC: Refuse adding looping MFC entries
# PIM_UNEXPECTED_KERNEL_UPCALL: Report unexpected kernel upcall
+# PIM_USE_QUAGGA_GETTIME: Prefer quagga_gettime
+# PIM_GETTIME_USE_GETTIMEOFDAY: Work-around improper monotonic clock
PIM_DEFS =
#PIM_DEFS += -DPIM_DEBUG_BYDEFAULT
@@ -37,6 +39,8 @@
PIM_DEFS += -DPIM_USE_QUAGGA_INET_CHECKSUM
PIM_DEFS += -DPIM_ENFORCE_LOOPFREE_MFC
#PIM_DEFS += -DPIM_UNEXPECTED_KERNEL_UPCALL
+#PIM_DEFS += -DPIM_USE_QUAGGA_GETTIME
+PIM_DEFS += -DPIM_GETTIME_USE_GETTIMEOFDAY
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" $(PIM_DEFS)
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 2efcbb8..51e5e36 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -285,6 +285,14 @@
zlog_notice("PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall");
#endif
+#ifdef PIM_FORCE_QUAGGA_REALTIME_STABILISED
+ zlog_notice("PIM_USE_QUAGGA_GETTIME: using Quagga's quagga_gettime"());
+#endif
+
+#ifdef PIM_GETTIME_USE_GETTIMEOFDAY
+ zlog_notice("PIM_GETTIME_USE_GETTIMEOFDAY: work-around improper monotonic clock");
+#endif
+
#ifdef HAVE_CLOCK_MONOTONIC
zlog_notice("HAVE_CLOCK_MONOTONIC");
#else
diff --git a/pimd/pim_time.c b/pimd/pim_time.c
index a4b1cc4..0771960 100644
--- a/pimd/pim_time.c
+++ b/pimd/pim_time.c
@@ -30,16 +30,31 @@
#include "pim_time.h"
-static int pim_gettime(enum quagga_clkid clkid, struct timeval *tv)
+static int pim_gettime(int clk_id, struct timeval *tv)
{
+ struct timespec ts;
int result;
- result = quagga_gettime(clkid, tv);
+#ifdef PIM_USE_QUAGGA_GETTIME
+ result = quagga_gettime(clk_id, tv);
if (result) {
- zlog_err("%s: quagga_gettime(clkid=%d) failure: errno=%d: %s",
- __PRETTY_FUNCTION__, clkid,
+ zlog_err("%s: quagga_gettime(clk_id=%d) failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, clk_id,
errno, safe_strerror(errno));
}
+#else
+ result = clock_gettime(clk_id, &ts);
+ if (result) {
+ zlog_err("%s: clock_gettime(clk_id=%d) failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, clk_id,
+ errno, safe_strerror(errno));
+ return result;
+ }
+ if (tv) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = 1000 * ts.tv_nsec;
+ }
+#endif
return result;
}
@@ -48,12 +63,28 @@
{
int result;
+#ifdef PIM_GETTIME_USE_GETTIMEOFDAY
+ result = gettimeofday(tv, 0);
+ if (result) {
+ zlog_err("%s: gettimeofday() failure: errno=%d: %s",
+ __PRETTY_FUNCTION__,
+ errno, safe_strerror(errno));
+ }
+#elif defined(PIM_USE_QUAGGA_GETTIME)
result = pim_gettime(QUAGGA_CLK_MONOTONIC, tv);
if (result) {
zlog_err("%s: pim_gettime(QUAGGA_CLK_MONOTONIC=%d) failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, QUAGGA_CLK_MONOTONIC,
+ errno, safe_strerror(errno));
+ }
+#else
+ result = pim_gettime(CLOCK_MONOTONIC, tv);
+ if (result) {
+ zlog_err("%s: pim_gettime(CLOCK_MONOTONIC=%d) failure: errno=%d: %s",
__PRETTY_FUNCTION__, CLOCK_MONOTONIC,
errno, safe_strerror(errno));
}
+#endif
return result;
}