Compare commits
1 Commits
85e049cbcb
...
1be34672e9
Author | SHA1 | Date | |
---|---|---|---|
|
1be34672e9 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
/linuxptp-4.2.tgz
|
/linuxptp-3.1.1.tgz
|
||||||
/linuxptp-testsuite-bf8ead.tar.gz
|
/linuxptp-testsuite-c66922.tar.gz
|
||||||
/clknetsim-5d1dc0.tar.gz
|
/clknetsim-c63e22.tar.gz
|
||||||
|
@ -1,3 +1 @@
|
|||||||
309e6ab1fa3f61b3deb1735c3082dc2070870be1 linuxptp-4.2.tgz
|
f905eabc6fd0f03c6a353f9c4ba188a3bd1b774c linuxptp-3.1.1.tgz
|
||||||
7594d0705a1a648d5f7380d476bb3afebff21f6c linuxptp-testsuite-bf8ead.tar.gz
|
|
||||||
3ae72eb0ddafd8d8aeea7eac382d6e4a958717ef clknetsim-5d1dc0.tar.gz
|
|
||||||
|
138
linuxptp-classthreshold.patch
Normal file
138
linuxptp-classthreshold.patch
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
Backported commit f774703cb1eee058a346aec3341fee0be329bd6d
|
||||||
|
Author: Karthikkumar V <kvaloor@altiostar.com>
|
||||||
|
Date: Fri Feb 26 06:54:07 2021 +0000
|
||||||
|
|
||||||
|
Clock Class Threshold Feature addition for PTP4L
|
||||||
|
|
||||||
|
This code changes brings in the ability to program the acceptable
|
||||||
|
clockClass threshold beyond which device will move to holdover/free-run.
|
||||||
|
Default clockClass threshold is 248.
|
||||||
|
Example Use-Case:
|
||||||
|
This is needed in the cases where T-SC/T-BC Slave might want to listen
|
||||||
|
only on PRC clockCLass and anything beyond that might not be acceptible
|
||||||
|
and would want to go to holdover (with SyncE backup or internal oscillator).
|
||||||
|
|
||||||
|
Signed-off-by: Karthikkumar V <kvaloor@altiostar.com>
|
||||||
|
Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
|
||||||
|
|
||||||
|
diff --git a/clock.c b/clock.c
|
||||||
|
index c1fcff6..d584748 100644
|
||||||
|
--- a/clock.c
|
||||||
|
+++ b/clock.c
|
||||||
|
@@ -114,6 +114,7 @@ struct clock {
|
||||||
|
int utc_offset;
|
||||||
|
int time_flags; /* grand master role */
|
||||||
|
int time_source; /* grand master role */
|
||||||
|
+ UInteger8 clock_class_threshold;
|
||||||
|
UInteger8 max_steps_removed;
|
||||||
|
enum servo_state servo_state;
|
||||||
|
enum timestamp_type timestamping;
|
||||||
|
@@ -978,6 +979,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
c->default_dataset.localPriority =
|
||||||
|
config_get_int(config, NULL, "G.8275.defaultDS.localPriority");
|
||||||
|
c->max_steps_removed = config_get_int(config, NULL,"maxStepsRemoved");
|
||||||
|
+ c->clock_class_threshold = config_get_int(config, NULL, "clock_class_threshold");
|
||||||
|
|
||||||
|
/* Harmonize the twoStepFlag with the time_stamping option. */
|
||||||
|
if (config_harmonize_onestep(config)) {
|
||||||
|
@@ -1711,6 +1713,11 @@ UInteger8 clock_max_steps_removed(struct clock *c)
|
||||||
|
return c->max_steps_removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
+UInteger8 clock_get_clock_class_threshold(struct clock *c)
|
||||||
|
+{
|
||||||
|
+ return c->clock_class_threshold;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
UInteger16 clock_steps_removed(struct clock *c)
|
||||||
|
{
|
||||||
|
return c->cur.stepsRemoved;
|
||||||
|
diff --git a/clock.h b/clock.h
|
||||||
|
index e7daf97..845d54f 100644
|
||||||
|
--- a/clock.h
|
||||||
|
+++ b/clock.h
|
||||||
|
@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c);
|
||||||
|
*/
|
||||||
|
UInteger8 clock_max_steps_removed(struct clock *c);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * Obtain the clock class threshold field from a clock's default data set.
|
||||||
|
+ * @param c The clock instance.
|
||||||
|
+ * @return Configured clock class threshold value.
|
||||||
|
+ */
|
||||||
|
+UInteger8 clock_get_clock_class_threshold(struct clock *c);
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Obtain the steps removed field from a clock's current data set.
|
||||||
|
* @param c The clock instance.
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index c3deddb..bf1049f 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -231,6 +231,7 @@ struct config_item config_tab[] = {
|
||||||
|
GLOB_ITEM_INT("clockAccuracy", 0xfe, 0, UINT8_MAX),
|
||||||
|
GLOB_ITEM_INT("clockClass", 248, 0, UINT8_MAX),
|
||||||
|
GLOB_ITEM_STR("clockIdentity", "000000.0000.000000"),
|
||||||
|
+ GLOB_ITEM_INT("clock_class_threshold", CLOCK_CLASS_THRESHOLD_DEFAULT, 6, CLOCK_CLASS_THRESHOLD_DEFAULT),
|
||||||
|
GLOB_ITEM_ENU("clock_servo", CLOCK_SERVO_PI, clock_servo_enu),
|
||||||
|
GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
|
||||||
|
GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
|
||||||
|
diff --git a/configs/default.cfg b/configs/default.cfg
|
||||||
|
index 9604219..b2ffa94 100644
|
||||||
|
--- a/configs/default.cfg
|
||||||
|
+++ b/configs/default.cfg
|
||||||
|
@@ -60,6 +60,7 @@ verbose 0
|
||||||
|
summary_interval 0
|
||||||
|
kernel_leap 1
|
||||||
|
check_fup_sync 0
|
||||||
|
+clock_class_threshold 248
|
||||||
|
#
|
||||||
|
# Servo Options
|
||||||
|
#
|
||||||
|
diff --git a/ds.h b/ds.h
|
||||||
|
index 9d9c417..dff6d5e 100644
|
||||||
|
--- a/ds.h
|
||||||
|
+++ b/ds.h
|
||||||
|
@@ -87,6 +87,7 @@ struct parent_ds {
|
||||||
|
|
||||||
|
#define CURRENT_UTC_OFFSET 37 /* 1 Jan 2017 */
|
||||||
|
#define INTERNAL_OSCILLATOR 0xA0
|
||||||
|
+#define CLOCK_CLASS_THRESHOLD_DEFAULT 248
|
||||||
|
|
||||||
|
struct timePropertiesDS {
|
||||||
|
Integer16 currentUtcOffset;
|
||||||
|
diff --git a/port.c b/port.c
|
||||||
|
index 2bb974c..eb3b319 100644
|
||||||
|
--- a/port.c
|
||||||
|
+++ b/port.c
|
||||||
|
@@ -1870,6 +1870,14 @@ int process_announce(struct port *p, struct ptp_message *m)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (m->announce.grandmasterClockQuality.clockClass >
|
||||||
|
+ clock_get_clock_class_threshold(p->clock)) {
|
||||||
|
+ pl_err(60, "port %hu: Master clock quality received is "
|
||||||
|
+ "greater than configured, ignoring master!",
|
||||||
|
+ portnum(p));
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
switch (p->state) {
|
||||||
|
case PS_INITIALIZING:
|
||||||
|
case PS_FAULTY:
|
||||||
|
diff --git a/ptp4l.8 b/ptp4l.8
|
||||||
|
index b04936a..ca76175 100644
|
||||||
|
--- a/ptp4l.8
|
||||||
|
+++ b/ptp4l.8
|
||||||
|
@@ -455,6 +455,11 @@ message is greater than or equal to the value of maxStepsRemoved the
|
||||||
|
Announce message is not considered in the operation of the BMCA.
|
||||||
|
The default value is 255.
|
||||||
|
.TP
|
||||||
|
+.B clock_class_threshold
|
||||||
|
+The maximum clock class value from master, acceptible to sub-ordinate
|
||||||
|
+clock beyond which it moves out of lock state.
|
||||||
|
+The default value is 248.
|
||||||
|
+.TP
|
||||||
|
|
||||||
|
.B domainNumber
|
||||||
|
The domain attribute of the local clock.
|
187
linuxptp-clockcheck.patch
Normal file
187
linuxptp-clockcheck.patch
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
commit 7e8eba5332671abfd95d06dd191059eded1d2cca
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
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 <jacob.e.keller@intel.com>
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <jacob.e.keller@intel.com>
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <jacob.e.keller@intel.com>
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <asubramanyam@altiostar.com>
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
|
||||||
|
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 {
|
82
linuxptp-deftxtout.patch
Normal file
82
linuxptp-deftxtout.patch
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
commit 1a2dfe9b00b79a59acf905476bbc33c74d5770a3
|
||||||
|
Author: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
Date: Thu Jul 8 12:59:30 2021 -0700
|
||||||
|
|
||||||
|
Increase the default tx_timestamp_timeout to 10
|
||||||
|
|
||||||
|
The tx_timestamp_timeout configuration defines the number of
|
||||||
|
milliseconds to wait for a Tx timestamp from the kernel stack. This
|
||||||
|
delay is necessary as Tx timestamps are captured after a packet is sent
|
||||||
|
and reported back via the socket error queue.
|
||||||
|
|
||||||
|
The current default is to poll for up to 1 millisecond. In practice, it
|
||||||
|
turns out that this is not always enough time for hardware and software
|
||||||
|
to capture the timestamp and report it back. Some hardware designs
|
||||||
|
require reading timestamps over registers or other slow mechanisms.
|
||||||
|
|
||||||
|
This extra delay results in the timestamp not being sent back to
|
||||||
|
userspace within the default 1 millisecond polling time. If that occurs
|
||||||
|
the following can be seen from ptp4l:
|
||||||
|
|
||||||
|
ptp4l[4756.840]: timed out while polling for tx timestamp
|
||||||
|
ptp4l[4756.840]: increasing tx_timestamp_timeout may correct this issue,
|
||||||
|
but it is likely caused by a driver bug
|
||||||
|
ptp4l[4756.840]: port 1 (p2p1): send sync failed
|
||||||
|
ptp4l[4756.840]: port 1 (p2p1): MASTER to FAULTY on FAULT_DETECTED
|
||||||
|
(FT_UNSPECIFIED)
|
||||||
|
|
||||||
|
This can confuse users because it implies this is a bug, when the
|
||||||
|
correct solution in many cases is to just increase the timeout to
|
||||||
|
a slightly higher value.
|
||||||
|
|
||||||
|
Since we know this is a problem for many drivers and hardware designs,
|
||||||
|
lets increase the default timeout.
|
||||||
|
|
||||||
|
Note that a longer timeout should not affect setups which return the
|
||||||
|
timestamp quickly. On modern kernels, the poll() call will return once
|
||||||
|
the timestamp is reported back to the socket error queue. (On old
|
||||||
|
kernels around the 3.x era the poll will sleep for the full duration
|
||||||
|
before reporting the timestamp, but this is now quite an old kernel
|
||||||
|
release).
|
||||||
|
|
||||||
|
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index 760b395..03d981e 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -324,7 +324,7 @@ struct config_item config_tab[] = {
|
||||||
|
GLOB_ITEM_INT("ts2phc.pulsewidth", 500000000, 1000000, 999000000),
|
||||||
|
PORT_ITEM_ENU("tsproc_mode", TSPROC_FILTER, tsproc_enu),
|
||||||
|
GLOB_ITEM_INT("twoStepFlag", 1, 0, 1),
|
||||||
|
- GLOB_ITEM_INT("tx_timestamp_timeout", 1, 1, INT_MAX),
|
||||||
|
+ GLOB_ITEM_INT("tx_timestamp_timeout", 10, 1, INT_MAX),
|
||||||
|
PORT_ITEM_INT("udp_ttl", 1, 1, 255),
|
||||||
|
PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F),
|
||||||
|
GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"),
|
||||||
|
diff --git a/configs/default.cfg b/configs/default.cfg
|
||||||
|
index 64ef3bd..d615610 100644
|
||||||
|
--- a/configs/default.cfg
|
||||||
|
+++ b/configs/default.cfg
|
||||||
|
@@ -51,7 +51,7 @@ hybrid_e2e 0
|
||||||
|
inhibit_multicast_service 0
|
||||||
|
net_sync_monitor 0
|
||||||
|
tc_spanning_tree 0
|
||||||
|
-tx_timestamp_timeout 1
|
||||||
|
+tx_timestamp_timeout 10
|
||||||
|
unicast_listen 0
|
||||||
|
unicast_master_table 0
|
||||||
|
unicast_req_duration 3600
|
||||||
|
diff --git a/ptp4l.8 b/ptp4l.8
|
||||||
|
index fe9e150..7ca3474 100644
|
||||||
|
--- a/ptp4l.8
|
||||||
|
+++ b/ptp4l.8
|
||||||
|
@@ -496,7 +496,7 @@ switches all implement this option together with the BMCA.
|
||||||
|
.B tx_timestamp_timeout
|
||||||
|
The number of milliseconds to poll waiting for the tx time stamp from the kernel
|
||||||
|
when a message has recently been sent.
|
||||||
|
-The default is 1.
|
||||||
|
+The default is 10.
|
||||||
|
.TP
|
||||||
|
.B check_fup_sync
|
||||||
|
Because of packet reordering that can occur in the network, in the
|
@ -1,23 +0,0 @@
|
|||||||
commit 99603cf0ab2413d59ae91101429b18d9ced6f88f
|
|
||||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
Date: Thu Jan 11 11:29:34 2024 +0100
|
|
||||||
|
|
||||||
config: Disable warnings about deprecated options.
|
|
||||||
|
|
||||||
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
30
linuxptp-eintr.patch
Normal file
30
linuxptp-eintr.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
commit c8de9f33e437fb15cff32c0028f651d7cb916a37
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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");
|
52
linuxptp-faultrearm.patch
Normal file
52
linuxptp-faultrearm.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
commit 134dc3c4655fcd9f314a5e56cd50db2f87366f5a
|
||||||
|
Author: davidjm via Linuxptp-devel <linuxptp-devel@lists.sourceforge.net>
|
||||||
|
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 <davidjm@arista.com>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
22
linuxptp-fclose.patch
Normal file
22
linuxptp-fclose.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
commit e8a82d1b5be2d5bf9450a9acfe44e957b4867870
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Tue Jul 20 11:41:35 2021 +0200
|
||||||
|
|
||||||
|
lstab: Close file after reading.
|
||||||
|
|
||||||
|
The lstab_read() function opens a file, but doesn't close it after use.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/lstab.c b/lstab.c
|
||||||
|
index e6e7ad2..0d6a427 100644
|
||||||
|
--- a/lstab.c
|
||||||
|
+++ b/lstab.c
|
||||||
|
@@ -144,6 +144,7 @@ static int lstab_read(struct lstab *lstab, const char *name)
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ fclose(fp);
|
||||||
|
if (!lstab->expiration_utc) {
|
||||||
|
fprintf(stderr, "missing expiration date in '%s'\n", name);
|
||||||
|
return -1;
|
208
linuxptp-freqcheck.patch
Normal file
208
linuxptp-freqcheck.patch
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
commit 513c7457865dba262a43e03fbe9178f4b08ba319
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/clockadj.c b/clockadj.c
|
||||||
|
index 957dc57..4c920b9 100644
|
||||||
|
--- a/clockadj.c
|
||||||
|
+++ b/clockadj.c
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@@ -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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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
|
96
linuxptp-logmsgs.patch
Normal file
96
linuxptp-logmsgs.patch
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
commit 3399fa15ae28610c1b288b573c4233a42c48f762
|
||||||
|
Author: Amar Subramanyam via Linuxptp-devel <linuxptp-devel@lists.sourceforge.net>
|
||||||
|
Date: Wed May 26 12:24:06 2021 +0300
|
||||||
|
|
||||||
|
Log optimization for ptp4l in jbod and client only mode (clientOnly=1 and boundary_clock_jbod=1)
|
||||||
|
|
||||||
|
The LISTENING port prints continuously
|
||||||
|
"selected best master clock 000000.0000.000003
|
||||||
|
updating UTC offset to 37"
|
||||||
|
|
||||||
|
We limited the log such that now it prints only when there is a
|
||||||
|
change in the best-master clock.
|
||||||
|
|
||||||
|
Signed-off-by: Amar Subramanyam <asubramanyam@altiostar.com>
|
||||||
|
Signed-off-by: Karthikkumar Valoor <kvaloor@altiostar.com>
|
||||||
|
Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
|
||||||
|
|
||||||
|
diff --git a/clock.c b/clock.c
|
||||||
|
index e545a9b..d428ae2 100644
|
||||||
|
--- a/clock.c
|
||||||
|
+++ b/clock.c
|
||||||
|
@@ -705,7 +705,8 @@ static void clock_update_slave(struct clock *c)
|
||||||
|
if (c->tds.currentUtcOffset < c->utc_offset) {
|
||||||
|
pr_warning("running in a temporal vortex");
|
||||||
|
}
|
||||||
|
- if ((c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE) ||
|
||||||
|
+ if (((c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE) &&
|
||||||
|
+ (c->tds.currentUtcOffset != c->utc_offset)) ||
|
||||||
|
(c->tds.currentUtcOffset > c->utc_offset)) {
|
||||||
|
pr_info("updating UTC offset to %d", c->tds.currentUtcOffset);
|
||||||
|
c->utc_offset = c->tds.currentUtcOffset;
|
||||||
|
@@ -1939,14 +1940,6 @@ static void handle_state_decision_event(struct clock *c)
|
||||||
|
best_id = c->dds.clockIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cid_eq(&best_id, &c->dds.clockIdentity)) {
|
||||||
|
- pr_notice("selected local clock %s as best master",
|
||||||
|
- cid2str(&best_id));
|
||||||
|
- } else {
|
||||||
|
- pr_notice("selected best master clock %s",
|
||||||
|
- cid2str(&best_id));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (!cid_eq(&best_id, &c->best_id)) {
|
||||||
|
clock_freq_est_reset(c);
|
||||||
|
tsproc_reset(c->tsproc, 1);
|
||||||
|
@@ -1957,6 +1950,13 @@ static void handle_state_decision_event(struct clock *c)
|
||||||
|
c->master_local_rr = 1.0;
|
||||||
|
c->nrr = 1.0;
|
||||||
|
fresh_best = 1;
|
||||||
|
+ if (cid_eq(&best_id, &c->dds.clockIdentity)) {
|
||||||
|
+ pr_notice("selected local clock %s as best master",
|
||||||
|
+ cid2str(&best_id));
|
||||||
|
+ } else {
|
||||||
|
+ pr_notice("selected best master clock %s",
|
||||||
|
+ cid2str(&best_id));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
c->best = best;
|
||||||
|
|
||||||
|
commit 766baf345cd4fb025d186f9c9bea5276aba398bc
|
||||||
|
Author: Amar Subramanyam via Linuxptp-devel <linuxptp-devel@lists.sourceforge.net>
|
||||||
|
Date: Wed May 26 12:24:07 2021 +0300
|
||||||
|
|
||||||
|
Log optimization for ptp4l in jbod and client only mode (clientOnly=1 and boundary_clock_jbod=1)
|
||||||
|
|
||||||
|
The port other than SLAVE (LISTENING port) prints an error
|
||||||
|
"port 1: master state recommended in slave only mode
|
||||||
|
ptp4l[1205469.356]: port 1: defaultDS.priority1 probably misconfigured"
|
||||||
|
for every ANNOUNCE RECEIPT Timeout.
|
||||||
|
|
||||||
|
This log is printed when the event EV_RS_MASTER is thrown
|
||||||
|
in clientOnly mode. But single port clientOnly mode will never
|
||||||
|
hit this event instead EV_RS_GRAND_MASTER will be hit.
|
||||||
|
EV_RS_MASTER is thrown when clientOnly=1 and boundary_clock_jbod=1
|
||||||
|
which results in continuous printing. So EV_RS_MASTER check when
|
||||||
|
clientOnly=1 to print this error can be avoided.
|
||||||
|
|
||||||
|
Signed-off-by: Amar Subramanyam <asubramanyam@altiostar.com>
|
||||||
|
Signed-off-by: Karthikkumar Valoor <kvaloor@altiostar.com>
|
||||||
|
Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
|
||||||
|
|
||||||
|
diff --git a/port.c b/port.c
|
||||||
|
index 250d46d..b5b775f 100644
|
||||||
|
--- a/port.c
|
||||||
|
+++ b/port.c
|
||||||
|
@@ -2536,7 +2536,7 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||||
|
static void bc_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||||
|
{
|
||||||
|
if (clock_slave_only(p->clock)) {
|
||||||
|
- if (event == EV_RS_MASTER || event == EV_RS_GRAND_MASTER) {
|
||||||
|
+ if (event == EV_RS_GRAND_MASTER) {
|
||||||
|
port_slave_priority_warning(p);
|
||||||
|
}
|
||||||
|
}
|
@ -1,75 +0,0 @@
|
|||||||
commit bbfaa1e253b889aeea97702bbbc87e731e0caf87
|
|
||||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
Date: Thu Feb 22 13:51:59 2024 +0100
|
|
||||||
|
|
||||||
lstab: Limit number of parsed leap seconds.
|
|
||||||
|
|
||||||
The lstab structure has a fixed-size array for leap seconds
|
|
||||||
(currently 28 + 200). Don't read more leap seconds from the leapfile to
|
|
||||||
avoid corrupting memory.
|
|
||||||
|
|
||||||
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/lstab.c b/lstab.c
|
|
||||||
index 24add26..8e35504 100644
|
|
||||||
--- a/lstab.c
|
|
||||||
+++ b/lstab.c
|
|
||||||
@@ -137,7 +137,7 @@ static int lstab_read(struct lstab *lstab, const char *name)
|
|
||||||
fprintf(stderr, "failed to open '%s' for reading: %m\n", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
- while (1) {
|
|
||||||
+ while (index < N_LEAPS) {
|
|
||||||
if (!fgets(buf, sizeof(buf), fp)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
commit 90ad2efc74b0f348fb6b417565b3ada7d161641b
|
|
||||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
Date: Thu Feb 22 13:56:53 2024 +0100
|
|
||||||
|
|
||||||
lstab: Don't free lstab on update.
|
|
||||||
|
|
||||||
The modification timestamp of the leapfile is checked with every
|
|
||||||
call of lstab_utc2tai(). If the file is modified, the provided lstab
|
|
||||||
structure is freed and a new one is allocated from the updated leapfile.
|
|
||||||
But the new lstab is not returned to the caller as the function doesn't
|
|
||||||
accept a pointer to the pointer to lstab. This causes reading from the
|
|
||||||
freed memory and leak of the newly allocated memory.
|
|
||||||
|
|
||||||
Modify update_leapsecond_table() to read the updated leapfile into the
|
|
||||||
existing lstab structure instead of the reallocation.
|
|
||||||
|
|
||||||
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/lstab.c b/lstab.c
|
|
||||||
index 8e35504..357ed27 100644
|
|
||||||
--- a/lstab.c
|
|
||||||
+++ b/lstab.c
|
|
||||||
@@ -195,7 +195,6 @@ struct lstab *lstab_create(const char *filename)
|
|
||||||
|
|
||||||
int update_leapsecond_table(struct lstab *lstab)
|
|
||||||
{
|
|
||||||
- const char* leapfile;
|
|
||||||
struct stat statbuf;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
@@ -212,14 +211,14 @@ int update_leapsecond_table(struct lstab *lstab)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
printf("updating leap seconds file\n");
|
|
||||||
- leapfile = lstab->leapfile;
|
|
||||||
- lstab_destroy(lstab);
|
|
||||||
|
|
||||||
- lstab = lstab_create(leapfile);
|
|
||||||
- if (!lstab) {
|
|
||||||
+ if (lstab_read(lstab, lstab->leapfile)) {
|
|
||||||
+ lstab->length = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ lstab->lsfile_mtime = statbuf.st_mtim.tv_sec;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
28
linuxptp-manfix.patch
Normal file
28
linuxptp-manfix.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
commit 0b80e32829ca7430be851fc64c4812896ad97c88
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Mon Jul 19 17:09:01 2021 +0200
|
||||||
|
|
||||||
|
Fix quoting in ptp4l man page.
|
||||||
|
|
||||||
|
In the groff syntax lines starting with a dot or quote are requests. A
|
||||||
|
line in the servo_offset_threshold description starts with a quote,
|
||||||
|
which breaks the output. Move a word to the beginning of the line to fix
|
||||||
|
it.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/ptp4l.8 b/ptp4l.8
|
||||||
|
index 7ca3474..a0779ef 100644
|
||||||
|
--- a/ptp4l.8
|
||||||
|
+++ b/ptp4l.8
|
||||||
|
@@ -788,8 +788,8 @@ The default value is 10.
|
||||||
|
.TP
|
||||||
|
.B servo_offset_threshold
|
||||||
|
The offset threshold used in order to transition from the SERVO_LOCKED
|
||||||
|
-to the SERVO_LOCKED_STABLE state. The transition occurs once the last
|
||||||
|
-'servo_num_offset_values' offsets are all below the threshold value.
|
||||||
|
+to the SERVO_LOCKED_STABLE state. The transition occurs once the
|
||||||
|
+last 'servo_num_offset_values' offsets are all below the threshold value.
|
||||||
|
The default value of offset_threshold is 0 (disabled).
|
||||||
|
.TP
|
||||||
|
.B slave_event_monitor
|
@ -1,29 +0,0 @@
|
|||||||
commit 0404c1924254c9162222dd5000a140165d21250c
|
|
||||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
Date: Thu Jan 25 15:23:44 2024 +0100
|
|
||||||
|
|
||||||
ts2phc: Fix offset for NMEA delays over 0.5 seconds.
|
|
||||||
|
|
||||||
The current code of ts2phc assumes that the NMEA RMC message is received
|
|
||||||
within 0.5 seconds of the pulse the timestamp in the message is refering
|
|
||||||
to. However, with most receivers NMEA messages are referenced to the
|
|
||||||
previous pulse. This causes a 1-second error in the measured offset for
|
|
||||||
receivers with delays over 0.5 seconds.
|
|
||||||
|
|
||||||
Add a 0.5 second correction to map the whole interval between pulses to
|
|
||||||
the preceding pulse.
|
|
||||||
|
|
||||||
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
|
|
||||||
diff --git a/ts2phc_nmea_pps_source.c b/ts2phc_nmea_pps_source.c
|
|
||||||
index 3a4267d..274b70a 100644
|
|
||||||
--- a/ts2phc_nmea_pps_source.c
|
|
||||||
+++ b/ts2phc_nmea_pps_source.c
|
|
||||||
@@ -191,6 +191,7 @@ static int ts2phc_nmea_pps_source_getppstime(struct ts2phc_pps_source *src,
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
rmc = tmv_add(rmc, duration_since_rmc);
|
|
||||||
+ rmc = tmv_add(rmc, nanoseconds_to_tmv(500000000));
|
|
||||||
utc_time = tmv_to_nanoseconds(rmc);
|
|
||||||
utc_time /= (int64_t) 1000000000;
|
|
||||||
*ts = tmv_to_timespec(rmc);
|
|
100
linuxptp-packalign.patch
Normal file
100
linuxptp-packalign.patch
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
commit 25dcf01e340d85bcdbe7b3c24eac7fe1ce7ea0c2
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
@@ -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));
|
510
linuxptp-phcerr.patch
Normal file
510
linuxptp-phcerr.patch
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
commit f32a8469a236728fb158ce997385b53f92b821cc
|
||||||
|
Author: Jacob Keller <jacob.e.keller@intel.com>
|
||||||
|
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 <jacob.e.keller@intel.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
@@ -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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
@@ -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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
commit 6e480c9572925a4ea8aac45a10a306e0c4e509a9
|
|
||||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
Date: Thu Jan 11 11:33:54 2024 +0100
|
|
||||||
|
|
||||||
Revert default PTP version to 2.0 for better compatibility.
|
|
||||||
|
|
||||||
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
|
|
||||||
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
|
|
84
linuxptp-soerror.patch
Normal file
84
linuxptp-soerror.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
commit 2db8da6d1e3db074c01516c74899d42089039bc8
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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.
|
@ -1,26 +0,0 @@
|
|||||||
commit b421a4c66ce636adff150dd1aa8eafa981c2693d
|
|
||||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
||||||
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 <mlichvar@redhat.com>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
614
linuxptp-udsro.patch
Normal file
614
linuxptp-udsro.patch
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
Patches backported from the upstream repository.
|
||||||
|
|
||||||
|
commit acc045034dd0db9dd4c4aca4b26528f8fed2ae78
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Thu Feb 11 16:47:08 2021 +0100
|
||||||
|
|
||||||
|
port: Ignore non-management messages on UDS port.
|
||||||
|
|
||||||
|
Drop non-management messages on the UDS port early in the processing to
|
||||||
|
prevent them from changing the port or clock state.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/port.c b/port.c
|
||||||
|
index fa49663..3fd06b1 100644
|
||||||
|
--- a/port.c
|
||||||
|
+++ b/port.c
|
||||||
|
@@ -56,6 +56,7 @@ enum syfu_event {
|
||||||
|
};
|
||||||
|
|
||||||
|
static int port_is_ieee8021as(struct port *p);
|
||||||
|
+static int port_is_uds(struct port *p);
|
||||||
|
static void port_nrate_initialize(struct port *p);
|
||||||
|
|
||||||
|
static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
|
||||||
|
@@ -691,6 +692,9 @@ static int port_ignore(struct port *p, struct ptp_message *m)
|
||||||
|
{
|
||||||
|
struct ClockIdentity c1, c2;
|
||||||
|
|
||||||
|
+ if (port_is_uds(p) && msg_type(m) != MANAGEMENT) {
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
if (incapable_ignore(p, m)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -771,6 +775,11 @@ static int port_is_ieee8021as(struct port *p)
|
||||||
|
return p->follow_up_info ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int port_is_uds(struct port *p)
|
||||||
|
+{
|
||||||
|
+ return transport_type(p->trp) == TRANS_UDS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void port_management_send_error(struct port *p, struct port *ingress,
|
||||||
|
struct ptp_message *msg, int error_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
commit 72ec806fa62a87cb7e5444e27fa6bdcbfe4e27ca
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Thu Feb 11 16:47:09 2021 +0100
|
||||||
|
|
||||||
|
clock: Don't allow COMMAND action on non-UDS port.
|
||||||
|
|
||||||
|
No COMMAND actions are currently supported, but check the port early in
|
||||||
|
clock_manage() before reaching port_manage().
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/clock.c b/clock.c
|
||||||
|
index a66d189..a6947bc 100644
|
||||||
|
--- a/clock.c
|
||||||
|
+++ b/clock.c
|
||||||
|
@@ -1423,6 +1423,11 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
return changed;
|
||||||
|
break;
|
||||||
|
case COMMAND:
|
||||||
|
+ if (p != c->uds_port) {
|
||||||
|
+ /* Sorry, only allowed on the UDS port. */
|
||||||
|
+ clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
+ return changed;
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return changed;
|
||||||
|
|
||||||
|
commit 2b45d80eadcb81c8bdf45baf98dabeebd912b1b0
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Thu Feb 11 16:47:10 2021 +0100
|
||||||
|
|
||||||
|
clock: Rename UDS variables to read-write.
|
||||||
|
|
||||||
|
In preparation for a new read-only UDS port, rename variables of the
|
||||||
|
current UDS port to make it clear it is read-write, as opposed to
|
||||||
|
read-only.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/clock.c b/clock.c
|
||||||
|
index a6947bc..d013b19 100644
|
||||||
|
--- a/clock.c
|
||||||
|
+++ b/clock.c
|
||||||
|
@@ -95,7 +95,7 @@ struct clock {
|
||||||
|
struct foreign_clock *best;
|
||||||
|
struct ClockIdentity best_id;
|
||||||
|
LIST_HEAD(ports_head, port) ports;
|
||||||
|
- struct port *uds_port;
|
||||||
|
+ struct port *uds_rw_port;
|
||||||
|
struct pollfd *pollfd;
|
||||||
|
int pollfd_valid;
|
||||||
|
int nports; /* does not include the UDS port */
|
||||||
|
@@ -129,7 +129,7 @@ struct clock {
|
||||||
|
struct clock_stats stats;
|
||||||
|
int stats_interval;
|
||||||
|
struct clockcheck *sanity_check;
|
||||||
|
- struct interface *udsif;
|
||||||
|
+ struct interface *uds_rw_if;
|
||||||
|
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
|
||||||
|
struct monitor *slave_event_monitor;
|
||||||
|
};
|
||||||
|
@@ -245,7 +245,7 @@ void clock_send_notification(struct clock *c, struct ptp_message *msg,
|
||||||
|
{
|
||||||
|
unsigned int event_pos = event / 8;
|
||||||
|
uint8_t mask = 1 << (event % 8);
|
||||||
|
- struct port *uds = c->uds_port;
|
||||||
|
+ struct port *uds = c->uds_rw_port;
|
||||||
|
struct clock_subscriber *s;
|
||||||
|
|
||||||
|
LIST_FOREACH(s, &c->subscribers, list) {
|
||||||
|
@@ -267,13 +267,13 @@ void clock_destroy(struct clock *c)
|
||||||
|
{
|
||||||
|
struct port *p, *tmp;
|
||||||
|
|
||||||
|
- interface_destroy(c->udsif);
|
||||||
|
+ interface_destroy(c->uds_rw_if);
|
||||||
|
clock_flush_subscriptions(c);
|
||||||
|
LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
|
||||||
|
clock_remove_port(c, p);
|
||||||
|
}
|
||||||
|
monitor_destroy(c->slave_event_monitor);
|
||||||
|
- port_close(c->uds_port);
|
||||||
|
+ port_close(c->uds_rw_port);
|
||||||
|
free(c->pollfd);
|
||||||
|
if (c->clkid != CLOCK_REALTIME) {
|
||||||
|
phc_close(c->clkid);
|
||||||
|
@@ -442,7 +442,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
|
||||||
|
datalen = sizeof(*gsn);
|
||||||
|
break;
|
||||||
|
case TLV_SUBSCRIBE_EVENTS_NP:
|
||||||
|
- if (p != c->uds_port) {
|
||||||
|
+ if (p != c->uds_rw_port) {
|
||||||
|
/* Only the UDS port allowed. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -784,7 +784,7 @@ static int forwarding(struct clock *c, struct port *p)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- if (p == c->uds_port && ps != PS_FAULTY) {
|
||||||
|
+ if (p == c->uds_rw_port && ps != PS_FAULTY) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
@@ -1044,20 +1044,20 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
|
||||||
|
/* Configure the UDS. */
|
||||||
|
uds_ifname = config_get_string(config, NULL, "uds_address");
|
||||||
|
- c->udsif = interface_create(uds_ifname);
|
||||||
|
- if (config_set_section_int(config, interface_name(c->udsif),
|
||||||
|
+ c->uds_rw_if = interface_create(uds_ifname);
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
|
||||||
|
"announceReceiptTimeout", 0)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
- if (config_set_section_int(config, interface_name(c->udsif),
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
|
||||||
|
"delay_mechanism", DM_AUTO)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
- if (config_set_section_int(config, interface_name(c->udsif),
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
|
||||||
|
"network_transport", TRANS_UDS)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
- if (config_set_section_int(config, interface_name(c->udsif),
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_rw_if),
|
||||||
|
"delay_filter_length", 1)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -1180,14 +1180,15 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the UDS interface. */
|
||||||
|
- c->uds_port = port_open(phc_device, phc_index, timestamping, 0, c->udsif, c);
|
||||||
|
- if (!c->uds_port) {
|
||||||
|
+ c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
|
||||||
|
+ c->uds_rw_if, c);
|
||||||
|
+ if (!c->uds_rw_port) {
|
||||||
|
pr_err("failed to open the UDS port");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
clock_fda_changed(c);
|
||||||
|
|
||||||
|
- c->slave_event_monitor = monitor_create(config, c->uds_port);
|
||||||
|
+ c->slave_event_monitor = monitor_create(config, c->uds_rw_port);
|
||||||
|
if (!c->slave_event_monitor) {
|
||||||
|
pr_err("failed to create slave event monitor");
|
||||||
|
return NULL;
|
||||||
|
@@ -1206,7 +1207,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
LIST_FOREACH(p, &c->ports, list) {
|
||||||
|
port_dispatch(p, EV_INITIALIZE, 0);
|
||||||
|
}
|
||||||
|
- port_dispatch(c->uds_port, EV_INITIALIZE, 0);
|
||||||
|
+ port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
@@ -1314,7 +1315,7 @@ static void clock_check_pollfd(struct clock *c)
|
||||||
|
clock_fill_pollfd(dest, p);
|
||||||
|
dest += N_CLOCK_PFD;
|
||||||
|
}
|
||||||
|
- clock_fill_pollfd(dest, c->uds_port);
|
||||||
|
+ clock_fill_pollfd(dest, c->uds_rw_port);
|
||||||
|
c->pollfd_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1331,7 +1332,7 @@ static int clock_do_forward_mgmt(struct clock *c,
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Don't forward any requests to the UDS port. */
|
||||||
|
- if (out == c->uds_port) {
|
||||||
|
+ if (out == c->uds_rw_port) {
|
||||||
|
switch (management_action(msg)) {
|
||||||
|
case GET:
|
||||||
|
case SET:
|
||||||
|
@@ -1362,7 +1363,7 @@ static void clock_forward_mgmt_msg(struct clock *c, struct port *p, struct ptp_m
|
||||||
|
pr_err("port %d: management forward failed",
|
||||||
|
port_number(piter));
|
||||||
|
}
|
||||||
|
- if (clock_do_forward_mgmt(c, p, c->uds_port, msg, &msg_ready))
|
||||||
|
+ if (clock_do_forward_mgmt(c, p, c->uds_rw_port, msg, &msg_ready))
|
||||||
|
pr_err("uds port: management forward failed");
|
||||||
|
if (msg_ready) {
|
||||||
|
msg_post_recv(msg, pdulen);
|
||||||
|
@@ -1414,7 +1415,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
clock_management_send_error(p, msg, TLV_WRONG_LENGTH);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
- if (p != c->uds_port) {
|
||||||
|
+ if (p != c->uds_rw_port) {
|
||||||
|
/* Sorry, only allowed on the UDS port. */
|
||||||
|
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
return changed;
|
||||||
|
@@ -1423,7 +1424,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
return changed;
|
||||||
|
break;
|
||||||
|
case COMMAND:
|
||||||
|
- if (p != c->uds_port) {
|
||||||
|
+ if (p != c->uds_rw_port) {
|
||||||
|
/* Sorry, only allowed on the UDS port. */
|
||||||
|
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
return changed;
|
||||||
|
@@ -1435,7 +1436,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
|
||||||
|
switch (mgt->id) {
|
||||||
|
case TLV_PORT_PROPERTIES_NP:
|
||||||
|
- if (p != c->uds_port) {
|
||||||
|
+ if (p != c->uds_rw_port) {
|
||||||
|
/* Only the UDS port allowed. */
|
||||||
|
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
return 0;
|
||||||
|
@@ -1500,7 +1501,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
|
||||||
|
void clock_notify_event(struct clock *c, enum notification event)
|
||||||
|
{
|
||||||
|
- struct port *uds = c->uds_port;
|
||||||
|
+ struct port *uds = c->uds_rw_port;
|
||||||
|
struct PortIdentity pid = port_identity(uds);
|
||||||
|
struct ptp_message *msg;
|
||||||
|
int id;
|
||||||
|
@@ -1604,7 +1605,7 @@ int clock_poll(struct clock *c)
|
||||||
|
/* Check the UDS port. */
|
||||||
|
for (i = 0; i < N_POLLFD; i++) {
|
||||||
|
if (cur[i].revents & (POLLIN|POLLPRI)) {
|
||||||
|
- event = port_event(c->uds_port, i);
|
||||||
|
+ event = port_event(c->uds_rw_port, i);
|
||||||
|
if (EV_STATE_DECISION_EVENT == event) {
|
||||||
|
c->sde = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
commit 1f74a16502b55ce8eaed3d7488542e5469ac8263
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Thu Feb 11 16:47:11 2021 +0100
|
||||||
|
|
||||||
|
clock: Add read-only UDS port for monitoring.
|
||||||
|
|
||||||
|
Add a second UDS port to allow untrusted applications to monitor ptp4l.
|
||||||
|
On this "read-only" UDS port disable non-GET actions and forwarding.
|
||||||
|
The path can be configured with the uds_ro_address option (default is
|
||||||
|
/var/run/ptp4lro).
|
||||||
|
|
||||||
|
Forwarding is disabled to limit the access to the local ptp4l instance.
|
||||||
|
|
||||||
|
Subscriptions are not enabled to prevent the applications from making a
|
||||||
|
large number of subscriptions or interfere with applications that have
|
||||||
|
access to the read-write UDS port.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/clock.c b/clock.c
|
||||||
|
index d013b19..8592d29 100644
|
||||||
|
--- a/clock.c
|
||||||
|
+++ b/clock.c
|
||||||
|
@@ -96,9 +96,10 @@ struct clock {
|
||||||
|
struct ClockIdentity best_id;
|
||||||
|
LIST_HEAD(ports_head, port) ports;
|
||||||
|
struct port *uds_rw_port;
|
||||||
|
+ struct port *uds_ro_port;
|
||||||
|
struct pollfd *pollfd;
|
||||||
|
int pollfd_valid;
|
||||||
|
- int nports; /* does not include the UDS port */
|
||||||
|
+ int nports; /* does not include the two UDS ports */
|
||||||
|
int last_port_number;
|
||||||
|
int sde;
|
||||||
|
int free_running;
|
||||||
|
@@ -130,6 +131,7 @@ struct clock {
|
||||||
|
int stats_interval;
|
||||||
|
struct clockcheck *sanity_check;
|
||||||
|
struct interface *uds_rw_if;
|
||||||
|
+ struct interface *uds_ro_if;
|
||||||
|
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
|
||||||
|
struct monitor *slave_event_monitor;
|
||||||
|
};
|
||||||
|
@@ -268,12 +270,14 @@ void clock_destroy(struct clock *c)
|
||||||
|
struct port *p, *tmp;
|
||||||
|
|
||||||
|
interface_destroy(c->uds_rw_if);
|
||||||
|
+ interface_destroy(c->uds_ro_if);
|
||||||
|
clock_flush_subscriptions(c);
|
||||||
|
LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
|
||||||
|
clock_remove_port(c, p);
|
||||||
|
}
|
||||||
|
monitor_destroy(c->slave_event_monitor);
|
||||||
|
port_close(c->uds_rw_port);
|
||||||
|
+ port_close(c->uds_ro_port);
|
||||||
|
free(c->pollfd);
|
||||||
|
if (c->clkid != CLOCK_REALTIME) {
|
||||||
|
phc_close(c->clkid);
|
||||||
|
@@ -443,7 +447,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
|
||||||
|
break;
|
||||||
|
case TLV_SUBSCRIBE_EVENTS_NP:
|
||||||
|
if (p != c->uds_rw_port) {
|
||||||
|
- /* Only the UDS port allowed. */
|
||||||
|
+ /* Only the UDS-RW port allowed. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sen = (struct subscribe_events_np *)tlv->data;
|
||||||
|
@@ -774,6 +778,10 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress)
|
||||||
|
static int forwarding(struct clock *c, struct port *p)
|
||||||
|
{
|
||||||
|
enum port_state ps = port_state(p);
|
||||||
|
+
|
||||||
|
+ if (p == c->uds_ro_port)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
switch (ps) {
|
||||||
|
case PS_MASTER:
|
||||||
|
case PS_GRAND_MASTER:
|
||||||
|
@@ -818,7 +826,7 @@ static int clock_add_port(struct clock *c, const char *phc_device,
|
||||||
|
{
|
||||||
|
struct port *p, *piter, *lastp = NULL;
|
||||||
|
|
||||||
|
- if (clock_resize_pollfd(c, c->nports + 1)) {
|
||||||
|
+ if (clock_resize_pollfd(c, c->nports + 2)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p = port_open(phc_device, phc_index, timestamping,
|
||||||
|
@@ -1043,6 +1051,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the UDS. */
|
||||||
|
+
|
||||||
|
uds_ifname = config_get_string(config, NULL, "uds_address");
|
||||||
|
c->uds_rw_if = interface_create(uds_ifname);
|
||||||
|
if (config_set_section_int(config, interface_name(c->uds_rw_if),
|
||||||
|
@@ -1062,6 +1071,25 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ uds_ifname = config_get_string(config, NULL, "uds_ro_address");
|
||||||
|
+ c->uds_ro_if = interface_create(uds_ifname);
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
|
||||||
|
+ "announceReceiptTimeout", 0)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
|
||||||
|
+ "delay_mechanism", DM_AUTO)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
|
||||||
|
+ "network_transport", TRANS_UDS)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ if (config_set_section_int(config, interface_name(c->uds_ro_if),
|
||||||
|
+ "delay_filter_length", 1)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
c->config = config;
|
||||||
|
c->free_running = config_get_int(config, NULL, "free_running");
|
||||||
|
c->freq_est_interval = config_get_int(config, NULL, "freq_est_interval");
|
||||||
|
@@ -1179,11 +1207,18 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Create the UDS interface. */
|
||||||
|
+ /* Create the UDS interfaces. */
|
||||||
|
+
|
||||||
|
c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
|
||||||
|
c->uds_rw_if, c);
|
||||||
|
if (!c->uds_rw_port) {
|
||||||
|
- pr_err("failed to open the UDS port");
|
||||||
|
+ pr_err("failed to open the UDS-RW port");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ c->uds_ro_port = port_open(phc_device, phc_index, timestamping, 0,
|
||||||
|
+ c->uds_ro_if, c);
|
||||||
|
+ if (!c->uds_ro_port) {
|
||||||
|
+ pr_err("failed to open the UDS-RO port");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
clock_fda_changed(c);
|
||||||
|
@@ -1208,6 +1243,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
|
||||||
|
port_dispatch(p, EV_INITIALIZE, 0);
|
||||||
|
}
|
||||||
|
port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
|
||||||
|
+ port_dispatch(c->uds_ro_port, EV_INITIALIZE, 0);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
@@ -1278,9 +1314,9 @@ static int clock_resize_pollfd(struct clock *c, int new_nports)
|
||||||
|
{
|
||||||
|
struct pollfd *new_pollfd;
|
||||||
|
|
||||||
|
- /* Need to allocate one whole extra block of fds for UDS. */
|
||||||
|
+ /* Need to allocate two whole extra blocks of fds for UDS ports. */
|
||||||
|
new_pollfd = realloc(c->pollfd,
|
||||||
|
- (new_nports + 1) * N_CLOCK_PFD *
|
||||||
|
+ (new_nports + 2) * N_CLOCK_PFD *
|
||||||
|
sizeof(struct pollfd));
|
||||||
|
if (!new_pollfd) {
|
||||||
|
return -1;
|
||||||
|
@@ -1316,6 +1352,8 @@ static void clock_check_pollfd(struct clock *c)
|
||||||
|
dest += N_CLOCK_PFD;
|
||||||
|
}
|
||||||
|
clock_fill_pollfd(dest, c->uds_rw_port);
|
||||||
|
+ dest += N_CLOCK_PFD;
|
||||||
|
+ clock_fill_pollfd(dest, c->uds_ro_port);
|
||||||
|
c->pollfd_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1331,7 +1369,8 @@ static int clock_do_forward_mgmt(struct clock *c,
|
||||||
|
if (in == out || !forwarding(c, out))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- /* Don't forward any requests to the UDS port. */
|
||||||
|
+ /* Don't forward any requests to the UDS-RW port
|
||||||
|
+ (the UDS-RO port doesn't allow any forwarding). */
|
||||||
|
if (out == c->uds_rw_port) {
|
||||||
|
switch (management_action(msg)) {
|
||||||
|
case GET:
|
||||||
|
@@ -1416,7 +1455,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
if (p != c->uds_rw_port) {
|
||||||
|
- /* Sorry, only allowed on the UDS port. */
|
||||||
|
+ /* Sorry, only allowed on the UDS-RW port. */
|
||||||
|
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
@@ -1425,7 +1464,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
break;
|
||||||
|
case COMMAND:
|
||||||
|
if (p != c->uds_rw_port) {
|
||||||
|
- /* Sorry, only allowed on the UDS port. */
|
||||||
|
+ /* Sorry, only allowed on the UDS-RW port. */
|
||||||
|
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
@@ -1437,7 +1476,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
|
||||||
|
switch (mgt->id) {
|
||||||
|
case TLV_PORT_PROPERTIES_NP:
|
||||||
|
if (p != c->uds_rw_port) {
|
||||||
|
- /* Only the UDS port allowed. */
|
||||||
|
+ /* Only the UDS-RW port allowed. */
|
||||||
|
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1548,7 +1587,7 @@ int clock_poll(struct clock *c)
|
||||||
|
struct port *p;
|
||||||
|
|
||||||
|
clock_check_pollfd(c);
|
||||||
|
- cnt = poll(c->pollfd, (c->nports + 1) * N_CLOCK_PFD, -1);
|
||||||
|
+ cnt = poll(c->pollfd, (c->nports + 2) * N_CLOCK_PFD, -1);
|
||||||
|
if (cnt < 0) {
|
||||||
|
if (EINTR == errno) {
|
||||||
|
return 0;
|
||||||
|
@@ -1602,7 +1641,7 @@ int clock_poll(struct clock *c)
|
||||||
|
cur += N_CLOCK_PFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Check the UDS port. */
|
||||||
|
+ /* Check the UDS ports. */
|
||||||
|
for (i = 0; i < N_POLLFD; i++) {
|
||||||
|
if (cur[i].revents & (POLLIN|POLLPRI)) {
|
||||||
|
event = port_event(c->uds_rw_port, i);
|
||||||
|
@@ -1611,6 +1650,13 @@ int clock_poll(struct clock *c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ cur += N_CLOCK_PFD;
|
||||||
|
+ for (i = 0; i < N_POLLFD; i++) {
|
||||||
|
+ if (cur[i].revents & (POLLIN|POLLPRI)) {
|
||||||
|
+ event = port_event(c->uds_ro_port, i);
|
||||||
|
+ /* sde is not expected on the UDS-RO port */
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (c->sde) {
|
||||||
|
handle_state_decision_event(c);
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index d237de9..96a5351 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -323,6 +323,7 @@ struct config_item config_tab[] = {
|
||||||
|
PORT_ITEM_INT("udp_ttl", 1, 1, 255),
|
||||||
|
PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F),
|
||||||
|
GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"),
|
||||||
|
+ GLOB_ITEM_STR("uds_ro_address", "/var/run/ptp4lro"),
|
||||||
|
PORT_ITEM_INT("unicast_listen", 0, 0, 1),
|
||||||
|
PORT_ITEM_INT("unicast_master_table", 0, 0, INT_MAX),
|
||||||
|
PORT_ITEM_INT("unicast_req_duration", 3600, 10, INT_MAX),
|
||||||
|
diff --git a/configs/default.cfg b/configs/default.cfg
|
||||||
|
index 8c19129..d5bab7d 100644
|
||||||
|
--- a/configs/default.cfg
|
||||||
|
+++ b/configs/default.cfg
|
||||||
|
@@ -90,6 +90,7 @@ p2p_dst_mac 01:80:C2:00:00:0E
|
||||||
|
udp_ttl 1
|
||||||
|
udp6_scope 0x0E
|
||||||
|
uds_address /var/run/ptp4l
|
||||||
|
+uds_ro_address /var/run/ptp4lro
|
||||||
|
#
|
||||||
|
# Default interface options
|
||||||
|
#
|
||||||
|
diff --git a/ptp4l.8 b/ptp4l.8
|
||||||
|
index b179b81..f9bd228 100644
|
||||||
|
--- a/ptp4l.8
|
||||||
|
+++ b/ptp4l.8
|
||||||
|
@@ -615,6 +615,12 @@ is only relevant with IPv6 transport. See RFC 4291. The default is
|
||||||
|
Specifies the address of the UNIX domain socket for receiving local
|
||||||
|
management messages. The default is /var/run/ptp4l.
|
||||||
|
.TP
|
||||||
|
+.B uds_ro_address
|
||||||
|
+Specifies the address of the second UNIX domain socket for receiving local
|
||||||
|
+management messages, which is restricted to GET actions and does not forward
|
||||||
|
+messages to other ports. Access to this socket can be given to untrusted
|
||||||
|
+applications for monitoring purposes. The default is /var/run/ptp4lro.
|
||||||
|
+.TP
|
||||||
|
.B dscp_event
|
||||||
|
Defines the Differentiated Services Codepoint (DSCP) to be used for PTP
|
||||||
|
event messages. Must be a value between 0 and 63. There are several media
|
||||||
|
|
||||||
|
commit d4c5343237588d265c605f3772337bc88cabe787
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Date: Thu Feb 11 16:47:12 2021 +0100
|
||||||
|
|
||||||
|
timemaster: Set uds_ro_address for ptp4l instances.
|
||||||
|
|
||||||
|
This prevents conflicts on the new UDS-RO port.
|
||||||
|
|
||||||
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/timemaster.c b/timemaster.c
|
||||||
|
index 00db59f..02408d6 100644
|
||||||
|
--- a/timemaster.c
|
||||||
|
+++ b/timemaster.c
|
||||||
|
@@ -712,7 +712,7 @@ static int add_ptp_source(struct ptp_domain *source,
|
||||||
|
char **ntp_config, struct script *script)
|
||||||
|
{
|
||||||
|
struct config_file *config_file;
|
||||||
|
- char **command, *uds_path, **interfaces, *message_tag;
|
||||||
|
+ char **command, *uds_path, *uds_path2, **interfaces, *message_tag;
|
||||||
|
char ts_interface[IF_NAMESIZE];
|
||||||
|
int i, j, num_interfaces, *phc, *phcs, hw_ts, sw_ts;
|
||||||
|
struct sk_ts_info ts_info;
|
||||||
|
@@ -809,6 +809,8 @@ static int add_ptp_source(struct ptp_domain *source,
|
||||||
|
|
||||||
|
uds_path = string_newf("%s/ptp4l.%d.socket",
|
||||||
|
config->rundir, *shm_segment);
|
||||||
|
+ uds_path2 = string_newf("%s/ptp4lro.%d.socket",
|
||||||
|
+ config->rundir, *shm_segment);
|
||||||
|
|
||||||
|
message_tag = string_newf("[%d", source->domain);
|
||||||
|
for (j = 0; interfaces[j]; j++)
|
||||||
|
@@ -832,8 +834,10 @@ static int add_ptp_source(struct ptp_domain *source,
|
||||||
|
"slaveOnly 1\n"
|
||||||
|
"domainNumber %d\n"
|
||||||
|
"uds_address %s\n"
|
||||||
|
+ "uds_ro_address %s\n"
|
||||||
|
"message_tag %s\n",
|
||||||
|
- source->domain, uds_path, message_tag);
|
||||||
|
+ source->domain, uds_path, uds_path2,
|
||||||
|
+ message_tag);
|
||||||
|
|
||||||
|
if (phcs[i] >= 0) {
|
||||||
|
/* HW time stamping */
|
||||||
|
@@ -868,6 +872,7 @@ static int add_ptp_source(struct ptp_domain *source,
|
||||||
|
|
||||||
|
free(message_tag);
|
||||||
|
free(uds_path);
|
||||||
|
+ free(uds_path2);
|
||||||
|
free(interfaces);
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
451
linuxptp-vlanbond.patch
Normal file
451
linuxptp-vlanbond.patch
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
commit afd709924edcea26fec24a6253d1b85fc94c88e6
|
||||||
|
Author: Hangbin Liu <liuhangbin@gmail.com>
|
||||||
|
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 <liuhangbin@gmail.com>
|
||||||
|
|
||||||
|
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 <vincent.cheng.xh@renesas.com>
|
||||||
|
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 <vincent.cheng.xh@renesas.com>
|
||||||
|
|
||||||
|
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 <liuhangbin@gmail.com>
|
||||||
|
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 <liuhangbin@gmail.com>
|
||||||
|
|
||||||
|
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 <liuhangbin@gmail.com>
|
||||||
|
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 <liuhangbin@gmail.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
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 ||
|
37
linuxptp-zerolength.patch
Normal file
37
linuxptp-zerolength.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
commit 9633ab52460f58c92c6daa35e9d24e4ce9c5ab1c
|
||||||
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
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 <mlichvar@redhat.com>
|
||||||
|
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)
|
@ -1,10 +1,10 @@
|
|||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
%global testsuite_ver bf8ead
|
%global testsuite_ver c66922
|
||||||
%global clknetsim_ver 5d1dc0
|
%global clknetsim_ver c63e22
|
||||||
|
|
||||||
Name: linuxptp
|
Name: linuxptp
|
||||||
Version: 4.2
|
Version: 3.1.1
|
||||||
Release: 2%{?dist}
|
Release: 9%{?dist}
|
||||||
Summary: PTP implementation for Linux
|
Summary: PTP implementation for Linux
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
@ -21,20 +21,40 @@ Source10: https://github.com/mlichvar/linuxptp-testsuite/archive/%{testsuite_ver
|
|||||||
# simulator for test suite
|
# simulator for test suite
|
||||||
Source11: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz
|
Source11: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz
|
||||||
|
|
||||||
# allow old syntax of SET SUBSCRIBE_EVENTS_NP command
|
# don't repeat some log messages in multi-port configuration
|
||||||
Patch1: linuxptp-subscribe.patch
|
Patch1: linuxptp-logmsgs.patch
|
||||||
# disable warning messages about deprecated options
|
# add option to set clockClass threshold
|
||||||
Patch2: linuxptp-deprecated.patch
|
Patch2: linuxptp-classthreshold.patch
|
||||||
# revert default PTP version to 2.0 for better compatibility
|
# increase default TX timestamp timeout to 10 ms
|
||||||
Patch3: linuxptp-ptpver.patch
|
Patch3: linuxptp-deftxtout.patch
|
||||||
# limit unicast message rate per address and grant duration
|
# limit unicast message rate per address and grant duration
|
||||||
Patch4: linuxptp-ucastrate.patch
|
Patch4: linuxptp-ucastrate.patch
|
||||||
# fix ts2phc to handle large NMEA delay
|
# add read-only UDS port
|
||||||
Patch5: linuxptp-nmeadelay.patch
|
Patch5: linuxptp-udsro.patch
|
||||||
# fix loading and reloading of leapfile
|
# fix quoting in ptp4l man page
|
||||||
Patch6: linuxptp-lstab.patch
|
Patch7: linuxptp-manfix.patch
|
||||||
# check for EL-specific kernels with vclock support
|
# 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
|
||||||
Patch12: linuxptp-vclock.patch
|
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
|
BuildRequires: gcc gcc-c++ make systemd
|
||||||
|
|
||||||
@ -49,7 +69,23 @@ Supporting legacy APIs and other platforms is not a goal.
|
|||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -a 10 -a 11 -n %{name}-%{!?gitfullver:%{version}}%{?gitfullver}
|
%setup -q -a 10 -a 11 -n %{name}-%{!?gitfullver:%{version}}%{?gitfullver}
|
||||||
%autopatch -p1
|
%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
|
||||||
mv linuxptp-testsuite-%{testsuite_ver}* testsuite
|
mv linuxptp-testsuite-%{testsuite_ver}* testsuite
|
||||||
mv clknetsim-%{clknetsim_ver}* testsuite/clknetsim
|
mv clknetsim-%{clknetsim_ver}* testsuite/clknetsim
|
||||||
|
|
||||||
@ -108,18 +144,10 @@ PATH=..:$PATH ./run
|
|||||||
%{_sbindir}/ptp4l
|
%{_sbindir}/ptp4l
|
||||||
%{_sbindir}/timemaster
|
%{_sbindir}/timemaster
|
||||||
%{_sbindir}/ts2phc
|
%{_sbindir}/ts2phc
|
||||||
%{_sbindir}/tz2alt
|
|
||||||
%{_mandir}/man5/*.5*
|
%{_mandir}/man5/*.5*
|
||||||
%{_mandir}/man8/*.8*
|
%{_mandir}/man8/*.8*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Thu Feb 22 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.2-2
|
|
||||||
- fix loading and reloading of leapfile
|
|
||||||
|
|
||||||
* Tue Jan 30 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.2-1
|
|
||||||
- update to 4.2 (RHEL-2026 RHEL-2342 RHEL-12182 RHEL-15929)
|
|
||||||
- fix ts2phc to handle large NMEA delay (RHEL-23208)
|
|
||||||
|
|
||||||
* Wed May 03 2023 Miroslav Lichvar <mlichvar@redhat.com> 3.1.1-9
|
* Wed May 03 2023 Miroslav Lichvar <mlichvar@redhat.com> 3.1.1-9
|
||||||
- clear pending errors on sockets (#2192559)
|
- clear pending errors on sockets (#2192559)
|
||||||
|
|
||||||
|
6
sources
6
sources
@ -1,3 +1,3 @@
|
|||||||
SHA512 (linuxptp-4.2.tgz) = 479e512efd0573602379a9e1d8ef5c0ec9e033944cee5aed11c68cea5e8a3f7d4b6f2d11f6d6d4718282010da52c2c8629d675d9b388cc0c3d574845a913cdbb
|
SHA512 (linuxptp-3.1.1.tgz) = c3c40987fe68480a8473097ebc3c506fb4f8f3b6456bbe637b2b3cb0b3e0182f1513b511fdc04b3607d5f7d8bd1bd22502bb86eb13f9fa4fa63a3331846b33ec
|
||||||
SHA512 (linuxptp-testsuite-bf8ead.tar.gz) = 6a6d190e8ef43cdb91304f9dc69fd4bc71590b2178c10a8305ddc2660fdc0963a00721db46b951afb0aaf73b268ce2927bca6551010477b6e59ce64aeec22bc6
|
SHA512 (linuxptp-testsuite-c66922.tar.gz) = 1cf30348bb72768e4de59c363f57b56257b01e5306e27b3d243418572ebfbf324c4cc9cb4f74cac04f8408223b501105aeec70a509cf76ae8e0945a01bc70dd6
|
||||||
SHA512 (clknetsim-5d1dc0.tar.gz) = 76889da425dc9d63ba78811661d78ffa922a63c4f83aeb809fef02c866f64a97b09dd4b0906ccfd1e20cee5091d8b886aadfce54cd338d3bf597b0e976a78927
|
SHA512 (clknetsim-c63e22.tar.gz) = 000b15b7877c32da06ea93d46dfc41bee51e13e7c3d9b64cfd660527f7ffdfefc5a3f49cc621512cd9f1bc28312113892630b2b6d06a2f3ee41cb4cb859219cd
|
||||||
|
Loading…
Reference in New Issue
Block a user