import linuxptp-3.1.1-1.el8

This commit is contained in:
CentOS Sources 2021-11-09 04:51:38 -05:00 committed by Stepan Oksanichenko
parent 9deacb1901
commit 6302d6bcba
18 changed files with 1046 additions and 1422 deletions

6
.gitignore vendored
View File

@ -1,3 +1,3 @@
SOURCES/clknetsim-8b4842.tar.gz
SOURCES/linuxptp-2.0.tgz
SOURCES/linuxptp-testsuite-a7f6e1.tar.gz
SOURCES/clknetsim-ce3c4a.tar.gz
SOURCES/linuxptp-3.1.1.tgz
SOURCES/linuxptp-testsuite-c66922.tar.gz

View File

@ -1,3 +1,3 @@
b674017c26433870107fb18e160c7d88d7d2eb86 SOURCES/clknetsim-8b4842.tar.gz
592ca42c6146a79c1fcabed7c19fa7af4803d4f6 SOURCES/linuxptp-2.0.tgz
2b8edc55e4967660a0c4a3892c817c0e8f55c3bc SOURCES/linuxptp-testsuite-a7f6e1.tar.gz
338f0be03fd391857adc47306a091952d30d6b89 SOURCES/clknetsim-ce3c4a.tar.gz
f905eabc6fd0f03c6a353f9c4ba188a3bd1b774c SOURCES/linuxptp-3.1.1.tgz
73af42ccc7911c1c2d08fe313cb67329229a5a4b SOURCES/linuxptp-testsuite-c66922.tar.gz

View File

@ -1,12 +0,0 @@
diff -up linuxptp-2.0/util.c.addreq linuxptp-2.0/util.c
--- linuxptp-2.0/util.c.addreq 2019-03-25 11:43:55.878146767 +0100
+++ linuxptp-2.0/util.c 2019-03-25 11:44:38.215244483 +0100
@@ -78,7 +78,7 @@ int addreq(enum transport_type type, str
case TRANS_UDP_IPV4:
bufa = &a->sin.sin_addr;
bufb = &b->sin.sin_addr;
- len = sizeof(a->sin);
+ len = sizeof(a->sin.sin_addr);
break;
case TRANS_IEEE_802_3:
bufa = &a->sll.sll_addr;

View File

@ -0,0 +1,138 @@
Backported commit f774703cb1eee058a346aec3341fee0be329bd6d
Author: Karthikkumar V <kvaloor@altiostar.com>
Date: Fri Feb 26 06:54:07 2021 +0000
Clock Class Threshold Feature addition for PTP4L
This code changes brings in the ability to program the acceptable
clockClass threshold beyond which device will move to holdover/free-run.
Default clockClass threshold is 248.
Example Use-Case:
This is needed in the cases where T-SC/T-BC Slave might want to listen
only on PRC clockCLass and anything beyond that might not be acceptible
and would want to go to holdover (with SyncE backup or internal oscillator).
Signed-off-by: Karthikkumar V <kvaloor@altiostar.com>
Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
diff --git a/clock.c b/clock.c
index c1fcff6..d584748 100644
--- a/clock.c
+++ b/clock.c
@@ -114,6 +114,7 @@ struct clock {
int utc_offset;
int time_flags; /* grand master role */
int time_source; /* grand master role */
+ UInteger8 clock_class_threshold;
UInteger8 max_steps_removed;
enum servo_state servo_state;
enum timestamp_type timestamping;
@@ -978,6 +979,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
c->default_dataset.localPriority =
config_get_int(config, NULL, "G.8275.defaultDS.localPriority");
c->max_steps_removed = config_get_int(config, NULL,"maxStepsRemoved");
+ c->clock_class_threshold = config_get_int(config, NULL, "clock_class_threshold");
/* Harmonize the twoStepFlag with the time_stamping option. */
if (config_harmonize_onestep(config)) {
@@ -1711,6 +1713,11 @@ UInteger8 clock_max_steps_removed(struct clock *c)
return c->max_steps_removed;
}
+UInteger8 clock_get_clock_class_threshold(struct clock *c)
+{
+ return c->clock_class_threshold;
+}
+
UInteger16 clock_steps_removed(struct clock *c)
{
return c->cur.stepsRemoved;
diff --git a/clock.h b/clock.h
index e7daf97..845d54f 100644
--- a/clock.h
+++ b/clock.h
@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c);
*/
UInteger8 clock_max_steps_removed(struct clock *c);
+/**
+ * Obtain the clock class threshold field from a clock's default data set.
+ * @param c The clock instance.
+ * @return Configured clock class threshold value.
+ */
+UInteger8 clock_get_clock_class_threshold(struct clock *c);
+
/**
* Obtain the steps removed field from a clock's current data set.
* @param c The clock instance.
diff --git a/config.c b/config.c
index c3deddb..bf1049f 100644
--- a/config.c
+++ b/config.c
@@ -231,6 +231,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_INT("clockAccuracy", 0xfe, 0, UINT8_MAX),
GLOB_ITEM_INT("clockClass", 248, 0, UINT8_MAX),
GLOB_ITEM_STR("clockIdentity", "000000.0000.000000"),
+ GLOB_ITEM_INT("clock_class_threshold", CLOCK_CLASS_THRESHOLD_DEFAULT, 6, CLOCK_CLASS_THRESHOLD_DEFAULT),
GLOB_ITEM_ENU("clock_servo", CLOCK_SERVO_PI, clock_servo_enu),
GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
diff --git a/configs/default.cfg b/configs/default.cfg
index 9604219..b2ffa94 100644
--- a/configs/default.cfg
+++ b/configs/default.cfg
@@ -60,6 +60,7 @@ verbose 0
summary_interval 0
kernel_leap 1
check_fup_sync 0
+clock_class_threshold 248
#
# Servo Options
#
diff --git a/ds.h b/ds.h
index 9d9c417..dff6d5e 100644
--- a/ds.h
+++ b/ds.h
@@ -87,6 +87,7 @@ struct parent_ds {
#define CURRENT_UTC_OFFSET 37 /* 1 Jan 2017 */
#define INTERNAL_OSCILLATOR 0xA0
+#define CLOCK_CLASS_THRESHOLD_DEFAULT 248
struct timePropertiesDS {
Integer16 currentUtcOffset;
diff --git a/port.c b/port.c
index 2bb974c..eb3b319 100644
--- a/port.c
+++ b/port.c
@@ -1870,6 +1870,14 @@ int process_announce(struct port *p, struct ptp_message *m)
return result;
}
+ if (m->announce.grandmasterClockQuality.clockClass >
+ clock_get_clock_class_threshold(p->clock)) {
+ pl_err(60, "port %hu: Master clock quality received is "
+ "greater than configured, ignoring master!",
+ portnum(p));
+ return result;
+ }
+
switch (p->state) {
case PS_INITIALIZING:
case PS_FAULTY:
diff --git a/ptp4l.8 b/ptp4l.8
index b04936a..ca76175 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -455,6 +455,11 @@ message is greater than or equal to the value of maxStepsRemoved the
Announce message is not considered in the operation of the BMCA.
The default value is 255.
.TP
+.B clock_class_threshold
+The maximum clock class value from master, acceptible to sub-ordinate
+clock beyond which it moves out of lock state.
+The default value is 248.
+.TP
.B domainNumber
The domain attribute of the local clock.

View File

@ -1,94 +0,0 @@
From 4b05d4b5d70c1ba76d95f94f1f4821c4b715fefe Mon Sep 17 00:00:00 2001
From: Richard Cochran <richardcochran@gmail.com>
Date: Sat, 17 Apr 2021 15:15:18 -0700
Subject: [PATCH 2/2] Validate the messageLength field of incoming messages.
The PTP messageLength field is redundant because the length of a PTP
message is precisely determined by the message type and the appended
TLVs. The current implementation validates the sizes of both the main
message (according to the fixed header length and fixed length by
type) and the TLVs (by using the 'L' of the TLV).
However, when forwarding a message, the messageLength field is used.
If a message arrives with a messageLength field larger than the actual
message size, the code will read and possibly write data beyond the
allocated buffer.
Fix the issue by validating the field on ingress. This prevents
reading and sending data past the message buffer when forwarding a
management message or other messages when operating as a transparent
clock, and it also prevents a memory corruption in msg_post_recv()
after forwarding a management message.
Reported-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
msg.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/msg.c b/msg.c
index dcb397c..c2d358b 100644
--- a/msg.c
+++ b/msg.c
@@ -184,7 +184,7 @@ static int suffix_post_recv(struct ptp_message *msg, int len)
{
uint8_t *ptr = msg_suffix(msg);
struct tlv_extra *extra;
- int err;
+ int err, suffix_len = 0;
if (!ptr)
return 0;
@@ -202,12 +202,14 @@ static int suffix_post_recv(struct ptp_message *msg, int len)
tlv_extra_recycle(extra);
return -EBADMSG;
}
+ suffix_len += sizeof(struct TLV);
len -= sizeof(struct TLV);
ptr += sizeof(struct TLV);
if (extra->tlv->length > len) {
tlv_extra_recycle(extra);
return -EBADMSG;
}
+ suffix_len += extra->tlv->length;
len -= extra->tlv->length;
ptr += extra->tlv->length;
err = tlv_post_recv(extra);
@@ -217,7 +219,7 @@ static int suffix_post_recv(struct ptp_message *msg, int len)
}
msg_tlv_attach(msg, extra);
}
- return 0;
+ return suffix_len;
}
static void suffix_pre_send(struct ptp_message *msg)
@@ -335,7 +337,7 @@ void msg_get(struct ptp_message *m)
int msg_post_recv(struct ptp_message *m, int cnt)
{
- int pdulen, type, err;
+ int err, pdulen, suffix_len, type;
if (cnt < sizeof(struct ptp_header))
return -EBADMSG;
@@ -420,9 +422,13 @@ int msg_post_recv(struct ptp_message *m, int cnt)
break;
}
- err = suffix_post_recv(m, cnt - pdulen);
- if (err)
- return err;
+ suffix_len = suffix_post_recv(m, cnt - pdulen);
+ if (suffix_len < 0) {
+ return suffix_len;
+ }
+ if (pdulen + suffix_len != m->header.messageLength) {
+ return -EBADMSG;
+ }
return 0;
}
--
2.20.1

View File

