From: Miroslav Lichvar Date: Tue, 26 Sep 2023 10:14:56 +0000 (+0200) Subject: ntp: extend local timestamp for PTP correction X-Git-Tag: 4.5-pre1~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0267475e33c49db9ca33023468b96c55cfacc68;p=thirdparty%2Fchrony.git ntp: extend local timestamp for PTP correction 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). --- diff --git a/ntp_core.c b/ntp_core.c index 0e415731..fae5e7b1 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -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; diff --git a/ntp_core.h b/ntp_core.h index a3c55468..5c5a6141 100644 --- a/ntp_core.h +++ b/ntp_core.h @@ -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 diff --git a/ntp_io.c b/ntp_io.c index fce7b177..f8347723 100644 --- 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) { diff --git a/test/unit/ntp_core.c b/test/unit/ntp_core.c index 08a15326..989b294b 100644 --- a/test/unit/ntp_core.c +++ b/test/unit/ntp_core.c @@ -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;