]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: allow wildcard in hwtimestamp directive
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 14 Dec 2016 11:15:32 +0000 (12:15 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 14 Dec 2016 15:19:35 +0000 (16:19 +0100)
If "*" was specified, use getifaddrs() to get a list of all interfaces,
and try to enable HW timestamping on all of them.

doc/chrony.conf.adoc
ntp_io_linux.c

index 88f6b94221adb677be0bbdc519ba8274fc5ac185..8f4598e7c72d1aed796e0e4001eb5969da0f8392 100644 (file)
@@ -1800,6 +1800,9 @@ interfaces. The timestamping used in measurements is indicated in the
 _measurements.log_ file if enabled by the <<log,*log measurements*>> directive,
 and the <<chronyc.adoc#ntpdata,*ntpdata*>> report in *chronyc*.
 +
+If the specified interface is _*_, *chronyd* will try to enable HW timestamping
+on all available interfaces.
++
 An example of the directive is:
 +
 ----
index 9cf791bf59b46e103642f7aa7c4301657b7170fe..8d0eea92a4f670a33c098a369bd0e1e445ffde08 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "sysincl.h"
 
+#include <ifaddrs.h>
 #include <linux/errqueue.h>
 #include <linux/ethtool.h>
 #include <linux/net_tstamp.h>
@@ -90,9 +91,16 @@ add_interface(const char *name)
   struct hwtstamp_config ts_config;
   struct ifreq req;
   int sock_fd, if_index, phc_index, phc_fd;
+  unsigned int i;
   struct Interface *iface;
   char phc_path[64];
 
+  /* Check if the interface was not already added */
+  for (i = 0; i < ARR_GetSize(interfaces); i++) {
+    if (!strcmp(name, ((struct Interface *)ARR_GetElement(interfaces, i))->name))
+      return 1;
+  }
+
   sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
   if (sock_fd < 0)
     return 0;
@@ -160,11 +168,37 @@ add_interface(const char *name)
 
   iface->clock = HCL_CreateInstance();
 
+  DEBUG_LOG(LOGF_NtpIOLinux, "Enabled HW timestamping on %s", name);
+
   return 1;
 }
 
 /* ================================================== */
 
+static int
+add_all_interfaces(void)
+{
+  struct ifaddrs *ifaddr, *ifa;
+  int r;
+
+  if (getifaddrs(&ifaddr)) {
+    DEBUG_LOG(LOGF_NtpIOLinux, "getifaddrs() failed : %s", strerror(errno));
+    return 0;
+  }
+
+  for (r = 0, ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+    if (add_interface(ifa->ifa_name))
+      r = 1;
+  }
+  
+  freeifaddrs(ifaddr);
+
+  /* Return success if at least one interface was added */
+  return r;
+}
+
+/* ================================================== */
+
 static void
 update_interface_speed(struct Interface *iface)
 {
@@ -202,19 +236,34 @@ NIO_Linux_Initialise(void)
   ARR_Instance config_hwts_ifaces;
   char *if_name;
   unsigned int i;
+  int wildcard, hwts;
 
   interfaces = ARR_CreateInstance(sizeof (struct Interface));
 
   config_hwts_ifaces = CNF_GetHwTsInterfaces();
 
-  /* Enable HW timestamping on all specified interfaces.  If no interface was
-     specified, use SW timestamping. */
-  if (ARR_GetSize(config_hwts_ifaces)) {
+  /* Enable HW timestamping on specified interfaces.  If "*" was specified, try
+     all interfaces.  If no interface was specified, enable SW timestamping. */
+
+  for (i = wildcard = 0; i < ARR_GetSize(config_hwts_ifaces); i++) {
+    if (!strcmp("*", *(char **)ARR_GetElement(config_hwts_ifaces, i)))
+      wildcard = 1;
+  }
+
+  if (!wildcard && ARR_GetSize(config_hwts_ifaces)) {
     for (i = 0; i < ARR_GetSize(config_hwts_ifaces); i++) {
       if_name = *(char **)ARR_GetElement(config_hwts_ifaces, i);
       if (!add_interface(if_name))
         LOG_FATAL(LOGF_NtpIO, "Could not enable HW timestamping on %s", if_name);
     }
+    hwts = 1;
+  } else if (wildcard && add_all_interfaces()) {
+    hwts = 1;
+  } else {
+    hwts = 0;
+  }
+
+  if (hwts) {
     ts_flags = SOF_TIMESTAMPING_RAW_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE;
     ts_tx_flags = SOF_TIMESTAMPING_TX_HARDWARE;
   } else {