@ -0,0 +1,82 @@
commit 1a2dfe9b00b79a59acf905476bbc33c74d5770a3
Author: Jacob Keller <jacob.e.keller@intel.com>
Date: Thu Jul 8 12:59:30 2021 -0700
Increase the default tx_timestamp_timeout to 10
The tx_timestamp_timeout configuration defines the number of
milliseconds to wait for a Tx timestamp from the kernel stack. This
delay is necessary as Tx timestamps are captured after a packet is sent
and reported back via the socket error queue.
The current default is to poll for up to 1 millisecond. In practice, it
turns out that this is not always enough time for hardware and software
to capture the timestamp and report it back. Some hardware designs
require reading timestamps over registers or other slow mechanisms.
This extra delay results in the timestamp not being sent back to
userspace within the default 1 millisecond polling time. If that occurs
the following can be seen from ptp4l:
ptp4l[4756.840]: timed out while polling for tx timestamp
ptp4l[4756.840]: increasing tx_timestamp_timeout may correct this issue,
but it is likely caused by a driver bug
ptp4l[4756.840]: port 1 (p2p1): send sync failed
ptp4l[4756.840]: port 1 (p2p1): MASTER to FAULTY on FAULT_DETECTED
(FT_UNSPECIFIED)
This can confuse users because it implies this is a bug, when the
correct solution in many cases is to just increase the timeout to
a slightly higher value.
Since we know this is a problem for many drivers and hardware designs,
lets increase the default timeout.
Note that a longer timeout should not affect setups which return the
timestamp quickly. On modern kernels, the poll() call will return once
the timestamp is reported back to the socket error queue. (On old
kernels around the 3.x era the poll will sleep for the full duration
before reporting the timestamp, but this is now quite an old kernel
release).
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
diff --git a/config.c b/config.c
index 760b395..03d981e 100644
--- a/config.c
+++ b/config.c
@@ -324,7 +324,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_INT("ts2phc.pulsewidth", 500000000, 1000000, 999000000),
PORT_ITEM_ENU("tsproc_mode", TSPROC_FILTER, tsproc_enu),
GLOB_ITEM_INT("twoStepFlag", 1, 0, 1),
- GLOB_ITEM_INT("tx_timestamp_timeout", 1, 1, INT_MAX),
+ GLOB_ITEM_INT("tx_timestamp_timeout", 10, 1, INT_MAX),
PORT_ITEM_INT("udp_ttl", 1, 1, 255),
PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F),
GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"),
diff --git a/configs/default.cfg b/configs/default.cfg
index 64ef3bd..d615610 100644
--- a/configs/default.cfg
+++ b/configs/default.cfg
@@ -51,7 +51,7 @@ hybrid_e2e 0
inhibit_multicast_service 0
net_sync_monitor 0
tc_spanning_tree 0
-tx_timestamp_timeout 1
+tx_timestamp_timeout 10
unicast_listen 0
unicast_master_table 0
unicast_req_duration 3600
diff --git a/ptp4l.8 b/ptp4l.8
index fe9e150..7ca3474 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -496,7 +496,7 @@ switches all implement this option together with the BMCA.
.B tx_timestamp_timeout
The number of milliseconds to poll waiting for the tx time stamp from the kernel
when a message has recently been sent.
-The default is 1.
+The default is 10.
.TP
.B check_fup_sync
Because of packet reordering that can occur in the network, in the

View File

