[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;
 }