]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: extend local timestamp for PTP correction
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 26 Sep 2023 10:14:56 +0000 (12:14 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 26 Sep 2023 13:10:19 +0000 (15:10 +0200)
Add two new fields to the NTP_Local_Timestamp structure:
- receive duration as the time it takes to receive the ethernet frame,
  currently known only with HW timestamping
- network correction as a generalized PTP correction

The PTP correction is provided by transparent clocks in the correction
field of PTP messages to remove the receive, processing and queueing
delays of network switches and routers. Only one-step end-to-end unicast
transparent clocks are useful for NTP-over-PTP. Two-step transparent
clocks use follow-up messages and peer-to-peer transparent clocks don't
handle delay requests.

The RX duration will be included in the network correction to compensate
for asymmetric link speeds of the server and client as the NTP RX
timestamp corresponds to the end of the reception (in order to
compensate for the asymmetry in the normal case when no corrections
are applied).

ntp_core.c
ntp_core.h
ntp_io.c
test/unit/ntp_core.c

index 0e4157311d0687cd8188f1d6265bd32334dd3373..fae5e7b19be77efe763b8b31fc12341e2ee7fba8 100644 (file)
@@ -420,6 +420,8 @@ zero_local_timestamp(NTP_Local_Timestamp *ts)
   UTI_ZeroTimespec(&ts->ts);
   ts->err = 0.0;
   ts->source = NTP_TS_DAEMON;
+  ts->rx_duration = 0.0;
+  ts->net_correction = 0.0;
 }
 
 /* ================================================== */
@@ -1299,6 +1301,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
     local_tx->ts = local_transmit;
     local_tx->err = local_transmit_err;
     local_tx->source = NTP_TS_DAEMON;
+    local_tx->rx_duration = 0.0;
+    local_tx->net_correction = 0.0;
   }
 
   if (local_ntp_rx)
@@ -2612,8 +2616,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
       UTI_CompareNtp64(&message->receive_ts, &message->transmit_ts) != 0) {
     ntp_rx = message->originate_ts;
     local_ntp_rx = &ntp_rx;
-    UTI_ZeroTimespec(&local_tx.ts);
-    local_tx.source = NTP_TS_DAEMON;
+    zero_local_timestamp(&local_tx);
     interleaved = CLG_GetNtpTxTimestamp(&ntp_rx, &local_tx.ts, &local_tx.source);
 
     tx_ts = &local_tx;
index a3c554688a4c84c81695d24fce3bd91bd612536b..5c5a6141e207a91858349a40634e702a54eed819 100644 (file)
@@ -42,6 +42,8 @@ typedef struct {
   struct timespec ts;
   double err;
   NTP_Timestamp_Source source;
+  double rx_duration;
+  double net_correction;
 } NTP_Local_Timestamp;
 
 /* This is a private data type used for storing the instance record for
index fce7b1772478c460a1968497966783b432b9b845..f8347723d8c4dc43d339f240792a5f80529405b2 100644 (file)
--- a/ntp_io.c
+++ b/ntp_io.c
@@ -431,6 +431,9 @@ process_message(SCK_Message *message, int sock_fd, int event)
 
   SCH_GetLastEventTime(&local_ts.ts, &local_ts.err, NULL);
   local_ts.source = NTP_TS_DAEMON;
+  local_ts.rx_duration = 0.0;
+  local_ts.net_correction = 0.0;
+
   sched_ts = local_ts.ts;
 
   if (message->addr_type != SCK_ADDR_IP) {
index 08a153260751bfb2e2532bdfb6f769c1f7ee56d0..989b294bc76606b0581ef0245cb1d2963cacbded 100644 (file)
@@ -99,8 +99,8 @@ send_request(NCR_Instance inst, int late_hwts)
     local_addr.ip_addr.family = IPADDR_UNSPEC;
     local_addr.if_index = INVALID_IF_INDEX;
     local_addr.sock_fd = 101;
+    zero_local_timestamp(&local_ts);
     local_ts.ts = current_time;
-    local_ts.err = 0.0;
     local_ts.source = NTP_TS_KERNEL;
 
     NCR_ProcessTxKnown(inst, &local_addr, &local_ts, &req_buffer, req_length);
@@ -122,8 +122,8 @@ process_request(NTP_Remote_Address *remote_addr)
   local_addr.ip_addr.family = IPADDR_UNSPEC;
   local_addr.if_index = INVALID_IF_INDEX;
   local_addr.sock_fd = 100;
+  zero_local_timestamp(&local_ts);
   local_ts.ts = current_time;
-  local_ts.err = 0.0;
   local_ts.source = NTP_TS_KERNEL;
 
   res_length = 0;
@@ -289,8 +289,8 @@ proc_response(NCR_Instance inst, int good, int valid, int updated_sync,
   local_addr.ip_addr.family = IPADDR_UNSPEC;
   local_addr.if_index = INVALID_IF_INDEX;
   local_addr.sock_fd = NTP_LVM_TO_MODE(res->lvm) != MODE_SERVER ? 100 : 101;
+  zero_local_timestamp(&local_ts);
   local_ts.ts = current_time;
-  local_ts.err = 0.0;
   local_ts.source = NTP_TS_KERNEL;
 
   prev_rx_count = inst->report.total_rx_count;