From fed1e1e7916023dcb90e88792d27aa805bb68a73 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 09 2021 09:51:38 +0000 Subject: import linuxptp-3.1.1-1.el8 --- diff --git a/.gitignore b/.gitignore index b71a5b8..59f8d4a 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.linuxptp.metadata b/.linuxptp.metadata index 03e8cd2..48191c2 100644 --- a/.linuxptp.metadata +++ b/.linuxptp.metadata @@ -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 diff --git a/SOURCES/linuxptp-addreq.patch b/SOURCES/linuxptp-addreq.patch deleted file mode 100644 index 284f7ee..0000000 --- a/SOURCES/linuxptp-addreq.patch +++ /dev/null @@ -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; diff --git a/SOURCES/linuxptp-classthreshold.patch b/SOURCES/linuxptp-classthreshold.patch new file mode 100644 index 0000000..71b0250 --- /dev/null +++ b/SOURCES/linuxptp-classthreshold.patch @@ -0,0 +1,138 @@ +Backported commit f774703cb1eee058a346aec3341fee0be329bd6d +Author: Karthikkumar V +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 + Signed-off-by: Ramana Reddy + +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. diff --git a/SOURCES/linuxptp-cve-2021-3570.patch b/SOURCES/linuxptp-cve-2021-3570.patch deleted file mode 100644 index f166e77..0000000 --- a/SOURCES/linuxptp-cve-2021-3570.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 4b05d4b5d70c1ba76d95f94f1f4821c4b715fefe Mon Sep 17 00:00:00 2001 -From: Richard Cochran -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 -Signed-off-by: Richard Cochran ---- - 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 - diff --git a/SOURCES/linuxptp-deftxtout.patch b/SOURCES/linuxptp-deftxtout.patch new file mode 100644 index 0000000..f47e24e --- /dev/null +++ b/SOURCES/linuxptp-deftxtout.patch @@ -0,0 +1,82 @@ +commit 1a2dfe9b00b79a59acf905476bbc33c74d5770a3 +Author: Jacob Keller +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 + +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 diff --git a/SOURCES/linuxptp-fclose.patch b/SOURCES/linuxptp-fclose.patch new file mode 100644 index 0000000..bde2872 --- /dev/null +++ b/SOURCES/linuxptp-fclose.patch @@ -0,0 +1,22 @@ +commit e8a82d1b5be2d5bf9450a9acfe44e957b4867870 +Author: Miroslav Lichvar +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 + +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; diff --git a/SOURCES/linuxptp-headers.patch b/SOURCES/linuxptp-headers.patch deleted file mode 100644 index c1aca97..0000000 --- a/SOURCES/linuxptp-headers.patch +++ /dev/null @@ -1,51 +0,0 @@ -commit d663a483c40939bad58301c256d86da1f3da6cc0 -Author: Miroslav Lichvar -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 - -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 -+#include - #include - #include - #include - #include --#include - #include - - #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 -+#include - #include - #include - #include -diff --git a/timemaster.c b/timemaster.c -index 058678f..00db59f 100644 ---- a/timemaster.c -+++ b/timemaster.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/SOURCES/linuxptp-hwtsfilter.patch b/SOURCES/linuxptp-hwtsfilter.patch deleted file mode 100644 index 3c3bc72..0000000 --- a/SOURCES/linuxptp-hwtsfilter.patch +++ /dev/null @@ -1,228 +0,0 @@ -commit 399907db7f9dc3f57c3f9831b3b4da705a2c51a3 -Author: Erez Geva -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 - Signed-off-by: Erez Geva - -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 diff --git a/SOURCES/linuxptp-logmsgs.patch b/SOURCES/linuxptp-logmsgs.patch new file mode 100644 index 0000000..c2a138f --- /dev/null +++ b/SOURCES/linuxptp-logmsgs.patch @@ -0,0 +1,96 @@ +commit 3399fa15ae28610c1b288b573c4233a42c48f762 +Author: Amar Subramanyam via Linuxptp-devel +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 + Signed-off-by: Karthikkumar Valoor + Signed-off-by: Ramana Reddy + +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 +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 + Signed-off-by: Karthikkumar Valoor + Signed-off-by: Ramana Reddy + +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); + } + } diff --git a/SOURCES/linuxptp-manfix.patch b/SOURCES/linuxptp-manfix.patch new file mode 100644 index 0000000..05edfc9 --- /dev/null +++ b/SOURCES/linuxptp-manfix.patch @@ -0,0 +1,28 @@ +commit 0b80e32829ca7430be851fc64c4812896ad97c88 +Author: Miroslav Lichvar +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 + +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 diff --git a/SOURCES/linuxptp-msgput.patch b/SOURCES/linuxptp-msgput.patch deleted file mode 100644 index 0fab821..0000000 --- a/SOURCES/linuxptp-msgput.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit 86723cfc6a7ac1d9b1bff5e90b7f4696d6460a0e -Author: Miroslav Lichvar -Date: Thu Mar 21 17:12:03 2019 +0100 - - pmc: Don't leak memory when msg_tlv_append() fails. - - Signed-off-by: Miroslav Lichvar - -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; diff --git a/SOURCES/linuxptp-sysoff.patch b/SOURCES/linuxptp-sysoff.patch deleted file mode 100644 index ce1e410..0000000 --- a/SOURCES/linuxptp-sysoff.patch +++ /dev/null @@ -1,486 +0,0 @@ -commit c0e49c708814ec783726fe92202371847703c5ed -Author: Miroslav Lichvar -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 - -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 -+#include - #include - #include - -@@ -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 -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 - -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 - - 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 -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 - -diff --git a/sysoff.c b/sysoff.c -index f709a9b..9f65d95 100644 ---- a/sysoff.c -+++ b/sysoff.c -@@ -22,6 +22,7 @@ - #include - #include - -+#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 -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 - -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 -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 - -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 -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 - Reported-by: Cliff Spradlin - Tested-by: Vladimir Oltean - -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, diff --git a/SOURCES/linuxptp-team.patch b/SOURCES/linuxptp-team.patch deleted file mode 100644 index 7bb7000..0000000 --- a/SOURCES/linuxptp-team.patch +++ /dev/null @@ -1,437 +0,0 @@ -commit 9c4d9ce0347ec35b2ff2babfc9ed9f8e6e51ac91 -Author: Hangbin Liu -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 - -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 /* Must come before linux/netlink.h on some systems. */ - #include - #include -+#include -+#include - #include - #include - #include -@@ -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 -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 - Fixes: 536a71031d5c ("ptp4l: use ts label to get ts info") - Signed-off-by: Hangbin Liu - -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 " diff --git a/SOURCES/linuxptp-timeout.patch b/SOURCES/linuxptp-timeout.patch deleted file mode 100644 index b104787..0000000 --- a/SOURCES/linuxptp-timeout.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit 241d8a064efa535029e28b87a8995add3cca8c0c -Author: Miroslav Lichvar -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 - -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); diff --git a/SOURCES/linuxptp-udsro.patch b/SOURCES/linuxptp-udsro.patch new file mode 100644 index 0000000..7030553 --- /dev/null +++ b/SOURCES/linuxptp-udsro.patch @@ -0,0 +1,614 @@ +Patches backported from the upstream repository. + +commit acc045034dd0db9dd4c4aca4b26528f8fed2ae78 +Author: Miroslav Lichvar +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 + +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 +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 + +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 +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 + +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 +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 + +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 +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 + +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); + } + diff --git a/SOURCES/linuxptp-zerolength.patch b/SOURCES/linuxptp-zerolength.patch index 8be7d1e..0ab5ed4 100644 --- a/SOURCES/linuxptp-zerolength.patch +++ b/SOURCES/linuxptp-zerolength.patch @@ -1,46 +1,37 @@ -commit 6b61ba29c78e26109426429c6d6b354f6e4443cd -Author: David Mirabito via Linuxptp-devel -Date: Tue Mar 19 13:42:48 2019 +1100 +commit 9633ab52460f58c92c6daa35e9d24e4ce9c5ab1c +Author: Miroslav Lichvar +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 + Signed-off-by: Miroslav Lichvar + 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) diff --git a/SPECS/linuxptp.spec b/SPECS/linuxptp.spec index 8f19d3a..5ec953e 100644 --- a/SPECS/linuxptp.spec +++ b/SPECS/linuxptp.spec @@ -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 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 2.0-5.el8_4.1 - validate length of forwarded messages (CVE-2021-3570)