ntp: check timestamping configuration when SIOCSHWTSTAMP fails
With future kernels it may be possible to get, but not set, the HW timestamping configuration on some specific interfaces like macvlan in containers. This would require the admin to configure the timestamping before starting chronyd. If SIOCSHWTSTAMP failed on an interface, try SIOCGHWTSTAMP to check if the current configuration matches the expected configuration and allow the interface to be used for HW timestamping.
This commit is contained in:
parent
08fd011b6a
commit
69d3913f3e
1 changed files with 23 additions and 12 deletions
|
@ -123,7 +123,7 @@ add_interface(CNF_HwTsInterface *conf_iface)
|
||||||
struct ethtool_ts_info ts_info;
|
struct ethtool_ts_info ts_info;
|
||||||
struct hwtstamp_config ts_config;
|
struct hwtstamp_config ts_config;
|
||||||
struct ifreq req;
|
struct ifreq req;
|
||||||
int sock_fd, if_index, phc_fd, req_hwts_flags;
|
int sock_fd, if_index, phc_fd, req_hwts_flags, rx_filter;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct Interface *iface;
|
struct Interface *iface;
|
||||||
|
|
||||||
|
@ -177,40 +177,51 @@ add_interface(CNF_HwTsInterface *conf_iface)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_config.flags = 0;
|
|
||||||
ts_config.tx_type = HWTSTAMP_TX_ON;
|
|
||||||
|
|
||||||
switch (conf_iface->rxfilter) {
|
switch (conf_iface->rxfilter) {
|
||||||
case CNF_HWTS_RXFILTER_ANY:
|
case CNF_HWTS_RXFILTER_ANY:
|
||||||
#ifdef HAVE_LINUX_TIMESTAMPING_RXFILTER_NTP
|
#ifdef HAVE_LINUX_TIMESTAMPING_RXFILTER_NTP
|
||||||
if (ts_info.rx_filters & (1 << HWTSTAMP_FILTER_NTP_ALL))
|
if (ts_info.rx_filters & (1 << HWTSTAMP_FILTER_NTP_ALL))
|
||||||
ts_config.rx_filter = HWTSTAMP_FILTER_NTP_ALL;
|
rx_filter = HWTSTAMP_FILTER_NTP_ALL;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (ts_info.rx_filters & (1 << HWTSTAMP_FILTER_ALL))
|
if (ts_info.rx_filters & (1 << HWTSTAMP_FILTER_ALL))
|
||||||
ts_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
rx_filter = HWTSTAMP_FILTER_ALL;
|
||||||
else
|
else
|
||||||
ts_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
rx_filter = HWTSTAMP_FILTER_NONE;
|
||||||
break;
|
break;
|
||||||
case CNF_HWTS_RXFILTER_NONE:
|
case CNF_HWTS_RXFILTER_NONE:
|
||||||
ts_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
rx_filter = HWTSTAMP_FILTER_NONE;
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_LINUX_TIMESTAMPING_RXFILTER_NTP
|
#ifdef HAVE_LINUX_TIMESTAMPING_RXFILTER_NTP
|
||||||
case CNF_HWTS_RXFILTER_NTP:
|
case CNF_HWTS_RXFILTER_NTP:
|
||||||
ts_config.rx_filter = HWTSTAMP_FILTER_NTP_ALL;
|
rx_filter = HWTSTAMP_FILTER_NTP_ALL;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ts_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
rx_filter = HWTSTAMP_FILTER_ALL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ts_config.flags = 0;
|
||||||
|
ts_config.tx_type = HWTSTAMP_TX_ON;
|
||||||
|
ts_config.rx_filter = rx_filter;
|
||||||
req.ifr_data = (char *)&ts_config;
|
req.ifr_data = (char *)&ts_config;
|
||||||
|
|
||||||
if (ioctl(sock_fd, SIOCSHWTSTAMP, &req)) {
|
if (ioctl(sock_fd, SIOCSHWTSTAMP, &req)) {
|
||||||
DEBUG_LOG("ioctl(%s) failed : %s", "SIOCSHWTSTAMP", strerror(errno));
|
DEBUG_LOG("ioctl(%s) failed : %s", "SIOCSHWTSTAMP", strerror(errno));
|
||||||
close(sock_fd);
|
|
||||||
return 0;
|
/* Check the current timestamping configuration in case this interface
|
||||||
|
allows only reading of the configuration and it was already configured
|
||||||
|
as requested */
|
||||||
|
req.ifr_data = (char *)&ts_config;
|
||||||
|
#ifdef SIOCGHWTSTAMP
|
||||||
|
if (ioctl(sock_fd, SIOCGHWTSTAMP, &req) ||
|
||||||
|
ts_config.tx_type != HWTSTAMP_TX_ON || ts_config.rx_filter != rx_filter)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
close(sock_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
|
|
Loading…
Reference in a new issue