@ -0,0 +1,22 @@
commit e8a82d1b5be2d5bf9450a9acfe44e957b4867870
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Jul 20 11:41:35 2021 +0200
lstab: Close file after reading.
The lstab_read() function opens a file, but doesn't close it after use.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/lstab.c b/lstab.c
index e6e7ad2..0d6a427 100644
--- a/lstab.c
+++ b/lstab.c
@@ -144,6 +144,7 @@ static int lstab_read(struct lstab *lstab, const char *name)
index++;
}
}
+ fclose(fp);
if (!lstab->expiration_utc) {
fprintf(stderr, "missing expiration date in '%s'\n", name);
return -1;

View File

@ -1,51 +0,0 @@
commit d663a483c40939bad58301c256d86da1f3da6cc0
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Nov 13 13:16:08 2018 +0100
Fix building with new kernel headers.
net_tstamp.h in recent kernel versions requires time.h for clockid_t.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/clock.c b/clock.c
index 9c493c3..8533b39 100644
--- a/clock.c
+++ b/clock.c
@@ -17,11 +17,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <errno.h>
+#include <time.h>
#include <linux/net_tstamp.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include <sys/queue.h>
#include "address.h"
diff --git a/sk.c b/sk.c
index e2b1f28..30162eb 100644
--- a/sk.c
+++ b/sk.c
@@ -18,6 +18,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <errno.h>
+#include <time.h>
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
diff --git a/timemaster.c b/timemaster.c
index 058678f..00db59f 100644
--- a/timemaster.c
+++ b/timemaster.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <libgen.h>
#include <limits.h>
+#include <time.h>
#include <linux/net_tstamp.h>
#include <net/if.h>
#include <signal.h>

View File

@ -1,228 +0,0 @@
commit 399907db7f9dc3f57c3f9831b3b4da705a2c51a3
Author: Erez Geva <erezgeva2@gmail.com>
Date: Tue Aug 28 22:05:28 2018 +0200
config: Add hardware time stamp filter setting mode
Add global option for the hardware time stamp setting.
The function could:
Normally set the filters as the PTP daemon require.
Check that the filters are proper but do not change them.
Full, set the RX filter to all and the TX filter as the PTP daemon require.
[ RC: added missing extern keyword and fixed indentation. ]
Signed-off-by: Erez Geva <erez.geva.ext@siemens.com>
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
diff --git a/config.c b/config.c
index 7914ba4..3530ce6 100644
--- a/config.c
+++ b/config.c
@@ -164,6 +164,13 @@ static struct config_enum delay_mech_enu[] = {
{ NULL, 0 },
};
+static struct config_enum hwts_filter_enu[] = {
+ { "normal", HWTS_FILTER_NORMAL },
+ { "check", HWTS_FILTER_CHECK },
+ { "full", HWTS_FILTER_FULL },
+ { NULL, 0 },
+};
+
static struct config_enum nw_trans_enu[] = {
{ "L2", TRANS_IEEE_802_3 },
{ "UDPv4", TRANS_UDP_IPV4 },
@@ -215,6 +222,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_INT("G.8275.defaultDS.localPriority", 128, 1, UINT8_MAX),
PORT_ITEM_INT("G.8275.portDS.localPriority", 128, 1, UINT8_MAX),
GLOB_ITEM_INT("gmCapable", 1, 0, 1),
+ GLOB_ITEM_ENU("hwts_filter", HWTS_FILTER_NORMAL, hwts_filter_enu),
PORT_ITEM_INT("hybrid_e2e", 0, 0, 1),
PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1),
PORT_ITEM_INT("ingressLatency", 0, INT_MIN, INT_MAX),
diff --git a/ptp4l.8 b/ptp4l.8
index 10c5c2f..39bf36e 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -661,6 +661,15 @@ The time source is a single byte code that gives an idea of the kind
of local clock in use. The value is purely informational, having no
effect on the outcome of the Best Master Clock algorithm, and is
advertised when the clock becomes grand master.
+.TP
+.B hwts_filter
+Select the hardware time stamp filter setting mode.
+Possible values are normal, check, full.
+Normal mode set the filters as needed.
+Check mode only check but do not set.
+Full mode set the receive filter to mark all packets with hardware time stamp,
+ so all applications can get them.
+The default is normal.
.SH UNICAST DISCOVERY OPTIONS
diff --git a/ptp4l.c b/ptp4l.c
index 9ef8169..3a9f084 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -191,6 +191,7 @@ int main(int argc, char *argv[])
assume_two_step = config_get_int(cfg, NULL, "assume_two_step");
sk_check_fupsync = config_get_int(cfg, NULL, "check_fup_sync");
sk_tx_timeout = config_get_int(cfg, NULL, "tx_timestamp_timeout");
+ sk_hwts_filter_mode = config_get_int(cfg, NULL, "hwts_filter");
if (config_get_int(cfg, NULL, "clock_servo") == CLOCK_SERVO_NTPSHM) {
config_set_int(cfg, "kernel_leap", 0);
diff --git a/sk.c b/sk.c
index f18b2bf..43f1800 100644
--- a/sk.c
+++ b/sk.c
@@ -40,39 +40,76 @@
int sk_tx_timeout = 1;
int sk_check_fupsync;
+enum hwts_filter_mode sk_hwts_filter_mode = HWTS_FILTER_NORMAL;
/* private methods */
-static int hwts_init(int fd, const char *device, int rx_filter, int tx_type)
+static void init_ifreq(struct ifreq *ifreq, struct hwtstamp_config *cfg,
+ const char *device)
{
- struct ifreq ifreq;
- struct hwtstamp_config cfg, req;
- int err;
+ memset(ifreq, 0, sizeof(*ifreq));
+ memset(cfg, 0, sizeof(*cfg));
- memset(&ifreq, 0, sizeof(ifreq));
- memset(&cfg, 0, sizeof(cfg));
+ strncpy(ifreq->ifr_name, device, sizeof(ifreq->ifr_name) - 1);
- strncpy(ifreq.ifr_name, device, sizeof(ifreq.ifr_name) - 1);
+ ifreq->ifr_data = (void *) cfg;
+}
- ifreq.ifr_data = (void *) &cfg;
- cfg.tx_type = tx_type;
- cfg.rx_filter = rx_filter;
- req = cfg;
- err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
- if (err < 0)
- return err;
+static int hwts_init(int fd, const char *device, int rx_filter,
+ int rx_filter2, int tx_type)
+{
+ struct ifreq ifreq;
+ struct hwtstamp_config cfg;
+ int err;
- if (memcmp(&cfg, &req, sizeof(cfg))) {
+ init_ifreq(&ifreq, &cfg, device);
- pr_debug("driver changed our HWTSTAMP options");
- pr_debug("tx_type %d not %d", cfg.tx_type, req.tx_type);
- pr_debug("rx_filter %d not %d", cfg.rx_filter, req.rx_filter);
+ switch (sk_hwts_filter_mode) {
+ case HWTS_FILTER_CHECK:
+ err = ioctl(fd, SIOCGHWTSTAMP, &ifreq);
+ if (err < 0) {
+ pr_err("ioctl SIOCGHWTSTAMP failed: %m");
+ return err;
+ }
+ break;
+ case HWTS_FILTER_FULL:
+ cfg.tx_type = tx_type;
+ cfg.rx_filter = HWTSTAMP_FILTER_ALL;
+ err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
+ if (err < 0) {
+ pr_err("ioctl SIOCSHWTSTAMP failed: %m");
+ return err;
+ }
+ break;
+ case HWTS_FILTER_NORMAL:
+ cfg.tx_type = tx_type;
+ cfg.rx_filter = rx_filter;
+ err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
+ if (err < 0) {
+ pr_info("driver rejected most general HWTSTAMP filter");
- if (cfg.tx_type != req.tx_type ||
- (cfg.rx_filter != HWTSTAMP_FILTER_ALL &&
- cfg.rx_filter != HWTSTAMP_FILTER_PTP_V2_EVENT)) {
- return -1;
+ init_ifreq(&ifreq, &cfg, device);
+ cfg.tx_type = tx_type;
+ cfg.rx_filter = rx_filter2;
+
+ err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
+ if (err < 0) {
+ pr_err("ioctl SIOCSHWTSTAMP failed: %m");
+ return err;
+ }
}
+ break;
+ }
+
+ if (cfg.tx_type != tx_type ||
+ (cfg.rx_filter != rx_filter &&
+ cfg.rx_filter != rx_filter2 &&
+ cfg.rx_filter != HWTSTAMP_FILTER_ALL)) {
+ pr_debug("tx_type %d not %d", cfg.tx_type, tx_type);
+ pr_debug("rx_filter %d not %d or %d", cfg.rx_filter, rx_filter,
+ rx_filter2);
+ pr_err("The current filter does not match the required");
+ return -1;
}
return 0;
@@ -450,15 +487,9 @@ int sk_timestamping_init(int fd, const char *device, enum timestamp_type type,
case TRANS_UDS:
return -1;
}
- err = hwts_init(fd, device, filter1, tx_type);
- if (err) {
- pr_info("driver rejected most general HWTSTAMP filter");
- err = hwts_init(fd, device, filter2, tx_type);
- if (err) {
- pr_err("ioctl SIOCSHWTSTAMP failed: %m");
- return err;
- }
- }
+ err = hwts_init(fd, device, filter1, filter2, tx_type);
+ if (err)
+ return err;
}
if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
diff --git a/sk.h b/sk.h
index d91d5d8..fd4d820 100644
--- a/sk.h
+++ b/sk.h
@@ -23,6 +23,16 @@
#include "address.h"
#include "transport.h"
+/**
+ * Defines the available Hardware time-stamp setting modes.
+ */
+
+enum hwts_filter_mode {
+ HWTS_FILTER_NORMAL, /* set hardware filters in normal way */
+ HWTS_FILTER_CHECK, /* check filters but do not change them */
+ HWTS_FILTER_FULL, /* Use time-stamp on all received packets */
+};
+
/**
* Contains timestamping information returned by the GET_TS_INFO ioctl.
* @valid: set to non-zero when the info struct contains valid data.
@@ -131,4 +141,9 @@ extern int sk_tx_timeout;
*/
extern int sk_check_fupsync;
+/**
+ * Hardware time-stamp setting mode
+ */
+extern enum hwts_filter_mode sk_hwts_filter_mode;
+
#endif

View File

@ -0,0 +1,96 @@
commit 3399fa15ae28610c1b288b573c4233a42c48f762
Author: Amar Subramanyam via Linuxptp-devel <linuxptp-devel@lists.sourceforge.net>
Date: Wed May 26 12:24:06 2021 +0300
Log optimization for ptp4l in jbod and client only mode (clientOnly=1 and boundary_clock_jbod=1)
The LISTENING port prints continuously
"selected best master clock 000000.0000.000003
updating UTC offset to 37"
We limited the log such that now it prints only when there is a
change in the best-master clock.
Signed-off-by: Amar Subramanyam <asubramanyam@altiostar.com>
Signed-off-by: Karthikkumar Valoor <kvaloor@altiostar.com>
Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
diff --git a/clock.c b/clock.c
index e545a9b..d428ae2 100644
--- a/clock.c
+++ b/clock.c
@@ -705,7 +705,8 @@ static void clock_update_slave(struct clock *c)
if (c->tds.currentUtcOffset < c->utc_offset) {
pr_warning("running in a temporal vortex");
}
- if ((c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE) ||
+ if (((c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE) &&
+ (c->tds.currentUtcOffset != c->utc_offset)) ||
(c->tds.currentUtcOffset > c->utc_offset)) {
pr_info("updating UTC offset to %d", c->tds.currentUtcOffset);
c->utc_offset = c->tds.currentUtcOffset;
@@ -1939,14 +1940,6 @@ static void handle_state_decision_event(struct clock *c)
best_id = c->dds.clockIdentity;
}
- if (cid_eq(&best_id, &c->dds.clockIdentity)) {
- pr_notice("selected local clock %s as best master",
- cid2str(&best_id));
- } else {
- pr_notice("selected best master clock %s",
- cid2str(&best_id));
- }
-
if (!cid_eq(&best_id, &c->best_id)) {
clock_freq_est_reset(c);
tsproc_reset(c->tsproc, 1);
@@ -1957,6 +1950,13 @@ static void handle_state_decision_event(struct clock *c)
c->master_local_rr = 1.0;
c->nrr = 1.0;
fresh_best = 1;
+ if (cid_eq(&best_id, &c->dds.clockIdentity)) {
+ pr_notice("selected local clock %s as best master",
+ cid2str(&best_id));
+ } else {
+ pr_notice("selected best master clock %s",
+ cid2str(&best_id));
+ }
}
c->best = best;
commit 766baf345cd4fb025d186f9c9bea5276aba398bc
Author: Amar Subramanyam via Linuxptp-devel <linuxptp-devel@lists.sourceforge.net>
Date: Wed May 26 12:24:07 2021 +0300
Log optimization for ptp4l in jbod and client only mode (clientOnly=1 and boundary_clock_jbod=1)
The port other than SLAVE (LISTENING port) prints an error
"port 1: master state recommended in slave only mode
ptp4l[1205469.356]: port 1: defaultDS.priority1 probably misconfigured"
for every ANNOUNCE RECEIPT Timeout.
This log is printed when the event EV_RS_MASTER is thrown
in clientOnly mode. But single port clientOnly mode will never
hit this event instead EV_RS_GRAND_MASTER will be hit.
EV_RS_MASTER is thrown when clientOnly=1 and boundary_clock_jbod=1
which results in continuous printing. So EV_RS_MASTER check when
clientOnly=1 to print this error can be avoided.
Signed-off-by: Amar Subramanyam <asubramanyam@altiostar.com>
Signed-off-by: Karthikkumar Valoor <kvaloor@altiostar.com>
Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
diff --git a/port.c b/port.c
index 250d46d..b5b775f 100644
--- a/port.c
+++ b/port.c
@@ -2536,7 +2536,7 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
static void bc_dispatch(struct port *p, enum fsm_event event, int mdiff)
{
if (clock_slave_only(p->clock)) {
- if (event == EV_RS_MASTER || event == EV_RS_GRAND_MASTER) {
+ if (event == EV_RS_GRAND_MASTER) {
port_slave_priority_warning(p);
}
}

View File

@ -0,0 +1,28 @@
commit 0b80e32829ca7430be851fc64c4812896ad97c88
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Jul 19 17:09:01 2021 +0200
Fix quoting in ptp4l man page.
In the groff syntax lines starting with a dot or quote are requests. A
line in the servo_offset_threshold description starts with a quote,
which breaks the output. Move a word to the beginning of the line to fix
it.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/ptp4l.8 b/ptp4l.8
index 7ca3474..a0779ef 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -788,8 +788,8 @@ The default value is 10.
.TP
.B servo_offset_threshold
The offset threshold used in order to transition from the SERVO_LOCKED
-to the SERVO_LOCKED_STABLE state. The transition occurs once the last
-'servo_num_offset_values' offsets are all below the threshold value.
+to the SERVO_LOCKED_STABLE state. The transition occurs once the
+last 'servo_num_offset_values' offsets are all below the threshold value.
The default value of offset_threshold is 0 (disabled).
.TP
.B slave_event_monitor

View File

@ -1,20 +0,0 @@
commit 86723cfc6a7ac1d9b1bff5e90b7f4696d6460a0e
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Mar 21 17:12:03 2019 +0100
pmc: Don't leak memory when msg_tlv_append() fails.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/pmc_common.c b/pmc_common.c
index 4a160f6..4d48e3a 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -546,6 +546,7 @@ int pmc_send_set_action(struct pmc *pmc, int id, void *data, int datasize)
}
extra = msg_tlv_append(msg, sizeof(*mgt) + datasize);
if (!extra) {
+ msg_put(msg);
return -ENOMEM;
}
mgt = (struct management_tlv *) extra->tlv;

View File

@ -1,486 +0,0 @@
commit c0e49c708814ec783726fe92202371847703c5ed
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Nov 12 17:27:58 2018 +0100
sysoff: Initialize data for ioctl(PTP_SYS_OFFSET).
This fixes valgrind errors.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/sysoff.c b/sysoff.c
index f7b6240..407a01c 100644
--- a/sysoff.c
+++ b/sysoff.c
@@ -18,6 +18,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
+#include <string.h>
#include <sys/ioctl.h>
#include <linux/ptp_clock.h>
@@ -76,6 +77,7 @@ int sysoff_measure(int fd, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay)
{
struct ptp_sys_offset pso;
+ memset(&pso, 0, sizeof(pso));
pso.n_samples = n_samples;
if (ioctl(fd, PTP_SYS_OFFSET, &pso)) {
perror("ioctl PTP_SYS_OFFSET");
commit 93baf34adb81046a5e1c3b9a3e685029f2046993
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Nov 12 17:27:59 2018 +0100
sysoff: Extend API for different sysoff methods.
The kernel supports different PTP_SYS_OFFSET* ioctls. Use the sysoff
enum to allow selecting between them in sysoff_measure().
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/phc2sys.c b/phc2sys.c
index 15f8d75..2cd477a 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -74,7 +74,7 @@ struct clock {
LIST_ENTRY(clock) dst_list;
clockid_t clkid;
int phc_index;
- int sysoff_supported;
+ int sysoff_method;
int is_utc;
int dest_only;
int state;
@@ -255,9 +255,8 @@ static struct clock *clock_add(struct node *node, char *device)
c->servo = servo_add(node, c);
if (clkid != CLOCK_INVALID && clkid != CLOCK_REALTIME)
- c->sysoff_supported = (SYSOFF_SUPPORTED ==
- sysoff_probe(CLOCKID_TO_FD(clkid),
- node->phc_readings));
+ c->sysoff_method = sysoff_probe(CLOCKID_TO_FD(clkid),
+ node->phc_readings);
LIST_INSERT_HEAD(&node->clocks, c, list);
return c;
@@ -784,11 +783,12 @@ static int do_loop(struct node *node, int subscriptions)
continue;
if (clock->clkid == CLOCK_REALTIME &&
- node->master->sysoff_supported) {
+ node->master->sysoff_method >= 0) {
/* use sysoff */
if (sysoff_measure(CLOCKID_TO_FD(node->master->clkid),
+ node->master->sysoff_method,
node->phc_readings,
- &offset, &ts, &delay))
+ &offset, &ts, &delay) < 0)
return -1;
} else {
/* use phc */
diff --git a/phc_ctl.c b/phc_ctl.c
index 4a78a19..b9a9cf4 100644
--- a/phc_ctl.c
+++ b/phc_ctl.c
@@ -367,10 +367,12 @@ static int do_cmp(clockid_t clkid, int cmdc, char *cmdv[])
struct timespec ts, rta, rtb;
int64_t sys_offset, delay = 0, offset;
uint64_t sys_ts;
+ int method;
- if (SYSOFF_SUPPORTED ==
- sysoff_measure(CLOCKID_TO_FD(clkid),
- 9, &sys_offset, &sys_ts, &delay)) {
+ method = sysoff_probe(CLOCKID_TO_FD(clkid), 9);
+
+ if (method >= 0 && sysoff_measure(CLOCKID_TO_FD(clkid), method, 9,
+ &sys_offset, &sys_ts, &delay) >= 0) {
pr_notice( "offset from CLOCK_REALTIME is %"PRId64"ns\n",
sys_offset);
return 0;
diff --git a/sysoff.c b/sysoff.c
index 407a01c..f709a9b 100644
--- a/sysoff.c
+++ b/sysoff.c
@@ -73,8 +73,8 @@ static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
return samples[0].offset;
}
-int sysoff_measure(int fd, int n_samples,
- int64_t *result, uint64_t *ts, int64_t *delay)
+static int sysoff_basic(int fd, int n_samples,
+ int64_t *result, uint64_t *ts, int64_t *delay)
{
struct ptp_sys_offset pso;
memset(&pso, 0, sizeof(pso));
@@ -84,13 +84,24 @@ int sysoff_measure(int fd, int n_samples,
return SYSOFF_RUN_TIME_MISSING;
}
*result = sysoff_estimate(pso.ts, n_samples, ts, delay);
- return SYSOFF_SUPPORTED;
+ return SYSOFF_BASIC;
+}
+
+int sysoff_measure(int fd, int method, int n_samples,
+ int64_t *result, uint64_t *ts, int64_t *delay)
+{
+ switch (method) {
+ case SYSOFF_BASIC:
+ return sysoff_basic(fd, n_samples, result, ts, delay);
+ }
+ return SYSOFF_COMPILE_TIME_MISSING;
}
int sysoff_probe(int fd, int n_samples)
{
int64_t junk, delay;
uint64_t ts;
+ int i;
if (n_samples > PTP_MAX_SAMPLES) {
fprintf(stderr, "warning: %d exceeds kernel max readings %d\n",
@@ -99,7 +110,13 @@ int sysoff_probe(int fd, int n_samples)
return SYSOFF_RUN_TIME_MISSING;
}
- return sysoff_measure(fd, n_samples, &junk, &ts, &delay);
+ for (i = 0; i < SYSOFF_LAST; i++) {
+ if (sysoff_measure(fd, i, n_samples, &junk, &ts, &delay) < 0)
+ continue;
+ return i;
+ }
+
+ return SYSOFF_RUN_TIME_MISSING;
}
#else /* !PTP_SYS_OFFSET */
diff --git a/sysoff.h b/sysoff.h
index cb70265..02ecdfa 100644
--- a/sysoff.h
+++ b/sysoff.h
@@ -21,13 +21,14 @@
#include <stdint.h>
enum {
- SYSOFF_SUPPORTED,
- SYSOFF_COMPILE_TIME_MISSING,
- SYSOFF_RUN_TIME_MISSING,
+ SYSOFF_COMPILE_TIME_MISSING = -2,
+ SYSOFF_RUN_TIME_MISSING = -1,
+ SYSOFF_BASIC,
+ SYSOFF_LAST,
};
/**
- * Check to see if the PTP_SYS_OFFSET ioctl is supported.
+ * Check to see if a PTP_SYS_OFFSET ioctl is supported.
* @param fd An open file descriptor to a PHC device.
* @return One of the SYSOFF_ enumeration values.
*/
@@ -36,11 +37,12 @@ int sysoff_probe(int fd, int n_samples);
/**
* Measure the offset between a PHC and the system time.
* @param fd An open file descriptor to a PHC device.
+ * @param method A non-negative SYSOFF_ value returned by sysoff_probe().
* @param n_samples The number of consecutive readings to make.
* @param result The estimated offset in nanoseconds.
* @param ts The system time corresponding to the 'result'.
* @param delay The delay in reading of the clock in nanoseconds.
* @return One of the SYSOFF_ enumeration values.
*/
-int sysoff_measure(int fd, int n_samples,
+int sysoff_measure(int fd, int method, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay);
commit 192b8e315c4585489d7aa7f59683035998805e40
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Nov 12 17:28:00 2018 +0100
sysoff: Add support for PTP_SYS_OFFSET_PRECISE ioctl.
This ioctl uses cross timestamping for a more accurate measurement of
the offset. It is supported on some onboard Intel NICs using the e1000e
driver and a virtual PHC with the ptp_kvm driver.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/sysoff.c b/sysoff.c
index f709a9b..9f65d95 100644
--- a/sysoff.c
+++ b/sysoff.c
@@ -22,6 +22,7 @@
#include <sys/ioctl.h>
#include <linux/ptp_clock.h>
+#include "print.h"
#include "sysoff.h"
#define NS_PER_SEC 1000000000LL
@@ -39,6 +40,23 @@ static struct {
uint64_t timestamp;
} samples[PTP_MAX_SAMPLES];
+static int sysoff_precise(int fd, int64_t *result, uint64_t *ts)
+{
+#ifdef PTP_SYS_OFFSET_PRECISE
+ struct ptp_sys_offset_precise pso;
+ memset(&pso, 0, sizeof(pso));
+ if (ioctl(fd, PTP_SYS_OFFSET_PRECISE, &pso)) {
+ pr_debug("ioctl PTP_SYS_OFFSET_PRECISE: %m");
+ return SYSOFF_RUN_TIME_MISSING;
+ }
+ *result = pctns(&pso.sys_realtime) - pctns(&pso.device);
+ *ts = pctns(&pso.sys_realtime);
+ return SYSOFF_PRECISE;
+#else
+ return SYSOFF_COMPILE_TIME_MISSING;
+#endif
+}
+
static void insertion_sort(int length, int64_t interval, int64_t offset, uint64_t ts)
{
int i = length - 1;
@@ -91,6 +109,9 @@ int sysoff_measure(int fd, int method, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay)
{
switch (method) {
+ case SYSOFF_PRECISE:
+ *delay = 0;
+ return sysoff_precise(fd, result, ts);
case SYSOFF_BASIC:
return sysoff_basic(fd, n_samples, result, ts, delay);
}
diff --git a/sysoff.h b/sysoff.h
index 02ecdfa..37f7353 100644
--- a/sysoff.h
+++ b/sysoff.h
@@ -23,6 +23,7 @@
enum {
SYSOFF_COMPILE_TIME_MISSING = -2,
SYSOFF_RUN_TIME_MISSING = -1,
+ SYSOFF_PRECISE,
SYSOFF_BASIC,
SYSOFF_LAST,
};
commit 68a9011c9d7d859920da339ba59c14dc1d617a45
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Nov 12 17:28:01 2018 +0100
sysoff: Add support for PTP_SYS_OFFSET_EXTENDED ioctl.
This is a more accurate variant of the the PTP_SYS_OFFSET ioctl, which
will probably be supported in future kernel versions.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/sysoff.c b/sysoff.c
index 9f65d95..b993ee9 100644
--- a/sysoff.c
+++ b/sysoff.c
@@ -71,17 +71,23 @@ static void insertion_sort(int length, int64_t interval, int64_t offset, uint64_
samples[i+1].timestamp = ts;
}
-static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
- uint64_t *ts, int64_t *delay)
+static int64_t sysoff_estimate(struct ptp_clock_time *pct, int extended,
+ int n_samples, uint64_t *ts, int64_t *delay)
{
int64_t t1, t2, tp;
int64_t interval, offset;
int i;
for (i = 0; i < n_samples; i++) {
- t1 = pctns(&pct[2*i]);
- tp = pctns(&pct[2*i+1]);
- t2 = pctns(&pct[2*i+2]);
+ if (extended) {
+ t1 = pctns(&pct[3*i]);
+ tp = pctns(&pct[3*i+1]);
+ t2 = pctns(&pct[3*i+2]);
+ } else {
+ t1 = pctns(&pct[2*i]);
+ tp = pctns(&pct[2*i+1]);
+ t2 = pctns(&pct[2*i+2]);
+ }
interval = t2 - t1;
offset = (t2 + t1) / 2 - tp;
insertion_sort(i, interval, offset, (t2 + t1) / 2);
@@ -91,6 +97,24 @@ static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples,
return samples[0].offset;
}
+static int sysoff_extended(int fd, int n_samples,
+ int64_t *result, uint64_t *ts, int64_t *delay)
+{
+#ifdef PTP_SYS_OFFSET_EXTENDED
+ struct ptp_sys_offset_extended pso;
+ memset(&pso, 0, sizeof(pso));
+ pso.n_samples = n_samples;
+ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, &pso)) {
+ pr_debug("ioctl PTP_SYS_OFFSET_EXTENDED: %m");
+ return SYSOFF_RUN_TIME_MISSING;
+ }
+ *result = sysoff_estimate(&pso.ts[0][0], 1, n_samples, ts, delay);
+ return SYSOFF_EXTENDED;
+#else
+ return SYSOFF_COMPILE_TIME_MISSING;
+#endif
+}
+
static int sysoff_basic(int fd, int n_samples,
int64_t *result, uint64_t *ts, int64_t *delay)
{
@@ -101,7 +125,7 @@ static int sysoff_basic(int fd, int n_samples,
perror("ioctl PTP_SYS_OFFSET");
return SYSOFF_RUN_TIME_MISSING;
}
- *result = sysoff_estimate(pso.ts, n_samples, ts, delay);
+ *result = sysoff_estimate(pso.ts, 0, n_samples, ts, delay);
return SYSOFF_BASIC;
}
@@ -112,6 +136,8 @@ int sysoff_measure(int fd, int method, int n_samples,
case SYSOFF_PRECISE:
*delay = 0;
return sysoff_precise(fd, result, ts);
+ case SYSOFF_EXTENDED:
+ return sysoff_extended(fd, n_samples, result, ts, delay);
case SYSOFF_BASIC:
return sysoff_basic(fd, n_samples, result, ts, delay);
}
diff --git a/sysoff.h b/sysoff.h
index 37f7353..79d2290 100644
--- a/sysoff.h
+++ b/sysoff.h
@@ -24,6 +24,7 @@ enum {
SYSOFF_COMPILE_TIME_MISSING = -2,
SYSOFF_RUN_TIME_MISSING = -1,
SYSOFF_PRECISE,
+ SYSOFF_EXTENDED,
SYSOFF_BASIC,
SYSOFF_LAST,
};
commit 8142da41b61fb5b9ee4ad8f5ab56adb0447cd37b
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Nov 12 17:28:02 2018 +0100
phc2sys: Use reversed sysoff when synchronizing to system clock.
If synchronizing a PHC to the system clock, use one of the
PTP_SYS_OFFSET ioctls (if supported) to measure the offset between the
two clocks. Negate the offset and switch the timestamp before passing
them to the servo.
This makes the synchronization between PHC and system clock symmetric.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/phc2sys.c b/phc2sys.c
index 2cd477a..b8f1ea0 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -790,6 +790,16 @@ static int do_loop(struct node *node, int subscriptions)
node->phc_readings,
&offset, &ts, &delay) < 0)
return -1;
+ } else if (node->master->clkid == CLOCK_REALTIME &&
+ clock->sysoff_method >= 0) {
+ /* use reversed sysoff */
+ if (sysoff_measure(CLOCKID_TO_FD(clock->clkid),
+ clock->sysoff_method,
+ node->phc_readings,
+ &offset, &ts, &delay) < 0)
+ return -1;
+ ts += offset;
+ offset = -offset;
} else {
/* use phc */
if (!read_phc(node->master->clkid, clock->clkid,
commit e0580929f451e685d92cd10d80b76f39e9b09a97
Author: Richard Cochran <richardcochran@gmail.com>
Date: Tue Dec 24 11:09:34 2019 -0800
phc2sys: Fix frequency estimation when synchronizing a PHC to the system clock.
When synchronizing a PHC to the Linux system clock (CLOCK_REALTIME),
the phc2sys uses the sysoff method, reversing the master and slave
roles.
The offset between a master clock and a slave clock is given by
offset = slave_ts - master_ts,
and the call to sysoff_measure() provides the 'offset' and 'slave_ts'
values. The needed local time stamp on the 'master' is given by
master_ts = slave_ts - offset,
but the code calcuates
master_ts = slave_ts + offset.
When passed to the servo, the local time stamp is used to estimate the
frequency offset between the two clocks before starting the main
synchronization loop. The effect of the bug may be seen with a simple
test. Here is a sample output with the existing code.
$ sudo testptp -d /dev/ptp1 -f 62400000
frequency adjustment okay
$ sudo ./phc2sys -m -q -c eth6 -s CLOCK_REALTIME -O0
phc2sys[90221.239]: eth6 sys offset 191001318 s0 freq -62400000 delay 5547
phc2sys[90222.239]: eth6 sys offset 253380897 s1 freq +8265884 delay 5507
phc2sys[90223.239]: eth6 sys offset -8301685 s2 freq -35801 delay 5487
phc2sys[90224.239]: eth6 sys offset -8297136 s2 freq -2521757 delay 5531
phc2sys[90225.239]: eth6 sys offset -5806117 s2 freq -2519879 delay 5542
phc2sys[90226.239]: eth6 sys offset -3317009 s2 freq -1772606 delay 5495
phc2sys[90227.240]: eth6 sys offset -1575231 s2 freq -1025931 delay 5505
phc2sys[90228.240]: eth6 sys offset -580249 s2 freq -503518 delay 5524
phc2sys[90229.240]: eth6 sys offset -107770 s2 freq -205114 delay 5519
phc2sys[90230.240]: eth6 sys offset 66298 s2 freq -63377 delay 5490
phc2sys[90230.881]: eth6 sys offset 86942 s2 freq -22844 delay 5495
And this is the output with the bug fix in place.
$ sudo testptp -d /dev/ptp1 -f 62400000
frequency adjustment okay
$ sudo ./phc2sys -m -q -c eth6 -s CLOCK_REALTIME -O0
phc2sys[90365.624]: eth6 sys offset 311912675 s0 freq -62400000 delay 5490
phc2sys[90366.624]: eth6 sys offset 374292766 s1 freq -31098 delay 5642
phc2sys[90367.624]: eth6 sys offset -3825 s2 freq -34923 delay 5617
phc2sys[90368.625]: eth6 sys offset 6 s2 freq -32240 delay 5564
phc2sys[90369.625]: eth6 sys offset 1241 s2 freq -31003 delay 5605
phc2sys[90370.625]: eth6 sys offset 1131 s2 freq -30741 delay 5600
phc2sys[90371.625]: eth6 sys offset 801 s2 freq -30732 delay 5621
phc2sys[90372.625]: eth6 sys offset 458 s2 freq -30834 delay 5640
phc2sys[90373.626]: eth6 sys offset 186 s2 freq -30969 delay 5598
phc2sys[90374.626]: eth6 sys offset 134 s2 freq -30965 delay 5599
phc2sys[90375.626]: eth6 sys offset 43 s2 freq -31016 delay 5595
phc2sys[90375.681]: eth6 sys offset -32 s2 freq -31078 delay 5541
This patch fixes the issue by correcting the calculation of the local
time stamp value.
Fixes: 8142da41b61f ("phc2sys: Use reversed sysoff when synchronizing to system clock.")
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Reported-by: Cliff Spradlin <cspradlin@google.com>
Tested-by: Vladimir Oltean <olteanv@gmail.com>
diff --git a/phc2sys.c b/phc2sys.c
index 28c657a..c0b7b3d 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -770,8 +770,8 @@ static int do_loop(struct node *node, int subscriptions)
node->phc_readings,
&offset, &ts, &delay) < 0)
return -1;
- ts += offset;
offset = -offset;
+ ts += offset;
} else {
/* use phc */
if (!read_phc(node->master->clkid, clock->clkid,

View File

@ -1,437 +0,0 @@
commit 9c4d9ce0347ec35b2ff2babfc9ed9f8e6e51ac91
Author: Hangbin Liu <liuhangbin@gmail.com>
Date: Fri Mar 22 15:02:46 2019 +0800
rtnl: add team activebackup support
This patch add team interface activebackup mode support. As linux team use
genl netlink message, when we get a rtnl link change notify, we have to setup
a new genl socket and request the current active port.
v2: check nlmsg_len before copy rta_data
v3: a) Do not make rtnl_buf global as it may be freed by calling rtnl_close()
while we are using it in rtnl_link_status()
b) Reorder declarations of variables as reversed Christmas tree for
function rtnl_link_status()
c) remove rtnl_len
v4: Remove the first !rtnl_buf check in rtnl_link_status as it's alway true
v5: a) Re-order {nl, rtnl}_open and add function nl_close()
b) revert the v3_{a,c}, v4 changes, use nl_close to close genl fd
c) do not use len in get_team_active_iface() as it may mislead reader
v6: Return index at the end to fix fd leak in get_team_active_iface()
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
diff --git a/missing.h b/missing.h
index 2f7adb9..8f92079 100644
--- a/missing.h
+++ b/missing.h
@@ -118,6 +118,22 @@ enum {
#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
#endif /*IFLA_BOND_MAX*/
+#ifndef NLA_TYPE_MAX
+enum {
+ NLA_UNSPEC,
+ NLA_U8,
+ NLA_U16,
+ NLA_U32,
+ NLA_U64,
+ NLA_STRING,
+ NLA_FLAG,
+ NLA_MSECS,
+ NLA_NESTED,
+ __NLA_TYPE_MAX,
+};
+#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
+#endif /*NLA_TYPE_MAX*/
+
#ifdef __UCLIBC__
#if (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L) && \
diff --git a/phc2sys.8 b/phc2sys.8
index 45cb0e3..b3a3de3 100644
--- a/phc2sys.8
+++ b/phc2sys.8
@@ -108,9 +108,9 @@ together with the
option, the master clock is used only to correct the offset by whole number of
seconds, which cannot be fixed with PPS alone. Not compatible with the
.B \-a
-option. This option does not support bonded interface (e.g. bond0). If
+option. This option does not support bonded interface (e.g. bond0, team0). If
.B ptp4l
-has a port on an active-backup bond interface, the
+has a port on an active-backup bond or team interface, the
.B \-a
option can be used to track the active interface.
.TP
diff --git a/rtnl.c b/rtnl.c
index f9a572b..59ed0ec 100644
--- a/rtnl.c
+++ b/rtnl.c
@@ -20,6 +20,8 @@
#include <sys/socket.h> /* Must come before linux/netlink.h on some systems. */
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
+#include <linux/genetlink.h>
+#include <linux/if_team.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,8 +32,39 @@
#include "print.h"
#include "rtnl.h"
+#define BUF_SIZE 4096
+#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
+
static int rtnl_len;
static char *rtnl_buf;
+static int get_team_active_iface(int master_index);
+
+static int nl_close(int fd)
+{
+ return close(fd);
+}
+
+static int nl_open(int family)
+{
+ int fd;
+ struct sockaddr_nl sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.nl_family = AF_NETLINK;
+ sa.nl_groups = RTNLGRP_LINK;
+
+ fd = socket(AF_NETLINK, SOCK_RAW, family);
+ if (fd < 0) {
+ pr_err("failed to open netlink socket: %m");
+ return -1;
+ }
+ if (bind(fd, (struct sockaddr *) &sa, sizeof(sa))) {
+ pr_err("failed to bind netlink socket: %m");
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
int rtnl_close(int fd)
{
@@ -40,7 +73,12 @@ int rtnl_close(int fd)
rtnl_buf = NULL;
rtnl_len = 0;
}
- return close(fd);
+ return nl_close(fd);
+}
+
+int rtnl_open(void)
+{
+ return nl_open(NETLINK_ROUTE);
}
static void rtnl_get_ts_device_callback(void *ctx, int linkup, int ts_index)
@@ -116,14 +154,24 @@ int rtnl_link_query(int fd, char *device)
return 0;
}
-static inline __u32 rta_getattr_u32(const struct rtattr *rta)
+static inline __u8 rta_getattr_u8(struct rtattr *rta)
+{
+ return *(__u8 *)RTA_DATA(rta);
+}
+
+static inline __u16 rta_getattr_u16(struct rtattr *rta)
+{
+ return *(__u16 *)RTA_DATA(rta);
+}
+
+static inline __u32 rta_getattr_u32(struct rtattr *rta)
{
return *(__u32 *)RTA_DATA(rta);
}
-static inline const char *rta_getattr_str(const struct rtattr *rta)
+static inline char *rta_getattr_str(struct rtattr *rta)
{
- return (const char *)RTA_DATA(rta);
+ return (char *)RTA_DATA(rta);
}
static int rtnl_rtattr_parse(struct rtattr *tb[], int max, struct rtattr *rta, int len)
@@ -150,12 +198,12 @@ static inline int rtnl_nested_rtattr_parse(struct rtattr *tb[], int max, struct
return rtnl_rtattr_parse(tb, max, RTA_DATA(rta), RTA_PAYLOAD(rta));
}
-static int rtnl_linkinfo_parse(struct rtattr *rta)
+static int rtnl_linkinfo_parse(int master_index, struct rtattr *rta)
{
- int index = -1;
- const char *kind;
struct rtattr *linkinfo[IFLA_INFO_MAX];
struct rtattr *bond[IFLA_BOND_MAX];
+ int index = -1;
+ char *kind;
if (rtnl_nested_rtattr_parse(linkinfo, IFLA_INFO_MAX, rta) < 0)
return -1;
@@ -172,6 +220,8 @@ static int rtnl_linkinfo_parse(struct rtattr *rta)
if (bond[IFLA_BOND_ACTIVE_SLAVE]) {
index = rta_getattr_u32(bond[IFLA_BOND_ACTIVE_SLAVE]);
}
+ } else if (kind && !strncmp(kind, "team", 4)) {
+ index = get_team_active_iface(master_index);
}
}
return index;
@@ -179,18 +229,18 @@ static int rtnl_linkinfo_parse(struct rtattr *rta)
int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx)
{
+ struct rtattr *tb[IFLA_MAX+1];
+ struct ifinfomsg *info = NULL;
int index, len, link_up;
- int slave_index = -1;
- struct iovec iov;
struct sockaddr_nl sa;
- struct msghdr msg;
+ int slave_index = -1;
struct nlmsghdr *nh;
- struct ifinfomsg *info = NULL;
- struct rtattr *tb[IFLA_MAX+1];
+ struct msghdr msg;
+ struct iovec iov;
index = if_nametoindex(device);
if (!rtnl_buf) {
- rtnl_len = 4096;
+ rtnl_len = BUF_SIZE;
rtnl_buf = malloc(rtnl_len);
if (!rtnl_buf) {
pr_err("rtnl: low memory");
@@ -246,7 +296,7 @@ int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx)
IFLA_PAYLOAD(nh));
if (tb[IFLA_LINKINFO])
- slave_index = rtnl_linkinfo_parse(tb[IFLA_LINKINFO]);
+ slave_index = rtnl_linkinfo_parse(index, tb[IFLA_LINKINFO]);
if (cb)
cb(ctx, link_up, slave_index);
@@ -255,24 +305,163 @@ int rtnl_link_status(int fd, char *device, rtnl_callback cb, void *ctx)
return 0;
}
-int rtnl_open(void)
+static int genl_send_msg(int fd, int family_id, int genl_cmd, int genl_version,
+ int rta_type, void *rta_data, int rta_len)
{
- int fd;
- struct sockaddr_nl sa;
+ struct sockaddr_nl daddr;
+ struct genlmsghdr *gnlh;
+ struct nlmsghdr *nlh;
+ struct rtattr *attr;
+ char msg[BUF_SIZE];
- memset(&sa, 0, sizeof(sa));
- sa.nl_family = AF_NETLINK;
- sa.nl_groups = RTNLGRP_LINK;
+ memset(&daddr, 0, sizeof(daddr));
+ daddr.nl_family = AF_NETLINK;
- fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (fd < 0) {
- pr_err("failed to open netlink socket: %m");
+ memset(&msg, 0, sizeof(msg));
+ nlh = (struct nlmsghdr *) msg;
+ nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+ nlh->nlmsg_type = family_id;
+ nlh->nlmsg_flags = NLM_F_REQUEST;
+
+ gnlh = (struct genlmsghdr *) NLMSG_DATA(nlh);
+ gnlh->cmd = genl_cmd;
+ gnlh->version = genl_version;
+
+ if (rta_data && rta_len > 0) {
+ attr = (struct rtattr *) GENLMSG_DATA(msg);
+ attr->rta_type = rta_type;
+ attr->rta_len = RTA_LENGTH(rta_len);
+ nlh->nlmsg_len += NLMSG_ALIGN(attr->rta_len);
+ if (nlh->nlmsg_len < sizeof(msg))
+ memcpy(RTA_DATA(attr), rta_data, rta_len);
+ else
+ return -1;
+ }
+
+ return sendto(fd, &msg, nlh->nlmsg_len, 0,
+ (struct sockaddr *)&daddr, sizeof(daddr));
+}
+
+static int genl_get_family_id(int fd, void *family_name)
+{
+ struct rtattr *tb[CTRL_ATTR_MAX+1];
+ struct nlmsghdr *nlh;
+ struct rtattr *attr;
+ char msg[BUF_SIZE];
+ int len, gf_id;
+
+ len = genl_send_msg(fd, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, 1,
+ CTRL_ATTR_FAMILY_NAME, family_name,
+ strlen(family_name) + 1);
+ if (len < 0)
+ return len;
+
+ len = recv(fd, &msg, sizeof(msg), 0);
+ if (len < 0)
+ return len;
+
+ nlh = (struct nlmsghdr *) msg;
+ if (nlh->nlmsg_type == NLMSG_ERROR || !NLMSG_OK(nlh, len))
return -1;
+
+ attr = (struct rtattr *) GENLMSG_DATA(msg);
+ rtnl_rtattr_parse(tb, CTRL_ATTR_MAX, attr, NLMSG_PAYLOAD(nlh, GENL_HDRLEN));
+
+ if (tb[CTRL_ATTR_FAMILY_ID])
+ gf_id = rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
+ else
+ gf_id = -1;
+
+ return gf_id;
+}
+
+static int parase_team_list_option(struct rtattr *attr)
+{
+ struct rtattr *tb[TEAM_ATTR_OPTION_MAX+1];
+ int len = RTA_PAYLOAD(attr);
+ const char *optname = "";
+ const char *mode = "";
+ int active_index = -1;
+
+ for (attr = RTA_DATA(attr); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
+ rtnl_nested_rtattr_parse(tb, TEAM_ATTR_OPTION_MAX, attr);
+
+ if (tb[TEAM_ATTR_OPTION_NAME])
+ optname = rta_getattr_str(tb[TEAM_ATTR_OPTION_NAME]);
+
+ if (!strcmp(optname, "mode") && tb[TEAM_ATTR_OPTION_TYPE] &&
+ rta_getattr_u8(tb[TEAM_ATTR_OPTION_TYPE]) == NLA_STRING)
+ mode = rta_getattr_str(tb[TEAM_ATTR_OPTION_DATA]);
+
+ if (!strcmp(optname, "activeport") && tb[TEAM_ATTR_OPTION_TYPE] &&
+ rta_getattr_u8(tb[TEAM_ATTR_OPTION_TYPE]) == NLA_U32)
+ active_index = rta_getattr_u32(tb[TEAM_ATTR_OPTION_DATA]);
}
- if (bind(fd, (struct sockaddr *) &sa, sizeof(sa))) {
- pr_err("failed to bind netlink socket: %m");
- close(fd);
+
+ if (strcmp(mode, "activebackup")) {
+ pr_err("team supported only in activebackup mode");
return -1;
+ } else {
+ return active_index;
}
- return fd;
+}
+
+static int get_team_active_iface(int master_index)
+{
+ struct rtattr *tb[TEAM_ATTR_MAX+1];
+ struct genlmsghdr *gnlh;
+ struct nlmsghdr *nlh;
+ char msg[BUF_SIZE];
+ int fd, gf_id, len;
+ int index = -1;
+
+ fd = nl_open(NETLINK_GENERIC);
+ if (fd < 0)
+ return fd;
+
+ gf_id = genl_get_family_id(fd, TEAM_GENL_NAME);
+ if (gf_id < 0) {
+ pr_err("get genl family failed");
+ goto no_info;
+ }
+
+ len = genl_send_msg(fd, gf_id, TEAM_CMD_OPTIONS_GET,
+ TEAM_GENL_VERSION, TEAM_ATTR_TEAM_IFINDEX,
+ &master_index, sizeof(master_index));
+ if (len < 0) {
+ pr_err("send team info request failed: %m");
+ goto no_info;
+ }
+
+ len = recv(fd, msg, sizeof(msg), 0);
+ if (len < 0) {
+ pr_err("recv team info failed: %m");
+ goto no_info;
+ }
+
+ nlh = (struct nlmsghdr *) msg;
+ for ( ; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
+ if (nlh->nlmsg_type != gf_id)
+ continue;
+
+ gnlh = (struct genlmsghdr *) NLMSG_DATA(nlh);
+ if (gnlh->cmd != TEAM_CMD_OPTIONS_GET)
+ continue;
+
+ rtnl_rtattr_parse(tb, TEAM_ATTR_MAX, (struct rtattr *)GENLMSG_DATA(msg),
+ NLMSG_PAYLOAD(nlh, GENL_HDRLEN));
+
+ if (tb[TEAM_ATTR_TEAM_IFINDEX] &&
+ master_index != rta_getattr_u32(tb[TEAM_ATTR_TEAM_IFINDEX]))
+ continue;
+
+ if (tb[TEAM_ATTR_LIST_OPTION]) {
+ index = parase_team_list_option(tb[TEAM_ATTR_LIST_OPTION]);
+ break;
+ }
+ }
+
+no_info:
+ nl_close(fd);
+ return index;
}
commit 51d76bdfb7423947dbb3e250c86d83f9edb0a15b
Author: Hangbin Liu <liuhangbin@gmail.com>
Date: Wed Mar 20 14:44:13 2019 +0800
port: should check the new phc_index before switching
In logic, when we want to switch phc, we should check if the new phc
index is valid instead of checking the previous one.
In reality, if we use linux team interface with activebackup mode. As
teamd is a userspace tool, it sets the new slave as active port after
receiving link change message. If we set current active port down and
another slave up. There is a race that we receive the new slave's link
up message while active port(ts_index) is still the old one. This means
we may use a link down interface as ts_index and get phc_index with -1.
If we update the p->phc_index to -1, there will be no possibility to
change it back to other value as we swith phc only when p->phc_index >= 0.
With this fix, we will not switch phc_index until receiving the real
active port(p->iface->ts_info.phc_index >= 0) update message.
Reported-by: Miroslav Lichvar <mlichvar@redhat.com>
Fixes: 536a71031d5c ("ptp4l: use ts label to get ts info")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
diff --git a/port.c b/port.c
index 9264211..facebd2 100644
--- a/port.c
+++ b/port.c
@@ -2442,7 +2442,7 @@ void port_link_status(void *ctx, int linkup, int ts_index)
sk_get_ts_info(p->iface->ts_label, &p->iface->ts_info);
/* Only switch phc with HW time stamping mode */
- if (p->phc_index >= 0 && p->iface->ts_info.valid) {
+ if (p->iface->ts_info.valid && p->iface->ts_info.phc_index >= 0) {
required_modes = clock_required_modes(p->clock);
if ((p->iface->ts_info.so_timestamping & required_modes) != required_modes) {
pr_err("interface '%s' does not support requested "

View File

@ -1,24 +0,0 @@
commit 241d8a064efa535029e28b87a8995add3cca8c0c
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Sep 25 18:16:19 2018 +0200
unicast: Process timeouts equal to current time.
Don't postpone processing of a timeout if it is equal to the current
time. This prevents an infinite loop with a simulated clock.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/unicast_service.c b/unicast_service.c
index ad0e06a..9c9b95b 100644
--- a/unicast_service.c
+++ b/unicast_service.c
@@ -502,7 +502,7 @@ int unicast_service_timer(struct port *p)
pr_debug("peek i={2^%d} tmo={%ld,%ld}", interval->log_period,
interval->tmo.tv_sec, interval->tmo.tv_nsec);
- if (timespec_compare(&now, &interval->tmo) >= 0) {
+ if (timespec_compare(&now, &interval->tmo) > 0) {
break;
}
interval = pqueue_extract(p->unicast_service->queue);

View File

@ -0,0 +1,614 @@
Patches backported from the upstream repository.
commit acc045034dd0db9dd4c4aca4b26528f8fed2ae78
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Feb 11 16:47:08 2021 +0100
port: Ignore non-management messages on UDS port.
Drop non-management messages on the UDS port early in the processing to
prevent them from changing the port or clock state.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/port.c b/port.c
index fa49663..3fd06b1 100644
--- a/port.c
+++ b/port.c
@@ -56,6 +56,7 @@ enum syfu_event {
};
static int port_is_ieee8021as(struct port *p);
+static int port_is_uds(struct port *p);
static void port_nrate_initialize(struct port *p);
static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
@@ -691,6 +692,9 @@ static int port_ignore(struct port *p, struct ptp_message *m)
{
struct ClockIdentity c1, c2;
+ if (port_is_uds(p) && msg_type(m) != MANAGEMENT) {
+ return 1;
+ }
if (incapable_ignore(p, m)) {
return 1;
}
@@ -771,6 +775,11 @@ static int port_is_ieee8021as(struct port *p)
return p->follow_up_info ? 1 : 0;
}
+static int port_is_uds(struct port *p)
+{
+ return transport_type(p->trp) == TRANS_UDS;
+}
+
static void port_management_send_error(struct port *p, struct port *ingress,
struct ptp_message *msg, int error_id)
{
commit 72ec806fa62a87cb7e5444e27fa6bdcbfe4e27ca
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Feb 11 16:47:09 2021 +0100
clock: Don't allow COMMAND action on non-UDS port.
No COMMAND actions are currently supported, but check the port early in
clock_manage() before reaching port_manage().
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/clock.c b/clock.c
index a66d189..a6947bc 100644
--- a/clock.c
+++ b/clock.c
@@ -1423,6 +1423,11 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
return changed;
break;
case COMMAND:
+ if (p != c->uds_port) {
+ /* Sorry, only allowed on the UDS port. */
+ clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
+ return changed;
+ }
break;
default:
return changed;
commit 2b45d80eadcb81c8bdf45baf98dabeebd912b1b0
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Feb 11 16:47:10 2021 +0100
clock: Rename UDS variables to read-write.
In preparation for a new read-only UDS port, rename variables of the
current UDS port to make it clear it is read-write, as opposed to
read-only.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/clock.c b/clock.c
index a6947bc..d013b19 100644
--- a/clock.c
+++ b/clock.c
@@ -95,7 +95,7 @@ struct clock {
struct foreign_clock *best;
struct ClockIdentity best_id;
LIST_HEAD(ports_head, port) ports;
- struct port *uds_port;
+ struct port *uds_rw_port;
struct pollfd *pollfd;
int pollfd_valid;
int nports; /* does not include the UDS port */
@@ -129,7 +129,7 @@ struct clock {
struct clock_stats stats;
int stats_interval;
struct clockcheck *sanity_check;
- struct interface *udsif;
+ struct interface *uds_rw_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
};
@@ -245,7 +245,7 @@ void clock_send_notification(struct clock *c, struct ptp_message *msg,
{
unsigned int event_pos = event / 8;
uint8_t mask = 1 << (event % 8);
- struct port *uds = c->uds_port;
+ struct port *uds = c->uds_rw_port;
struct clock_subscriber *s;
LIST_FOREACH(s, &c->subscribers, list) {
@@ -267,13 +267,13 @@ void clock_destroy(struct clock *c)
{
struct port *p, *tmp;
- interface_destroy(c->udsif);
+ interface_destroy(c->uds_rw_if);
clock_flush_subscriptions(c);
LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
clock_remove_port(c, p);
}
monitor_destroy(c->slave_event_monitor);
- port_close(c->uds_port);
+ port_close(c->uds_rw_port);
free(c->pollfd);
if (c->clkid != CLOCK_REALTIME) {
phc_close(c->clkid);
@@ -442,7 +442,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
datalen = sizeof(*gsn);
break;
case TLV_SUBSCRIBE_EVENTS_NP:
- if (p != c->uds_port) {
+ if (p != c->uds_rw_port) {
/* Only the UDS port allowed. */
break;
}
@@ -784,7 +784,7 @@ static int forwarding(struct clock *c, struct port *p)
default:
break;
}
- if (p == c->uds_port && ps != PS_FAULTY) {
+ if (p == c->uds_rw_port && ps != PS_FAULTY) {
return 1;
}
return 0;
@@ -1044,20 +1044,20 @@ struct clock *clock_create(enum clock_type type, struct config *config,
/* Configure the UDS. */
uds_ifname = config_get_string(config, NULL, "uds_address");
- c->udsif = interface_create(uds_ifname);
- if (config_set_section_int(config, interface_name(c->udsif),
+ c->uds_rw_if = interface_create(uds_ifname);
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
"announceReceiptTimeout", 0)) {
return NULL;
}
- if (config_set_section_int(config, interface_name(c->udsif),
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
"delay_mechanism", DM_AUTO)) {
return NULL;
}
- if (config_set_section_int(config, interface_name(c->udsif),
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
"network_transport", TRANS_UDS)) {
return NULL;
}
- if (config_set_section_int(config, interface_name(c->udsif),
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
"delay_filter_length", 1)) {
return NULL;
}
@@ -1180,14 +1180,15 @@ struct clock *clock_create(enum clock_type type, struct config *config,
}
/* Create the UDS interface. */
- c->uds_port = port_open(phc_device, phc_index, timestamping, 0, c->udsif, c);
- if (!c->uds_port) {
+ c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
+ c->uds_rw_if, c);
+ if (!c->uds_rw_port) {
pr_err("failed to open the UDS port");
return NULL;
}
clock_fda_changed(c);
- c->slave_event_monitor = monitor_create(config, c->uds_port);
+ c->slave_event_monitor = monitor_create(config, c->uds_rw_port);
if (!c->slave_event_monitor) {
pr_err("failed to create slave event monitor");
return NULL;
@@ -1206,7 +1207,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
LIST_FOREACH(p, &c->ports, list) {
port_dispatch(p, EV_INITIALIZE, 0);
}
- port_dispatch(c->uds_port, EV_INITIALIZE, 0);
+ port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
return c;
}
@@ -1314,7 +1315,7 @@ static void clock_check_pollfd(struct clock *c)
clock_fill_pollfd(dest, p);
dest += N_CLOCK_PFD;
}
- clock_fill_pollfd(dest, c->uds_port);
+ clock_fill_pollfd(dest, c->uds_rw_port);
c->pollfd_valid = 1;
}
@@ -1331,7 +1332,7 @@ static int clock_do_forward_mgmt(struct clock *c,
return 0;
/* Don't forward any requests to the UDS port. */
- if (out == c->uds_port) {
+ if (out == c->uds_rw_port) {
switch (management_action(msg)) {
case GET:
case SET:
@@ -1362,7 +1363,7 @@ static void clock_forward_mgmt_msg(struct clock *c, struct port *p, struct ptp_m
pr_err("port %d: management forward failed",
port_number(piter));
}
- if (clock_do_forward_mgmt(c, p, c->uds_port, msg, &msg_ready))
+ if (clock_do_forward_mgmt(c, p, c->uds_rw_port, msg, &msg_ready))
pr_err("uds port: management forward failed");
if (msg_ready) {
msg_post_recv(msg, pdulen);
@@ -1414,7 +1415,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
clock_management_send_error(p, msg, TLV_WRONG_LENGTH);
return changed;
}
- if (p != c->uds_port) {
+ if (p != c->uds_rw_port) {
/* Sorry, only allowed on the UDS port. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
return changed;
@@ -1423,7 +1424,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
return changed;
break;
case COMMAND:
- if (p != c->uds_port) {
+ if (p != c->uds_rw_port) {
/* Sorry, only allowed on the UDS port. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
return changed;
@@ -1435,7 +1436,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
switch (mgt->id) {
case TLV_PORT_PROPERTIES_NP:
- if (p != c->uds_port) {
+ if (p != c->uds_rw_port) {
/* Only the UDS port allowed. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
return 0;
@@ -1500,7 +1501,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
void clock_notify_event(struct clock *c, enum notification event)
{
- struct port *uds = c->uds_port;
+ struct port *uds = c->uds_rw_port;
struct PortIdentity pid = port_identity(uds);
struct ptp_message *msg;
int id;
@@ -1604,7 +1605,7 @@ int clock_poll(struct clock *c)
/* Check the UDS port. */
for (i = 0; i < N_POLLFD; i++) {
if (cur[i].revents & (POLLIN|POLLPRI)) {
- event = port_event(c->uds_port, i);
+ event = port_event(c->uds_rw_port, i);
if (EV_STATE_DECISION_EVENT == event) {
c->sde = 1;
}
commit 1f74a16502b55ce8eaed3d7488542e5469ac8263
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Feb 11 16:47:11 2021 +0100
clock: Add read-only UDS port for monitoring.
Add a second UDS port to allow untrusted applications to monitor ptp4l.
On this "read-only" UDS port disable non-GET actions and forwarding.
The path can be configured with the uds_ro_address option (default is
/var/run/ptp4lro).
Forwarding is disabled to limit the access to the local ptp4l instance.
Subscriptions are not enabled to prevent the applications from making a
large number of subscriptions or interfere with applications that have
access to the read-write UDS port.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/clock.c b/clock.c
index d013b19..8592d29 100644
--- a/clock.c
+++ b/clock.c
@@ -96,9 +96,10 @@ struct clock {
struct ClockIdentity best_id;
LIST_HEAD(ports_head, port) ports;
struct port *uds_rw_port;
+ struct port *uds_ro_port;
struct pollfd *pollfd;
int pollfd_valid;
- int nports; /* does not include the UDS port */
+ int nports; /* does not include the two UDS ports */
int last_port_number;
int sde;
int free_running;
@@ -130,6 +131,7 @@ struct clock {
int stats_interval;
struct clockcheck *sanity_check;
struct interface *uds_rw_if;
+ struct interface *uds_ro_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
};
@@ -268,12 +270,14 @@ void clock_destroy(struct clock *c)
struct port *p, *tmp;
interface_destroy(c->uds_rw_if);
+ interface_destroy(c->uds_ro_if);
clock_flush_subscriptions(c);
LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
clock_remove_port(c, p);
}
monitor_destroy(c->slave_event_monitor);
port_close(c->uds_rw_port);
+ port_close(c->uds_ro_port);
free(c->pollfd);
if (c->clkid != CLOCK_REALTIME) {
phc_close(c->clkid);
@@ -443,7 +447,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
break;
case TLV_SUBSCRIBE_EVENTS_NP:
if (p != c->uds_rw_port) {
- /* Only the UDS port allowed. */
+ /* Only the UDS-RW port allowed. */
break;
}
sen = (struct subscribe_events_np *)tlv->data;
@@ -774,6 +778,10 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress)
static int forwarding(struct clock *c, struct port *p)
{
enum port_state ps = port_state(p);
+
+ if (p == c->uds_ro_port)
+ return 0;
+
switch (ps) {
case PS_MASTER:
case PS_GRAND_MASTER:
@@ -818,7 +826,7 @@ static int clock_add_port(struct clock *c, const char *phc_device,
{
struct port *p, *piter, *lastp = NULL;
- if (clock_resize_pollfd(c, c->nports + 1)) {
+ if (clock_resize_pollfd(c, c->nports + 2)) {
return -1;
}
p = port_open(phc_device, phc_index, timestamping,
@@ -1043,6 +1051,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
}
/* Configure the UDS. */
+
uds_ifname = config_get_string(config, NULL, "uds_address");
c->uds_rw_if = interface_create(uds_ifname);
if (config_set_section_int(config, interface_name(c->uds_rw_if),
@@ -1062,6 +1071,25 @@ struct clock *clock_create(enum clock_type type, struct config *config,
return NULL;
}
+ uds_ifname = config_get_string(config, NULL, "uds_ro_address");
+ c->uds_ro_if = interface_create(uds_ifname);
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
+ "announceReceiptTimeout", 0)) {
+ return NULL;
+ }
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
+ "delay_mechanism", DM_AUTO)) {
+ return NULL;
+ }
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
+ "network_transport", TRANS_UDS)) {
+ return NULL;
+ }
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
+ "delay_filter_length", 1)) {
+ return NULL;
+ }
+
c->config = config;
c->free_running = config_get_int(config, NULL, "free_running");
c->freq_est_interval = config_get_int(config, NULL, "freq_est_interval");
@@ -1179,11 +1207,18 @@ struct clock *clock_create(enum clock_type type, struct config *config,
return NULL;
}
- /* Create the UDS interface. */
+ /* Create the UDS interfaces. */
+
c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
c->uds_rw_if, c);
if (!c->uds_rw_port) {
- pr_err("failed to open the UDS port");
+ pr_err("failed to open the UDS-RW port");
+ return NULL;
+ }
+ c->uds_ro_port = port_open(phc_device, phc_index, timestamping, 0,
+ c->uds_ro_if, c);
+ if (!c->uds_ro_port) {
+ pr_err("failed to open the UDS-RO port");
return NULL;
}
clock_fda_changed(c);
@@ -1208,6 +1243,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
port_dispatch(p, EV_INITIALIZE, 0);
}
port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
+ port_dispatch(c->uds_ro_port, EV_INITIALIZE, 0);
return c;
}
@@ -1278,9 +1314,9 @@ static int clock_resize_pollfd(struct clock *c, int new_nports)
{
struct pollfd *new_pollfd;
- /* Need to allocate one whole extra block of fds for UDS. */
+ /* Need to allocate two whole extra blocks of fds for UDS ports. */
new_pollfd = realloc(c->pollfd,
- (new_nports + 1) * N_CLOCK_PFD *
+ (new_nports + 2) * N_CLOCK_PFD *
sizeof(struct pollfd));
if (!new_pollfd) {
return -1;
@@ -1316,6 +1352,8 @@ static void clock_check_pollfd(struct clock *c)
dest += N_CLOCK_PFD;
}
clock_fill_pollfd(dest, c->uds_rw_port);
+ dest += N_CLOCK_PFD;
+ clock_fill_pollfd(dest, c->uds_ro_port);
c->pollfd_valid = 1;
}
@@ -1331,7 +1369,8 @@ static int clock_do_forward_mgmt(struct clock *c,
if (in == out || !forwarding(c, out))
return 0;
- /* Don't forward any requests to the UDS port. */
+ /* Don't forward any requests to the UDS-RW port
+ (the UDS-RO port doesn't allow any forwarding). */
if (out == c->uds_rw_port) {
switch (management_action(msg)) {
case GET:
@@ -1416,7 +1455,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
return changed;
}
if (p != c->uds_rw_port) {
- /* Sorry, only allowed on the UDS port. */
+ /* Sorry, only allowed on the UDS-RW port. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
return changed;
}
@@ -1425,7 +1464,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
break;
case COMMAND:
if (p != c->uds_rw_port) {
- /* Sorry, only allowed on the UDS port. */
+ /* Sorry, only allowed on the UDS-RW port. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
return changed;
}
@@ -1437,7 +1476,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
switch (mgt->id) {
case TLV_PORT_PROPERTIES_NP:
if (p != c->uds_rw_port) {
- /* Only the UDS port allowed. */
+ /* Only the UDS-RW port allowed. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
return 0;
}
@@ -1548,7 +1587,7 @@ int clock_poll(struct clock *c)
struct port *p;
clock_check_pollfd(c);
- cnt = poll(c->pollfd, (c->nports + 1) * N_CLOCK_PFD, -1);
+ cnt = poll(c->pollfd, (c->nports + 2) * N_CLOCK_PFD, -1);
if (cnt < 0) {
if (EINTR == errno) {
return 0;
@@ -1602,7 +1641,7 @@ int clock_poll(struct clock *c)
cur += N_CLOCK_PFD;
}
- /* Check the UDS port. */
+ /* Check the UDS ports. */
for (i = 0; i < N_POLLFD; i++) {
if (cur[i].revents & (POLLIN|POLLPRI)) {
event = port_event(c->uds_rw_port, i);
@@ -1611,6 +1650,13 @@ int clock_poll(struct clock *c)
}
}
}
+ cur += N_CLOCK_PFD;
+ for (i = 0; i < N_POLLFD; i++) {
+ if (cur[i].revents & (POLLIN|POLLPRI)) {
+ event = port_event(c->uds_ro_port, i);
+ /* sde is not expected on the UDS-RO port */
+ }
+ }
if (c->sde) {
handle_state_decision_event(c);
diff --git a/config.c b/config.c
index d237de9..96a5351 100644
--- a/config.c
+++ b/config.c
@@ -323,6 +323,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("udp_ttl", 1, 1, 255),
PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F),
GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"),
+ GLOB_ITEM_STR("uds_ro_address", "/var/run/ptp4lro"),
PORT_ITEM_INT("unicast_listen", 0, 0, 1),
PORT_ITEM_INT("unicast_master_table", 0, 0, INT_MAX),
PORT_ITEM_INT("unicast_req_duration", 3600, 10, INT_MAX),
diff --git a/configs/default.cfg b/configs/default.cfg
index 8c19129..d5bab7d 100644
--- a/configs/default.cfg
+++ b/configs/default.cfg
@@ -90,6 +90,7 @@ p2p_dst_mac 01:80:C2:00:00:0E
udp_ttl 1
udp6_scope 0x0E
uds_address /var/run/ptp4l
+uds_ro_address /var/run/ptp4lro
#
# Default interface options
#
diff --git a/ptp4l.8 b/ptp4l.8
index b179b81..f9bd228 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -615,6 +615,12 @@ is only relevant with IPv6 transport. See RFC 4291. The default is
Specifies the address of the UNIX domain socket for receiving local
management messages. The default is /var/run/ptp4l.
.TP
+.B uds_ro_address
+Specifies the address of the second UNIX domain socket for receiving local
+management messages, which is restricted to GET actions and does not forward
+messages to other ports. Access to this socket can be given to untrusted
+applications for monitoring purposes. The default is /var/run/ptp4lro.
+.TP
.B dscp_event
Defines the Differentiated Services Codepoint (DSCP) to be used for PTP
event messages. Must be a value between 0 and 63. There are several media
commit d4c5343237588d265c605f3772337bc88cabe787
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Thu Feb 11 16:47:12 2021 +0100
timemaster: Set uds_ro_address for ptp4l instances.
This prevents conflicts on the new UDS-RO port.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/timemaster.c b/timemaster.c
index 00db59f..02408d6 100644
--- a/timemaster.c
+++ b/timemaster.c
@@ -712,7 +712,7 @@ static int add_ptp_source(struct ptp_domain *source,
char **ntp_config, struct script *script)
{
struct config_file *config_file;
- char **command, *uds_path, **interfaces, *message_tag;
+ char **command, *uds_path, *uds_path2, **interfaces, *message_tag;
char ts_interface[IF_NAMESIZE];
int i, j, num_interfaces, *phc, *phcs, hw_ts, sw_ts;
struct sk_ts_info ts_info;
@@ -809,6 +809,8 @@ static int add_ptp_source(struct ptp_domain *source,
uds_path = string_newf("%s/ptp4l.%d.socket",
config->rundir, *shm_segment);
+ uds_path2 = string_newf("%s/ptp4lro.%d.socket",
+ config->rundir, *shm_segment);
message_tag = string_newf("[%d", source->domain);
for (j = 0; interfaces[j]; j++)
@@ -832,8 +834,10 @@ static int add_ptp_source(struct ptp_domain *source,
"slaveOnly 1\n"
"domainNumber %d\n"
"uds_address %s\n"
+ "uds_ro_address %s\n"
"message_tag %s\n",
- source->domain, uds_path, message_tag);
+ source->domain, uds_path, uds_path2,
+ message_tag);
if (phcs[i] >= 0) {
/* HW time stamping */
@@ -868,6 +872,7 @@ static int add_ptp_source(struct ptp_domain *source,
free(message_tag);
free(uds_path);
+ free(uds_path2);
free(interfaces);
}

View File

@ -1,46 +1,37 @@
commit 6b61ba29c78e26109426429c6d6b354f6e4443cd
Author: David Mirabito via Linuxptp-devel <linuxptp-devel@lists.sourceforge.net>
Date: Tue Mar 19 13:42:48 2019 +1100
commit 9633ab52460f58c92c6daa35e9d24e4ce9c5ab1c
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Feb 23 11:01:43 2021 +0100
Avoid fault when receiving zero length packets
sk: Don't return error for zero-length messages.
The manpage for recvmsg says -1 will be returned on error, Zero indicates an
"orderly shutdown", presumably only in case of stream sockets.
Further, UNIX Network Programming, Vol 1 says ".. a return value of 0 from
recvfrom is acceptable for a datagram protocol"
The recvmsg() call can return zero for a zero-length UDP message, which
should be handled as a bad message and not a fault of the port. This was
addressed in commit 6b61ba29c78e ("Avoid fault when receiving zero
length packets"), but later regressed in commit a6e0b83bd503
("sk: Convey transmit path errors to the caller.").
Such packets have been observed in the wild, aimed at PTP's multicast
address and port, possibly related to malformed management queries.
Patch to properly check return from recvmesg and not trigger the fault
codepath. Instead, such packets are treated as "Bad Message" the same as
non-zero but still too-short UDP payloads.
Signed-off-by: David Mirabito <davidjm@arista.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Fixes: a6e0b83bd503 ("sk: Convey transmit path errors to the caller.")
diff --git a/port.c b/port.c
index ad9554f..9264211 100644
--- a/port.c
+++ b/port.c
@@ -2563,7 +2563,7 @@ static enum fsm_event bc_event(struct port *p, int fd_index)
msg->hwts.type = p->timestamping;
cnt = transport_recv(p->trp, fd, msg);
- if (cnt <= 0) {
+ if (cnt < 0) {
pr_err("port %hu: recv message failed", portnum(p));
msg_put(msg);
return EV_FAULT_DETECTED;
diff --git a/sk.c b/sk.c
index 30162eb..93ba77a 100644
index c9ef4d2..8be0708 100644
--- a/sk.c
+++ b/sk.c
@@ -359,7 +359,7 @@ int sk_receive(int fd, void *buf, int buflen,
@@ -391,7 +391,7 @@ int sk_receive(int fd, void *buf, int buflen,
if (!ts) {
memset(&hwts->ts, 0, sizeof(hwts->ts));
- return cnt < 1 ? -errno : cnt;
+ return cnt < 0 ? -errno : cnt;
}
cnt = recvmsg(fd, &msg, flags);
- if (cnt < 1)
+ if (cnt < 0)
pr_err("recvmsg%sfailed: %m",
flags == MSG_ERRQUEUE ? " tx timestamp " : " ");
switch (hwts->type) {
@@ -407,7 +407,7 @@ int sk_receive(int fd, void *buf, int buflen,
hwts->ts = timespec_to_tmv(ts[1]);
break;
}
- return cnt < 1 ? -errno : cnt;
+ return cnt < 0 ? -errno : cnt;
}
int sk_set_priority(int fd, int family, uint8_t dscp)

View File

@ -1,10 +1,10 @@
%global _hardened_build 1
%global testsuite_ver a7f6e1
%global clknetsim_ver 8b4842
%global testsuite_ver c66922
%global clknetsim_ver ce3c4a
Name: linuxptp
Version: 2.0
Release: 5%{?dist}.1
Version: 3.1.1
Release: 1%{?dist}
Summary: PTP implementation for Linux
Group: System Environment/Base
@ -21,26 +21,22 @@ Source10: https://github.com/mlichvar/linuxptp-testsuite/archive/%{testsuite_ver
# simulator for test suite
Source11: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz
# fix building with new kernel headers
Patch1: linuxptp-headers.patch
# fix timeout handling to work with simulated clock
Patch2: linuxptp-timeout.patch
# add support for more accurate synchronization to phc2sys
Patch3: linuxptp-sysoff.patch
# don't repeat some log messages in multi-port configuration
Patch1: linuxptp-logmsgs.patch
# add option to set clockClass threshold
Patch2: linuxptp-classthreshold.patch
# increase default TX timestamp timeout to 10 ms
Patch3: linuxptp-deftxtout.patch
# limit unicast message rate per address and grant duration
Patch4: linuxptp-ucastrate.patch
# add support for active-backup team interface
Patch5: linuxptp-team.patch
# fix comparing of unicast addresses
Patch6: linuxptp-addreq.patch
# don't leak memory when allocation fails
Patch7: linuxptp-msgput.patch
# add hwts_filter option to ptp4l
Patch8: linuxptp-hwtsfilter.patch
# add read-only UDS port
Patch5: linuxptp-udsro.patch
# fix quoting in ptp4l man page
Patch7: linuxptp-manfix.patch
# close lstab file after use
Patch8: linuxptp-fclose.patch
# fix handling of zero-length messages
Patch9: linuxptp-zerolength.patch
# validate length of forwarded messages
Patch10: linuxptp-cve-2021-3570.patch
BuildRequires: kernel-headers > 4.18.0-87
BuildRequires: systemd
@ -56,16 +52,14 @@ Supporting legacy APIs and other platforms is not a goal.
%prep
%setup -q -a 10 -a 11 -n %{name}-%{!?gitfullver:%{version}}%{?gitfullver}
%patch1 -p1 -b .headers
%patch2 -p1 -b .timeout
%patch3 -p1 -b .sysoff
%patch1 -p1 -b .logmsgs
%patch2 -p1 -b .classthreshold
%patch3 -p1 -b .deftxtout
%patch4 -p1 -b .ucastrate
%patch5 -p1 -b .team
%patch6 -p1 -b .addreq
%patch7 -p1 -b .msgput
%patch8 -p1 -b .hwtsfilter
%patch5 -p1 -b .udsro
%patch7 -p1 -b .manfix
%patch8 -p1 -b .fclose
%patch9 -p1 -b .zerolength
%patch10 -p1 -b .cve-2021-3570
mv linuxptp-testsuite-%{testsuite_ver}* testsuite
mv clknetsim-%{clknetsim_ver}* testsuite/clknetsim
@ -89,6 +83,9 @@ echo 'OPTIONS="-a -r"' > $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/phc2sys
echo '.so man8/ptp4l.8' > $RPM_BUILD_ROOT%{_mandir}/man5/ptp4l.conf.5
echo '.so man8/timemaster.8' > $RPM_BUILD_ROOT%{_mandir}/man5/timemaster.conf.5
# Remove patch backup files and non-linuxptp configuration
find configs -type f ! -name '*.cfg' -delete
%check
cd testsuite
# set random seed to get deterministic results
@ -121,10 +118,18 @@ PATH=..:$PATH ./run
%{_sbindir}/pmc
%{_sbindir}/ptp4l
%{_sbindir}/timemaster
%{_sbindir}/ts2phc
%{_mandir}/man5/*.5*
%{_mandir}/man8/*.8*
%changelog
* Mon Jul 26 2021 Miroslav Lichvar <mlichvar@redhat.com> 3.1.1-1
- update to 3.1.1 (#1895005 CVE-2021-3571)
- add read-only UDS port (#1929797)
- add option to set clockClass threshold (#1980386)
- don't repeat some log messages in multi-port configuration (#1980377)
- increase default TX timestamp timeout to 10 ms (#1977136)
* Thu Jun 24 2021 Miroslav Lichvar <mlichvar@redhat.com> 2.0-5.el8_4.1
- validate length of forwarded messages (CVE-2021-3570)