
Fix clock selection algorithm behavior where a clock source starts to match requirements but is not selected because it has the same ha_priority than active. In a HA configuration with two or more clocks configured with equal ha_priority if no clock source matches the requirements the first one in the configuration file is selected active. This is a standard behavior to always have a clock source, even when they are not synchronized. When one of the clock sources starts to match the requirements it must be selected active, regardless of the priority. But when a second clock source starts to match the requirements and has the same ha_priority as the active, the active remains the clock source. There is no need to switch active when they have equal ha_priority. Test plan: two sources with the same priority PASS: Verify a clock source is selected active when it starts to match the requirements and the current active doesn't match them, even if they have equal ha_priority. PASS: Verify a clock source isn't selected active when it starts to match the requirements and the current active also matches them. Regression: two sources with different priority PASS: Verify a clock source is selected active when it starts to match the requirements and the current active doesn't match them, even if their ha_priority is lower than the actives. PASS: Verify a clock source is selected active when it starts to match the requirements and the current active also matches them but has lower ha_priority configured. PASS: Verify a clock source isn't selected active when it starts to match the requirements and the current active also matches them and has higher ha_priority configured. Story: 2010723 Task: 48699 Change-Id: If80532b7b8febcc164f7c748a8d4122b4f10fd3b Signed-off-by: Andre Mauricio Zelak <andre.zelak@windriver.com>
293 lines
9.6 KiB
Diff
293 lines
9.6 KiB
Diff
From 4af24949b94eda84b4b74d77b9164cf3fe0eccf9 Mon Sep 17 00:00:00 2001
|
|
From: Andre Mauricio Zelak <andre.zelak@windriver.com>
|
|
Date: Mon, 12 Jun 2023 18:18:29 -0300
|
|
Subject: [PATCH 35/50] 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>
|
|
|
|
[commit 6823e077b2466dcc3c7cbce8ab384b0ef9a62811 upstream]
|
|
Signed-off-by: Andre Mauricio Zelak <andre.zelak@windriver.com>
|
|
---
|
|
clock.c | 72 +++++++++++++++++++++++++++++++++++++--------
|
|
config.c | 1 +
|
|
configs/default.cfg | 1 +
|
|
ptp4l.8 | 6 ++++
|
|
4 files changed, 67 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/clock.c b/clock.c
|
|
index d653c33..869e35d 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;
|
|
};
|
|
@@ -266,12 +268,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);
|
|
@@ -441,7 +445,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;
|
|
@@ -772,6 +776,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:
|
|
@@ -816,7 +824,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,
|
|
@@ -1041,6 +1049,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),
|
|
@@ -1060,6 +1069,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");
|
|
@@ -1177,11 +1205,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);
|
|
@@ -1206,6 +1241,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;
|
|
}
|
|
@@ -1276,9 +1312,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;
|
|
@@ -1314,6 +1350,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;
|
|
}
|
|
|
|
@@ -1329,7 +1367,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:
|
|
@@ -1414,7 +1453,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;
|
|
}
|
|
@@ -1423,7 +1462,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;
|
|
}
|
|
@@ -1435,7 +1474,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 fea7f67..d45e948 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
|
|
--
|
|
2.25.1
|
|
|