]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: check software timestamps on Linux
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 23 Sep 2021 11:00:24 +0000 (13:00 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 23 Sep 2021 13:51:35 +0000 (15:51 +0200)
Apparently some routers with hardware NAT acceleration have a bug
causing the kernel timestamps to be corrupted and break NTP. Similarly
to the sanity check applied to hardware timestamps, require the
kernel/driver timestamps to be within one second of the daemon timestamp
to be accepted.

ntp_io_linux.c

index ce19b86b6da4f01255bbf5df6c7bacb618d1402a..4d099cc9df5f94b81d9df54bfcfcb3c5775ebb64 100644 (file)
@@ -73,7 +73,7 @@ struct Interface {
 /* Minimum interval between PHC readings */
 #define MIN_PHC_POLL -6
 
-/* Maximum acceptable offset between HW and daemon/kernel timestamp */
+/* Maximum acceptable offset between SW/HW and daemon timestamp */
 #define MAX_TS_DELAY 1.0
 
 /* Array of Interfaces */
@@ -619,6 +619,28 @@ process_hw_timestamp(struct Interface *iface, struct timespec *hw_ts,
   local_ts->source = NTP_TS_HARDWARE;
 }
 
+/* ================================================== */
+
+static void
+process_sw_timestamp(struct timespec *sw_ts, NTP_Local_Timestamp *local_ts)
+{
+  double ts_delay, local_err;
+  struct timespec ts;
+
+  LCL_CookTime(sw_ts, &ts, &local_err);
+
+  ts_delay = UTI_DiffTimespecsToDouble(&local_ts->ts, &ts);
+
+  if (fabs(ts_delay) > MAX_TS_DELAY) {
+    DEBUG_LOG("Unacceptable timestamp delay %.9f", ts_delay);
+    return;
+  }
+
+  local_ts->ts = ts;
+  local_ts->err = local_err;
+  local_ts->source = NTP_TS_KERNEL;
+}
+
 /* ================================================== */
 /* Extract UDP data from a layer 2 message.  Supported is Ethernet
    with optional VLAN tags. */
@@ -744,8 +766,7 @@ NIO_Linux_ProcessMessage(SCK_Message *message, NTP_Local_Address *local_addr,
 
   if (local_ts->source == NTP_TS_DAEMON && !UTI_IsZeroTimespec(&message->timestamp.kernel) &&
       (!is_tx || UTI_IsZeroTimespec(&message->timestamp.hw))) {
-    LCL_CookTime(&message->timestamp.kernel, &local_ts->ts, &local_ts->err);
-    local_ts->source = NTP_TS_KERNEL;
+    process_sw_timestamp(&message->timestamp.kernel, local_ts);
   }
 
   /* If the kernel is slow with enabling RX timestamping, open a dummy