]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: save PTP correction from NTP-over-PTP messages
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 26 Sep 2023 10:22:47 +0000 (12:22 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 26 Sep 2023 13:14:13 +0000 (15:14 +0200)
When the RX duration is known (HW timestamping), save the PTP correction
from received PTP messages in the local RX timestamp.

ntp_io.c
ntp_io.h
ntp_io_linux.c

index f8347723d8c4dc43d339f240792a5f80529405b2..ec2fd7b4f9644fc79e8dac122295b3efb397b24b 100644 (file)
--- a/ntp_io.c
+++ b/ntp_io.c
@@ -459,7 +459,7 @@ process_message(SCK_Message *message, int sock_fd, int event)
     DEBUG_LOG("Updated RX timestamp delay=%.9f tss=%u",
               UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts), local_ts.source);
 
-  if (!NIO_UnwrapMessage(message, sock_fd))
+  if (!NIO_UnwrapMessage(message, sock_fd, &local_ts.net_correction))
     return;
 
   /* Just ignore the packet if it's not of a recognized length */
@@ -498,8 +498,9 @@ read_from_socket(int sock_fd, int event, void *anything)
 /* ================================================== */
 
 int
-NIO_UnwrapMessage(SCK_Message *message, int sock_fd)
+NIO_UnwrapMessage(SCK_Message *message, int sock_fd, double *net_correction)
 {
+  double ptp_correction;
   PTP_NtpMessage *msg;
 
   if (!is_ptp_socket(sock_fd))
@@ -525,7 +526,14 @@ NIO_UnwrapMessage(SCK_Message *message, int sock_fd)
   message->data = (char *)message->data + PTP_NTP_PREFIX_LENGTH;
   message->length -= PTP_NTP_PREFIX_LENGTH;
 
-  DEBUG_LOG("Unwrapped PTP->NTP len=%d", message->length);
+  ptp_correction = UTI_Integer64NetworkToHost(*(Integer64 *)msg->header.correction) /
+                   ((1 << 16) * 1.0e9);
+
+  /* Use the correction only if the RX duration is known (i.e. HW timestamp) */
+  if (*net_correction > 0.0)
+    *net_correction += ptp_correction;
+
+  DEBUG_LOG("Unwrapped PTP->NTP len=%d corr=%.9f", message->length, ptp_correction);
 
   return 1;
 }
index 427bd966ea95f35593c874382cb3e2f48f58e2f1..30f4992295e3c40072df61a9e4635ec6cf73041e 100644 (file)
--- a/ntp_io.h
+++ b/ntp_io.h
@@ -64,7 +64,7 @@ extern int NIO_IsServerSocketOpen(void);
 extern int NIO_IsServerConnectable(NTP_Remote_Address *remote_addr);
 
 /* Function to unwrap an NTP message from non-native transport (e.g. PTP) */
-extern int NIO_UnwrapMessage(SCK_Message *message, int sock_fd);
+extern int NIO_UnwrapMessage(SCK_Message *message, int sock_fd, double *net_correction);
 
 /* Function to transmit a packet */
 extern int NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
index 8f93f599dd8ca8eeefff81a8056c631c9639af6d..e797f34af6fe86d08b75a104e832889b4c5e5c24 100644 (file)
@@ -559,7 +559,7 @@ process_hw_timestamp(struct Interface *iface, struct timespec *hw_ts,
                      NTP_Local_Timestamp *local_ts, int rx_ntp_length, int family,
                      int l2_length)
 {
-  double rx_correction, ts_delay, local_err;
+  double rx_correction = 0.0, ts_delay, local_err;
   struct timespec ts;
 
   poll_phc(iface, &local_ts->ts);
@@ -600,6 +600,10 @@ process_hw_timestamp(struct Interface *iface, struct timespec *hw_ts,
   local_ts->ts = ts;
   local_ts->err = local_err;
   local_ts->source = NTP_TS_HARDWARE;
+  local_ts->rx_duration = rx_correction;
+  /* Network correction needs to include the RX duration to avoid
+     asymmetric correction with asymmetric link speeds */
+  local_ts->net_correction = rx_correction;
 }
 
 /* ================================================== */
@@ -723,6 +727,7 @@ NIO_Linux_ProcessMessage(SCK_Message *message, NTP_Local_Address *local_addr,
 {
   struct Interface *iface;
   int is_tx, ts_if_index, l2_length;
+  double c;
 
   is_tx = event == SCH_FILE_EXCEPTION;
   iface = NULL;
@@ -783,7 +788,7 @@ NIO_Linux_ProcessMessage(SCK_Message *message, NTP_Local_Address *local_addr,
     return 1;
   }
 
-  if (!NIO_UnwrapMessage(message, local_addr->sock_fd))
+  if (!NIO_UnwrapMessage(message, local_addr->sock_fd, &c))
     return 1;
 
   if (message->length < NTP_HEADER_LENGTH || message->length > sizeof (NTP_Packet))