ntp: check software timestamps on Linux
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.
This commit is contained in:
parent
7ee5f4888e
commit
127826a399
1 changed files with 24 additions and 3 deletions
|
@ -73,7 +73,7 @@ struct Interface {
|
||||||
/* Minimum interval between PHC readings */
|
/* Minimum interval between PHC readings */
|
||||||
#define MIN_PHC_POLL -6
|
#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
|
#define MAX_TS_DELAY 1.0
|
||||||
|
|
||||||
/* Array of Interfaces */
|
/* Array of Interfaces */
|
||||||
|
@ -619,6 +619,28 @@ process_hw_timestamp(struct Interface *iface, struct timespec *hw_ts,
|
||||||
local_ts->source = NTP_TS_HARDWARE;
|
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
|
/* Extract UDP data from a layer 2 message. Supported is Ethernet
|
||||||
with optional VLAN tags. */
|
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) &&
|
if (local_ts->source == NTP_TS_DAEMON && !UTI_IsZeroTimespec(&message->timestamp.kernel) &&
|
||||||
(!is_tx || UTI_IsZeroTimespec(&message->timestamp.hw))) {
|
(!is_tx || UTI_IsZeroTimespec(&message->timestamp.hw))) {
|
||||||
LCL_CookTime(&message->timestamp.kernel, &local_ts->ts, &local_ts->err);
|
process_sw_timestamp(&message->timestamp.kernel, local_ts);
|
||||||
local_ts->source = NTP_TS_KERNEL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the kernel is slow with enabling RX timestamping, open a dummy
|
/* If the kernel is slow with enabling RX timestamping, open a dummy
|
||||||
|
|
Loading…
Reference in a new issue