From 2c55db4376ab354a876e85e531aab5682348e117 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 3 Jan 2024 14:54:36 +0100 Subject: [PATCH] update to 4.2 (RHEL-2026 RHEL-2342 RHEL-12182 RHEL-15929) Resolves: RHEL-2026 RHEL-2342 RHEL-12182 RHEL-15929 --- .gitignore | 6 +- linuxptp-classthreshold.patch | 138 --- linuxptp-clockcheck.patch | 187 ----- linuxptp-deftxtout.patch | 82 -- linuxptp-deprecated.patch | 23 + linuxptp-eintr.patch | 30 - linuxptp-faultrearm.patch | 52 -- linuxptp-fclose.patch | 22 - linuxptp-freqcheck.patch | 208 ----- linuxptp-logmsgs.patch | 96 --- linuxptp-manfix.patch | 28 - linuxptp-packalign.patch | 100 --- linuxptp-phcerr.patch | 510 ----------- linuxptp-ptpver.patch | 60 ++ linuxptp-soerror.patch | 84 -- linuxptp-subscribe.patch | 26 + linuxptp-udsro.patch | 614 -------------- linuxptp-vclock.patch | 1487 +-------------------------------- linuxptp-vlanbond.patch | 451 ---------- linuxptp-zerolength.patch | 37 - linuxptp.spec | 63 +- sources | 6 +- 22 files changed, 130 insertions(+), 4180 deletions(-) delete mode 100644 linuxptp-classthreshold.patch delete mode 100644 linuxptp-clockcheck.patch delete mode 100644 linuxptp-deftxtout.patch create mode 100644 linuxptp-deprecated.patch delete mode 100644 linuxptp-eintr.patch delete mode 100644 linuxptp-faultrearm.patch delete mode 100644 linuxptp-fclose.patch delete mode 100644 linuxptp-freqcheck.patch delete mode 100644 linuxptp-logmsgs.patch delete mode 100644 linuxptp-manfix.patch delete mode 100644 linuxptp-packalign.patch delete mode 100644 linuxptp-phcerr.patch create mode 100644 linuxptp-ptpver.patch delete mode 100644 linuxptp-soerror.patch create mode 100644 linuxptp-subscribe.patch delete mode 100644 linuxptp-udsro.patch delete mode 100644 linuxptp-vlanbond.patch delete mode 100644 linuxptp-zerolength.patch diff --git a/.gitignore b/.gitignore index 5206ba6..bc3f565 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/linuxptp-3.1.1.tgz -/linuxptp-testsuite-c66922.tar.gz -/clknetsim-c63e22.tar.gz +/linuxptp-4.2.tgz +/linuxptp-testsuite-bf8ead.tar.gz +/clknetsim-5d1dc0.tar.gz diff --git a/linuxptp-classthreshold.patch b/linuxptp-classthreshold.patch deleted file mode 100644 index 71b0250..0000000 --- a/linuxptp-classthreshold.patch +++ /dev/null @@ -1,138 +0,0 @@ -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/linuxptp-clockcheck.patch b/linuxptp-clockcheck.patch deleted file mode 100644 index d371166..0000000 --- a/linuxptp-clockcheck.patch +++ /dev/null @@ -1,187 +0,0 @@ -commit 7e8eba5332671abfd95d06dd191059eded1d2cca -Author: Miroslav Lichvar -Date: Mon May 31 11:07:52 2021 +0200 - - clock: Reset state when switching port with same best clock. - - When the best port is changed, but the ID of the best clock doesn't - change (e.g. a passive port is activated on link failure), reset the - current delay and other master/link-specific state to avoid the switch - throwing the clock off. - - Reviewed-by: Jacob Keller - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index d428ae2..f14006f 100644 ---- a/clock.c -+++ b/clock.c -@@ -1940,7 +1940,7 @@ static void handle_state_decision_event(struct clock *c) - best_id = c->dds.clockIdentity; - } - -- if (!cid_eq(&best_id, &c->best_id)) { -+ if (!cid_eq(&best_id, &c->best_id) || best != c->best) { - clock_freq_est_reset(c); - tsproc_reset(c->tsproc, 1); - if (!tmv_is_zero(c->initial_delay)) - -commit 262a49b07eaccc0f0237e3cd4df01b185b8f664f -Author: Miroslav Lichvar -Date: Mon May 31 11:07:53 2021 +0200 - - clock: Reset clock check on best clock/port change. - - Reset the clock check when the best clock or port changes, together with - the other state like current estimated delay and frequency. This avoids - false positives if the clock is controlled by an external process when - not synchronized by PTP (e.g. phc2sys -rr). - - Reviewed-by: Jacob Keller - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index f14006f..7d0f985 100644 ---- a/clock.c -+++ b/clock.c -@@ -1942,6 +1942,8 @@ static void handle_state_decision_event(struct clock *c) - - if (!cid_eq(&best_id, &c->best_id) || best != c->best) { - clock_freq_est_reset(c); -+ if (c->sanity_check) -+ clockcheck_reset(c->sanity_check); - tsproc_reset(c->tsproc, 1); - if (!tmv_is_zero(c->initial_delay)) - tsproc_set_delay(c->tsproc, c->initial_delay); -diff --git a/clockcheck.c b/clockcheck.c -index d48a578..d0b4714 100644 ---- a/clockcheck.c -+++ b/clockcheck.c -@@ -47,9 +47,16 @@ struct clockcheck *clockcheck_create(int freq_limit) - if (!cc) - return NULL; - cc->freq_limit = freq_limit; -+ clockcheck_reset(cc); -+ return cc; -+} -+ -+void clockcheck_reset(struct clockcheck *cc) -+{ -+ cc->freq_known = 0; - cc->max_freq = -CHECK_MAX_FREQ; - cc->min_freq = CHECK_MAX_FREQ; -- return cc; -+ cc->last_ts = 0; - } - - int clockcheck_sample(struct clockcheck *cc, uint64_t ts) -diff --git a/clockcheck.h b/clockcheck.h -index 78aca48..1ff86eb 100644 ---- a/clockcheck.h -+++ b/clockcheck.h -@@ -33,6 +33,12 @@ struct clockcheck; - */ - struct clockcheck *clockcheck_create(int freq_limit); - -+/** -+ * Reset a clock check. -+ * @param cc Pointer to a clock check obtained via @ref clockcheck_create(). -+ */ -+void clockcheck_reset(struct clockcheck *cc); -+ - /** - * Perform the sanity check on a time stamp. - * @param cc Pointer to a clock check obtained via @ref clockcheck_create(). - -commit e117e37e379556fa23337db2518bb44d8793e039 -Author: Miroslav Lichvar -Date: Mon May 31 11:07:54 2021 +0200 - - port: Don't check timestamps from non-slave ports. - - Don't perform the sanity check on receive timestamps from ports in - non-slave states to avoid false positives in the jbod mode, where - the timestamps can be generated by different clocks. - - Reviewed-by: Jacob Keller - Signed-off-by: Miroslav Lichvar - -diff --git a/port.c b/port.c -index b5b775f..ec5c92e 100644 ---- a/port.c -+++ b/port.c -@@ -2749,7 +2749,10 @@ static enum fsm_event bc_event(struct port *p, int fd_index) - } - if (msg_sots_valid(msg)) { - ts_add(&msg->hwts.ts, -p->rx_timestamp_offset); -- clock_check_ts(p->clock, tmv_to_nanoseconds(msg->hwts.ts)); -+ if (p->state == PS_SLAVE) { -+ clock_check_ts(p->clock, -+ tmv_to_nanoseconds(msg->hwts.ts)); -+ } - } - - switch (msg_type(msg)) { - -commit 6df84259647757bc53818a039734f8ff85618c02 -Author: Miroslav Lichvar -Date: Mon May 31 11:07:55 2021 +0200 - - port: Don't renew raw transport. - - Renewing of the transport on announce/sync timeout is needed in the - client-only mode to avoid getting stuck with a broken multicast socket - when the link goes down. - - This shouldn't be necessary with the raw transport. Closing and binding - of raw sockets can apparently be so slow that it triggers a false - positive in the clock check. - - Reported-by: Amar Subramanyam - Signed-off-by: Miroslav Lichvar - Reviewed-by: Jacob Keller - -diff --git a/port.c b/port.c -index ec5c92e..c057591 100644 ---- a/port.c -+++ b/port.c -@@ -1811,6 +1811,12 @@ static int port_renew_transport(struct port *p) - if (!port_is_enabled(p)) { - return 0; - } -+ -+ /* Closing and binding of raw sockets is too slow and unnecessary */ -+ if (transport_type(p->trp) == TRANS_IEEE_802_3) { -+ return 0; -+ } -+ - transport_close(p->trp, &p->fda); - port_clear_fda(p, FD_FIRST_TIMER); - res = transport_open(p->trp, p->iface, &p->fda, p->timestamping); - -commit a082bcd700e4955ebaa00d7039bf4bce92048ac4 -Author: Miroslav Lichvar -Date: Mon May 31 11:07:56 2021 +0200 - - clockcheck: Increase minimum interval. - - Increase the minimum check interval to 1 second to measure the frequency - offset more accurately and with default configuration make false - positives less likely due to a heavily overloaded system. - - Signed-off-by: Miroslav Lichvar - Reviewed-by: Jacob Keller - -diff --git a/clockcheck.c b/clockcheck.c -index d0b4714..f0141be 100644 ---- a/clockcheck.c -+++ b/clockcheck.c -@@ -23,7 +23,7 @@ - #include "clockcheck.h" - #include "print.h" - --#define CHECK_MIN_INTERVAL 100000000 -+#define CHECK_MIN_INTERVAL 1000000000 - #define CHECK_MAX_FREQ 900000000 - - struct clockcheck { diff --git a/linuxptp-deftxtout.patch b/linuxptp-deftxtout.patch deleted file mode 100644 index f47e24e..0000000 --- a/linuxptp-deftxtout.patch +++ /dev/null @@ -1,82 +0,0 @@ -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/linuxptp-deprecated.patch b/linuxptp-deprecated.patch new file mode 100644 index 0000000..ae3e4c1 --- /dev/null +++ b/linuxptp-deprecated.patch @@ -0,0 +1,23 @@ +commit 99603cf0ab2413d59ae91101429b18d9ced6f88f +Author: Miroslav Lichvar +Date: Thu Jan 11 11:29:34 2024 +0100 + + config: Disable warnings about deprecated options. + + Signed-off-by: Miroslav Lichvar + +diff --git a/config.c b/config.c +index ad675c8..398b420 100644 +--- a/config.c ++++ b/config.c +@@ -750,8 +750,10 @@ static void check_deprecated_options(const char **option) + } + + if (new_option) { ++#if 0 + fprintf(stderr, "option %s is deprecated, please use %s instead\n", + *option, new_option); ++#endif + *option = new_option; + } + } diff --git a/linuxptp-eintr.patch b/linuxptp-eintr.patch deleted file mode 100644 index 2ea76ad..0000000 --- a/linuxptp-eintr.patch +++ /dev/null @@ -1,30 +0,0 @@ -commit c8de9f33e437fb15cff32c0028f651d7cb916a37 -Author: Miroslav Lichvar -Date: Tue Sep 13 13:44:10 2022 +0200 - - sk: Handle EINTR when waiting for transmit timestamp. - - If ptp4l received a signal in poll() waiting for a transmit timestamp, - multiple (possibly confusing) error messages are logged before exit. - - If poll() returns with EINTR, call it once again to get the timestamp - and avoid logging the errors. Don't call it in a loop to avoid getting - stuck in case the timestamp is lost and the signal is repeated before - the poll timeout can be reached. - - Signed-off-by: Miroslav Lichvar - -diff --git a/sk.c b/sk.c -index 80075be..d27abff 100644 ---- a/sk.c -+++ b/sk.c -@@ -354,6 +354,9 @@ int sk_receive(int fd, void *buf, int buflen, - if (flags == MSG_ERRQUEUE) { - struct pollfd pfd = { fd, sk_events, 0 }; - res = poll(&pfd, 1, sk_tx_timeout); -+ /* Retry once on EINTR to avoid logging errors before exit */ -+ if (res < 0 && errno == EINTR) -+ res = poll(&pfd, 1, sk_tx_timeout); - if (res < 1) { - pr_err(res ? "poll for tx timestamp failed: %m" : - "timed out while polling for tx timestamp"); diff --git a/linuxptp-faultrearm.patch b/linuxptp-faultrearm.patch deleted file mode 100644 index b298f79..0000000 --- a/linuxptp-faultrearm.patch +++ /dev/null @@ -1,52 +0,0 @@ -commit 134dc3c4655fcd9f314a5e56cd50db2f87366f5a -Author: davidjm via Linuxptp-devel -Date: Wed Nov 23 15:50:30 2022 -0800 - - Don't re-arm fault clearing timer on unrelated netlink events - - Set the timer only when an event causes the port to transition to the - FAULTY state, rather than potentially re-arming the timeout when an - event occurs while the port was already FAULTY. - - Concretely this occurs when a port is in fault, perhaps due to a - single time out while polling for tx-timestamp. If any other port in the - system (including unrelated ones ptp4l does not even know about) cause - netlink messages to be sent. As it stands, clock_poll() will note that - the port is in fault (from before, not due to the current event) and - reset the timeout to its original value. - - If such unrelated netlink messages arrive at a regular enough cadence - the timeout may be repeatedly reset, not trigger on time (if at all) and - the port may not get a chance to clear its fault, perhaps indefinitely. - - Signed-off-by: David Mirabito - -diff --git a/clock.c b/clock.c -index eea7983..451473e 100644 ---- a/clock.c -+++ b/clock.c -@@ -1586,6 +1586,7 @@ void clock_set_sde(struct clock *c, int sde) - int clock_poll(struct clock *c) - { - int cnt, i; -+ enum port_state prior_state; - enum fsm_event event; - struct pollfd *cur; - struct port *p; -@@ -1609,6 +1610,7 @@ int clock_poll(struct clock *c) - /* Let the ports handle their events. */ - for (i = 0; i < N_POLLFD; i++) { - if (cur[i].revents & (POLLIN|POLLPRI|POLLERR)) { -+ prior_state = port_state(p); - if (cur[i].revents & POLLERR) { - pr_err("port %d: unexpected socket error", - port_number(p)); -@@ -1624,7 +1626,7 @@ int clock_poll(struct clock *c) - } - port_dispatch(p, event, 0); - /* Clear any fault after a little while. */ -- if (PS_FAULTY == port_state(p)) { -+ if ((PS_FAULTY == port_state(p)) && (prior_state != PS_FAULTY)) { - clock_fault_timeout(p, 1); - break; - } diff --git a/linuxptp-fclose.patch b/linuxptp-fclose.patch deleted file mode 100644 index bde2872..0000000 --- a/linuxptp-fclose.patch +++ /dev/null @@ -1,22 +0,0 @@ -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/linuxptp-freqcheck.patch b/linuxptp-freqcheck.patch deleted file mode 100644 index 28d1b93..0000000 --- a/linuxptp-freqcheck.patch +++ /dev/null @@ -1,208 +0,0 @@ -commit 513c7457865dba262a43e03fbe9178f4b08ba319 -Author: Miroslav Lichvar -Date: Mon Oct 24 15:25:30 2022 +0200 - - Drop support for old kernels returning zero frequency. - - Kernels before 3.10 had a bug in reading of the system clock frequency, - which was worked around by commit da347d7a36f2 ("ptp4l: Set clock - frequency on start"). - - Drop this workaround and support for the old kernels to make - clockadj_get_freq() useful. - - (Rebased to 3.1.1) - - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index f3df220..9079428 100644 ---- a/clock.c -+++ b/clock.c -@@ -1147,11 +1147,6 @@ struct clock *clock_create(enum clock_type type, struct config *config, - - if (c->clkid != CLOCK_INVALID) { - fadj = (int) clockadj_get_freq(c->clkid); -- /* Due to a bug in older kernels, the reading may silently fail -- and return 0. Set the frequency back to make sure fadj is -- the actual frequency of the clock. */ -- clockadj_set_freq(c->clkid, fadj); -- - /* Disable write phase mode if not implemented by driver */ - if (c->write_phase_mode && !phc_has_writephase(c->clkid)) { - pr_err("clock does not support write phase mode"); -@@ -1746,7 +1741,6 @@ int clock_switch_phc(struct clock *c, int phc_index) - return -1; - } - fadj = (int) clockadj_get_freq(clkid); -- clockadj_set_freq(clkid, fadj); - servo = servo_create(c->config, c->servo_type, -fadj, max_adj, 0); - if (!servo) { - pr_err("Switching PHC, failed to create clock servo"); -diff --git a/phc2sys.c b/phc2sys.c -index 5f6fbaa..af948eb 100644 ---- a/phc2sys.c -+++ b/phc2sys.c -@@ -147,9 +147,6 @@ static struct servo *servo_add(struct phc2sys_private *priv, - - clockadj_init(clock->clkid); - ppb = clockadj_get_freq(clock->clkid); -- /* The reading may silently fail and return 0, reset the frequency to -- make sure ppb is the actual frequency of the clock. */ -- clockadj_set_freq(clock->clkid, ppb); - if (clock->clkid == CLOCK_REALTIME) { - sysclk_set_leap(0); - max_ppb = sysclk_max_freq(); -diff --git a/ts2phc_slave.c b/ts2phc_slave.c -index 749efe5..5541d91 100644 ---- a/ts2phc_slave.c -+++ b/ts2phc_slave.c -@@ -183,10 +183,6 @@ static struct ts2phc_slave *ts2phc_slave_create(struct config *cfg, const char * - pr_debug("PHC slave %s has ptp index %d", device, junk); - - fadj = (int) clockadj_get_freq(slave->clk); -- /* Due to a bug in older kernels, the reading may silently fail -- and return 0. Set the frequency back to make sure fadj is -- the actual frequency of the clock. */ -- clockadj_set_freq(slave->clk, fadj); - - max_adj = phc_max_adj(slave->clk); - - -commit 80d6875b0072c7ea636a5631e590fa72d169c351 -Author: Miroslav Lichvar -Date: Mon Oct 24 15:25:31 2022 +0200 - - Don't accept errors in clockadj_get_freq(). - - Exit if an error is returned from the clock_adjtime() call in - clockadj_get_freq(). No recoverable errors are expected. - - Signed-off-by: Miroslav Lichvar - -diff --git a/clockadj.c b/clockadj.c -index 957dc57..4c920b9 100644 ---- a/clockadj.c -+++ b/clockadj.c -@@ -19,6 +19,7 @@ - - #include - #include -+#include - #include - #include - -@@ -72,6 +73,7 @@ double clockadj_get_freq(clockid_t clkid) - memset(&tx, 0, sizeof(tx)); - if (clock_adjtime(clkid, &tx) < 0) { - pr_err("failed to read out the clock frequency adjustment: %m"); -+ exit(1); - } else { - f = tx.freq / 65.536; - if (clkid == CLOCK_REALTIME && realtime_nominal_tick && tx.tick) - -commit 211cbfe810ef4082d1af8e9b50f65d4f6fd7246a -Author: Miroslav Lichvar -Date: Mon Oct 24 15:25:32 2022 +0200 - - Extend clockcheck to check for changes in frequency. - - Before setting the new frequency offset on a clock update, compare the - current frequency returned by the kernel with the value saved from the - previous update. Print a warning message if the difference is larger - than 1 ppb, allowing for rounding errors in conversion to and from - double. The kernel caches the value set by clock_adjtime() in shifted - ppm, it doesn't request it from the driver, which can have a lower - resulution. - - This should detect misconfigurations where multiple processes are trying - to control the clock (e.g. another ptp4l/phc2sys instance or an NTP - client), even when they don't step the clock. - - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index 9079428..eea7983 100644 ---- a/clock.c -+++ b/clock.c -@@ -1760,6 +1760,9 @@ int clock_switch_phc(struct clock *c, int phc_index) - - static void clock_synchronize_locked(struct clock *c, double adj) - { -+ if (c->sanity_check) { -+ clockcheck_freq(c->sanity_check, clockadj_get_freq(c->clkid)); -+ } - clockadj_set_freq(c->clkid, -adj); - if (c->clkid == CLOCK_REALTIME) { - sysclk_set_sync(); -diff --git a/clockcheck.c b/clockcheck.c -index f0141be..b5a69cc 100644 ---- a/clockcheck.c -+++ b/clockcheck.c -@@ -123,6 +123,16 @@ void clockcheck_set_freq(struct clockcheck *cc, int freq) - cc->freq_known = 1; - } - -+int clockcheck_freq(struct clockcheck *cc, int freq) -+{ -+ /* Allow difference of 1 ppb due to conversion to/from double */ -+ if (cc->freq_known && abs(cc->current_freq - freq) > 1) { -+ pr_warning("clockcheck: clock frequency changed unexpectedly!"); -+ return 1; -+ } -+ return 0; -+} -+ - void clockcheck_step(struct clockcheck *cc, int64_t step) - { - if (cc->last_ts) -diff --git a/clockcheck.h b/clockcheck.h -index 1ff86eb..4b09b98 100644 ---- a/clockcheck.h -+++ b/clockcheck.h -@@ -54,6 +54,14 @@ int clockcheck_sample(struct clockcheck *cc, uint64_t ts); - */ - void clockcheck_set_freq(struct clockcheck *cc, int freq); - -+/** -+ * Check whether the frequency correction did not change unexpectedly. -+ * @param cc Pointer to a clock check obtained via @ref clockcheck_create(). -+ * @param freq Current reading of the frequency correction in ppb. -+ * @return Zero if the frequency did not change, non-zero otherwise. -+ */ -+int clockcheck_freq(struct clockcheck *cc, int freq); -+ - /** - * Inform clock check that the clock was stepped. - * @param cc Pointer to a clock check obtained via @ref clockcheck_create(). -diff --git a/phc2sys.c b/phc2sys.c -index af948eb..4daa1bf 100644 ---- a/phc2sys.c -+++ b/phc2sys.c -@@ -566,6 +566,9 @@ static void update_clock(struct phc2sys_private *priv, struct clock *clock, - /* Fall through. */ - case SERVO_LOCKED: - case SERVO_LOCKED_STABLE: -+ if (clock->sanity_check) -+ clockcheck_freq(clock->sanity_check, -+ clockadj_get_freq(clock->clkid)); - clockadj_set_freq(clock->clkid, -ppb); - if (clock->clkid == CLOCK_REALTIME) - sysclk_set_sync(); -diff --git a/ptp4l.8 b/ptp4l.8 -index 4917240..f760e2b 100644 ---- a/ptp4l.8 -+++ b/ptp4l.8 -@@ -605,8 +605,10 @@ This option used to be called - The maximum allowed frequency offset between uncorrected clock and the system - monotonic clock in parts per billion (ppb). This is used as a sanity check of - the synchronized clock. When a larger offset is measured, a warning message --will be printed and the servo will be reset. When set to 0, the sanity check is --disabled. The default is 200000000 (20%). -+will be printed and the servo will be reset. If the frequency correction set by -+ptp4l changes unexpectedly between updates of the clock (e.g. due to another -+process trying to control the clock), a warning message will be printed. When -+set to 0, the sanity check is disabled. The default is 200000000 (20%). - .TP - .B initial_delay - The initial path delay of the clock in nanoseconds used for synchronization of diff --git a/linuxptp-logmsgs.patch b/linuxptp-logmsgs.patch deleted file mode 100644 index c2a138f..0000000 --- a/linuxptp-logmsgs.patch +++ /dev/null @@ -1,96 +0,0 @@ -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/linuxptp-manfix.patch b/linuxptp-manfix.patch deleted file mode 100644 index 05edfc9..0000000 --- a/linuxptp-manfix.patch +++ /dev/null @@ -1,28 +0,0 @@ -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/linuxptp-packalign.patch b/linuxptp-packalign.patch deleted file mode 100644 index c5ed8a6..0000000 --- a/linuxptp-packalign.patch +++ /dev/null @@ -1,100 +0,0 @@ -commit 25dcf01e340d85bcdbe7b3c24eac7fe1ce7ea0c2 -Author: Miroslav Lichvar -Date: Wed Mar 10 17:05:55 2021 +0100 - - Avoid unaligned pointers to packed members. - - This fixes "taking address of packed member ... may result in an - unaligned pointer value [-Waddress-of-packed-member]" warnings from gcc. - - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index 7005636..f88df58 100644 ---- a/clock.c -+++ b/clock.c -@@ -350,6 +350,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p, - struct time_status_np *tsn; - struct tlv_extra *extra; - struct PTPText *text; -+ uint16_t duration; - int datalen = 0; - - extra = tlv_extra_alloc(); -@@ -452,7 +453,8 @@ static int clock_management_fill_response(struct clock *c, struct port *p, - break; - } - sen = (struct subscribe_events_np *)tlv->data; -- clock_get_subscription(c, req, sen->bitmask, &sen->duration); -+ clock_get_subscription(c, req, sen->bitmask, &duration); -+ memcpy(&sen->duration, &duration, sizeof(sen->duration)); - datalen = sizeof(*sen); - break; - case TLV_SYNCHRONIZATION_UNCERTAIN_NP: -diff --git a/msg.c b/msg.c -index c4516ad..dcb397c 100644 ---- a/msg.c -+++ b/msg.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -36,8 +37,8 @@ int assume_two_step = 0; - - struct message_storage { - unsigned char reserved[MSG_HEADROOM]; -- struct ptp_message msg; --} PACKED; -+ struct ptp_message msg __attribute__((aligned (8))); -+}; - - static TAILQ_HEAD(msg_pool, ptp_message) msg_pool = TAILQ_HEAD_INITIALIZER(msg_pool); - -diff --git a/tlv.c b/tlv.c -index 879bb7e..98ef6e1 100644 ---- a/tlv.c -+++ b/tlv.c -@@ -67,7 +67,7 @@ static void timestamp_net2host(struct Timestamp *t) - NTOHL(t->nanoseconds); - } - --static uint16_t flip16(uint16_t *p) -+static uint16_t flip16(void *p) - { - uint16_t v; - memcpy(&v, p, sizeof(v)); -@@ -76,7 +76,7 @@ static uint16_t flip16(uint16_t *p) - return v; - } - --static int64_t host2net64_unaligned(int64_t *p) -+static int64_t host2net64_unaligned(void *p) - { - int64_t v; - memcpy(&v, p, sizeof(v)); -@@ -85,7 +85,7 @@ static int64_t host2net64_unaligned(int64_t *p) - return v; - } - --static int64_t net2host64_unaligned(int64_t *p) -+static int64_t net2host64_unaligned(void *p) - { - int64_t v; - memcpy(&v, p, sizeof(v)); -diff --git a/util.h b/util.h -index 41e33d4..739c8fd 100644 ---- a/util.h -+++ b/util.h -@@ -57,7 +57,7 @@ const char *ts_str(enum timestamp_type ts); - */ - int addreq(enum transport_type type, struct address *a, struct address *b); - --static inline uint16_t align16(uint16_t *p) -+static inline uint16_t align16(void *p) - { - uint16_t v; - memcpy(&v, p, sizeof(v)); diff --git a/linuxptp-phcerr.patch b/linuxptp-phcerr.patch deleted file mode 100644 index cae86b3..0000000 --- a/linuxptp-phcerr.patch +++ /dev/null @@ -1,510 +0,0 @@ -commit f32a8469a236728fb158ce997385b53f92b821cc -Author: Jacob Keller -Date: Tue Nov 23 14:43:26 2021 -0800 - - phc2sys: move read_phc into clock_adj.c - - The read_phc function implemented in phc2sys.c is used to perform clock - comparison between two arbitrary clocks using clock_gettime. - - This support is used to allow phc2sys to work on any pair of clocks and - is implemented in a very similar manner as the kernel PTP_SYS_OFFSET - ioctls. - - Make this function easier to re-use by moving it out of phc2sys.c and - into a more accessible location. clockadj.c seems like a reasonable - location as this file has many functions which deal with clockid_t - values, and this functionality is tangentially related to adjusting - clocks. - - Moving this function will allow using it in the phc_ctl program in a - future change. - - Notice that read_phc returned 0 on failure and 1 on success. This is - fairly non-standard, so lets update clockadj_compare to return 0 on - success and -1 on failure. Fix the call sites to check correctly and - report an error. - - Signed-off-by: Jacob Keller - -diff --git a/clockadj.c b/clockadj.c -index b5c78cd..e8c5789 100644 ---- a/clockadj.c -+++ b/clockadj.c -@@ -139,6 +139,37 @@ int clockadj_max_freq(clockid_t clkid) - return f; - } - -+int clockadj_compare(clockid_t clkid, clockid_t sysclk, int readings, -+ int64_t *offset, uint64_t *ts, int64_t *delay) -+{ -+ struct timespec tdst1, tdst2, tsrc; -+ int i; -+ int64_t interval, best_interval = INT64_MAX; -+ -+ /* Pick the quickest clkid reading. */ -+ for (i = 0; i < readings; i++) { -+ if (clock_gettime(sysclk, &tdst1) || -+ clock_gettime(clkid, &tsrc) || -+ clock_gettime(sysclk, &tdst2)) { -+ pr_err("failed to read clock: %m"); -+ return -1; -+ } -+ -+ interval = (tdst2.tv_sec - tdst1.tv_sec) * NS_PER_SEC + -+ tdst2.tv_nsec - tdst1.tv_nsec; -+ -+ if (best_interval > interval) { -+ best_interval = interval; -+ *offset = (tdst1.tv_sec - tsrc.tv_sec) * NS_PER_SEC + -+ tdst1.tv_nsec - tsrc.tv_nsec + interval / 2; -+ *ts = tdst2.tv_sec * NS_PER_SEC + tdst2.tv_nsec; -+ } -+ } -+ *delay = best_interval; -+ -+ return 0; -+} -+ - void sysclk_set_leap(int leap) - { - clockid_t clkid = CLOCK_REALTIME; -diff --git a/clockadj.h b/clockadj.h -index 43325c8..b63ae38 100644 ---- a/clockadj.h -+++ b/clockadj.h -@@ -63,6 +63,24 @@ void clockadj_step(clockid_t clkid, int64_t step); - */ - int clockadj_max_freq(clockid_t clkid); - -+/** -+ * Compare offset between two clocks -+ * @param clkid A clock ID obtained using phc_open() or CLOCK_REALTIME -+ * @param sysclk A clock ID obtained using phc_open() or CLOCK_REALTIME -+ * @param readings Number of readings to try -+ * @param offset On return, the nanoseconds offset between the clocks -+ * @param ts On return, the time of sysclk in nanoseconds that was used -+ * @param delay On return, the interval between two reads of sysclk -+ * @return Zero on success and non-zero on failure. -+ * -+ * Compare the offset between two clocks in a similar manner as the -+ * PTP_SYS_OFFSET ioctls. Performs multiple reads of sysclk with a read of -+ * clkid between in order to calculate the time difference of sysclk minus -+ * clkid. -+ */ -+int clockadj_compare(clockid_t clkid, clockid_t sysclk, int readings, -+ int64_t *offset, uint64_t *ts, int64_t *delay); -+ - /** - * Set the system clock to insert/delete leap second at midnight. - * @param leap +1 to insert leap second, -1 to delete leap second, -diff --git a/phc2sys.c b/phc2sys.c -index a36cbe0..7a547fa 100644 ---- a/phc2sys.c -+++ b/phc2sys.c -@@ -486,37 +486,6 @@ static void reconfigure(struct phc2sys_private *priv) - pr_info("selecting %s as the master clock", src->device); - } - --static int read_phc(clockid_t clkid, clockid_t sysclk, int readings, -- int64_t *offset, uint64_t *ts, int64_t *delay) --{ -- struct timespec tdst1, tdst2, tsrc; -- int i; -- int64_t interval, best_interval = INT64_MAX; -- -- /* Pick the quickest clkid reading. */ -- for (i = 0; i < readings; i++) { -- if (clock_gettime(sysclk, &tdst1) || -- clock_gettime(clkid, &tsrc) || -- clock_gettime(sysclk, &tdst2)) { -- pr_err("failed to read clock: %m"); -- return 0; -- } -- -- interval = (tdst2.tv_sec - tdst1.tv_sec) * NS_PER_SEC + -- tdst2.tv_nsec - tdst1.tv_nsec; -- -- if (best_interval > interval) { -- best_interval = interval; -- *offset = (tdst1.tv_sec - tsrc.tv_sec) * NS_PER_SEC + -- tdst1.tv_nsec - tsrc.tv_nsec + interval / 2; -- *ts = tdst2.tv_sec * NS_PER_SEC + tdst2.tv_nsec; -- } -- } -- *delay = best_interval; -- -- return 1; --} -- - static int64_t get_sync_offset(struct phc2sys_private *priv, struct clock *dst) - { - int direction = priv->forced_sync_offset; -@@ -672,8 +641,10 @@ static int do_pps_loop(struct phc2sys_private *priv, struct clock *clock, - /* If a PHC is available, use it to get the whole number - of seconds in the offset and PPS for the rest. */ - if (src != CLOCK_INVALID) { -- if (!read_phc(src, clock->clkid, priv->phc_readings, -- &phc_offset, &phc_ts, &phc_delay)) -+ if (clockadj_compare(src, clock->clkid, -+ priv->phc_readings, -+ &phc_offset, &phc_ts, -+ &phc_delay)) - return -1; - - /* Convert the time stamp to the PHC time. */ -@@ -781,10 +752,11 @@ static int do_loop(struct phc2sys_private *priv, int subscriptions) - ts += offset; - } else { - /* use phc */ -- if (!read_phc(priv->master->clkid, clock->clkid, -- priv->phc_readings, -- &offset, &ts, &delay)) -- continue; -+ if (clockadj_compare(priv->master->clkid, -+ clock->clkid, -+ priv->phc_readings, -+ &offset, &ts, &delay)) -+ return -1; - } - update_clock(priv, clock, offset, ts, delay); - } - -commit 96486bda9ac1613fb36feb84d76ababd8972bba6 -Author: Miroslav Lichvar -Date: Tue May 17 12:31:45 2022 +0200 - - clockadj: Change clockadj_compare() to return errno. - - Return -errno from the failed clock_gettime() to allow the callers to - check for specific errors. - - Signed-off-by: Miroslav Lichvar - -diff --git a/clockadj.c b/clockadj.c -index e8c5789..957dc57 100644 ---- a/clockadj.c -+++ b/clockadj.c -@@ -17,6 +17,7 @@ - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -+#include - #include - #include - #include -@@ -152,7 +153,7 @@ int clockadj_compare(clockid_t clkid, clockid_t sysclk, int readings, - clock_gettime(clkid, &tsrc) || - clock_gettime(sysclk, &tdst2)) { - pr_err("failed to read clock: %m"); -- return -1; -+ return -errno; - } - - interval = (tdst2.tv_sec - tdst1.tv_sec) * NS_PER_SEC + -diff --git a/clockadj.h b/clockadj.h -index b63ae38..6db1d79 100644 ---- a/clockadj.h -+++ b/clockadj.h -@@ -71,7 +71,7 @@ int clockadj_max_freq(clockid_t clkid); - * @param offset On return, the nanoseconds offset between the clocks - * @param ts On return, the time of sysclk in nanoseconds that was used - * @param delay On return, the interval between two reads of sysclk -- * @return Zero on success and non-zero on failure. -+ * @return Zero on success, or negative error code on failure. - * - * Compare the offset between two clocks in a similar manner as the - * PTP_SYS_OFFSET ioctls. Performs multiple reads of sysclk with a read of - -commit a523e893a15001025379e3c2dedb231e99cc886f -Author: Miroslav Lichvar -Date: Thu Mar 24 11:55:35 2022 +0100 - - sysoff: Change sysoff_measure() to return errno. - - Return -errno from failed ioctl instead of the SYSOFF_* enum from the - measurement functions to allow the callers to check for specific errors. - - Signed-off-by: Miroslav Lichvar - -diff --git a/sysoff.c b/sysoff.c -index 2743859..5d3b907 100644 ---- a/sysoff.c -+++ b/sysoff.c -@@ -17,6 +17,7 @@ - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -+#include - #include - #include - #include -@@ -38,11 +39,11 @@ static int sysoff_precise(int fd, int64_t *result, uint64_t *ts) - 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; -+ return -errno; - } - *result = pctns(&pso.sys_realtime) - pctns(&pso.device); - *ts = pctns(&pso.sys_realtime); -- return SYSOFF_PRECISE; -+ return 0; - } - - static int64_t sysoff_estimate(struct ptp_clock_time *pct, int extended, -@@ -98,10 +99,10 @@ static int sysoff_extended(int fd, int n_samples, - 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; -+ return -errno; - } - *result = sysoff_estimate(&pso.ts[0][0], 1, n_samples, ts, delay); -- return SYSOFF_EXTENDED; -+ return 0; - } - - static int sysoff_basic(int fd, int n_samples, -@@ -112,10 +113,10 @@ static int sysoff_basic(int fd, int n_samples, - pso.n_samples = n_samples; - if (ioctl(fd, PTP_SYS_OFFSET, &pso)) { - perror("ioctl PTP_SYS_OFFSET"); -- return SYSOFF_RUN_TIME_MISSING; -+ return -errno; - } - *result = sysoff_estimate(pso.ts, 0, n_samples, ts, delay); -- return SYSOFF_BASIC; -+ return 0; - } - - int sysoff_measure(int fd, int method, int n_samples, -@@ -130,7 +131,7 @@ int sysoff_measure(int fd, int method, int n_samples, - case SYSOFF_BASIC: - return sysoff_basic(fd, n_samples, result, ts, delay); - } -- return SYSOFF_RUN_TIME_MISSING; -+ return -EOPNOTSUPP; - } - - int sysoff_probe(int fd, int n_samples) -diff --git a/sysoff.h b/sysoff.h -index e4de919..5480f8f 100644 ---- a/sysoff.h -+++ b/sysoff.h -@@ -44,7 +44,7 @@ int sysoff_probe(int fd, int n_samples); - * @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. -+ * @return Zero on success, negative error code otherwise. - */ - int sysoff_measure(int fd, int method, int n_samples, - int64_t *result, uint64_t *ts, int64_t *delay); - -commit 25b340eb1daad807d9485728f0917ec25a376e0c -Author: Miroslav Lichvar -Date: Wed May 18 10:21:29 2022 +0200 - - sysoff: Change log level of ioctl error messages. - - Change the log level of ioctl error messages to the error level to make - them visible in default configuration, with the exception of EOPNOTSUPP - which is expected in probing and should stay at the debug level to avoid - confusing users. - - Signed-off-by: Miroslav Lichvar - -diff --git a/sysoff.c b/sysoff.c -index 5d3b907..a425275 100644 ---- a/sysoff.c -+++ b/sysoff.c -@@ -28,6 +28,14 @@ - - #define NS_PER_SEC 1000000000LL - -+static void print_ioctl_error(const char *name) -+{ -+ if (errno == EOPNOTSUPP) -+ pr_debug("ioctl %s: %s", name, strerror(errno)); -+ else -+ pr_err("ioctl %s: %s", name, strerror(errno)); -+} -+ - static int64_t pctns(struct ptp_clock_time *t) - { - return t->sec * NS_PER_SEC + t->nsec; -@@ -38,7 +46,7 @@ static int sysoff_precise(int fd, int64_t *result, uint64_t *ts) - 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"); -+ print_ioctl_error("PTP_SYS_OFFSET_PRECISE"); - return -errno; - } - *result = pctns(&pso.sys_realtime) - pctns(&pso.device); -@@ -98,7 +106,7 @@ static int sysoff_extended(int fd, int n_samples, - 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"); -+ print_ioctl_error("PTP_SYS_OFFSET_EXTENDED"); - return -errno; - } - *result = sysoff_estimate(&pso.ts[0][0], 1, n_samples, ts, delay); -@@ -112,7 +120,7 @@ static int sysoff_basic(int fd, int n_samples, - memset(&pso, 0, sizeof(pso)); - pso.n_samples = n_samples; - if (ioctl(fd, PTP_SYS_OFFSET, &pso)) { -- perror("ioctl PTP_SYS_OFFSET"); -+ print_ioctl_error("PTP_SYS_OFFSET"); - return -errno; - } - *result = sysoff_estimate(pso.ts, 0, n_samples, ts, delay); - -commit 755cf11ad6e5d02e11519b6e2644ee0f71da91ea -Author: Miroslav Lichvar -Date: Thu Mar 24 12:41:49 2022 +0100 - - sysoff: Retry on EBUSY when probing supported ioctls. - - Handle EBUSY when probing support for a PTP_SYS_OFFSET ioctl. Try each - ioctl up to three times before giving up on it to make the detection - more reliable. - - Signed-off-by: Miroslav Lichvar - -diff --git a/sysoff.c b/sysoff.c -index a425275..fc1f7ca 100644 ---- a/sysoff.c -+++ b/sysoff.c -@@ -145,8 +145,8 @@ int sysoff_measure(int fd, int method, int n_samples, - int sysoff_probe(int fd, int n_samples) - { - int64_t junk, delay; -+ int i, j, err; - uint64_t ts; -- int i; - - if (n_samples > PTP_MAX_SAMPLES) { - fprintf(stderr, "warning: %d exceeds kernel max readings %d\n", -@@ -156,9 +156,15 @@ int sysoff_probe(int fd, int n_samples) - } - - for (i = 0; i < SYSOFF_LAST; i++) { -- if (sysoff_measure(fd, i, n_samples, &junk, &ts, &delay) < 0) -- continue; -- return i; -+ for (j = 0; j < 3; j++) { -+ err = sysoff_measure(fd, i, n_samples, &junk, &ts, -+ &delay); -+ if (err == -EBUSY) -+ continue; -+ if (err) -+ break; -+ return i; -+ } - } - - return SYSOFF_RUN_TIME_MISSING; - -commit d1e8ea2405a42b42bcaf2166717fe0da6e9871ae -Author: Miroslav Lichvar -Date: Tue Mar 8 12:18:31 2022 +0100 - - phc2sys: Don't exit when reading of PHC fails with EBUSY. - - Reading of the PHC can occasionally fail with some drivers, e.g. the ice - driver returns EBUSY when it fails to get a lock. Continue in the loop - instead of exiting on the error. - - Signed-off-by: Miroslav Lichvar - -diff --git a/phc2sys.c b/phc2sys.c -index 7a547fa..b4e2e87 100644 ---- a/phc2sys.c -+++ b/phc2sys.c -@@ -623,6 +623,7 @@ static int do_pps_loop(struct phc2sys_private *priv, struct clock *clock, - int64_t pps_offset, phc_offset, phc_delay; - uint64_t pps_ts, phc_ts; - clockid_t src = priv->master->clkid; -+ int err; - - priv->master->source_label = "pps"; - -@@ -641,10 +642,13 @@ static int do_pps_loop(struct phc2sys_private *priv, struct clock *clock, - /* If a PHC is available, use it to get the whole number - of seconds in the offset and PPS for the rest. */ - if (src != CLOCK_INVALID) { -- if (clockadj_compare(src, clock->clkid, -- priv->phc_readings, -- &phc_offset, &phc_ts, -- &phc_delay)) -+ err = clockadj_compare(src, clock->clkid, -+ priv->phc_readings, -+ &phc_offset, &phc_ts, -+ &phc_delay); -+ if (err == -EBUSY) -+ continue; -+ if (err) - return -1; - - /* Convert the time stamp to the PHC time. */ -@@ -692,6 +696,7 @@ static int do_loop(struct phc2sys_private *priv, int subscriptions) - struct clock *clock; - uint64_t ts; - int64_t offset, delay; -+ int err; - - interval.tv_sec = priv->phc_interval; - interval.tv_nsec = (priv->phc_interval - interval.tv_sec) * 1e9; -@@ -735,29 +740,32 @@ static int do_loop(struct phc2sys_private *priv, int subscriptions) - if (clock->clkid == CLOCK_REALTIME && - priv->master->sysoff_method >= 0) { - /* use sysoff */ -- if (sysoff_measure(CLOCKID_TO_FD(priv->master->clkid), -- priv->master->sysoff_method, -- priv->phc_readings, -- &offset, &ts, &delay) < 0) -- return -1; -+ err = sysoff_measure(CLOCKID_TO_FD(priv->master->clkid), -+ priv->master->sysoff_method, -+ priv->phc_readings, -+ &offset, &ts, &delay); - } else if (priv->master->clkid == CLOCK_REALTIME && - clock->sysoff_method >= 0) { - /* use reversed sysoff */ -- if (sysoff_measure(CLOCKID_TO_FD(clock->clkid), -- clock->sysoff_method, -- priv->phc_readings, -- &offset, &ts, &delay) < 0) -- return -1; -- offset = -offset; -- ts += offset; -+ err = sysoff_measure(CLOCKID_TO_FD(clock->clkid), -+ clock->sysoff_method, -+ priv->phc_readings, -+ &offset, &ts, &delay); -+ if (!err) { -+ offset = -offset; -+ ts += offset; -+ } - } else { - /* use phc */ -- if (clockadj_compare(priv->master->clkid, -- clock->clkid, -- priv->phc_readings, -- &offset, &ts, &delay)) -- return -1; -+ err = clockadj_compare(priv->master->clkid, -+ clock->clkid, -+ priv->phc_readings, -+ &offset, &ts, &delay); - } -+ if (err == -EBUSY) -+ continue; -+ if (err) -+ return -1; - update_clock(priv, clock, offset, ts, delay); - } - } diff --git a/linuxptp-ptpver.patch b/linuxptp-ptpver.patch new file mode 100644 index 0000000..ca7bad7 --- /dev/null +++ b/linuxptp-ptpver.patch @@ -0,0 +1,60 @@ +commit 6e480c9572925a4ea8aac45a10a306e0c4e509a9 +Author: Miroslav Lichvar +Date: Thu Jan 11 11:33:54 2024 +0100 + + Revert default PTP version to 2.0 for better compatibility. + + Signed-off-by: Miroslav Lichvar + +diff --git a/config.c b/config.c +index 398b420..d7775c0 100644 +--- a/config.c ++++ b/config.c +@@ -319,7 +319,7 @@ struct config_item config_tab[] = { + GLOB_ITEM_STR("productDescription", ";;"), + PORT_ITEM_STR("ptp_dst_mac", "01:1B:19:00:00:00"), + PORT_ITEM_STR("p2p_dst_mac", "01:80:C2:00:00:0E"), +- GLOB_ITEM_INT("ptp_minor_version", 1, 0, 1), ++ GLOB_ITEM_INT("ptp_minor_version", 0, 0, 1), + GLOB_ITEM_STR("refclock_sock_address", "/var/run/refclock.ptp.sock"), + GLOB_ITEM_STR("revisionData", ";;"), + GLOB_ITEM_INT("sanity_freq_limit", 200000000, 0, INT_MAX), +diff --git a/configs/default.cfg b/configs/default.cfg +index 0c7661c..8f94c16 100644 +--- a/configs/default.cfg ++++ b/configs/default.cfg +@@ -46,7 +46,7 @@ power_profile.2011.networkTimeInaccuracy -1 + power_profile.2017.totalTimeInaccuracy -1 + power_profile.grandmasterID 0 + power_profile.version none +-ptp_minor_version 1 ++ptp_minor_version 0 + # + # Run time options + # +diff --git a/msg.h b/msg.h +index 9c80f45..786ddc7 100644 +--- a/msg.h ++++ b/msg.h +@@ -32,7 +32,7 @@ + + /* Version definition for IEEE 1588-2019 */ + #define PTP_MAJOR_VERSION 2 +-#define PTP_MINOR_VERSION 1 ++#define PTP_MINOR_VERSION 0 + #define PTP_VERSION (PTP_MINOR_VERSION << 4 | PTP_MAJOR_VERSION) + + #define MAJOR_VERSION_MASK 0x0f +diff --git a/ptp4l.8 b/ptp4l.8 +index 4cb9adb..c59b0b4 100644 +--- a/ptp4l.8 ++++ b/ptp4l.8 +@@ -813,7 +813,7 @@ The default is 128. + .TP + .B ptp_minor_version + This option sets the minorVersionPTP in the common PTP message header. +-The default is 1. ++The default (specific to the installed linuxptp package) is 0. + + .TP + .B refclock_sock_address diff --git a/linuxptp-soerror.patch b/linuxptp-soerror.patch deleted file mode 100644 index 6ff6958..0000000 --- a/linuxptp-soerror.patch +++ /dev/null @@ -1,84 +0,0 @@ -commit 2db8da6d1e3db074c01516c74899d42089039bc8 -Author: Miroslav Lichvar -Date: Wed Apr 26 13:45:41 2023 +0200 - - Clear pending errors on sockets. - - When the netlink socket of a port (used for receiving link up/down - events) had an error (e.g. ENOBUFS due to the kernel sending too many - messages), ptp4l switched the port to the faulty state, but it kept - getting POLLERR on the socket and logged "port 1: unexpected socket - error" in an infinite loop. - - Unlike the PTP event and general sockets, the netlink sockets cannot be - closed in the faulty state as they are needed to receive the link up event. - - Instead, receive and clear the error on all descriptors getting POLLERR - with getsockopt(SO_ERROR). Include the error in the log message together - with the descriptor index to make it easier to debug issues like this in - future. - - (Rebased to 3.1.1) - - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index 469aab6..2821fc4 100644 ---- a/clock.c -+++ b/clock.c -@@ -1611,8 +1611,10 @@ int clock_poll(struct clock *c) - if (cur[i].revents & (POLLIN|POLLPRI|POLLERR)) { - prior_state = port_state(p); - if (cur[i].revents & POLLERR) { -- pr_err("port %d: unexpected socket error", -- port_number(p)); -+ int error = sk_get_error(cur[i].fd); -+ pr_err("port %d: error on fda[%d]: %s", -+ port_number(p), i, -+ strerror(error)); - event = EV_FAULT_DETECTED; - } else { - event = port_event(p, i); -diff --git a/sk.c b/sk.c -index 3595649..47d8c3b 100644 ---- a/sk.c -+++ b/sk.c -@@ -413,6 +413,20 @@ int sk_receive(int fd, void *buf, int buflen, - return cnt < 0 ? -errno : cnt; - } - -+int sk_get_error(int fd) -+{ -+ socklen_t len; -+ int error; -+ -+ len = sizeof (error); -+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { -+ pr_err("getsockopt SO_ERROR failed: %m"); -+ return -1; -+ } -+ -+ return error; -+} -+ - int sk_set_priority(int fd, int family, uint8_t dscp) - { - int level, optname, tos; -diff --git a/sk.h b/sk.h -index 04d26ee..ba88e2f 100644 ---- a/sk.h -+++ b/sk.h -@@ -109,6 +109,13 @@ int sk_interface_addr(const char *name, int family, struct address *addr); - int sk_receive(int fd, void *buf, int buflen, - struct address *addr, struct hw_timestamp *hwts, int flags); - -+/** -+ * Get and clear a pending socket error. -+ * @param fd An open socket. -+ * @return The error. -+ */ -+int sk_get_error(int fd); -+ - /** - * Set DSCP value for socket. - * @param fd An open socket. diff --git a/linuxptp-subscribe.patch b/linuxptp-subscribe.patch new file mode 100644 index 0000000..2bdf033 --- /dev/null +++ b/linuxptp-subscribe.patch @@ -0,0 +1,26 @@ +commit b421a4c66ce636adff150dd1aa8eafa981c2693d +Author: Miroslav Lichvar +Date: Wed Jan 3 14:45:51 2024 +0100 + + pmc: Allow missing values in SUBSCRIBE_EVENTS_NP command. + + Don't require all supported notifications to be specified in the command + for compatibility with older scripts. + + Signed-off-by: Miroslav Lichvar + +diff --git a/pmc_common.c b/pmc_common.c +index 62e34a6..b88cfc2 100644 +--- a/pmc_common.c ++++ b/pmc_common.c +@@ -310,8 +310,8 @@ static void do_set_action(struct pmc *pmc, int action, int index, char *str) + onoff_port_state, + onoff_time_status, + onoff_parent_data_set); +- if (cnt != 4) { +- fprintf(stderr, "%s SET needs 4 values\n", ++ if (cnt < 2) { ++ fprintf(stderr, "%s SET needs at least 2 values\n", + idtab[index].name); + break; + } diff --git a/linuxptp-udsro.patch b/linuxptp-udsro.patch deleted file mode 100644 index 7030553..0000000 --- a/linuxptp-udsro.patch +++ /dev/null @@ -1,614 +0,0 @@ -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/linuxptp-vclock.patch b/linuxptp-vclock.patch index 3c87694..94a8ff8 100644 --- a/linuxptp-vclock.patch +++ b/linuxptp-vclock.patch @@ -1,1463 +1,11 @@ -Patches backported from the upstream repository. - -commit 6d2e07353d042b845da60dc6e3a20a71932678d0 -Author: Miroslav Lichvar -Date: Tue Mar 8 11:46:58 2022 +0100 - - rtnl: Fix rtnl_rtattr_parse() to process max attribute. - - Initialize the whole array passed to rtnl_rtattr_parse() and don't - ignore the last attribute with the maximum value. This will be needed to - get the ETHTOOL_A_PHC_VCLOCKS_INDEX attribute. - - Signed-off-by: Miroslav Lichvar - Acked-by: Hangbin Liu - -diff --git a/rtnl.c b/rtnl.c -index b7a2667..b02e07d 100644 ---- a/rtnl.c -+++ b/rtnl.c -@@ -178,10 +178,10 @@ static int rtnl_rtattr_parse(struct rtattr *tb[], int max, struct rtattr *rta, i - { - unsigned short type; - -- memset(tb, 0, sizeof(struct rtattr *) * max); -+ memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); - while (RTA_OK(rta, len)) { - type = rta->rta_type; -- if ((type < max) && (!tb[type])) -+ if ((type <= max) && (!tb[type])) - tb[type] = rta; - rta = RTA_NEXT(rta, len); - } -@@ -200,8 +200,8 @@ static inline int rtnl_nested_rtattr_parse(struct rtattr *tb[], int max, struct - - static int rtnl_linkinfo_parse(int master_index, struct rtattr *rta) - { -- struct rtattr *linkinfo[IFLA_INFO_MAX]; -- struct rtattr *bond[IFLA_BOND_MAX]; -+ struct rtattr *linkinfo[IFLA_INFO_MAX+1]; -+ struct rtattr *bond[IFLA_BOND_MAX+1]; - int index = -1; - char *kind; - -commit 8c557a7c7e5eebc6f0d7e1de44c53791fba265c1 -Author: Miroslav Lichvar -Date: Tue Mar 8 11:46:59 2022 +0100 - - rtnl: Add function to detect virtual clocks. - - Add a function using ethtool netlink to check whether a PHC is a virtual - clock of an interface. - - Signed-off-by: Miroslav Lichvar - Acked-by: Hangbin Liu - -diff --git a/incdefs.sh b/incdefs.sh -index 19e620e..21333e5 100755 ---- a/incdefs.sh -+++ b/incdefs.sh -@@ -86,6 +86,10 @@ kernel_flags() - if grep -q HWTSTAMP_TX_ONESTEP_P2P ${prefix}${tstamp}; then - printf " -DHAVE_ONESTEP_P2P" - fi -+ -+ if grep -q SOF_TIMESTAMPING_BIND_PHC ${prefix}${tstamp}; then -+ printf " -DHAVE_VCLOCKS" -+ fi - } - - flags="$(user_flags)$(kernel_flags)" -diff --git a/missing.h b/missing.h -index 35eaf15..3df7bd1 100644 ---- a/missing.h -+++ b/missing.h -@@ -251,6 +251,107 @@ enum { - #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) - #endif /*NLA_TYPE_MAX*/ - -+#ifndef ETHTOOL_GENL_NAME -+#define ETHTOOL_GENL_NAME "ethtool" -+#define ETHTOOL_GENL_VERSION 1 -+#endif -+ -+#ifndef HAVE_VCLOCKS -+enum { -+ ETHTOOL_MSG_USER_NONE, -+ ETHTOOL_MSG_STRSET_GET, -+ ETHTOOL_MSG_LINKINFO_GET, -+ ETHTOOL_MSG_LINKINFO_SET, -+ ETHTOOL_MSG_LINKMODES_GET, -+ ETHTOOL_MSG_LINKMODES_SET, -+ ETHTOOL_MSG_LINKSTATE_GET, -+ ETHTOOL_MSG_DEBUG_GET, -+ ETHTOOL_MSG_DEBUG_SET, -+ ETHTOOL_MSG_WOL_GET, -+ ETHTOOL_MSG_WOL_SET, -+ ETHTOOL_MSG_FEATURES_GET, -+ ETHTOOL_MSG_FEATURES_SET, -+ ETHTOOL_MSG_PRIVFLAGS_GET, -+ ETHTOOL_MSG_PRIVFLAGS_SET, -+ ETHTOOL_MSG_RINGS_GET, -+ ETHTOOL_MSG_RINGS_SET, -+ ETHTOOL_MSG_CHANNELS_GET, -+ ETHTOOL_MSG_CHANNELS_SET, -+ ETHTOOL_MSG_COALESCE_GET, -+ ETHTOOL_MSG_COALESCE_SET, -+ ETHTOOL_MSG_PAUSE_GET, -+ ETHTOOL_MSG_PAUSE_SET, -+ ETHTOOL_MSG_EEE_GET, -+ ETHTOOL_MSG_EEE_SET, -+ ETHTOOL_MSG_TSINFO_GET, -+ ETHTOOL_MSG_CABLE_TEST_ACT, -+ ETHTOOL_MSG_CABLE_TEST_TDR_ACT, -+ ETHTOOL_MSG_TUNNEL_INFO_GET, -+ ETHTOOL_MSG_FEC_GET, -+ ETHTOOL_MSG_FEC_SET, -+ ETHTOOL_MSG_MODULE_EEPROM_GET, -+ ETHTOOL_MSG_STATS_GET, -+ ETHTOOL_MSG_PHC_VCLOCKS_GET, -+}; -+ -+enum { -+ ETHTOOL_MSG_KERNEL_NONE, -+ ETHTOOL_MSG_STRSET_GET_REPLY, -+ ETHTOOL_MSG_LINKINFO_GET_REPLY, -+ ETHTOOL_MSG_LINKINFO_NTF, -+ ETHTOOL_MSG_LINKMODES_GET_REPLY, -+ ETHTOOL_MSG_LINKMODES_NTF, -+ ETHTOOL_MSG_LINKSTATE_GET_REPLY, -+ ETHTOOL_MSG_DEBUG_GET_REPLY, -+ ETHTOOL_MSG_DEBUG_NTF, -+ ETHTOOL_MSG_WOL_GET_REPLY, -+ ETHTOOL_MSG_WOL_NTF, -+ ETHTOOL_MSG_FEATURES_GET_REPLY, -+ ETHTOOL_MSG_FEATURES_SET_REPLY, -+ ETHTOOL_MSG_FEATURES_NTF, -+ ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, -+ ETHTOOL_MSG_PRIVFLAGS_NTF, -+ ETHTOOL_MSG_RINGS_GET_REPLY, -+ ETHTOOL_MSG_RINGS_NTF, -+ ETHTOOL_MSG_CHANNELS_GET_REPLY, -+ ETHTOOL_MSG_CHANNELS_NTF, -+ ETHTOOL_MSG_COALESCE_GET_REPLY, -+ ETHTOOL_MSG_COALESCE_NTF, -+ ETHTOOL_MSG_PAUSE_GET_REPLY, -+ ETHTOOL_MSG_PAUSE_NTF, -+ ETHTOOL_MSG_EEE_GET_REPLY, -+ ETHTOOL_MSG_EEE_NTF, -+ ETHTOOL_MSG_TSINFO_GET_REPLY, -+ ETHTOOL_MSG_CABLE_TEST_NTF, -+ ETHTOOL_MSG_CABLE_TEST_TDR_NTF, -+ ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY, -+ ETHTOOL_MSG_FEC_GET_REPLY, -+ ETHTOOL_MSG_FEC_NTF, -+ ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, -+ ETHTOOL_MSG_STATS_GET_REPLY, -+ ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY, -+}; -+ -+enum { -+ ETHTOOL_A_HEADER_UNSPEC, -+ ETHTOOL_A_HEADER_DEV_INDEX, /* u32 */ -+ ETHTOOL_A_HEADER_DEV_NAME, /* string */ -+ ETHTOOL_A_HEADER_FLAGS, /* u32 - ETHTOOL_FLAG_* */ -+ __ETHTOOL_A_HEADER_CNT, -+ ETHTOOL_A_HEADER_MAX = __ETHTOOL_A_HEADER_CNT - 1 -+}; -+ -+enum { -+ ETHTOOL_A_PHC_VCLOCKS_UNSPEC, -+ ETHTOOL_A_PHC_VCLOCKS_HEADER, /* nest - _A_HEADER_* */ -+ ETHTOOL_A_PHC_VCLOCKS_NUM, /* u32 */ -+ ETHTOOL_A_PHC_VCLOCKS_INDEX, /* array, s32 */ -+ __ETHTOOL_A_PHC_VCLOCKS_CNT, -+ ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1) -+}; -+ -+#endif /* HAVE_VCLOCKS */ -+ - #ifdef __UCLIBC__ - - #if (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L) && \ -diff --git a/rtnl.c b/rtnl.c -index b02e07d..a8999b2 100644 ---- a/rtnl.c -+++ b/rtnl.c -@@ -19,6 +19,9 @@ - #include - #include /* Must come before linux/netlink.h on some systems. */ - #include -+#ifdef HAVE_VCLOCKS -+#include -+#endif - #include - #include - #include -@@ -465,3 +468,85 @@ no_info: - nl_close(fd); - return index; - } -+ -+static int rtnl_search_vclocks(struct rtattr *attr, int phc_index) -+{ -+ int i, len = RTA_PAYLOAD(attr); -+ -+ for (i = 0; i < len / sizeof (__s32); i++) { -+ if (((__s32 *)RTA_DATA(attr))[i] == phc_index) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+int rtnl_iface_has_vclock(const char *device, int phc_index) -+{ -+ struct rtattr *tb[ETHTOOL_A_PHC_VCLOCKS_MAX + 1]; -+ int index, fd, gf_id, len, ret = 0; -+ struct genlmsghdr *gnlh; -+ struct nlmsghdr *nlh; -+ char msg[BUF_SIZE]; -+ struct { -+ struct nlattr attr; -+ uint32_t index; -+ } req; -+ -+ index = if_nametoindex(device); -+ -+ fd = nl_open(NETLINK_GENERIC); -+ if (fd < 0) -+ return 0; -+ -+ gf_id = genl_get_family_id(fd, ETHTOOL_GENL_NAME); -+ if (gf_id < 0) { -+ pr_debug("ethtool netlink not supported"); -+ goto no_info; -+ } -+ -+ req.attr.nla_len = sizeof(req); -+ req.attr.nla_type = ETHTOOL_A_HEADER_DEV_INDEX; -+ req.index = index; -+ -+ len = genl_send_msg(fd, gf_id, ETHTOOL_MSG_PHC_VCLOCKS_GET, -+ ETHTOOL_GENL_VERSION, -+ NLA_F_NESTED | ETHTOOL_A_PHC_VCLOCKS_HEADER, -+ &req, sizeof(req)); -+ -+ if (len < 0) { -+ pr_err("send vclock request failed: %m"); -+ goto no_info; -+ } -+ -+ len = recv(fd, msg, sizeof(msg), 0); -+ if (len < 0) { -+ pr_err("recv vclock failed: %m"); -+ goto no_info; -+ } -+ -+ for (nlh = (struct nlmsghdr *) msg; 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 != ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY) -+ continue; -+ -+ if (rtnl_rtattr_parse(tb, ETHTOOL_A_PHC_VCLOCKS_MAX, -+ (struct rtattr *) GENLMSG_DATA(msg), -+ NLMSG_PAYLOAD(nlh, GENL_HDRLEN))) -+ continue; -+ -+ if (tb[ETHTOOL_A_PHC_VCLOCKS_INDEX]) { -+ ret = rtnl_search_vclocks(tb[ETHTOOL_A_PHC_VCLOCKS_INDEX], -+ phc_index); -+ break; -+ } -+ } -+ -+no_info: -+ nl_close(fd); -+ return ret; -+} -diff --git a/rtnl.h b/rtnl.h -index 8fef4a9..96fee29 100644 ---- a/rtnl.h -+++ b/rtnl.h -@@ -59,6 +59,15 @@ int rtnl_link_query(int fd, const char *device); - */ - int rtnl_link_status(int fd, const char *device, rtnl_callback cb, void *ctx); - -+/** -+ * Check if the PHC is a virtual clock of the interface (i.e. sockets bound to -+ * the interface also need to be bound to the clock). -+ * @param device Name of the interface. -+ * @param phc_index Index of the clock to check. -+ * @return 1 if true, otherwise 0. -+ */ -+int rtnl_iface_has_vclock(const char *device, int phc_index); -+ - /** - * Open a RT netlink socket for monitoring link state. - * @return A valid socket, or -1 on error. -commit 5477078bf5c9ef050c3bcb037f856b693f1247e7 -Author: Miroslav Lichvar -Date: Tue Mar 8 11:47:00 2022 +0100 - - Add support for binding sockets to virtual clocks. - - With the latest kernels it is possible to create virtual PHCs on top of - a free-running physical PHC. In order for the application to get - timestamps captured by the clock which it is controlling, it needs to - bind its sockets to the clock using a new field in the SO_TIMESTAMPING - option. - - Extend the interface structure with the vclock index and modify the - transport code to pass it to sk_timestamping_init() to bind the sockets - to the clock. - - Signed-off-by: Miroslav Lichvar - -diff --git a/interface.c b/interface.c -index 65bdff0..445a270 100644 ---- a/interface.c -+++ b/interface.c -@@ -12,6 +12,7 @@ struct interface { - char name[MAX_IFNAME_SIZE + 1]; - char ts_label[MAX_IFNAME_SIZE + 1]; - struct sk_ts_info ts_info; -+ int vclock; - }; - - struct interface *interface_create(const char *name) -@@ -23,6 +24,7 @@ struct interface *interface_create(const char *name) - return NULL; - } - strncpy(iface->name, name, MAX_IFNAME_SIZE); -+ iface->vclock = -1; - - return iface; - } -@@ -76,3 +78,13 @@ bool interface_tsmodes_supported(struct interface *iface, int modes) - } - return false; - } -+ -+void interface_set_vclock(struct interface *iface, int vclock) -+{ -+ iface->vclock = vclock; -+} -+ -+int interface_get_vclock(struct interface *iface) -+{ -+ return iface->vclock; -+} -diff --git a/interface.h b/interface.h -index 8bf2727..752f4f1 100644 ---- a/interface.h -+++ b/interface.h -@@ -91,4 +91,18 @@ bool interface_tsinfo_valid(struct interface *iface); - */ - bool interface_tsmodes_supported(struct interface *iface, int modes); - -+/** -+ * Set the vclock (virtual PHC) to be used for timestamping on an interface. -+ * @param iface The interface of interest. -+ * @param vclock The index of the vclock. -+ */ -+void interface_set_vclock(struct interface *iface, int vclock); -+ -+/** -+ * Get the vclock index set for the interface. -+ * @param iface The interface of interest. -+ * @return The index of the vclock, or -1 if not set. -+ */ -+int interface_get_vclock(struct interface *iface); -+ - #endif -diff --git a/missing.h b/missing.h -index 3df7bd1..c5194f4 100644 ---- a/missing.h -+++ b/missing.h -@@ -62,6 +62,17 @@ enum { - }; - #endif - -+#ifndef HAVE_VCLOCKS -+enum { -+ SOF_TIMESTAMPING_BIND_PHC = (1 << 15), -+}; -+ -+struct so_timestamping { -+ int flags; -+ int bind_phc; -+}; -+#endif -+ - #ifdef PTP_EXTTS_REQUEST2 - #define PTP_EXTTS_REQUEST_FAILED "PTP_EXTTS_REQUEST2 failed: %m" - #else -diff --git a/raw.c b/raw.c -index 0bd15b0..ce64684 100644 ---- a/raw.c -+++ b/raw.c -@@ -243,7 +243,8 @@ static int raw_open(struct transport *t, struct interface *iface, - if (gfd < 0) - goto no_general; - -- if (sk_timestamping_init(efd, name, ts_type, TRANS_IEEE_802_3)) -+ if (sk_timestamping_init(efd, name, ts_type, TRANS_IEEE_802_3, -+ interface_get_vclock(iface))) - goto no_timestamping; - - if (sk_general_init(gfd)) -diff --git a/sk.c b/sk.c -index 8be0708..b55d6b5 100644 ---- a/sk.c -+++ b/sk.c -@@ -447,9 +447,10 @@ int sk_set_priority(int fd, int family, uint8_t dscp) - } - - int sk_timestamping_init(int fd, const char *device, enum timestamp_type type, -- enum transport_type transport) -+ enum transport_type transport, int vclock) - { - int err, filter1, filter2 = 0, flags, tx_type = HWTSTAMP_TX_ON; -+ struct so_timestamping timestamping; - - switch (type) { - case TS_SOFTWARE: -@@ -509,8 +510,14 @@ int sk_timestamping_init(int fd, const char *device, enum timestamp_type type, - return err; - } - -+ if (vclock >= 0) -+ flags |= SOF_TIMESTAMPING_BIND_PHC; -+ -+ timestamping.flags = flags; -+ timestamping.bind_phc = vclock; -+ - if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, -- &flags, sizeof(flags)) < 0) { -+ ×tamping, sizeof(timestamping)) < 0) { - pr_err("ioctl SO_TIMESTAMPING failed: %m"); - return -1; - } -diff --git a/sk.h b/sk.h -index 04d26ee..486dbc4 100644 ---- a/sk.h -+++ b/sk.h -@@ -124,10 +124,11 @@ int sk_set_priority(int fd, int family, uint8_t dscp); - * @param device The name of the network interface to configure. - * @param type The requested flavor of time stamping. - * @param transport The type of transport used. -+ * @param vclock Index of the virtual PHC, or -1 for the physical clock. - * @return Zero on success, non-zero otherwise. - */ - int sk_timestamping_init(int fd, const char *device, enum timestamp_type type, -- enum transport_type transport); -+ enum transport_type transport, int vclock); - - /** - * Limits the time that RECVMSG(2) will poll while waiting for the tx timestamp -diff --git a/udp.c b/udp.c -index 826bd12..7c9402e 100644 ---- a/udp.c -+++ b/udp.c -@@ -179,7 +179,8 @@ static int udp_open(struct transport *t, struct interface *iface, - if (gfd < 0) - goto no_general; - -- if (sk_timestamping_init(efd, interface_label(iface), ts_type, TRANS_UDP_IPV4)) -+ if (sk_timestamping_init(efd, interface_label(iface), ts_type, TRANS_UDP_IPV4, -+ interface_get_vclock(iface))) - goto no_timestamping; - - if (sk_general_init(gfd)) -diff --git a/udp6.c b/udp6.c -index ba5482e..bde1710 100644 ---- a/udp6.c -+++ b/udp6.c -@@ -196,7 +196,8 @@ static int udp6_open(struct transport *t, struct interface *iface, - if (gfd < 0) - goto no_general; - -- if (sk_timestamping_init(efd, interface_label(iface), ts_type, TRANS_UDP_IPV6)) -+ if (sk_timestamping_init(efd, interface_label(iface), ts_type, -+ TRANS_UDP_IPV6, interface_get_vclock(iface))) - goto no_timestamping; - - if (sk_general_init(gfd)) -commit daaaff6b553290cf09284b0cc7756b9e24358ace -Author: Miroslav Lichvar -Date: Tue Mar 8 11:47:01 2022 +0100 - - config: Add port-specific phc_index option. - - Allow the PHC index to be configured for each port. The default value is - -1, which enables the original behavior using the PHC specified by -p or - the index from ETHTOOL_GET_TS_INFO. - - (Rebased to 3.1.1) - - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index 49bd4a9..67b3372 100644 ---- a/clock.c -+++ b/clock.c -@@ -900,7 +900,7 @@ struct clock *clock_create(enum clock_type type, struct config *config, - char ts_label[IF_NAMESIZE], phc[32], *tmp; - enum timestamp_type timestamping; - int fadj = 0, max_adj = 0, sw_ts; -- int phc_index, required_modes = 0; -+ int phc_index, conf_phc_index, required_modes = 0; - struct clock *c = &the_clock; - const char *uds_ifname; - struct port *p; -@@ -1018,6 +1018,8 @@ struct clock *clock_create(enum clock_type type, struct config *config, - - iface = STAILQ_FIRST(&config->interfaces); - -+ conf_phc_index = config_get_int(config, interface_name(iface), "phc_index"); -+ - /* determine PHC Clock index */ - if (config_get_int(config, NULL, "free_running")) { - phc_index = -1; -@@ -1027,6 +1029,8 @@ struct clock *clock_create(enum clock_type type, struct config *config, - if (1 != sscanf(phc_device, "/dev/ptp%d", &phc_index)) { - phc_index = -1; - } -+ } else if (conf_phc_index >= 0) { -+ phc_index = conf_phc_index; - } else if (interface_tsinfo_valid(iface)) { - phc_index = interface_phc_index(iface); - } else { -diff --git a/config.c b/config.c -index ef5e833..0613eda 100644 ---- a/config.c -+++ b/config.c -@@ -282,6 +282,7 @@ struct config_item config_tab[] = { - PORT_ITEM_INT("operLogPdelayReqInterval", 0, INT8_MIN, INT8_MAX), - PORT_ITEM_INT("operLogSyncInterval", 0, INT8_MIN, INT8_MAX), - PORT_ITEM_INT("path_trace_enabled", 0, 0, 1), -+ PORT_ITEM_INT("phc_index", -1, -1, INT_MAX), - GLOB_ITEM_DBL("pi_integral_const", 0.0, 0.0, DBL_MAX), - GLOB_ITEM_DBL("pi_integral_exponent", 0.4, -DBL_MAX, DBL_MAX), - GLOB_ITEM_DBL("pi_integral_norm_max", 0.3, DBL_MIN, 2.0), -diff --git a/configs/default.cfg b/configs/default.cfg -index 8c19129..45888d5 100644 ---- a/configs/default.cfg -+++ b/configs/default.cfg -@@ -103,6 +103,7 @@ delay_filter_length 10 - egressLatency 0 - ingressLatency 0 - boundary_clock_jbod 0 -+phc_index -1 - # - # Clock description - # -diff --git a/port.c b/port.c -index d26b87f..7912ee6 100644 ---- a/port.c -+++ b/port.c -@@ -3057,7 +3057,9 @@ struct port *port_open(const char *phc_device, - goto err_port; - } - -- p->phc_index = phc_index; -+ p->phc_index = config_get_int(cfg, interface_name(interface), "phc_index"); -+ if (p->phc_index < 0) -+ p->phc_index = phc_index; - p->jbod = config_get_int(cfg, interface_name(interface), "boundary_clock_jbod"); - transport = config_get_int(cfg, interface_name(interface), "network_transport"); - p->master_only = config_get_int(cfg, interface_name(interface), "masterOnly"); -@@ -3080,8 +3082,8 @@ struct port *port_open(const char *phc_device, - ; /* UDS cannot have a PHC. */ - } else if (!interface_tsinfo_valid(interface)) { - pr_warning("port %d: get_ts_info not supported", number); -- } else if (phc_index >= 0 && -- phc_index != interface_phc_index(interface)) { -+ } else if (p->phc_index >= 0 && -+ p->phc_index != interface_phc_index(interface)) { - if (p->jbod) { - pr_warning("port %d: just a bunch of devices", number); - p->phc_index = interface_phc_index(interface); -diff --git a/ptp4l.8 b/ptp4l.8 -index b179b81..fc73e84 100644 ---- a/ptp4l.8 -+++ b/ptp4l.8 -@@ -365,6 +365,11 @@ collection of clocks must be synchronized by an external program, for - example phc2sys(8) in "automatic" mode. - The default is 0 (disabled). - .TP -+.B phc_index -+Specifies the index of the PHC to be used for synchronization with hardware -+timestamping. The default is -1, which means the index will be set to the PHC -+associated with the interface, or the device specified by the \fB-p\fP option. -+.TP - .B udp_ttl - Specifies the Time to live (TTL) value for IPv4 multicast messages and the hop - limit for IPv6 multicast messages. This option is only relevant with the IPv4 -commit bb50991e8b9ecbcea53abbd0164a51e3e0bfe246 -Author: Miroslav Lichvar -Date: Tue Mar 8 11:47:02 2022 +0100 - - port: Check for virtual clocks. - - If the PHC specified with the phc_index or -p option is a virtual clock - of the interface, bind sockets to the virtual clock instead of the real - clock to get correct timestamps. - - (Rebased to 3.1.1) - - Signed-off-by: Miroslav Lichvar - -diff --git a/port.c b/port.c -index 7912ee6..b4dcd1b 100644 ---- a/port.c -+++ b/port.c -@@ -3084,7 +3084,12 @@ struct port *port_open(const char *phc_device, - pr_warning("port %d: get_ts_info not supported", number); - } else if (p->phc_index >= 0 && - p->phc_index != interface_phc_index(interface)) { -- if (p->jbod) { -+ if (rtnl_iface_has_vclock(interface_name(interface), -+ p->phc_index)) { -+ pr_info("port %d: /dev/ptp%d is virtual clock", -+ number, p->phc_index); -+ interface_set_vclock(interface, p->phc_index); -+ } else if (p->jbod) { - pr_warning("port %d: just a bunch of devices", number); - p->phc_index = interface_phc_index(interface); - } else if (phc_device) { -diff --git a/ptp4l.8 b/ptp4l.8 -index fc73e84..d0446d5 100644 ---- a/ptp4l.8 -+++ b/ptp4l.8 -@@ -367,8 +367,11 @@ The default is 0 (disabled). - .TP - .B phc_index - Specifies the index of the PHC to be used for synchronization with hardware --timestamping. The default is -1, which means the index will be set to the PHC --associated with the interface, or the device specified by the \fB-p\fP option. -+timestamping. This option is useful with virtual clocks running on top of a -+free-running physical clock (created by writing to -+/sys/class/ptp/ptp*/n_vclocks). -+The default is -1, which means the index will be set to the PHC associated with -+the interface, or the device specified by the \fB-p\fP option. - .TP - .B udp_ttl - Specifies the Time to live (TTL) value for IPv4 multicast messages and the hop -commit 2b1657a65c0f3c880a0b9982401d419108560a1f -Author: Miroslav Lichvar -Date: Tue Mar 8 11:47:03 2022 +0100 - - tlv: Add PORT_HWCLOCK_NP. - - Add a new command to get the PHC index associated with the port. This - will be needed for phc2sys -a to use the correct PHC for synchronization - if ptp4l is using a virtual clock. - - The TLV also contains a flag indicating a virtual clock. - - To follow the PORT_PROPERTIES_NP access policy, PORT_HWCLOCK_NP is - limited to the UDS-RW port. - - (Rebased to 3.1.1) - - Signed-off-by: Miroslav Lichvar - -diff --git a/clock.c b/clock.c -index 67b3372..39df135 100644 ---- a/clock.c -+++ b/clock.c -@@ -1482,6 +1482,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) - - switch (mgt->id) { - case TLV_PORT_PROPERTIES_NP: -+ case TLV_PORT_HWCLOCK_NP: - if (p != c->uds_rw_port) { - /* Only the UDS-RW port allowed. */ - clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); -diff --git a/pmc.c b/pmc.c -index 65d1d61..3832f0d 100644 ---- a/pmc.c -+++ b/pmc.c -@@ -144,6 +144,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) - struct subscribe_events_np *sen; - struct management_tlv_datum *mtd; - struct port_properties_np *ppn; -+ struct port_hwclock_np *phn; - struct timePropertiesDS *tp; - struct management_tlv *mgt; - struct time_status_np *tsn; -@@ -487,6 +488,16 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) - pcp->stats.txMsgType[SIGNALING], - pcp->stats.txMsgType[MANAGEMENT]); - break; -+ case TLV_PORT_HWCLOCK_NP: -+ phn = (struct port_hwclock_np *) mgt->data; -+ fprintf(fp, "PORT_HWCLOCK_NP " -+ IFMT "portIdentity %s" -+ IFMT "phcIndex %d" -+ IFMT "flags %hhu", -+ pid2str(&phn->portIdentity), -+ phn->phc_index, -+ phn->flags); -+ break; - case TLV_LOG_ANNOUNCE_INTERVAL: - mtd = (struct management_tlv_datum *) mgt->data; - fprintf(fp, "LOG_ANNOUNCE_INTERVAL " -diff --git a/pmc_common.c b/pmc_common.c -index f07f6f6..756edf5 100644 ---- a/pmc_common.c -+++ b/pmc_common.c -@@ -132,6 +132,7 @@ struct management_id idtab[] = { - { "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action }, - { "PORT_STATS_NP", TLV_PORT_STATS_NP, do_get_action }, - { "PORT_PROPERTIES_NP", TLV_PORT_PROPERTIES_NP, do_get_action }, -+ { "PORT_HWCLOCK_NP", TLV_PORT_HWCLOCK_NP, do_get_action }, - }; - - static void do_get_action(struct pmc *pmc, int action, int index, char *str) -diff --git a/port.c b/port.c -index b4dcd1b..e309b98 100644 ---- a/port.c -+++ b/port.c -@@ -797,6 +797,7 @@ static int port_management_fill_response(struct port *target, - struct management_tlv_datum *mtd; - struct clock_description *desc; - struct port_properties_np *ppn; -+ struct port_hwclock_np *phn; - struct port_stats_np *psn; - struct management_tlv *tlv; - struct port_ds_np *pdsnp; -@@ -961,6 +962,14 @@ static int port_management_fill_response(struct port *target, - psn->stats = target->stats; - datalen = sizeof(*psn); - break; -+ case TLV_PORT_HWCLOCK_NP: -+ phn = (struct port_hwclock_np *)tlv->data; -+ phn->portIdentity = target->portIdentity; -+ phn->phc_index = target->phc_index; -+ phn->flags = interface_get_vclock(target->iface) >= 0 ? -+ PORT_HWCLOCK_VCLOCK : 0; -+ datalen = sizeof(*phn); -+ break; - default: - /* The caller should *not* respond to this message. */ - tlv_extra_recycle(extra); -diff --git a/tlv.c b/tlv.c -index 738e404..38aeb80 100644 ---- a/tlv.c -+++ b/tlv.c -@@ -123,6 +123,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, - struct grandmaster_settings_np *gsn; - struct subscribe_events_np *sen; - struct port_properties_np *ppn; -+ struct port_hwclock_np *phn; - struct port_stats_np *psn; - struct mgmt_clock_description *cd; - int extra_len = 0, len; -@@ -326,6 +327,14 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, - ntohs(psn->portIdentity.portNumber); - extra_len = sizeof(struct port_stats_np); - break; -+ case TLV_PORT_HWCLOCK_NP: -+ if (data_len < sizeof(struct port_hwclock_np)) -+ goto bad_length; -+ phn = (struct port_hwclock_np *)m->data; -+ phn->portIdentity.portNumber = ntohs(phn->portIdentity.portNumber); -+ phn->phc_index = ntohl(phn->phc_index); -+ extra_len = sizeof(struct port_hwclock_np); -+ break; - case TLV_SAVE_IN_NON_VOLATILE_STORAGE: - case TLV_RESET_NON_VOLATILE_STORAGE: - case TLV_INITIALIZE: -@@ -352,6 +361,7 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) - struct defaultDS *dds; - struct currentDS *cds; - struct parentDS *pds; -+ struct port_hwclock_np *phn; - struct timePropertiesDS *tp; - struct portDS *p; - struct port_ds_np *pdsnp; -@@ -437,6 +447,11 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) - psn->portIdentity.portNumber = - htons(psn->portIdentity.portNumber); - break; -+ case TLV_PORT_HWCLOCK_NP: -+ phn = (struct port_hwclock_np *)m->data; -+ phn->portIdentity.portNumber = htons(phn->portIdentity.portNumber); -+ phn->phc_index = htonl(phn->phc_index); -+ break; - } - } - -diff --git a/tlv.h b/tlv.h -index a205119..5ac3d7c 100644 ---- a/tlv.h -+++ b/tlv.h -@@ -125,6 +125,7 @@ enum management_action { - #define TLV_PORT_DATA_SET_NP 0xC002 - #define TLV_PORT_PROPERTIES_NP 0xC004 - #define TLV_PORT_STATS_NP 0xC005 -+#define TLV_PORT_HWCLOCK_NP 0xC009 - - /* Management error ID values */ - #define TLV_RESPONSE_TOO_BIG 0x0001 -@@ -144,6 +145,9 @@ enum management_action { - #define CANCEL_UNICAST_MAINTAIN_GRANT (1 << 1) - #define GRANT_UNICAST_RENEWAL_INVITED (1 << 0) - -+/* Flags in PORT_HWCLOCK_NP */ -+#define PORT_HWCLOCK_VCLOCK (1 << 0) -+ - struct ack_cancel_unicast_xmit_tlv { - Enumeration16 type; - UInteger16 length; -@@ -344,6 +348,12 @@ struct port_properties_np { - struct PTPText interface; - } PACKED; - -+struct port_hwclock_np { -+ struct PortIdentity portIdentity; -+ Integer32 phc_index; -+ UInteger8 flags; -+} PACKED; -+ - struct port_stats_np { - struct PortIdentity portIdentity; - struct PortStats stats; -commit a64a45a0eedec82376fd9dab4d960b6fa652513e -Author: Miroslav Lichvar -Date: Tue Mar 8 11:47:04 2022 +0100 - - phc2sys: Use PHC index from PORT_HWCLOCK_NP. - - When running in the automatic mode, get the PHC index of the port - from PORT_HWCLOCK_NP instead of calling sk_get_ts_info(). This allows - phc2sys -a to synchronize (to) a virtual clock. - - (Rebased to 3.1.1) - - Signed-off-by: Miroslav Lichvar - -diff --git a/phc2sys.c b/phc2sys.c -index a36cbe0..adbe37d 100644 ---- a/phc2sys.c -+++ b/phc2sys.c -@@ -135,7 +135,8 @@ static void run_pmc_events(struct phc2sys_private *priv); - static int normalize_state(int state); - static int run_pmc_port_properties(struct phc2sys_private *priv, - int timeout, unsigned int port, -- int *state, int *tstamping, char *iface); -+ int *state, int *tstamping, int *phc_index, -+ char *iface); - - static struct servo *servo_add(struct phc2sys_private *priv, - struct clock *clock) -@@ -172,14 +173,21 @@ static struct servo *servo_add(struct phc2sys_private *priv, - return servo; - } - --static struct clock *clock_add(struct phc2sys_private *priv, char *device) -+static struct clock *clock_add(struct phc2sys_private *priv, char *device, -+ int phc_index) - { - struct clock *c; - clockid_t clkid = CLOCK_INVALID; -- int phc_index = -1; -+ char phc_device[19]; - - if (device) { -- clkid = posix_clock_open(device, &phc_index); -+ if (phc_index >= 0) { -+ snprintf(phc_device, sizeof(phc_device), "/dev/ptp%d", -+ phc_index); -+ clkid = posix_clock_open(phc_device, &phc_index); -+ } else { -+ clkid = posix_clock_open(device, &phc_index); -+ } - if (clkid == CLOCK_INVALID) - return NULL; - } -@@ -279,7 +287,7 @@ static struct port *port_get(struct phc2sys_private *priv, unsigned int number) - } - - static struct port *port_add(struct phc2sys_private *priv, unsigned int number, -- char *device) -+ char *device, int phc_index) - { - struct port *p; - struct clock *c = NULL, *tmp; -@@ -296,7 +304,7 @@ static struct port *port_add(struct phc2sys_private *priv, unsigned int number, - } - } - if (!c) { -- c = clock_add(priv, device); -+ c = clock_add(priv, device, phc_index); - if (!c) - return NULL; - } -@@ -316,17 +324,16 @@ static void clock_reinit(struct phc2sys_private *priv, struct clock *clock, - { - int phc_index = -1, phc_switched = 0; - int state, timestamping, ret = -1; -+ char iface[IFNAMSIZ], phc_device[19]; - struct port *p; - struct servo *servo; -- struct sk_ts_info ts_info; -- char iface[IFNAMSIZ]; - clockid_t clkid = CLOCK_INVALID; - - LIST_FOREACH(p, &priv->ports, list) { - if (p->clock == clock) { - ret = run_pmc_port_properties(priv, 1000, p->number, - &state, ×tamping, -- iface); -+ &phc_index, iface); - if (ret > 0) - p->state = normalize_state(state); - } -@@ -339,9 +346,10 @@ static void clock_reinit(struct phc2sys_private *priv, struct clock *clock, - clock->device = strdup(iface); - } - /* Check if phc index changed */ -- if (!sk_get_ts_info(clock->device, &ts_info) && -- clock->phc_index != ts_info.phc_index) { -- clkid = posix_clock_open(clock->device, &phc_index); -+ if (clock->phc_index != phc_index) { -+ snprintf(phc_device, sizeof(phc_device), "/dev/ptp%d", -+ phc_index); -+ clkid = posix_clock_open(phc_device, &phc_index); - if (clkid == CLOCK_INVALID) - return; - -@@ -1099,11 +1107,13 @@ static void run_pmc_events(struct phc2sys_private *priv) - - static int run_pmc_port_properties(struct phc2sys_private *priv, int timeout, - unsigned int port, -- int *state, int *tstamping, char *iface) -+ int *state, int *tstamping, int *phc_index, -+ char *iface) - { - struct ptp_message *msg; - int res, len; - struct port_properties_np *ppn; -+ struct port_hwclock_np *phn; - - pmc_target_port(priv->pmc, port); - while (1) { -@@ -1125,6 +1135,21 @@ static int run_pmc_port_properties(struct phc2sys_private *priv, int timeout, - memcpy(iface, ppn->interface.text, len); - iface[len] = '\0'; - -+ msg_put(msg); -+ break; -+ } -+ while (1) { -+ res = run_pmc(priv, timeout, TLV_PORT_HWCLOCK_NP, &msg); -+ if (res <= 0) -+ goto out; -+ -+ phn = get_mgt_data(msg); -+ if (ppn->portIdentity.portNumber != port) { -+ msg_put(msg); -+ continue; -+ } -+ *phc_index = phn->phc_index; -+ - msg_put(msg); - res = 1; - break; -@@ -1164,7 +1189,7 @@ static int auto_init_ports(struct phc2sys_private *priv, int add_rt) - struct clock *clock; - int number_ports, res; - unsigned int i; -- int state, timestamping; -+ int state, timestamping, phc_index; - char iface[IFNAMSIZ]; - - while (1) { -@@ -1193,7 +1218,7 @@ static int auto_init_ports(struct phc2sys_private *priv, int add_rt) - - for (i = 1; i <= number_ports; i++) { - res = run_pmc_port_properties(priv, 1000, i, &state, -- ×tamping, iface); -+ ×tamping, &phc_index, iface); - if (res == -1) { - /* port does not exist, ignore the port */ - continue; -@@ -1206,7 +1231,7 @@ static int auto_init_ports(struct phc2sys_private *priv, int add_rt) - /* ignore ports with software time stamping */ - continue; - } -- port = port_add(priv, i, iface); -+ port = port_add(priv, i, iface, phc_index); - if (!port) - return -1; - port->state = normalize_state(state); -@@ -1221,7 +1246,7 @@ static int auto_init_ports(struct phc2sys_private *priv, int add_rt) - priv->state_changed = 1; - - if (add_rt) { -- clock = clock_add(priv, "CLOCK_REALTIME"); -+ clock = clock_add(priv, "CLOCK_REALTIME", -1); - if (!clock) - return -1; - if (add_rt == 1) -@@ -1598,7 +1623,7 @@ int main(int argc, char *argv[]) - goto end; - } - -- src = clock_add(&priv, src_name); -+ src = clock_add(&priv, src_name, -1); - free(src_name); - if (!src) { - fprintf(stderr, -@@ -1608,7 +1633,7 @@ int main(int argc, char *argv[]) - src->state = PS_SLAVE; - priv.master = src; - -- dst = clock_add(&priv, dst_name ? dst_name : "CLOCK_REALTIME"); -+ dst = clock_add(&priv, dst_name ? dst_name : "CLOCK_REALTIME", -1); - free(dst_name); - if (!dst) { - fprintf(stderr, -commit 3238beafd5aca017a29f335e94b1ff05f4596fe3 -Author: Miroslav Lichvar -Date: Tue Mar 8 11:47:05 2022 +0100 - - timemaster: Add support for virtual clocks. - - Add "use_vclocks" option to enable synchronization with virtual clocks. - This enables multiple ptp4l instances sharing an interface to use - hardware timestamping. By default, vclocks are enabled if running on - Linux 5.18 or later, which should have all features to make them work as - well as physical clocks. - - When preparing the script, count how many vclocks are needed for each - physical clock. Add a placeholder option in the form of "--phc_index - %PHC0-0%" to the generated ptp4l commands that need hardware clock. The - index of the virtual clock is unknown at this point. - - When running the script (not just printing), create the required number - of virtual clocks by writing to /sys/.../n_vclocks and fix the - --phc_index options to refer to the indices of the created vclocks. On - exit, remove the virtual clocks to restore the original state. - - Signed-off-by: Miroslav Lichvar - -diff --git a/timemaster.8 b/timemaster.8 -index 2f92976..102768c 100644 ---- a/timemaster.8 -+++ b/timemaster.8 -@@ -97,6 +97,15 @@ configuration error). If a process was terminated and is not started again, - \fBtimemaster\fR will kill the other processes and exit with a non-zero status. - The default value is 1 (enabled). - -+.TP -+.B use_vclocks -+Enable or disable synchronization with virtual clocks. If enabled, -+\fBtimemaster\fR will create virtual clocks running on top of physical clocks -+needed by configured PTP domains. This enables hardware time stamping for -+multiple \fBptp4l\fR instances using the same network interface. The default -+value is -1, which enables the virtual clocks if running on Linux 5.18 or -+later. -+ - .SS [ntp_server address] - - The \fBntp_server\fR section specifies an NTP server that should be used as a -@@ -140,8 +149,8 @@ Specify which network interfaces should be used for this PTP domain. A separate - \fBptp4l\fR instance will be started for each group of interfaces sharing the - same PHC and for each interface that supports only SW time stamping. HW time - stamping is enabled automatically. If an interface with HW time stamping is --specified also in other PTP domains, only the \fBptp4l\fR instance from the --first PTP domain will be using HW time stamping. -+specified also in other PTP domains and virtual clocks are disabled, only the -+\fBptp4l\fR instance from the first PTP domain will be using HW time stamping. - - .TP - .B ntp_poll -@@ -333,6 +342,7 @@ ntp_program chronyd - rundir /var/run/timemaster - first_shm_segment 1 - restart_processes 0 -+use_vclocks 0 - - [chronyd] - path /usr/sbin/chronyd -diff --git a/timemaster.c b/timemaster.c -index 02408d6..1fbadcb 100644 ---- a/timemaster.c -+++ b/timemaster.c -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -33,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -46,6 +48,7 @@ - - #define DEFAULT_FIRST_SHM_SEGMENT 0 - #define DEFAULT_RESTART_PROCESSES 1 -+#define DEFAULT_USE_VCLOCKS -1 - - #define DEFAULT_NTP_PROGRAM CHRONYD - #define DEFAULT_NTP_MINPOLL 6 -@@ -111,6 +114,7 @@ struct timemaster_config { - char *rundir; - int first_shm_segment; - int restart_processes; -+ int use_vclocks; - struct program_config chronyd; - struct program_config ntpd; - struct program_config phc2sys; -@@ -122,7 +126,13 @@ struct config_file { - char *content; - }; - -+struct phc_vclocks { -+ int pclock_index; -+ int vclocks; -+}; -+ - struct script { -+ struct phc_vclocks **vclocks; - struct config_file **configs; - char ***commands; - int **command_groups; -@@ -393,6 +403,8 @@ static int parse_timemaster_settings(char **settings, - r = parse_int(value, &config->first_shm_segment); - } else if (!strcasecmp(name, "restart_processes")) { - r = parse_int(value, &config->restart_processes); -+ } else if (!strcasecmp(name, "use_vclocks")) { -+ r = parse_int(value, &config->use_vclocks); - } else { - pr_err("unknown timemaster setting %s", name); - return 1; -@@ -520,6 +532,20 @@ static void config_destroy(struct timemaster_config *config) - free(config); - } - -+static int check_kernel_version(int version, int patch) -+{ -+ struct utsname uts; -+ int v, p; -+ -+ if (uname(&uts) < 0) -+ return 1; -+ if (sscanf(uts.release, "%d.%d", &v, &p) < 2) -+ return 1; -+ if (version > v || (version == v && patch > p)) -+ return 1; -+ return 0; -+} -+ - static struct timemaster_config *config_parse(char *path) - { - struct timemaster_config *config = xcalloc(1, sizeof(*config)); -@@ -533,6 +559,7 @@ static struct timemaster_config *config_parse(char *path) - config->rundir = xstrdup(DEFAULT_RUNDIR); - config->first_shm_segment = DEFAULT_FIRST_SHM_SEGMENT; - config->restart_processes = DEFAULT_RESTART_PROCESSES; -+ config->use_vclocks = DEFAULT_USE_VCLOCKS; - - init_program_config(&config->chronyd, "chronyd", - NULL, DEFAULT_CHRONYD_SETTINGS, NULL); -@@ -593,6 +620,9 @@ static struct timemaster_config *config_parse(char *path) - - fclose(f); - -+ if (config->use_vclocks < 0) -+ config->use_vclocks = !check_kernel_version(5, 18); -+ - if (section_name) - free(section_name); - if (section_lines) -@@ -608,7 +638,7 @@ static struct timemaster_config *config_parse(char *path) - - static char **get_ptp4l_command(struct program_config *config, - struct config_file *file, char **interfaces, -- int hw_ts) -+ char *phc_index, int hw_ts) - { - char **command = (char **)parray_new(); - -@@ -617,6 +647,9 @@ static char **get_ptp4l_command(struct program_config *config, - parray_extend((void ***)&command, - xstrdup("-f"), xstrdup(file->path), - xstrdup(hw_ts ? "-H" : "-S"), NULL); -+ if (phc_index && phc_index[0]) -+ parray_extend((void ***)&command, -+ xstrdup("--phc_index"), xstrdup(phc_index), NULL); - - for (; *interfaces; interfaces++) - parray_extend((void ***)&command, -@@ -706,6 +739,24 @@ static int add_ntp_source(struct ntp_server *source, char **ntp_config) - return 0; - } - -+static int add_vclock(struct script *script, int pclock_index) -+{ -+ struct phc_vclocks **vclocks, *v; -+ -+ for (vclocks = script->vclocks; *vclocks; vclocks++) { -+ if ((*vclocks)->pclock_index != pclock_index) -+ continue; -+ return (*vclocks)->vclocks++; -+ } -+ -+ v = xmalloc(sizeof(*v)); -+ v->pclock_index = pclock_index; -+ v->vclocks = 1; -+ parray_append((void ***)&script->vclocks, v); -+ -+ return 0; -+} -+ - static int add_ptp_source(struct ptp_domain *source, - struct timemaster_config *config, int *shm_segment, - int *command_group, int ***allocated_phcs, -@@ -713,7 +764,7 @@ static int add_ptp_source(struct ptp_domain *source, - { - struct config_file *config_file; - char **command, *uds_path, *uds_path2, **interfaces, *message_tag; -- char ts_interface[IF_NAMESIZE]; -+ char ts_interface[IF_NAMESIZE], vclock_index[20]; - int i, j, num_interfaces, *phc, *phcs, hw_ts, sw_ts; - struct sk_ts_info ts_info; - -@@ -801,10 +852,18 @@ static int add_ptp_source(struct ptp_domain *source, - } - } - -- /* don't use this PHC in other sources */ -- phc = xmalloc(sizeof(int)); -- *phc = phcs[i]; -- parray_append((void ***)allocated_phcs, phc); -+ if (config->use_vclocks) { -+ /* request new vclock for the PHC */ -+ int vclock = add_vclock(script, phcs[i]); -+ snprintf(vclock_index, sizeof(vclock_index), -+ "%%PHC%d-%d%%", phcs[i], vclock); -+ } else { -+ /* don't use this PHC in other sources */ -+ phc = xmalloc(sizeof(int)); -+ *phc = phcs[i]; -+ parray_append((void ***)allocated_phcs, phc); -+ vclock_index[0] = '\0'; -+ } - } - - uds_path = string_newf("%s/ptp4l.%d.socket", -@@ -842,7 +901,8 @@ static int add_ptp_source(struct ptp_domain *source, - if (phcs[i] >= 0) { - /* HW time stamping */ - command = get_ptp4l_command(&config->ptp4l, config_file, -- interfaces, 1); -+ interfaces, -+ vclock_index, 1); - add_command(command, *command_group, script); - - command = get_phc2sys_command(&config->phc2sys, -@@ -854,7 +914,7 @@ static int add_ptp_source(struct ptp_domain *source, - } else { - /* SW time stamping */ - command = get_ptp4l_command(&config->ptp4l, config_file, -- interfaces, 0); -+ interfaces, NULL, 0); - add_command(command, (*command_group)++, script); - - string_appendf(&config_file->content, -@@ -943,6 +1003,11 @@ static void script_destroy(struct script *script) - char ***commands, **command; - int **groups; - struct config_file *config, **configs; -+ struct phc_vclocks **vclocks; -+ -+ for (vclocks = script->vclocks; *vclocks; vclocks++) -+ free(*vclocks); -+ free(script->vclocks); - - for (configs = script->configs; *configs; configs++) { - config = *configs; -@@ -974,6 +1039,7 @@ static struct script *script_create(struct timemaster_config *config) - int **allocated_phcs = (int **)parray_new(); - int ret = 0, shm_segment, command_group = 0; - -+ script->vclocks = (struct phc_vclocks **)parray_new(); - script->configs = (struct config_file **)parray_new(); - script->commands = (char ***)parray_new(); - script->command_groups = (int **)parray_new(); -@@ -1116,6 +1182,102 @@ static int remove_config_files(struct config_file **configs) - return 0; - } - -+static int set_phc_n_vclocks(int phc_index, int n_vclocks) -+{ -+ char path[PATH_MAX]; -+ FILE *f; -+ -+ snprintf(path, sizeof(path), "/sys/class/ptp/ptp%d/n_vclocks", -+ phc_index); -+ f = fopen(path, "w"); -+ if (!f) { -+ pr_err("failed to open %s: %m", path); -+ return 1; -+ } -+ fprintf(f, "%d\n", n_vclocks); -+ fclose(f); -+ -+ return 0; -+} -+ -+static int create_vclocks(struct phc_vclocks **phc_vclocks) -+{ -+ struct phc_vclocks **vclocks; -+ -+ for (vclocks = phc_vclocks; *vclocks; vclocks++) { -+ if (set_phc_n_vclocks((*vclocks)->pclock_index, -+ (*vclocks)->vclocks)) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int remove_vclocks(struct phc_vclocks **phc_vclocks) -+{ -+ struct phc_vclocks **vclocks; -+ -+ for (vclocks = phc_vclocks; *vclocks; vclocks++) { -+ if (set_phc_n_vclocks((*vclocks)->pclock_index, 0)) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int get_vclock_index(int pindex, int vclock) -+{ -+ char pattern[PATH_MAX], *s; -+ int n, vindex; -+ glob_t gl; -+ -+ snprintf(pattern, sizeof(pattern), "/sys/class/ptp/ptp%d/ptp[0-9]*", -+ pindex); -+ -+ if (glob(pattern, 0, NULL, &gl)) { -+ pr_err("glob(%s) failed", pattern); -+ return -1; -+ } -+ -+ if (vclock >= gl.gl_pathc || -+ !(s = strrchr(gl.gl_pathv[vclock], '/')) || -+ sscanf(s + 1, "ptp%d%n", &vindex, &n) != 1 || -+ n != strlen(s + 1)) { -+ pr_err("missing vclock %d:%d", pindex, vclock); -+ globfree(&gl); -+ return -1; -+ } -+ -+ globfree(&gl); -+ -+ return vindex; -+} -+ -+static int translate_vclock_options(char ***commands) -+{ -+ int n, pindex, vclock, vindex, blen; -+ char **command; -+ -+ for (; *commands; commands++) { -+ for (command = *commands; *command; command++) { -+ if (sscanf(*command, "%%PHC%d-%d%%%n", -+ &pindex, &vclock, &n) != 2 || -+ n != strlen(*command)) -+ continue; -+ vindex = get_vclock_index(pindex, vclock); -+ if (vindex < 0) -+ return 1; -+ -+ /* overwrite the string with the vclock PHC index */ -+ blen = strlen(*command) + 1; -+ if (snprintf(*command, blen, "%d", vindex) >= blen) -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ - static int script_run(struct script *script) - { - struct timespec ts_start, ts_now; -@@ -1135,6 +1297,12 @@ static int script_run(struct script *script) - if (create_config_files(script->configs)) - return 1; - -+ if (create_vclocks(script->vclocks)) -+ return 1; -+ -+ if (translate_vclock_options(script->commands)) -+ return 1; -+ - sigemptyset(&mask); - sigaddset(&mask, SIGCHLD); - sigaddset(&mask, SIGTERM); -@@ -1278,6 +1446,9 @@ static int script_run(struct script *script) - - free(pids); - -+ if (remove_vclocks(script->vclocks)) -+ return 1; -+ - if (remove_config_files(script->configs)) - return 1; - -@@ -1289,13 +1460,20 @@ static void script_print(struct script *script) - char ***commands, **command; - int **groups; - struct config_file *config, **configs; -+ struct phc_vclocks **vclocks; - - for (configs = script->configs; *configs; configs++) { - config = *configs; - fprintf(stderr, "%s:\n\n%s\n", config->path, config->content); - } - -- fprintf(stderr, "commands:\n\n"); -+ fprintf(stderr, "virtual clocks:\n\n"); -+ for (vclocks = script->vclocks; *vclocks; vclocks++) { -+ fprintf(stderr, "PHC%d: %d\n", -+ (*vclocks)->pclock_index, (*vclocks)->vclocks); -+ } -+ -+ fprintf(stderr, "\ncommands:\n\n"); - for (commands = script->commands, groups = script->command_groups; - *commands; commands++, groups++) { - fprintf(stderr, "[%d] ", **groups); -commit e09b9fda7435799afad45c96b56ac020e7f7b3d3 +commit b2ceafdd8e4cde6c0cef67373006049b12f45c4a Author: Miroslav Lichvar Date: Thu Apr 28 14:23:57 2022 +0200 timemaster: Check for RH-specific kernel with vclock support. diff --git a/timemaster.8 b/timemaster.8 -index 102768c..edf5818 100644 +index bc0b5b6..50699d6 100644 --- a/timemaster.8 +++ b/timemaster.8 @@ -104,7 +104,7 @@ Enable or disable synchronization with virtual clocks. If enabled, @@ -1470,7 +18,7 @@ index 102768c..edf5818 100644 .SS [ntp_server address] diff --git a/timemaster.c b/timemaster.c -index 1fbadcb..287d77c 100644 +index fab71fc..05f0af4 100644 --- a/timemaster.c +++ b/timemaster.c @@ -546,6 +546,23 @@ static int check_kernel_version(int version, int patch) @@ -1507,32 +55,3 @@ index 1fbadcb..287d77c 100644 if (section_name) free(section_name); -commit 5f402a959959edc7248415a98581f3eaab3c9735 -Author: Miroslav Lichvar -Date: Thu Jul 14 17:06:15 2022 +0200 - - port: Disable PHC switch with vclocks. - - With a virtual PHC, don't try to switch to the physical PHC after a - link-state change. JBOD and other multi-PHC configurations are not - supported with vclocks yet. - - Fixes: 9b9c2c58e6ed ("port: Check for virtual clocks.") - - Signed-off-by: Miroslav Lichvar - -diff --git a/port.c b/port.c -index e309b98..70b6e60 100644 ---- a/port.c -+++ b/port.c -@@ -2591,8 +2591,9 @@ void port_link_status(void *ctx, int linkup, int ts_index) - (p->link_status & LINK_STATE_CHANGED || p->link_status & TS_LABEL_CHANGED)) { - interface_get_tsinfo(p->iface); - -- /* Only switch phc with HW time stamping mode */ -+ /* Only switch a non-vclock PHC with HW time stamping. */ - if (interface_tsinfo_valid(p->iface) && -+ interface_get_vclock(p->iface) < 0 && - interface_phc_index(p->iface) >= 0) { - required_modes = clock_required_modes(p->clock); - if (!interface_tsmodes_supported(p->iface, required_modes)) { diff --git a/linuxptp-vlanbond.patch b/linuxptp-vlanbond.patch deleted file mode 100644 index 590e1e6..0000000 --- a/linuxptp-vlanbond.patch +++ /dev/null @@ -1,451 +0,0 @@ -commit afd709924edcea26fec24a6253d1b85fc94c88e6 -Author: Hangbin Liu -Date: Wed May 25 14:46:14 2022 +0800 - - ptp4l: init iface->ts_label when interface created - - It's redundant to ensure tslabel if we could get ts_info directly from - the interface. By init iface->ts_label when interface created, there is - no need to take care of ts_label on other places. - - It will also make the later vlan over bonding support patch more clear - after removing function interface_ensure_tslabel(). - - Signed-off-by: Hangbin Liu - -diff --git a/clock.c b/clock.c -index 7ffbd6a..d4f273f 100644 ---- a/clock.c -+++ b/clock.c -@@ -1006,9 +1006,8 @@ struct clock *clock_create(enum clock_type type, struct config *config, - required_modes = clock_required_modes(c); - STAILQ_FOREACH(iface, &config->interfaces, list) { - memset(ts_label, 0, sizeof(ts_label)); -- rtnl_get_ts_device(interface_name(iface), ts_label); -- interface_set_label(iface, ts_label); -- interface_ensure_tslabel(iface); -+ if (!rtnl_get_ts_device(interface_name(iface), ts_label)) -+ interface_set_label(iface, ts_label); - interface_get_tsinfo(iface); - if (interface_tsinfo_valid(iface) && - !interface_tsmodes_supported(iface, required_modes)) { -diff --git a/interface.c b/interface.c -index 445a270..6c2630c 100644 ---- a/interface.c -+++ b/interface.c -@@ -24,6 +24,7 @@ struct interface *interface_create(const char *name) - return NULL; - } - strncpy(iface->name, name, MAX_IFNAME_SIZE); -+ strncpy(iface->ts_label, name, MAX_IFNAME_SIZE); - iface->vclock = -1; - - return iface; -@@ -34,13 +35,6 @@ void interface_destroy(struct interface *iface) - free(iface); - } - --void interface_ensure_tslabel(struct interface *iface) --{ -- if (!iface->ts_label[0]) { -- memcpy(iface->ts_label, iface->name, MAX_IFNAME_SIZE); -- } --} -- - int interface_get_tsinfo(struct interface *iface) - { - return sk_get_ts_info(iface->ts_label, &iface->ts_info); -diff --git a/interface.h b/interface.h -index 752f4f1..5fc7836 100644 ---- a/interface.h -+++ b/interface.h -@@ -33,12 +33,6 @@ struct interface *interface_create(const char *name); - */ - void interface_destroy(struct interface *iface); - --/** -- * Ensures that an interface has a proper time stamping label. -- * @param iface The interface of interest. -- */ --void interface_ensure_tslabel(struct interface *iface); -- - /** - * Populate the time stamping information of a given interface. - * @param iface The interface of interest. -diff --git a/nsm.c b/nsm.c -index 5aa925b..8d4a362 100644 ---- a/nsm.c -+++ b/nsm.c -@@ -274,9 +274,8 @@ static int nsm_open(struct nsm *nsm, struct config *cfg) - STAILQ_FOREACH(iface, &cfg->interfaces, list) { - ifname = interface_name(iface); - memset(ts_label, 0, sizeof(ts_label)); -- rtnl_get_ts_device(ifname, ts_label); -- interface_set_label(iface, ts_label); -- interface_ensure_tslabel(iface); -+ if (!rtnl_get_ts_device(ifname, ts_label)) -+ interface_set_label(iface, ts_label); - count++; - } - if (count != 1) { -diff --git a/pmc_common.c b/pmc_common.c -index 756edf5..ee2ece6 100644 ---- a/pmc_common.c -+++ b/pmc_common.c -@@ -405,7 +405,6 @@ struct pmc *pmc_create(struct config *cfg, enum transport_type transport_type, - pr_err("failed to create interface"); - goto failed; - } -- interface_ensure_tslabel(pmc->iface); - - if (transport_open(pmc->transport, pmc->iface, - &pmc->fdarray, TS_SOFTWARE)) { - -commit 6aab466eb0563c1025c78ab496b22a8833b02d20 -Author: Vincent Cheng -Date: Fri Jan 8 10:21:14 2021 -0500 - - port: Fix link down/up to continue using phc_index set from command line -p option. - - In the scenario where a port link goes down and up, current code checks - the port's phc_index against the interface's phc_index and if they are - different will set the port phc_index to the interface phc_index. - - If the phc_index was initially set by the command line -p option, then we - end up using the wrong phc_index. - - Fix is to skip updating the port phc_index with the interface phc_index - when port link is back up if it was initialy set from the command line. - - Signed-off-by: Vincent Cheng - -diff --git a/port.c b/port.c -index 70b6e60..d22f30f 100644 ---- a/port.c -+++ b/port.c -@@ -2601,6 +2601,11 @@ void port_link_status(void *ctx, int linkup, int ts_index) - "timestamping mode, set link status down by force.", - interface_label(p->iface)); - p->link_status = LINK_DOWN | LINK_STATE_CHANGED; -+ } else if (p->phc_from_cmdline) { -+ pr_warning("port %d: taking /dev/ptp%d from the " -+ "command line, not the attached ptp%d", -+ portnum(p), p->phc_index, -+ interface_phc_index(p->iface)); - } else if (p->phc_index != interface_phc_index(p->iface)) { - p->phc_index = interface_phc_index(p->iface); - -@@ -3107,6 +3112,7 @@ struct port *port_open(const char *phc_device, - "not the attached ptp%d", number, phc_device, - interface_phc_index(interface)); - p->phc_index = phc_index; -+ p->phc_from_cmdline = 1; - } else { - pr_err("port %d: PHC device mismatch", number); - pr_err("port %d: /dev/ptp%d requested, ptp%d attached", -diff --git a/port_private.h b/port_private.h -index fcabaa6..6e40e15 100644 ---- a/port_private.h -+++ b/port_private.h -@@ -69,6 +69,7 @@ struct port { - struct fdarray fda; - int fault_fd; - int phc_index; -+ int phc_from_cmdline; - - void (*dispatch)(struct port *p, enum fsm_event event, int mdiff); - enum fsm_event (*event)(struct port *p, int fd_index); - -commit 45f20e824fdfb8748d73495ccc7578dc70866282 -Author: Hangbin Liu -Date: Wed May 25 14:46:15 2022 +0800 - - port: refactor port_link_status - - Split port_change_phc() logic form port_link_status() to improve the - readability of the code - - (Rebased to 3.1.1) - - Signed-off-by: Hangbin Liu - -diff --git a/port.c b/port.c -index d22f30f..031b212 100644 ---- a/port.c -+++ b/port.c -@@ -2563,10 +2563,43 @@ static void bc_dispatch(struct port *p, enum fsm_event event, int mdiff) - } - } - -+static void port_change_phc(struct port *p) -+{ -+ int required_modes; -+ -+ /* Only switch a non-vclock PHC with HW time stamping. */ -+ if (!interface_tsinfo_valid(p->iface) || -+ interface_get_vclock(p->iface) >= 0 || -+ interface_phc_index(p->iface) < 0) -+ return; -+ -+ required_modes = clock_required_modes(p->clock); -+ if (!interface_tsmodes_supported(p->iface, required_modes)) { -+ pr_err("interface '%s' does not support requested " -+ "timestamping mode, set link status down by force.", -+ interface_label(p->iface)); -+ p->link_status = LINK_DOWN | LINK_STATE_CHANGED; -+ } else if (p->phc_from_cmdline) { -+ pr_warning("port %d: taking /dev/ptp%d from the " -+ "command line, not the attached ptp%d", -+ portnum(p), p->phc_index, -+ interface_phc_index(p->iface)); -+ } else if (p->phc_index != interface_phc_index(p->iface)) { -+ p->phc_index = interface_phc_index(p->iface); -+ -+ if (clock_switch_phc(p->clock, p->phc_index)) { -+ p->last_fault_type = FT_SWITCH_PHC; -+ port_dispatch(p, EV_FAULT_DETECTED, 0); -+ return; -+ } -+ clock_sync_interval(p->clock, p->log_sync_interval); -+ } -+} -+ - void port_link_status(void *ctx, int linkup, int ts_index) - { - char ts_label[MAX_IFNAME_SIZE + 1] = {0}; -- int link_state, required_modes; -+ int link_state; - const char *old_ts_label; - struct port *p = ctx; - -@@ -2590,33 +2623,7 @@ void port_link_status(void *ctx, int linkup, int ts_index) - if (p->link_status & LINK_UP && - (p->link_status & LINK_STATE_CHANGED || p->link_status & TS_LABEL_CHANGED)) { - interface_get_tsinfo(p->iface); -- -- /* Only switch a non-vclock PHC with HW time stamping. */ -- if (interface_tsinfo_valid(p->iface) && -- interface_get_vclock(p->iface) < 0 && -- interface_phc_index(p->iface) >= 0) { -- required_modes = clock_required_modes(p->clock); -- if (!interface_tsmodes_supported(p->iface, required_modes)) { -- pr_err("interface '%s' does not support requested " -- "timestamping mode, set link status down by force.", -- interface_label(p->iface)); -- p->link_status = LINK_DOWN | LINK_STATE_CHANGED; -- } else if (p->phc_from_cmdline) { -- pr_warning("port %d: taking /dev/ptp%d from the " -- "command line, not the attached ptp%d", -- portnum(p), p->phc_index, -- interface_phc_index(p->iface)); -- } else if (p->phc_index != interface_phc_index(p->iface)) { -- p->phc_index = interface_phc_index(p->iface); -- -- if (clock_switch_phc(p->clock, p->phc_index)) { -- p->last_fault_type = FT_SWITCH_PHC; -- port_dispatch(p, EV_FAULT_DETECTED, 0); -- return; -- } -- clock_sync_interval(p->clock, p->log_sync_interval); -- } -- } -+ port_change_phc(p); - } - - /* - -commit 878c2eac77cc7abd1d86620a82ae9046545439ea -Author: Hangbin Liu -Date: Wed May 25 14:46:16 2022 +0800 - - ptp4l: add VLAN over bond support - - Latest Linux kernel has supported getting active port's PHC from bond - directly. This would help topology like VLAN over bond to get PHC natively, - as VLAN also albe to get downlink's PHC. - - To achieve this, the new hwtstamp flag is needed when passing hwtstamp_config - to kernel. Let's supply the flag first, and fall back without flag if user - run on old kernel. - - We also need to update the PHC index in port_link_status() when there is - a RTNL event. The PHC info will be update in later port_change_phc(). - - Signed-off-by: Hangbin Liu - -diff --git a/clock.c b/clock.c -index d4f273f..f3df220 100644 ---- a/clock.c -+++ b/clock.c -@@ -1758,6 +1758,9 @@ int clock_switch_phc(struct clock *c, int phc_index) - c->clkid = clkid; - c->servo = servo; - c->servo_state = SERVO_UNLOCKED; -+ -+ pr_info("Switched to /dev/ptp%d as PTP clock", phc_index); -+ - return 0; - } - -diff --git a/missing.h b/missing.h -index c5194f4..5f684dd 100644 ---- a/missing.h -+++ b/missing.h -@@ -73,6 +73,12 @@ struct so_timestamping { - }; - #endif - -+#ifndef HWTSTAMP_FLAG_BONDED_PHC_INDEX -+enum { -+ HWTSTAMP_FLAG_BONDED_PHC_INDEX = (1<<0), -+}; -+#endif -+ - #ifdef PTP_EXTTS_REQUEST2 - #define PTP_EXTTS_REQUEST_FAILED "PTP_EXTTS_REQUEST2 failed: %m" - #else -diff --git a/port.c b/port.c -index 031b212..ae9c4d3 100644 ---- a/port.c -+++ b/port.c -@@ -2619,12 +2619,18 @@ void port_link_status(void *ctx, int linkup, int ts_index) - pr_notice("port %hu: ts label changed to %s", portnum(p), ts_label); - } - -+ /* phc index may changed while ts_label keeps the same after failover. -+ * e.g. vlan over bond. Since the lower link changed, we still set -+ * the TS_LABEL_CHANGED flag. -+ */ -+ interface_get_tsinfo(p->iface); -+ if (p->phc_index != interface_phc_index(p->iface)) -+ p->link_status |= TS_LABEL_CHANGED; -+ - /* Both link down/up and change ts_label may change phc index. */ - if (p->link_status & LINK_UP && -- (p->link_status & LINK_STATE_CHANGED || p->link_status & TS_LABEL_CHANGED)) { -- interface_get_tsinfo(p->iface); -+ (p->link_status & LINK_STATE_CHANGED || p->link_status & TS_LABEL_CHANGED)) - port_change_phc(p); -- } - - /* - * A port going down can affect the BMCA result. -diff --git a/sk.c b/sk.c -index b55d6b5..80075be 100644 ---- a/sk.c -+++ b/sk.c -@@ -66,6 +66,11 @@ static int hwts_init(int fd, const char *device, int rx_filter, - - init_ifreq(&ifreq, &cfg, device); - -+ cfg.flags = HWTSTAMP_FLAG_BONDED_PHC_INDEX; -+ /* Fall back without flag if user run new build on old kernel */ -+ if (ioctl(fd, SIOCGHWTSTAMP, &ifreq) == -EINVAL) -+ init_ifreq(&ifreq, &cfg, device); -+ - switch (sk_hwts_filter_mode) { - case HWTS_FILTER_CHECK: - err = ioctl(fd, SIOCGHWTSTAMP, &ifreq); - -commit 98edb4d72b3d1d4e988f810b9a9cb1078212e5dc -Author: Miroslav Lichvar -Date: Tue Nov 22 17:07:16 2022 +0100 - - port: Avoid faults with vclocks and PHC from command line. - - After commit afeabf3c90ed ("ptp4l: add VLAN over bond support") the - TS_LABEL_CHANGED flag was set on link status changes when the used - PHC index was different from the PHC index of the interface. - - This caused the port to be constantly switching to the faulty state when - using vclocks, or a different PHC device was forced with the -p option, - where it is expected the used PHC doesn't match the interface's PHC. - - Rework port_link_status() and port_change_phc() to avoid setting the - flag and switch the clock only in the cases where it is expected. - - Fixes: afeabf3c90ed ("ptp4l: add VLAN over bond support") - Signed-off-by: Miroslav Lichvar - -diff --git a/port.c b/port.c -index ae9c4d3..96e097a 100644 ---- a/port.c -+++ b/port.c -@@ -2567,10 +2567,13 @@ static void port_change_phc(struct port *p) - { - int required_modes; - -- /* Only switch a non-vclock PHC with HW time stamping. */ -- if (!interface_tsinfo_valid(p->iface) || -+ /* Try to switch only if the interface is up, it has HW time stamping -+ using a non-vclock PHC, and the PHC actually changed. */ -+ if (!(p->link_status & LINK_UP) || -+ !interface_tsinfo_valid(p->iface) || - interface_get_vclock(p->iface) >= 0 || -- interface_phc_index(p->iface) < 0) -+ interface_phc_index(p->iface) < 0 || -+ p->phc_index == interface_phc_index(p->iface)) - return; - - required_modes = clock_required_modes(p->clock); -@@ -2584,7 +2587,7 @@ static void port_change_phc(struct port *p) - "command line, not the attached ptp%d", - portnum(p), p->phc_index, - interface_phc_index(p->iface)); -- } else if (p->phc_index != interface_phc_index(p->iface)) { -+ } else { - p->phc_index = interface_phc_index(p->iface); - - if (clock_switch_phc(p->clock, p->phc_index)) { -@@ -2619,18 +2622,12 @@ void port_link_status(void *ctx, int linkup, int ts_index) - pr_notice("port %hu: ts label changed to %s", portnum(p), ts_label); - } - -- /* phc index may changed while ts_label keeps the same after failover. -- * e.g. vlan over bond. Since the lower link changed, we still set -- * the TS_LABEL_CHANGED flag. -- */ -+ /* The PHC index may change even with the same ts_label, e.g. after -+ failover with VLAN over bond. */ - interface_get_tsinfo(p->iface); -- if (p->phc_index != interface_phc_index(p->iface)) -- p->link_status |= TS_LABEL_CHANGED; - -- /* Both link down/up and change ts_label may change phc index. */ -- if (p->link_status & LINK_UP && -- (p->link_status & LINK_STATE_CHANGED || p->link_status & TS_LABEL_CHANGED)) -- port_change_phc(p); -+ /* Switch the clock if needed */ -+ port_change_phc(p); - - /* - * A port going down can affect the BMCA result. -commit 8cf63218e4cc33d63bb783bf322d4a0d2f4be73e -Author: Miroslav Lichvar -Date: Wed Mar 15 11:24:16 2023 +0100 - - port: Don't switch to PHC with SW timestamping. - - When ptp4l was configured to use SW timestamping, but the interface - supported also HW timestamping, ptp4l detected a change of the PHC on - start, switched to it from the system clock, and tried to control the - PHC using SW timestamps. - - Don't switch the PHC if the current PHC index is -1, which is expected - with SW timestamping and in the free-running mode. - - Fixes: afeabf3c90ed ("ptp4l: add VLAN over bond support") - Signed-off-by: Miroslav Lichvar - -diff --git a/port.c b/port.c -index 96e097a..32ee83b 100644 ---- a/port.c -+++ b/port.c -@@ -2570,6 +2570,7 @@ static void port_change_phc(struct port *p) - /* Try to switch only if the interface is up, it has HW time stamping - using a non-vclock PHC, and the PHC actually changed. */ - if (!(p->link_status & LINK_UP) || -+ p->phc_index < 0 || - !interface_tsinfo_valid(p->iface) || - interface_get_vclock(p->iface) >= 0 || - interface_phc_index(p->iface) < 0 || diff --git a/linuxptp-zerolength.patch b/linuxptp-zerolength.patch deleted file mode 100644 index 0ab5ed4..0000000 --- a/linuxptp-zerolength.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit 9633ab52460f58c92c6daa35e9d24e4ce9c5ab1c -Author: Miroslav Lichvar -Date: Tue Feb 23 11:01:43 2021 +0100 - - sk: Don't return error for zero-length messages. - - 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."). - - Signed-off-by: Miroslav Lichvar - Fixes: a6e0b83bd503 ("sk: Convey transmit path errors to the caller.") - -diff --git a/sk.c b/sk.c -index c9ef4d2..8be0708 100644 ---- a/sk.c -+++ b/sk.c -@@ -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; - } - - 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/linuxptp.spec b/linuxptp.spec index 2a6a2aa..6d00e26 100644 --- a/linuxptp.spec +++ b/linuxptp.spec @@ -1,9 +1,9 @@ %global _hardened_build 1 -%global testsuite_ver c66922 -%global clknetsim_ver c63e22 +%global testsuite_ver bf8ead +%global clknetsim_ver 5d1dc0 Name: linuxptp -Version: 3.1.1 +Version: 4.2 Release: 9%{?dist} Summary: PTP implementation for Linux @@ -21,40 +21,16 @@ 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 -# 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 +# allow old syntax of SET SUBSCRIBE_EVENTS_NP command +Patch1: linuxptp-subscribe.patch +# disable warning messages about deprecated options +Patch2: linuxptp-deprecated.patch +# revert default PTP version to 2.0 for better compatibility +Patch3: linuxptp-ptpver.patch # limit unicast message rate per address and grant duration Patch4: linuxptp-ucastrate.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 -# avoid unaligned pointers to packed members -Patch10: linuxptp-packalign.patch -# make sanity clock check more reliable -Patch11: linuxptp-clockcheck.patch -# add support for virtual clocks +# check for EL-specific kernels with vclock support Patch12: linuxptp-vclock.patch -# handle PHC read failing with EBUSY in phc2sys -Patch13: linuxptp-phcerr.patch -# add support for VLAN over bond -Patch14: linuxptp-vlanbond.patch -# handle EINTR when waiting for transmit timestamp -Patch15: linuxptp-eintr.patch -# check for unexpected changes in frequency offset -Patch16: linuxptp-freqcheck.patch -# don't re-arm fault clearing timer on unrelated netlink events -Patch17: linuxptp-faultrearm.patch -# clear pending errors on sockets -Patch18: linuxptp-soerror.patch BuildRequires: gcc gcc-c++ make systemd @@ -69,23 +45,7 @@ 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 .logmsgs -%patch2 -p1 -b .classthreshold -%patch3 -p1 -b .deftxtout -%patch4 -p1 -b .ucastrate -%patch5 -p1 -b .udsro -%patch7 -p1 -b .manfix -%patch8 -p1 -b .fclose -%patch9 -p1 -b .zerolength -%patch10 -p1 -b .packalign -%patch11 -p1 -b .clockcheck -%patch12 -p1 -b .vclock -%patch13 -p1 -b .phcerr -%patch14 -p1 -b .vlanbond -%patch15 -p1 -b .eintr -%patch16 -p1 -b .freqcheck -%patch17 -p1 -b .faultrearm -%patch18 -p1 -b .soerror +%autopatch -p1 mv linuxptp-testsuite-%{testsuite_ver}* testsuite mv clknetsim-%{clknetsim_ver}* testsuite/clknetsim @@ -144,6 +104,7 @@ PATH=..:$PATH ./run %{_sbindir}/ptp4l %{_sbindir}/timemaster %{_sbindir}/ts2phc +%{_sbindir}/tz2alt %{_mandir}/man5/*.5* %{_mandir}/man8/*.8* diff --git a/sources b/sources index b30da34..aedb360 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (linuxptp-3.1.1.tgz) = c3c40987fe68480a8473097ebc3c506fb4f8f3b6456bbe637b2b3cb0b3e0182f1513b511fdc04b3607d5f7d8bd1bd22502bb86eb13f9fa4fa63a3331846b33ec -SHA512 (linuxptp-testsuite-c66922.tar.gz) = 1cf30348bb72768e4de59c363f57b56257b01e5306e27b3d243418572ebfbf324c4cc9cb4f74cac04f8408223b501105aeec70a509cf76ae8e0945a01bc70dd6 -SHA512 (clknetsim-c63e22.tar.gz) = 000b15b7877c32da06ea93d46dfc41bee51e13e7c3d9b64cfd660527f7ffdfefc5a3f49cc621512cd9f1bc28312113892630b2b6d06a2f3ee41cb4cb859219cd +SHA512 (linuxptp-4.2.tgz) = 479e512efd0573602379a9e1d8ef5c0ec9e033944cee5aed11c68cea5e8a3f7d4b6f2d11f6d6d4718282010da52c2c8629d675d9b388cc0c3d574845a913cdbb +SHA512 (linuxptp-testsuite-bf8ead.tar.gz) = 6a6d190e8ef43cdb91304f9dc69fd4bc71590b2178c10a8305ddc2660fdc0963a00721db46b951afb0aaf73b268ce2927bca6551010477b6e59ce64aeec22bc6 +SHA512 (clknetsim-5d1dc0.tar.gz) = 76889da425dc9d63ba78811661d78ffa922a63c4f83aeb809fef02c866f64a97b09dd4b0906ccfd1e20cee5091d8b886aadfce54cd338d3bf597b0e976a78927