ntp: always try to enable SW timestamping on Linux
Request SW timestamps with SCM_TIMESTAMPING even if HW timestamping is enabled. This replaces SCM_TIMESTAMP(NS) for RX and enables TX SW timestamping on interfaces that don't support HW timestamping (or don't have it enabled) if another interface has HW timestamping enabled.
This commit is contained in:
parent
b712c100d7
commit
b799cfd1c4
2 changed files with 25 additions and 25 deletions
23
ntp_io.c
23
ntp_io.c
|
@ -204,21 +204,18 @@ prepare_socket(int family, int port_number, int client_only)
|
||||||
/* Don't quit - we might survive anyway */
|
/* Don't quit - we might survive anyway */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SO_TIMESTAMP
|
/* Enable kernel/HW timestamping of packets */
|
||||||
/* Enable receiving of timestamp control messages */
|
|
||||||
#ifdef SO_TIMESTAMPNS
|
|
||||||
/* Try nanosecond resolution first */
|
|
||||||
if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMPNS, (char *)&on_off, sizeof(on_off)) < 0)
|
|
||||||
#endif
|
|
||||||
if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMP, (char *)&on_off, sizeof(on_off)) < 0) {
|
|
||||||
LOG(LOGS_ERR, "Could not set %s socket option", "SO_TIMESTAMP");
|
|
||||||
/* Don't quit - we might survive anyway */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_TIMESTAMPING
|
#ifdef HAVE_LINUX_TIMESTAMPING
|
||||||
NIO_Linux_SetTimestampSocketOptions(sock_fd, client_only, &events);
|
if (!NIO_Linux_SetTimestampSocketOptions(sock_fd, client_only, &events))
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SO_TIMESTAMPNS
|
||||||
|
if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMPNS, (char *)&on_off, sizeof(on_off)) < 0)
|
||||||
|
#endif
|
||||||
|
#ifdef SO_TIMESTAMP
|
||||||
|
if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMP, (char *)&on_off, sizeof(on_off)) < 0)
|
||||||
|
LOG(LOGS_ERR, "Could not set %s socket option", "SO_TIMESTAMP");
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
#ifdef IP_FREEBIND
|
#ifdef IP_FREEBIND
|
||||||
/* Allow binding to address that doesn't exist yet */
|
/* Allow binding to address that doesn't exist yet */
|
||||||
|
|
|
@ -280,12 +280,12 @@ NIO_Linux_Initialise(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ts_flags = SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE;
|
||||||
|
ts_tx_flags = SOF_TIMESTAMPING_TX_SOFTWARE;
|
||||||
|
|
||||||
if (hwts) {
|
if (hwts) {
|
||||||
ts_flags = SOF_TIMESTAMPING_RAW_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE;
|
ts_flags |= SOF_TIMESTAMPING_RAW_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE;
|
||||||
ts_tx_flags = SOF_TIMESTAMPING_TX_HARDWARE;
|
ts_tx_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
|
||||||
} else {
|
|
||||||
ts_flags = SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE;
|
|
||||||
ts_tx_flags = SOF_TIMESTAMPING_TX_SOFTWARE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable IP_PKTINFO in messages looped back to the error queue */
|
/* Enable IP_PKTINFO in messages looped back to the error queue */
|
||||||
|
@ -504,10 +504,7 @@ NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *loc
|
||||||
|
|
||||||
memcpy(&ts3, CMSG_DATA(cmsg), sizeof (ts3));
|
memcpy(&ts3, CMSG_DATA(cmsg), sizeof (ts3));
|
||||||
|
|
||||||
if (!UTI_IsZeroTimespec(&ts3.ts[0])) {
|
if (!UTI_IsZeroTimespec(&ts3.ts[2])) {
|
||||||
LCL_CookTime(&ts3.ts[0], &local_ts->ts, &local_ts->err);
|
|
||||||
local_ts->source = NTP_TS_KERNEL;
|
|
||||||
} else if (!UTI_IsZeroTimespec(&ts3.ts[2])) {
|
|
||||||
iface = get_interface(local_addr->if_index);
|
iface = get_interface(local_addr->if_index);
|
||||||
if (iface) {
|
if (iface) {
|
||||||
process_hw_timestamp(iface, &ts3.ts[2], local_ts, !is_tx ? length : 0,
|
process_hw_timestamp(iface, &ts3.ts[2], local_ts, !is_tx ? length : 0,
|
||||||
|
@ -516,6 +513,12 @@ NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *loc
|
||||||
DEBUG_LOG("HW clock not found for interface %d", local_addr->if_index);
|
DEBUG_LOG("HW clock not found for interface %d", local_addr->if_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (local_ts->source == NTP_TS_DAEMON && !UTI_IsZeroTimespec(&ts3.ts[0]) &&
|
||||||
|
(!is_tx || UTI_IsZeroTimespec(&ts3.ts[2]))) {
|
||||||
|
LCL_CookTime(&ts3.ts[0], &local_ts->ts, &local_ts->err);
|
||||||
|
local_ts->source = NTP_TS_KERNEL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) ||
|
if ((cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) ||
|
||||||
|
@ -555,9 +558,9 @@ NIO_Linux_ProcessMessage(NTP_Remote_Address *remote_addr, NTP_Local_Address *loc
|
||||||
iface->l2_udp6_ntp_start = l2_length - length;
|
iface->l2_udp6_ntp_start = l2_length - length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drop the message if HW timestamp is missing or its processing failed */
|
/* Drop the message if it has no timestamp or its processing failed */
|
||||||
if ((ts_flags & SOF_TIMESTAMPING_RAW_HARDWARE) && local_ts->source != NTP_TS_HARDWARE) {
|
if (local_ts->source == NTP_TS_DAEMON) {
|
||||||
DEBUG_LOG("Missing HW timestamp");
|
DEBUG_LOG("Missing TX timestamp");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue