From ae5d4011d022166ab0cbfd689d7273eb45974a0b Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 02 2021 12:52:47 +0000 Subject: import linuxptp-3.1.1-2.el9 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59f8d4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +SOURCES/clknetsim-ce3c4a.tar.gz +SOURCES/linuxptp-3.1.1.tgz +SOURCES/linuxptp-testsuite-c66922.tar.gz diff --git a/.linuxptp.metadata b/.linuxptp.metadata new file mode 100644 index 0000000..48191c2 --- /dev/null +++ b/.linuxptp.metadata @@ -0,0 +1,3 @@ +338f0be03fd391857adc47306a091952d30d6b89 SOURCES/clknetsim-ce3c4a.tar.gz +f905eabc6fd0f03c6a353f9c4ba188a3bd1b774c SOURCES/linuxptp-3.1.1.tgz +73af42ccc7911c1c2d08fe313cb67329229a5a4b SOURCES/linuxptp-testsuite-c66922.tar.gz diff --git a/SOURCES/linuxptp-classthreshold.patch b/SOURCES/linuxptp-classthreshold.patch new file mode 100644 index 0000000..71b0250 --- /dev/null +++ b/SOURCES/linuxptp-classthreshold.patch @@ -0,0 +1,138 @@ +Backported commit f774703cb1eee058a346aec3341fee0be329bd6d +Author: Karthikkumar V +Date: Fri Feb 26 06:54:07 2021 +0000 + + Clock Class Threshold Feature addition for PTP4L + + This code changes brings in the ability to program the acceptable + clockClass threshold beyond which device will move to holdover/free-run. + Default clockClass threshold is 248. + Example Use-Case: + This is needed in the cases where T-SC/T-BC Slave might want to listen + only on PRC clockCLass and anything beyond that might not be acceptible + and would want to go to holdover (with SyncE backup or internal oscillator). + + Signed-off-by: Karthikkumar V + Signed-off-by: Ramana Reddy + +diff --git a/clock.c b/clock.c +index c1fcff6..d584748 100644 +--- a/clock.c ++++ b/clock.c +@@ -114,6 +114,7 @@ struct clock { + int utc_offset; + int time_flags; /* grand master role */ + int time_source; /* grand master role */ ++ UInteger8 clock_class_threshold; + UInteger8 max_steps_removed; + enum servo_state servo_state; + enum timestamp_type timestamping; +@@ -978,6 +979,7 @@ struct clock *clock_create(enum clock_type type, struct config *config, + c->default_dataset.localPriority = + config_get_int(config, NULL, "G.8275.defaultDS.localPriority"); + c->max_steps_removed = config_get_int(config, NULL,"maxStepsRemoved"); ++ c->clock_class_threshold = config_get_int(config, NULL, "clock_class_threshold"); + + /* Harmonize the twoStepFlag with the time_stamping option. */ + if (config_harmonize_onestep(config)) { +@@ -1711,6 +1713,11 @@ UInteger8 clock_max_steps_removed(struct clock *c) + return c->max_steps_removed; + } + ++UInteger8 clock_get_clock_class_threshold(struct clock *c) ++{ ++ return c->clock_class_threshold; ++} ++ + UInteger16 clock_steps_removed(struct clock *c) + { + return c->cur.stepsRemoved; +diff --git a/clock.h b/clock.h +index e7daf97..845d54f 100644 +--- a/clock.h ++++ b/clock.h +@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c); + */ + UInteger8 clock_max_steps_removed(struct clock *c); + ++/** ++ * Obtain the clock class threshold field from a clock's default data set. ++ * @param c The clock instance. ++ * @return Configured clock class threshold value. ++ */ ++UInteger8 clock_get_clock_class_threshold(struct clock *c); ++ + /** + * Obtain the steps removed field from a clock's current data set. + * @param c The clock instance. +diff --git a/config.c b/config.c +index c3deddb..bf1049f 100644 +--- a/config.c ++++ b/config.c +@@ -231,6 +231,7 @@ struct config_item config_tab[] = { + GLOB_ITEM_INT("clockAccuracy", 0xfe, 0, UINT8_MAX), + GLOB_ITEM_INT("clockClass", 248, 0, UINT8_MAX), + GLOB_ITEM_STR("clockIdentity", "000000.0000.000000"), ++ GLOB_ITEM_INT("clock_class_threshold", CLOCK_CLASS_THRESHOLD_DEFAULT, 6, CLOCK_CLASS_THRESHOLD_DEFAULT), + GLOB_ITEM_ENU("clock_servo", CLOCK_SERVO_PI, clock_servo_enu), + GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu), + GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu), +diff --git a/configs/default.cfg b/configs/default.cfg +index 9604219..b2ffa94 100644 +--- a/configs/default.cfg ++++ b/configs/default.cfg +@@ -60,6 +60,7 @@ verbose 0 + summary_interval 0 + kernel_leap 1 + check_fup_sync 0 ++clock_class_threshold 248 + # + # Servo Options + # +diff --git a/ds.h b/ds.h +index 9d9c417..dff6d5e 100644 +--- a/ds.h ++++ b/ds.h +@@ -87,6 +87,7 @@ struct parent_ds { + + #define CURRENT_UTC_OFFSET 37 /* 1 Jan 2017 */ + #define INTERNAL_OSCILLATOR 0xA0 ++#define CLOCK_CLASS_THRESHOLD_DEFAULT 248 + + struct timePropertiesDS { + Integer16 currentUtcOffset; +diff --git a/port.c b/port.c +index 2bb974c..eb3b319 100644 +--- a/port.c ++++ b/port.c +@@ -1870,6 +1870,14 @@ int process_announce(struct port *p, struct ptp_message *m) + return result; + } + ++ if (m->announce.grandmasterClockQuality.clockClass > ++ clock_get_clock_class_threshold(p->clock)) { ++ pl_err(60, "port %hu: Master clock quality received is " ++ "greater than configured, ignoring master!", ++ portnum(p)); ++ return result; ++ } ++ + switch (p->state) { + case PS_INITIALIZING: + case PS_FAULTY: +diff --git a/ptp4l.8 b/ptp4l.8 +index b04936a..ca76175 100644 +--- a/ptp4l.8 ++++ b/ptp4l.8 +@@ -455,6 +455,11 @@ message is greater than or equal to the value of maxStepsRemoved the + Announce message is not considered in the operation of the BMCA. + The default value is 255. + .TP ++.B clock_class_threshold ++The maximum clock class value from master, acceptible to sub-ordinate ++clock beyond which it moves out of lock state. ++The default value is 248. ++.TP + + .B domainNumber + The domain attribute of the local clock. diff --git a/SOURCES/linuxptp-deftxtout.patch b/SOURCES/linuxptp-deftxtout.patch new file mode 100644 index 0000000..f47e24e --- /dev/null +++ b/SOURCES/linuxptp-deftxtout.patch @@ -0,0 +1,82 @@ +commit 1a2dfe9b00b79a59acf905476bbc33c74d5770a3 +Author: Jacob Keller +Date: Thu Jul 8 12:59:30 2021 -0700 + + Increase the default tx_timestamp_timeout to 10 + + The tx_timestamp_timeout configuration defines the number of + milliseconds to wait for a Tx timestamp from the kernel stack. This + delay is necessary as Tx timestamps are captured after a packet is sent + and reported back via the socket error queue. + + The current default is to poll for up to 1 millisecond. In practice, it + turns out that this is not always enough time for hardware and software + to capture the timestamp and report it back. Some hardware designs + require reading timestamps over registers or other slow mechanisms. + + This extra delay results in the timestamp not being sent back to + userspace within the default 1 millisecond polling time. If that occurs + the following can be seen from ptp4l: + + ptp4l[4756.840]: timed out while polling for tx timestamp + ptp4l[4756.840]: increasing tx_timestamp_timeout may correct this issue, + but it is likely caused by a driver bug + ptp4l[4756.840]: port 1 (p2p1): send sync failed + ptp4l[4756.840]: port 1 (p2p1): MASTER to FAULTY on FAULT_DETECTED + (FT_UNSPECIFIED) + + This can confuse users because it implies this is a bug, when the + correct solution in many cases is to just increase the timeout to + a slightly higher value. + + Since we know this is a problem for many drivers and hardware designs, + lets increase the default timeout. + + Note that a longer timeout should not affect setups which return the + timestamp quickly. On modern kernels, the poll() call will return once + the timestamp is reported back to the socket error queue. (On old + kernels around the 3.x era the poll will sleep for the full duration + before reporting the timestamp, but this is now quite an old kernel + release). + + Signed-off-by: Jacob Keller + +diff --git a/config.c b/config.c +index 760b395..03d981e 100644 +--- a/config.c ++++ b/config.c +@@ -324,7 +324,7 @@ struct config_item config_tab[] = { + GLOB_ITEM_INT("ts2phc.pulsewidth", 500000000, 1000000, 999000000), + PORT_ITEM_ENU("tsproc_mode", TSPROC_FILTER, tsproc_enu), + GLOB_ITEM_INT("twoStepFlag", 1, 0, 1), +- GLOB_ITEM_INT("tx_timestamp_timeout", 1, 1, INT_MAX), ++ GLOB_ITEM_INT("tx_timestamp_timeout", 10, 1, INT_MAX), + PORT_ITEM_INT("udp_ttl", 1, 1, 255), + PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F), + GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"), +diff --git a/configs/default.cfg b/configs/default.cfg +index 64ef3bd..d615610 100644 +--- a/configs/default.cfg ++++ b/configs/default.cfg +@@ -51,7 +51,7 @@ hybrid_e2e 0 + inhibit_multicast_service 0 + net_sync_monitor 0 + tc_spanning_tree 0 +-tx_timestamp_timeout 1 ++tx_timestamp_timeout 10 + unicast_listen 0 + unicast_master_table 0 + unicast_req_duration 3600 +diff --git a/ptp4l.8 b/ptp4l.8 +index fe9e150..7ca3474 100644 +--- a/ptp4l.8 ++++ b/ptp4l.8 +@@ -496,7 +496,7 @@ switches all implement this option together with the BMCA. + .B tx_timestamp_timeout + The number of milliseconds to poll waiting for the tx time stamp from the kernel + when a message has recently been sent. +-The default is 1. ++The default is 10. + .TP + .B check_fup_sync + Because of packet reordering that can occur in the network, in the diff --git a/SOURCES/linuxptp-fclose.patch b/SOURCES/linuxptp-fclose.patch new file mode 100644 index 0000000..bde2872 --- /dev/null +++ b/SOURCES/linuxptp-fclose.patch @@ -0,0 +1,22 @@ +commit e8a82d1b5be2d5bf9450a9acfe44e957b4867870 +Author: Miroslav Lichvar +Date: Tue Jul 20 11:41:35 2021 +0200 + + lstab: Close file after reading. + + The lstab_read() function opens a file, but doesn't close it after use. + + Signed-off-by: Miroslav Lichvar + +diff --git a/lstab.c b/lstab.c +index e6e7ad2..0d6a427 100644 +--- a/lstab.c ++++ b/lstab.c +@@ -144,6 +144,7 @@ static int lstab_read(struct lstab *lstab, const char *name) + index++; + } + } ++ fclose(fp); + if (!lstab->expiration_utc) { + fprintf(stderr, "missing expiration date in '%s'\n", name); + return -1; diff --git a/SOURCES/linuxptp-logmsgs.patch b/SOURCES/linuxptp-logmsgs.patch new file mode 100644 index 0000000..c2a138f --- /dev/null +++ b/SOURCES/linuxptp-logmsgs.patch @@ -0,0 +1,96 @@ +commit 3399fa15ae28610c1b288b573c4233a42c48f762 +Author: Amar Subramanyam via Linuxptp-devel +Date: Wed May 26 12:24:06 2021 +0300 + + Log optimization for ptp4l in jbod and client only mode (clientOnly=1 and boundary_clock_jbod=1) + + The LISTENING port prints continuously + "selected best master clock 000000.0000.000003 + updating UTC offset to 37" + + We limited the log such that now it prints only when there is a + change in the best-master clock. + + Signed-off-by: Amar Subramanyam + Signed-off-by: Karthikkumar Valoor + Signed-off-by: Ramana Reddy + +diff --git a/clock.c b/clock.c +index e545a9b..d428ae2 100644 +--- a/clock.c ++++ b/clock.c +@@ -705,7 +705,8 @@ static void clock_update_slave(struct clock *c) + if (c->tds.currentUtcOffset < c->utc_offset) { + pr_warning("running in a temporal vortex"); + } +- if ((c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE) || ++ if (((c->tds.flags & UTC_OFF_VALID && c->tds.flags & TIME_TRACEABLE) && ++ (c->tds.currentUtcOffset != c->utc_offset)) || + (c->tds.currentUtcOffset > c->utc_offset)) { + pr_info("updating UTC offset to %d", c->tds.currentUtcOffset); + c->utc_offset = c->tds.currentUtcOffset; +@@ -1939,14 +1940,6 @@ static void handle_state_decision_event(struct clock *c) + best_id = c->dds.clockIdentity; + } + +- if (cid_eq(&best_id, &c->dds.clockIdentity)) { +- pr_notice("selected local clock %s as best master", +- cid2str(&best_id)); +- } else { +- pr_notice("selected best master clock %s", +- cid2str(&best_id)); +- } +- + if (!cid_eq(&best_id, &c->best_id)) { + clock_freq_est_reset(c); + tsproc_reset(c->tsproc, 1); +@@ -1957,6 +1950,13 @@ static void handle_state_decision_event(struct clock *c) + c->master_local_rr = 1.0; + c->nrr = 1.0; + fresh_best = 1; ++ if (cid_eq(&best_id, &c->dds.clockIdentity)) { ++ pr_notice("selected local clock %s as best master", ++ cid2str(&best_id)); ++ } else { ++ pr_notice("selected best master clock %s", ++ cid2str(&best_id)); ++ } + } + + c->best = best; + +commit 766baf345cd4fb025d186f9c9bea5276aba398bc +Author: Amar Subramanyam via Linuxptp-devel +Date: Wed May 26 12:24:07 2021 +0300 + + Log optimization for ptp4l in jbod and client only mode (clientOnly=1 and boundary_clock_jbod=1) + + The port other than SLAVE (LISTENING port) prints an error + "port 1: master state recommended in slave only mode + ptp4l[1205469.356]: port 1: defaultDS.priority1 probably misconfigured" + for every ANNOUNCE RECEIPT Timeout. + + This log is printed when the event EV_RS_MASTER is thrown + in clientOnly mode. But single port clientOnly mode will never + hit this event instead EV_RS_GRAND_MASTER will be hit. + EV_RS_MASTER is thrown when clientOnly=1 and boundary_clock_jbod=1 + which results in continuous printing. So EV_RS_MASTER check when + clientOnly=1 to print this error can be avoided. + + Signed-off-by: Amar Subramanyam + Signed-off-by: Karthikkumar Valoor + Signed-off-by: Ramana Reddy + +diff --git a/port.c b/port.c +index 250d46d..b5b775f 100644 +--- a/port.c ++++ b/port.c +@@ -2536,7 +2536,7 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff) + static void bc_dispatch(struct port *p, enum fsm_event event, int mdiff) + { + if (clock_slave_only(p->clock)) { +- if (event == EV_RS_MASTER || event == EV_RS_GRAND_MASTER) { ++ if (event == EV_RS_GRAND_MASTER) { + port_slave_priority_warning(p); + } + } diff --git a/SOURCES/linuxptp-manfix.patch b/SOURCES/linuxptp-manfix.patch new file mode 100644 index 0000000..05edfc9 --- /dev/null +++ b/SOURCES/linuxptp-manfix.patch @@ -0,0 +1,28 @@ +commit 0b80e32829ca7430be851fc64c4812896ad97c88 +Author: Miroslav Lichvar +Date: Mon Jul 19 17:09:01 2021 +0200 + + Fix quoting in ptp4l man page. + + In the groff syntax lines starting with a dot or quote are requests. A + line in the servo_offset_threshold description starts with a quote, + which breaks the output. Move a word to the beginning of the line to fix + it. + + Signed-off-by: Miroslav Lichvar + +diff --git a/ptp4l.8 b/ptp4l.8 +index 7ca3474..a0779ef 100644 +--- a/ptp4l.8 ++++ b/ptp4l.8 +@@ -788,8 +788,8 @@ The default value is 10. + .TP + .B servo_offset_threshold + The offset threshold used in order to transition from the SERVO_LOCKED +-to the SERVO_LOCKED_STABLE state. The transition occurs once the last +-'servo_num_offset_values' offsets are all below the threshold value. ++to the SERVO_LOCKED_STABLE state. The transition occurs once the ++last 'servo_num_offset_values' offsets are all below the threshold value. + The default value of offset_threshold is 0 (disabled). + .TP + .B slave_event_monitor diff --git a/SOURCES/linuxptp-packalign.patch b/SOURCES/linuxptp-packalign.patch new file mode 100644 index 0000000..c5ed8a6 --- /dev/null +++ b/SOURCES/linuxptp-packalign.patch @@ -0,0 +1,100 @@ +commit 25dcf01e340d85bcdbe7b3c24eac7fe1ce7ea0c2 +Author: Miroslav Lichvar +Date: Wed Mar 10 17:05:55 2021 +0100 + + Avoid unaligned pointers to packed members. + + This fixes "taking address of packed member ... may result in an + unaligned pointer value [-Waddress-of-packed-member]" warnings from gcc. + + Signed-off-by: Miroslav Lichvar + +diff --git a/clock.c b/clock.c +index 7005636..f88df58 100644 +--- a/clock.c ++++ b/clock.c +@@ -350,6 +350,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p, + struct time_status_np *tsn; + struct tlv_extra *extra; + struct PTPText *text; ++ uint16_t duration; + int datalen = 0; + + extra = tlv_extra_alloc(); +@@ -452,7 +453,8 @@ static int clock_management_fill_response(struct clock *c, struct port *p, + break; + } + sen = (struct subscribe_events_np *)tlv->data; +- clock_get_subscription(c, req, sen->bitmask, &sen->duration); ++ clock_get_subscription(c, req, sen->bitmask, &duration); ++ memcpy(&sen->duration, &duration, sizeof(sen->duration)); + datalen = sizeof(*sen); + break; + case TLV_SYNCHRONIZATION_UNCERTAIN_NP: +diff --git a/msg.c b/msg.c +index c4516ad..dcb397c 100644 +--- a/msg.c ++++ b/msg.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -36,8 +37,8 @@ int assume_two_step = 0; + + struct message_storage { + unsigned char reserved[MSG_HEADROOM]; +- struct ptp_message msg; +-} PACKED; ++ struct ptp_message msg __attribute__((aligned (8))); ++}; + + static TAILQ_HEAD(msg_pool, ptp_message) msg_pool = TAILQ_HEAD_INITIALIZER(msg_pool); + +diff --git a/tlv.c b/tlv.c +index 879bb7e..98ef6e1 100644 +--- a/tlv.c ++++ b/tlv.c +@@ -67,7 +67,7 @@ static void timestamp_net2host(struct Timestamp *t) + NTOHL(t->nanoseconds); + } + +-static uint16_t flip16(uint16_t *p) ++static uint16_t flip16(void *p) + { + uint16_t v; + memcpy(&v, p, sizeof(v)); +@@ -76,7 +76,7 @@ static uint16_t flip16(uint16_t *p) + return v; + } + +-static int64_t host2net64_unaligned(int64_t *p) ++static int64_t host2net64_unaligned(void *p) + { + int64_t v; + memcpy(&v, p, sizeof(v)); +@@ -85,7 +85,7 @@ static int64_t host2net64_unaligned(int64_t *p) + return v; + } + +-static int64_t net2host64_unaligned(int64_t *p) ++static int64_t net2host64_unaligned(void *p) + { + int64_t v; + memcpy(&v, p, sizeof(v)); +diff --git a/util.h b/util.h +index 41e33d4..739c8fd 100644 +--- a/util.h ++++ b/util.h +@@ -57,7 +57,7 @@ const char *ts_str(enum timestamp_type ts); + */ + int addreq(enum transport_type type, struct address *a, struct address *b); + +-static inline uint16_t align16(uint16_t *p) ++static inline uint16_t align16(void *p) + { + uint16_t v; + memcpy(&v, p, sizeof(v)); diff --git a/SOURCES/linuxptp-ucastrate.patch b/SOURCES/linuxptp-ucastrate.patch new file mode 100644 index 0000000..77fad5c --- /dev/null +++ b/SOURCES/linuxptp-ucastrate.patch @@ -0,0 +1,45 @@ +commit a36602f1e65cd6bace6ed9405b0ce359de4a27d1 +Author: Miroslav Lichvar +Date: Thu Jan 3 15:23:54 2019 +0100 + + unicast: limit message rate and grant duration + + Deny service requests with logInterMessagePeriod smaller than -7 (128 + packets per second) or larger than 16. This limits the network and CPU + consumption per address and prevents undefined shifts in the calculation + of the interval. + + Also, limit the maximum grant duration to one hour. + + Signed-off-by: Miroslav Lichvar + +diff --git a/unicast_service.c b/unicast_service.c +index 9c9b95b..c6c17c6 100644 +--- a/unicast_service.c ++++ b/unicast_service.c +@@ -31,6 +31,9 @@ + #include "unicast_service.h" + #include "util.h" + ++#define MIN_LOG_INTER_MESSAGE_PERIOD -7 ++#define MAX_LOG_INTER_MESSAGE_PERIOD 16 ++#define MAX_DURATION 3600 + #define QUEUE_LEN 16 + + struct unicast_client_address { +@@ -289,6 +292,15 @@ int unicast_service_add(struct port *p, struct ptp_message *m, + return SERVICE_DENIED; + } + ++ if (req->logInterMessagePeriod < MIN_LOG_INTER_MESSAGE_PERIOD || ++ req->logInterMessagePeriod > MAX_LOG_INTER_MESSAGE_PERIOD) { ++ return SERVICE_DENIED; ++ } ++ ++ if (req->durationField > MAX_DURATION) { ++ req->durationField = MAX_DURATION; ++ } ++ + LIST_FOREACH(itmp, &p->unicast_service->intervals, list) { + /* + * Remember the interval of interest. diff --git a/SOURCES/linuxptp-udsro.patch b/SOURCES/linuxptp-udsro.patch new file mode 100644 index 0000000..7030553 --- /dev/null +++ b/SOURCES/linuxptp-udsro.patch @@ -0,0 +1,614 @@ +Patches backported from the upstream repository. + +commit acc045034dd0db9dd4c4aca4b26528f8fed2ae78 +Author: Miroslav Lichvar +Date: Thu Feb 11 16:47:08 2021 +0100 + + port: Ignore non-management messages on UDS port. + + Drop non-management messages on the UDS port early in the processing to + prevent them from changing the port or clock state. + + Signed-off-by: Miroslav Lichvar + +diff --git a/port.c b/port.c +index fa49663..3fd06b1 100644 +--- a/port.c ++++ b/port.c +@@ -56,6 +56,7 @@ enum syfu_event { + }; + + static int port_is_ieee8021as(struct port *p); ++static int port_is_uds(struct port *p); + static void port_nrate_initialize(struct port *p); + + static int announce_compare(struct ptp_message *m1, struct ptp_message *m2) +@@ -691,6 +692,9 @@ static int port_ignore(struct port *p, struct ptp_message *m) + { + struct ClockIdentity c1, c2; + ++ if (port_is_uds(p) && msg_type(m) != MANAGEMENT) { ++ return 1; ++ } + if (incapable_ignore(p, m)) { + return 1; + } +@@ -771,6 +775,11 @@ static int port_is_ieee8021as(struct port *p) + return p->follow_up_info ? 1 : 0; + } + ++static int port_is_uds(struct port *p) ++{ ++ return transport_type(p->trp) == TRANS_UDS; ++} ++ + static void port_management_send_error(struct port *p, struct port *ingress, + struct ptp_message *msg, int error_id) + { + +commit 72ec806fa62a87cb7e5444e27fa6bdcbfe4e27ca +Author: Miroslav Lichvar +Date: Thu Feb 11 16:47:09 2021 +0100 + + clock: Don't allow COMMAND action on non-UDS port. + + No COMMAND actions are currently supported, but check the port early in + clock_manage() before reaching port_manage(). + + Signed-off-by: Miroslav Lichvar + +diff --git a/clock.c b/clock.c +index a66d189..a6947bc 100644 +--- a/clock.c ++++ b/clock.c +@@ -1423,6 +1423,11 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + return changed; + break; + case COMMAND: ++ if (p != c->uds_port) { ++ /* Sorry, only allowed on the UDS port. */ ++ clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); ++ return changed; ++ } + break; + default: + return changed; + +commit 2b45d80eadcb81c8bdf45baf98dabeebd912b1b0 +Author: Miroslav Lichvar +Date: Thu Feb 11 16:47:10 2021 +0100 + + clock: Rename UDS variables to read-write. + + In preparation for a new read-only UDS port, rename variables of the + current UDS port to make it clear it is read-write, as opposed to + read-only. + + Signed-off-by: Miroslav Lichvar + +diff --git a/clock.c b/clock.c +index a6947bc..d013b19 100644 +--- a/clock.c ++++ b/clock.c +@@ -95,7 +95,7 @@ struct clock { + struct foreign_clock *best; + struct ClockIdentity best_id; + LIST_HEAD(ports_head, port) ports; +- struct port *uds_port; ++ struct port *uds_rw_port; + struct pollfd *pollfd; + int pollfd_valid; + int nports; /* does not include the UDS port */ +@@ -129,7 +129,7 @@ struct clock { + struct clock_stats stats; + int stats_interval; + struct clockcheck *sanity_check; +- struct interface *udsif; ++ struct interface *uds_rw_if; + LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers; + struct monitor *slave_event_monitor; + }; +@@ -245,7 +245,7 @@ void clock_send_notification(struct clock *c, struct ptp_message *msg, + { + unsigned int event_pos = event / 8; + uint8_t mask = 1 << (event % 8); +- struct port *uds = c->uds_port; ++ struct port *uds = c->uds_rw_port; + struct clock_subscriber *s; + + LIST_FOREACH(s, &c->subscribers, list) { +@@ -267,13 +267,13 @@ void clock_destroy(struct clock *c) + { + struct port *p, *tmp; + +- interface_destroy(c->udsif); ++ interface_destroy(c->uds_rw_if); + clock_flush_subscriptions(c); + LIST_FOREACH_SAFE(p, &c->ports, list, tmp) { + clock_remove_port(c, p); + } + monitor_destroy(c->slave_event_monitor); +- port_close(c->uds_port); ++ port_close(c->uds_rw_port); + free(c->pollfd); + if (c->clkid != CLOCK_REALTIME) { + phc_close(c->clkid); +@@ -442,7 +442,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p, + datalen = sizeof(*gsn); + break; + case TLV_SUBSCRIBE_EVENTS_NP: +- if (p != c->uds_port) { ++ if (p != c->uds_rw_port) { + /* Only the UDS port allowed. */ + break; + } +@@ -784,7 +784,7 @@ static int forwarding(struct clock *c, struct port *p) + default: + break; + } +- if (p == c->uds_port && ps != PS_FAULTY) { ++ if (p == c->uds_rw_port && ps != PS_FAULTY) { + return 1; + } + return 0; +@@ -1044,20 +1044,20 @@ struct clock *clock_create(enum clock_type type, struct config *config, + + /* Configure the UDS. */ + uds_ifname = config_get_string(config, NULL, "uds_address"); +- c->udsif = interface_create(uds_ifname); +- if (config_set_section_int(config, interface_name(c->udsif), ++ c->uds_rw_if = interface_create(uds_ifname); ++ if (config_set_section_int(config, interface_name(c->uds_rw_if), + "announceReceiptTimeout", 0)) { + return NULL; + } +- if (config_set_section_int(config, interface_name(c->udsif), ++ if (config_set_section_int(config, interface_name(c->uds_rw_if), + "delay_mechanism", DM_AUTO)) { + return NULL; + } +- if (config_set_section_int(config, interface_name(c->udsif), ++ if (config_set_section_int(config, interface_name(c->uds_rw_if), + "network_transport", TRANS_UDS)) { + return NULL; + } +- if (config_set_section_int(config, interface_name(c->udsif), ++ if (config_set_section_int(config, interface_name(c->uds_rw_if), + "delay_filter_length", 1)) { + return NULL; + } +@@ -1180,14 +1180,15 @@ struct clock *clock_create(enum clock_type type, struct config *config, + } + + /* Create the UDS interface. */ +- c->uds_port = port_open(phc_device, phc_index, timestamping, 0, c->udsif, c); +- if (!c->uds_port) { ++ c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0, ++ c->uds_rw_if, c); ++ if (!c->uds_rw_port) { + pr_err("failed to open the UDS port"); + return NULL; + } + clock_fda_changed(c); + +- c->slave_event_monitor = monitor_create(config, c->uds_port); ++ c->slave_event_monitor = monitor_create(config, c->uds_rw_port); + if (!c->slave_event_monitor) { + pr_err("failed to create slave event monitor"); + return NULL; +@@ -1206,7 +1207,7 @@ struct clock *clock_create(enum clock_type type, struct config *config, + LIST_FOREACH(p, &c->ports, list) { + port_dispatch(p, EV_INITIALIZE, 0); + } +- port_dispatch(c->uds_port, EV_INITIALIZE, 0); ++ port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0); + + return c; + } +@@ -1314,7 +1315,7 @@ static void clock_check_pollfd(struct clock *c) + clock_fill_pollfd(dest, p); + dest += N_CLOCK_PFD; + } +- clock_fill_pollfd(dest, c->uds_port); ++ clock_fill_pollfd(dest, c->uds_rw_port); + c->pollfd_valid = 1; + } + +@@ -1331,7 +1332,7 @@ static int clock_do_forward_mgmt(struct clock *c, + return 0; + + /* Don't forward any requests to the UDS port. */ +- if (out == c->uds_port) { ++ if (out == c->uds_rw_port) { + switch (management_action(msg)) { + case GET: + case SET: +@@ -1362,7 +1363,7 @@ static void clock_forward_mgmt_msg(struct clock *c, struct port *p, struct ptp_m + pr_err("port %d: management forward failed", + port_number(piter)); + } +- if (clock_do_forward_mgmt(c, p, c->uds_port, msg, &msg_ready)) ++ if (clock_do_forward_mgmt(c, p, c->uds_rw_port, msg, &msg_ready)) + pr_err("uds port: management forward failed"); + if (msg_ready) { + msg_post_recv(msg, pdulen); +@@ -1414,7 +1415,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + clock_management_send_error(p, msg, TLV_WRONG_LENGTH); + return changed; + } +- if (p != c->uds_port) { ++ if (p != c->uds_rw_port) { + /* Sorry, only allowed on the UDS port. */ + clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); + return changed; +@@ -1423,7 +1424,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + return changed; + break; + case COMMAND: +- if (p != c->uds_port) { ++ if (p != c->uds_rw_port) { + /* Sorry, only allowed on the UDS port. */ + clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); + return changed; +@@ -1435,7 +1436,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + + switch (mgt->id) { + case TLV_PORT_PROPERTIES_NP: +- if (p != c->uds_port) { ++ if (p != c->uds_rw_port) { + /* Only the UDS port allowed. */ + clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); + return 0; +@@ -1500,7 +1501,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + + void clock_notify_event(struct clock *c, enum notification event) + { +- struct port *uds = c->uds_port; ++ struct port *uds = c->uds_rw_port; + struct PortIdentity pid = port_identity(uds); + struct ptp_message *msg; + int id; +@@ -1604,7 +1605,7 @@ int clock_poll(struct clock *c) + /* Check the UDS port. */ + for (i = 0; i < N_POLLFD; i++) { + if (cur[i].revents & (POLLIN|POLLPRI)) { +- event = port_event(c->uds_port, i); ++ event = port_event(c->uds_rw_port, i); + if (EV_STATE_DECISION_EVENT == event) { + c->sde = 1; + } + +commit 1f74a16502b55ce8eaed3d7488542e5469ac8263 +Author: Miroslav Lichvar +Date: Thu Feb 11 16:47:11 2021 +0100 + + clock: Add read-only UDS port for monitoring. + + Add a second UDS port to allow untrusted applications to monitor ptp4l. + On this "read-only" UDS port disable non-GET actions and forwarding. + The path can be configured with the uds_ro_address option (default is + /var/run/ptp4lro). + + Forwarding is disabled to limit the access to the local ptp4l instance. + + Subscriptions are not enabled to prevent the applications from making a + large number of subscriptions or interfere with applications that have + access to the read-write UDS port. + + Signed-off-by: Miroslav Lichvar + +diff --git a/clock.c b/clock.c +index d013b19..8592d29 100644 +--- a/clock.c ++++ b/clock.c +@@ -96,9 +96,10 @@ struct clock { + struct ClockIdentity best_id; + LIST_HEAD(ports_head, port) ports; + struct port *uds_rw_port; ++ struct port *uds_ro_port; + struct pollfd *pollfd; + int pollfd_valid; +- int nports; /* does not include the UDS port */ ++ int nports; /* does not include the two UDS ports */ + int last_port_number; + int sde; + int free_running; +@@ -130,6 +131,7 @@ struct clock { + int stats_interval; + struct clockcheck *sanity_check; + struct interface *uds_rw_if; ++ struct interface *uds_ro_if; + LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers; + struct monitor *slave_event_monitor; + }; +@@ -268,12 +270,14 @@ void clock_destroy(struct clock *c) + struct port *p, *tmp; + + interface_destroy(c->uds_rw_if); ++ interface_destroy(c->uds_ro_if); + clock_flush_subscriptions(c); + LIST_FOREACH_SAFE(p, &c->ports, list, tmp) { + clock_remove_port(c, p); + } + monitor_destroy(c->slave_event_monitor); + port_close(c->uds_rw_port); ++ port_close(c->uds_ro_port); + free(c->pollfd); + if (c->clkid != CLOCK_REALTIME) { + phc_close(c->clkid); +@@ -443,7 +447,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p, + break; + case TLV_SUBSCRIBE_EVENTS_NP: + if (p != c->uds_rw_port) { +- /* Only the UDS port allowed. */ ++ /* Only the UDS-RW port allowed. */ + break; + } + sen = (struct subscribe_events_np *)tlv->data; +@@ -774,6 +778,10 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress) + static int forwarding(struct clock *c, struct port *p) + { + enum port_state ps = port_state(p); ++ ++ if (p == c->uds_ro_port) ++ return 0; ++ + switch (ps) { + case PS_MASTER: + case PS_GRAND_MASTER: +@@ -818,7 +826,7 @@ static int clock_add_port(struct clock *c, const char *phc_device, + { + struct port *p, *piter, *lastp = NULL; + +- if (clock_resize_pollfd(c, c->nports + 1)) { ++ if (clock_resize_pollfd(c, c->nports + 2)) { + return -1; + } + p = port_open(phc_device, phc_index, timestamping, +@@ -1043,6 +1051,7 @@ struct clock *clock_create(enum clock_type type, struct config *config, + } + + /* Configure the UDS. */ ++ + uds_ifname = config_get_string(config, NULL, "uds_address"); + c->uds_rw_if = interface_create(uds_ifname); + if (config_set_section_int(config, interface_name(c->uds_rw_if), +@@ -1062,6 +1071,25 @@ struct clock *clock_create(enum clock_type type, struct config *config, + return NULL; + } + ++ uds_ifname = config_get_string(config, NULL, "uds_ro_address"); ++ c->uds_ro_if = interface_create(uds_ifname); ++ if (config_set_section_int(config, interface_name(c->uds_ro_if), ++ "announceReceiptTimeout", 0)) { ++ return NULL; ++ } ++ if (config_set_section_int(config, interface_name(c->uds_ro_if), ++ "delay_mechanism", DM_AUTO)) { ++ return NULL; ++ } ++ if (config_set_section_int(config, interface_name(c->uds_ro_if), ++ "network_transport", TRANS_UDS)) { ++ return NULL; ++ } ++ if (config_set_section_int(config, interface_name(c->uds_ro_if), ++ "delay_filter_length", 1)) { ++ return NULL; ++ } ++ + c->config = config; + c->free_running = config_get_int(config, NULL, "free_running"); + c->freq_est_interval = config_get_int(config, NULL, "freq_est_interval"); +@@ -1179,11 +1207,18 @@ struct clock *clock_create(enum clock_type type, struct config *config, + return NULL; + } + +- /* Create the UDS interface. */ ++ /* Create the UDS interfaces. */ ++ + c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0, + c->uds_rw_if, c); + if (!c->uds_rw_port) { +- pr_err("failed to open the UDS port"); ++ pr_err("failed to open the UDS-RW port"); ++ return NULL; ++ } ++ c->uds_ro_port = port_open(phc_device, phc_index, timestamping, 0, ++ c->uds_ro_if, c); ++ if (!c->uds_ro_port) { ++ pr_err("failed to open the UDS-RO port"); + return NULL; + } + clock_fda_changed(c); +@@ -1208,6 +1243,7 @@ struct clock *clock_create(enum clock_type type, struct config *config, + port_dispatch(p, EV_INITIALIZE, 0); + } + port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0); ++ port_dispatch(c->uds_ro_port, EV_INITIALIZE, 0); + + return c; + } +@@ -1278,9 +1314,9 @@ static int clock_resize_pollfd(struct clock *c, int new_nports) + { + struct pollfd *new_pollfd; + +- /* Need to allocate one whole extra block of fds for UDS. */ ++ /* Need to allocate two whole extra blocks of fds for UDS ports. */ + new_pollfd = realloc(c->pollfd, +- (new_nports + 1) * N_CLOCK_PFD * ++ (new_nports + 2) * N_CLOCK_PFD * + sizeof(struct pollfd)); + if (!new_pollfd) { + return -1; +@@ -1316,6 +1352,8 @@ static void clock_check_pollfd(struct clock *c) + dest += N_CLOCK_PFD; + } + clock_fill_pollfd(dest, c->uds_rw_port); ++ dest += N_CLOCK_PFD; ++ clock_fill_pollfd(dest, c->uds_ro_port); + c->pollfd_valid = 1; + } + +@@ -1331,7 +1369,8 @@ static int clock_do_forward_mgmt(struct clock *c, + if (in == out || !forwarding(c, out)) + return 0; + +- /* Don't forward any requests to the UDS port. */ ++ /* Don't forward any requests to the UDS-RW port ++ (the UDS-RO port doesn't allow any forwarding). */ + if (out == c->uds_rw_port) { + switch (management_action(msg)) { + case GET: +@@ -1416,7 +1455,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + return changed; + } + if (p != c->uds_rw_port) { +- /* Sorry, only allowed on the UDS port. */ ++ /* Sorry, only allowed on the UDS-RW port. */ + clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); + return changed; + } +@@ -1425,7 +1464,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + break; + case COMMAND: + if (p != c->uds_rw_port) { +- /* Sorry, only allowed on the UDS port. */ ++ /* Sorry, only allowed on the UDS-RW port. */ + clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); + return changed; + } +@@ -1437,7 +1476,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) + switch (mgt->id) { + case TLV_PORT_PROPERTIES_NP: + if (p != c->uds_rw_port) { +- /* Only the UDS port allowed. */ ++ /* Only the UDS-RW port allowed. */ + clock_management_send_error(p, msg, TLV_NOT_SUPPORTED); + return 0; + } +@@ -1548,7 +1587,7 @@ int clock_poll(struct clock *c) + struct port *p; + + clock_check_pollfd(c); +- cnt = poll(c->pollfd, (c->nports + 1) * N_CLOCK_PFD, -1); ++ cnt = poll(c->pollfd, (c->nports + 2) * N_CLOCK_PFD, -1); + if (cnt < 0) { + if (EINTR == errno) { + return 0; +@@ -1602,7 +1641,7 @@ int clock_poll(struct clock *c) + cur += N_CLOCK_PFD; + } + +- /* Check the UDS port. */ ++ /* Check the UDS ports. */ + for (i = 0; i < N_POLLFD; i++) { + if (cur[i].revents & (POLLIN|POLLPRI)) { + event = port_event(c->uds_rw_port, i); +@@ -1611,6 +1650,13 @@ int clock_poll(struct clock *c) + } + } + } ++ cur += N_CLOCK_PFD; ++ for (i = 0; i < N_POLLFD; i++) { ++ if (cur[i].revents & (POLLIN|POLLPRI)) { ++ event = port_event(c->uds_ro_port, i); ++ /* sde is not expected on the UDS-RO port */ ++ } ++ } + + if (c->sde) { + handle_state_decision_event(c); +diff --git a/config.c b/config.c +index d237de9..96a5351 100644 +--- a/config.c ++++ b/config.c +@@ -323,6 +323,7 @@ struct config_item config_tab[] = { + PORT_ITEM_INT("udp_ttl", 1, 1, 255), + PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F), + GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"), ++ GLOB_ITEM_STR("uds_ro_address", "/var/run/ptp4lro"), + PORT_ITEM_INT("unicast_listen", 0, 0, 1), + PORT_ITEM_INT("unicast_master_table", 0, 0, INT_MAX), + PORT_ITEM_INT("unicast_req_duration", 3600, 10, INT_MAX), +diff --git a/configs/default.cfg b/configs/default.cfg +index 8c19129..d5bab7d 100644 +--- a/configs/default.cfg ++++ b/configs/default.cfg +@@ -90,6 +90,7 @@ p2p_dst_mac 01:80:C2:00:00:0E + udp_ttl 1 + udp6_scope 0x0E + uds_address /var/run/ptp4l ++uds_ro_address /var/run/ptp4lro + # + # Default interface options + # +diff --git a/ptp4l.8 b/ptp4l.8 +index b179b81..f9bd228 100644 +--- a/ptp4l.8 ++++ b/ptp4l.8 +@@ -615,6 +615,12 @@ is only relevant with IPv6 transport. See RFC 4291. The default is + Specifies the address of the UNIX domain socket for receiving local + management messages. The default is /var/run/ptp4l. + .TP ++.B uds_ro_address ++Specifies the address of the second UNIX domain socket for receiving local ++management messages, which is restricted to GET actions and does not forward ++messages to other ports. Access to this socket can be given to untrusted ++applications for monitoring purposes. The default is /var/run/ptp4lro. ++.TP + .B dscp_event + Defines the Differentiated Services Codepoint (DSCP) to be used for PTP + event messages. Must be a value between 0 and 63. There are several media + +commit d4c5343237588d265c605f3772337bc88cabe787 +Author: Miroslav Lichvar +Date: Thu Feb 11 16:47:12 2021 +0100 + + timemaster: Set uds_ro_address for ptp4l instances. + + This prevents conflicts on the new UDS-RO port. + + Signed-off-by: Miroslav Lichvar + +diff --git a/timemaster.c b/timemaster.c +index 00db59f..02408d6 100644 +--- a/timemaster.c ++++ b/timemaster.c +@@ -712,7 +712,7 @@ static int add_ptp_source(struct ptp_domain *source, + char **ntp_config, struct script *script) + { + struct config_file *config_file; +- char **command, *uds_path, **interfaces, *message_tag; ++ char **command, *uds_path, *uds_path2, **interfaces, *message_tag; + char ts_interface[IF_NAMESIZE]; + int i, j, num_interfaces, *phc, *phcs, hw_ts, sw_ts; + struct sk_ts_info ts_info; +@@ -809,6 +809,8 @@ static int add_ptp_source(struct ptp_domain *source, + + uds_path = string_newf("%s/ptp4l.%d.socket", + config->rundir, *shm_segment); ++ uds_path2 = string_newf("%s/ptp4lro.%d.socket", ++ config->rundir, *shm_segment); + + message_tag = string_newf("[%d", source->domain); + for (j = 0; interfaces[j]; j++) +@@ -832,8 +834,10 @@ static int add_ptp_source(struct ptp_domain *source, + "slaveOnly 1\n" + "domainNumber %d\n" + "uds_address %s\n" ++ "uds_ro_address %s\n" + "message_tag %s\n", +- source->domain, uds_path, message_tag); ++ source->domain, uds_path, uds_path2, ++ message_tag); + + if (phcs[i] >= 0) { + /* HW time stamping */ +@@ -868,6 +872,7 @@ static int add_ptp_source(struct ptp_domain *source, + + free(message_tag); + free(uds_path); ++ free(uds_path2); + free(interfaces); + } + diff --git a/SOURCES/linuxptp-zerolength.patch b/SOURCES/linuxptp-zerolength.patch new file mode 100644 index 0000000..0ab5ed4 --- /dev/null +++ b/SOURCES/linuxptp-zerolength.patch @@ -0,0 +1,37 @@ +commit 9633ab52460f58c92c6daa35e9d24e4ce9c5ab1c +Author: Miroslav Lichvar +Date: Tue Feb 23 11:01:43 2021 +0100 + + sk: Don't return error for zero-length messages. + + The recvmsg() call can return zero for a zero-length UDP message, which + should be handled as a bad message and not a fault of the port. This was + addressed in commit 6b61ba29c78e ("Avoid fault when receiving zero + length packets"), but later regressed in commit a6e0b83bd503 + ("sk: Convey transmit path errors to the caller."). + + Signed-off-by: Miroslav Lichvar + Fixes: a6e0b83bd503 ("sk: Convey transmit path errors to the caller.") + +diff --git a/sk.c b/sk.c +index c9ef4d2..8be0708 100644 +--- a/sk.c ++++ b/sk.c +@@ -391,7 +391,7 @@ int sk_receive(int fd, void *buf, int buflen, + + if (!ts) { + memset(&hwts->ts, 0, sizeof(hwts->ts)); +- return cnt < 1 ? -errno : cnt; ++ return cnt < 0 ? -errno : cnt; + } + + switch (hwts->type) { +@@ -407,7 +407,7 @@ int sk_receive(int fd, void *buf, int buflen, + hwts->ts = timespec_to_tmv(ts[1]); + break; + } +- return cnt < 1 ? -errno : cnt; ++ return cnt < 0 ? -errno : cnt; + } + + int sk_set_priority(int fd, int family, uint8_t dscp) diff --git a/SOURCES/phc2sys.service b/SOURCES/phc2sys.service new file mode 100644 index 0000000..ff2f77e --- /dev/null +++ b/SOURCES/phc2sys.service @@ -0,0 +1,11 @@ +[Unit] +Description=Synchronize system clock or PTP hardware clock (PHC) +After=ntpdate.service ptp4l.service + +[Service] +Type=simple +EnvironmentFile=-/etc/sysconfig/phc2sys +ExecStart=/usr/sbin/phc2sys $OPTIONS + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/ptp4l.conf b/SOURCES/ptp4l.conf new file mode 100644 index 0000000..4b4b1db --- /dev/null +++ b/SOURCES/ptp4l.conf @@ -0,0 +1,14 @@ +# For more information about this file, see the ptp4l(8) man page. +# Examples are available in /usr/share/doc/linuxptp/configs. + +[global] +domainNumber 0 +slaveOnly 1 +time_stamping hardware +tx_timestamp_timeout 1 +logging_level 6 +summary_interval 0 + +[eth0] +network_transport UDPv4 +hybrid_e2e 0 diff --git a/SOURCES/ptp4l.service b/SOURCES/ptp4l.service new file mode 100644 index 0000000..fbb26d1 --- /dev/null +++ b/SOURCES/ptp4l.service @@ -0,0 +1,12 @@ +[Unit] +Description=Precision Time Protocol (PTP) service +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +EnvironmentFile=-/etc/sysconfig/ptp4l +ExecStart=/usr/sbin/ptp4l $OPTIONS + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/timemaster.conf b/SOURCES/timemaster.conf new file mode 100644 index 0000000..1476209 --- /dev/null +++ b/SOURCES/timemaster.conf @@ -0,0 +1,26 @@ +# Configuration file for timemaster + +#[ntp_server ntp-server.local] +#minpoll 4 +#maxpoll 4 + +#[ptp_domain 0] +#interfaces eth0 +#delay 10e-6 + +[timemaster] +ntp_program chronyd + +[chrony.conf] +include /etc/chrony.conf + +[ptp4l.conf] + +[chronyd] +path /usr/sbin/chronyd + +[phc2sys] +path /usr/sbin/phc2sys + +[ptp4l] +path /usr/sbin/ptp4l diff --git a/SOURCES/timemaster.service b/SOURCES/timemaster.service new file mode 100644 index 0000000..a6bda33 --- /dev/null +++ b/SOURCES/timemaster.service @@ -0,0 +1,12 @@ +[Unit] +Description=Synchronize system clock to NTP and PTP time sources +After=chronyd.service ntpd.service ntpdate.service sntp.service network-online.target +Conflicts=chronyd.service ntpd.service phc2sys.service ptp4l.service +Wants=network-online.target + +[Service] +Type=simple +ExecStart=/usr/sbin/timemaster -f /etc/timemaster.conf + +[Install] +WantedBy=multi-user.target diff --git a/SPECS/linuxptp.spec b/SPECS/linuxptp.spec new file mode 100644 index 0000000..b7c700e --- /dev/null +++ b/SPECS/linuxptp.spec @@ -0,0 +1,278 @@ +%global _hardened_build 1 +%global testsuite_ver c66922 +%global clknetsim_ver ce3c4a + +Name: linuxptp +Version: 3.1.1 +Release: 2%{?dist} +Summary: PTP implementation for Linux + +License: GPLv2+ +URL: http://linuxptp.sourceforge.net/ + +Source0: https://downloads.sourceforge.net/%{name}/%{name}-%{version}.tgz +Source1: phc2sys.service +Source2: ptp4l.service +Source3: timemaster.service +Source4: timemaster.conf +Source5: ptp4l.conf +# external test suite +Source10: https://github.com/mlichvar/linuxptp-testsuite/archive/%{testsuite_ver}/linuxptp-testsuite-%{testsuite_ver}.tar.gz +# simulator for test suite +Source11: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz + +# don't repeat some log messages in multi-port configuration +Patch1: linuxptp-logmsgs.patch +# add option to set clockClass threshold +Patch2: linuxptp-classthreshold.patch +# increase default TX timestamp timeout to 10 ms +Patch3: linuxptp-deftxtout.patch +# limit unicast message rate per address and grant duration +Patch4: linuxptp-ucastrate.patch +# add read-only UDS port +Patch5: linuxptp-udsro.patch +# fix quoting in ptp4l man page +Patch7: linuxptp-manfix.patch +# close lstab file after use +Patch8: linuxptp-fclose.patch +# fix handling of zero-length messages +Patch9: linuxptp-zerolength.patch +# avoid unaligned pointers to packed members +Patch10: linuxptp-packalign.patch + +BuildRequires: gcc gcc-c++ make systemd + +%{?systemd_requires} + +%description +This software is an implementation of the Precision Time Protocol (PTP) +according to IEEE standard 1588 for Linux. The dual design goals are to provide +a robust implementation of the standard and to use the most relevant and modern +Application Programming Interfaces (API) offered by the Linux kernel. +Supporting legacy APIs and other platforms is not a goal. + +%prep +%setup -q -a 10 -a 11 -n %{name}-%{!?gitfullver:%{version}}%{?gitfullver} +%patch1 -p1 -b .logmsgs +%patch2 -p1 -b .classthreshold +%patch3 -p1 -b .deftxtout +%patch4 -p1 -b .ucastrate +%patch5 -p1 -b .udsro +%patch7 -p1 -b .manfix +%patch8 -p1 -b .fclose +%patch9 -p1 -b .zerolength +%patch10 -p1 -b .packalign +mv linuxptp-testsuite-%{testsuite_ver}* testsuite +mv clknetsim-%{clknetsim_ver}* testsuite/clknetsim + +%build +%{make_build} \ + EXTRA_CFLAGS="$RPM_OPT_FLAGS" \ + EXTRA_LDFLAGS="$RPM_LD_FLAGS" + +%install +%makeinstall + +mkdir -p $RPM_BUILD_ROOT{%{_sysconfdir}/sysconfig,%{_unitdir},%{_mandir}/man5} +install -m 644 -p %{SOURCE1} %{SOURCE2} %{SOURCE3} $RPM_BUILD_ROOT%{_unitdir} +install -m 644 -p %{SOURCE4} %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir} + +echo 'OPTIONS="-f /etc/ptp4l.conf"' > \ + $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ptp4l +echo 'OPTIONS="-a -r"' > $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/phc2sys + +echo '.so man8/ptp4l.8' > $RPM_BUILD_ROOT%{_mandir}/man5/ptp4l.conf.5 +echo '.so man8/timemaster.8' > $RPM_BUILD_ROOT%{_mandir}/man5/timemaster.conf.5 + +# Remove patch backup files and non-linuxptp configuration +find configs -type f ! -name '*.cfg' -delete + +%check +cd testsuite +# set random seed to get deterministic results +export CLKNETSIM_RANDOM_SEED=26743 +%{make_build} -C clknetsim +PATH=..:$PATH ./run + +%post +%systemd_post phc2sys.service ptp4l.service timemaster.service + +%preun +%systemd_preun phc2sys.service ptp4l.service timemaster.service + +%postun +%systemd_postun_with_restart phc2sys.service ptp4l.service timemaster.service + +%files +%doc COPYING README.org configs +%config(noreplace) %{_sysconfdir}/ptp4l.conf +%config(noreplace) %{_sysconfdir}/sysconfig/phc2sys +%config(noreplace) %{_sysconfdir}/sysconfig/ptp4l +%config(noreplace) %{_sysconfdir}/timemaster.conf +%{_unitdir}/phc2sys.service +%{_unitdir}/ptp4l.service +%{_unitdir}/timemaster.service +%{_sbindir}/hwstamp_ctl +%{_sbindir}/nsm +%{_sbindir}/phc2sys +%{_sbindir}/phc_ctl +%{_sbindir}/pmc +%{_sbindir}/ptp4l +%{_sbindir}/timemaster +%{_sbindir}/ts2phc +%{_mandir}/man5/*.5* +%{_mandir}/man8/*.8* + +%changelog +* Mon Aug 09 2021 Mohan Boddu - 3.1.1-2 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Mon Aug 02 2021 Miroslav Lichvar 3.1.1-1 +- update to 3.1.1 (#1979954 CVE-2021-3570 CVE-2021-3571) +- add read-only UDS port +- add option to set clockClass threshold +- don't repeat some log messages in multi-port configuration +- increase default TX timestamp timeout to 10 ms +- limit unicast message rate per address and grant duration + +* Tue Jun 22 2021 Mohan Boddu - 3.1-5 +- Rebuilt for RHEL 9 BETA for openssl 3.0 + Related: rhbz#1971065 + +* Fri Apr 16 2021 Mohan Boddu - 3.1-4 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Thu Feb 25 2021 Miroslav Lichvar 3.1-3 +- fix handling of zero-length messages +- minimize default configuration +- remove obsolete build requirement + +* Tue Jan 26 2021 Fedora Release Engineering - 3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Sep 29 2020 Miroslav Lichvar 3.1-1 +- update to 3.1 + +* Mon Jul 27 2020 Miroslav Lichvar 3.0-1 +- update to 3.0 + +* Mon Feb 03 2020 Miroslav Lichvar 2.0-7.20191225gite05809 +- update to 20191225gite05809 +- fix testing with new glibc + +* Wed Jan 29 2020 Fedora Release Engineering - 2.0-6.20190912git48e605 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Sep 25 2019 Miroslav Lichvar 2.0-5.20190912git48e605 +- update to 20190912git48e605 + +* Thu Jul 25 2019 Fedora Release Engineering - 2.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 2.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Nov 13 2018 Miroslav Lichvar 2.0-2 +- start ptp4l, timemaster and phc2sys after network-online target +- fix building with new kernel headers + +* Mon Aug 13 2018 Miroslav Lichvar 2.0-1 +- update to 2.0 + +* Thu Aug 09 2018 Miroslav Lichvar 2.0-0.1.20180805gita27407 +- update to 20180805gita27407 + +* Mon Jul 16 2018 Miroslav Lichvar 1.9.2-3 +- add gcc and gcc-c++ to build requirements + +* Fri Jul 13 2018 Fedora Release Engineering - 1.9.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Apr 09 2018 Miroslav Lichvar 1.9.2-1 +- update to 1.9.2 + +* Wed Feb 07 2018 Fedora Release Engineering - 1.8-7.20180101git303b08 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Jan 30 2018 Miroslav Lichvar 1.8-6.20180101git303b08 +- use macro for systemd scriptlet dependencies + +* Thu Jan 11 2018 Miroslav Lichvar 1.8-5.20180101git303b08 +- update to 20180101git303b08 + +* Thu Aug 03 2017 Fedora Release Engineering - 1.8-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 1.8-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Nov 07 2016 Miroslav Lichvar 1.8-1 +- update to 1.8 + +* Fri Jul 22 2016 Miroslav Lichvar 1.7-1 +- update to 1.7 +- add delay option to default timemaster.conf + +* Thu Feb 04 2016 Fedora Release Engineering - 1.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Sep 22 2015 Miroslav Lichvar 1.6-1 +- update to 1.6 +- set random seed in testing to get deterministic results +- remove trailing whitespace in default timemaster.conf + +* Wed Jun 17 2015 Fedora Release Engineering - 1.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon Jan 05 2015 Miroslav Lichvar 1.5-1 +- update to 1.5 + +* Sun Aug 17 2014 Fedora Release Engineering - 1.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 1.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri Feb 21 2014 Miroslav Lichvar 1.4-1 +- update to 1.4 +- replace hardening build flags with _hardened_build +- include test suite + +* Fri Aug 02 2013 Miroslav Lichvar 1.3-1 +- update to 1.3 + +* Tue Jul 30 2013 Miroslav Lichvar 1.2-3.20130730git7789f0 +- update to 20130730git7789f0 + +* Fri Jul 19 2013 Miroslav Lichvar 1.2-2.20130719git46db40 +- update to 20130719git46db40 +- drop old systemd scriptlets +- add man page link for ptp4l.conf + +* Mon Apr 22 2013 Miroslav Lichvar 1.2-1 +- update to 1.2 + +* Mon Feb 18 2013 Miroslav Lichvar 1.1-1 +- update to 1.1 +- log phc2sys output + +* Thu Feb 14 2013 Fedora Release Engineering - 1.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Dec 13 2012 Miroslav Lichvar 1.0-1 +- update to 1.0 + +* Fri Nov 09 2012 Miroslav Lichvar 0-0.3.20121109git4e8107 +- update to 20121109git4e8107 +- install unchanged default.cfg as ptp4l.conf +- drop conflicts from phc2sys service + +* Fri Sep 21 2012 Miroslav Lichvar 0-0.2.20120920git6ce135 +- fix issues found in package review (#859193) + +* Thu Sep 20 2012 Miroslav Lichvar 0-0.1.20120920git6ce135 +- initial release