Miroslav Lichvar e11a36
Patches backported from the upstream repository.
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
commit acc045034dd0db9dd4c4aca4b26528f8fed2ae78
Miroslav Lichvar e11a36
Author: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Date:   Thu Feb 11 16:47:08 2021 +0100
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
    port: Ignore non-management messages on UDS port.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Drop non-management messages on the UDS port early in the processing to
Miroslav Lichvar e11a36
    prevent them from changing the port or clock state.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
diff --git a/port.c b/port.c
Miroslav Lichvar e11a36
index fa49663..3fd06b1 100644
Miroslav Lichvar e11a36
--- a/port.c
Miroslav Lichvar e11a36
+++ b/port.c
Miroslav Lichvar e11a36
@@ -56,6 +56,7 @@ enum syfu_event {
Miroslav Lichvar e11a36
 };
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 static int port_is_ieee8021as(struct port *p);
Miroslav Lichvar e11a36
+static int port_is_uds(struct port *p);
Miroslav Lichvar e11a36
 static void port_nrate_initialize(struct port *p);
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
Miroslav Lichvar e11a36
@@ -691,6 +692,9 @@ static int port_ignore(struct port *p, struct ptp_message *m)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	struct ClockIdentity c1, c2;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
+	if (port_is_uds(p) && msg_type(m) != MANAGEMENT) {
Miroslav Lichvar e11a36
+		return 1;
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
 	if (incapable_ignore(p, m)) {
Miroslav Lichvar e11a36
 		return 1;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
@@ -771,6 +775,11 @@ static int port_is_ieee8021as(struct port *p)
Miroslav Lichvar e11a36
 	return p->follow_up_info ? 1 : 0;
Miroslav Lichvar e11a36
 }
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
+static int port_is_uds(struct port *p)
Miroslav Lichvar e11a36
+{
Miroslav Lichvar e11a36
+	return transport_type(p->trp) == TRANS_UDS;
Miroslav Lichvar e11a36
+}
Miroslav Lichvar e11a36
+
Miroslav Lichvar e11a36
 static void port_management_send_error(struct port *p, struct port *ingress,
Miroslav Lichvar e11a36
 				       struct ptp_message *msg, int error_id)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
commit 72ec806fa62a87cb7e5444e27fa6bdcbfe4e27ca
Miroslav Lichvar e11a36
Author: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Date:   Thu Feb 11 16:47:09 2021 +0100
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
    clock: Don't allow COMMAND action on non-UDS port.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    No COMMAND actions are currently supported, but check the port early in
Miroslav Lichvar e11a36
    clock_manage() before reaching port_manage().
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
diff --git a/clock.c b/clock.c
Miroslav Lichvar e11a36
index a66d189..a6947bc 100644
Miroslav Lichvar e11a36
--- a/clock.c
Miroslav Lichvar e11a36
+++ b/clock.c
Miroslav Lichvar e11a36
@@ -1423,6 +1423,11 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	case COMMAND:
Miroslav Lichvar e11a36
+		if (p != c->uds_port) {
Miroslav Lichvar e11a36
+			/* Sorry, only allowed on the UDS port. */
Miroslav Lichvar e11a36
+			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
+			return changed;
Miroslav Lichvar e11a36
+		}
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	default:
Miroslav Lichvar e11a36
 		return changed;
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
commit 2b45d80eadcb81c8bdf45baf98dabeebd912b1b0
Miroslav Lichvar e11a36
Author: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Date:   Thu Feb 11 16:47:10 2021 +0100
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
    clock: Rename UDS variables to read-write.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    In preparation for a new read-only UDS port, rename variables of the
Miroslav Lichvar e11a36
    current UDS port to make it clear it is read-write, as opposed to
Miroslav Lichvar e11a36
    read-only.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
diff --git a/clock.c b/clock.c
Miroslav Lichvar e11a36
index a6947bc..d013b19 100644
Miroslav Lichvar e11a36
--- a/clock.c
Miroslav Lichvar e11a36
+++ b/clock.c
Miroslav Lichvar e11a36
@@ -95,7 +95,7 @@ struct clock {
Miroslav Lichvar e11a36
 	struct foreign_clock *best;
Miroslav Lichvar e11a36
 	struct ClockIdentity best_id;
Miroslav Lichvar e11a36
 	LIST_HEAD(ports_head, port) ports;
Miroslav Lichvar e11a36
-	struct port *uds_port;
Miroslav Lichvar e11a36
+	struct port *uds_rw_port;
Miroslav Lichvar e11a36
 	struct pollfd *pollfd;
Miroslav Lichvar e11a36
 	int pollfd_valid;
Miroslav Lichvar e11a36
 	int nports; /* does not include the UDS port */
Miroslav Lichvar e11a36
@@ -129,7 +129,7 @@ struct clock {
Miroslav Lichvar e11a36
 	struct clock_stats stats;
Miroslav Lichvar e11a36
 	int stats_interval;
Miroslav Lichvar e11a36
 	struct clockcheck *sanity_check;
Miroslav Lichvar e11a36
-	struct interface *udsif;
Miroslav Lichvar e11a36
+	struct interface *uds_rw_if;
Miroslav Lichvar e11a36
 	LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
Miroslav Lichvar e11a36
 	struct monitor *slave_event_monitor;
Miroslav Lichvar e11a36
 };
Miroslav Lichvar e11a36
@@ -245,7 +245,7 @@ void clock_send_notification(struct clock *c, struct ptp_message *msg,
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	unsigned int event_pos = event / 8;
Miroslav Lichvar e11a36
 	uint8_t mask = 1 << (event % 8);
Miroslav Lichvar e11a36
-	struct port *uds = c->uds_port;
Miroslav Lichvar e11a36
+	struct port *uds = c->uds_rw_port;
Miroslav Lichvar e11a36
 	struct clock_subscriber *s;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	LIST_FOREACH(s, &c->subscribers, list) {
Miroslav Lichvar e11a36
@@ -267,13 +267,13 @@ void clock_destroy(struct clock *c)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	struct port *p, *tmp;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	interface_destroy(c->udsif);
Miroslav Lichvar e11a36
+	interface_destroy(c->uds_rw_if);
Miroslav Lichvar e11a36
 	clock_flush_subscriptions(c);
Miroslav Lichvar e11a36
 	LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
Miroslav Lichvar e11a36
 		clock_remove_port(c, p);
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	monitor_destroy(c->slave_event_monitor);
Miroslav Lichvar e11a36
-	port_close(c->uds_port);
Miroslav Lichvar e11a36
+	port_close(c->uds_rw_port);
Miroslav Lichvar e11a36
 	free(c->pollfd);
Miroslav Lichvar e11a36
 	if (c->clkid != CLOCK_REALTIME) {
Miroslav Lichvar e11a36
 		phc_close(c->clkid);
Miroslav Lichvar e11a36
@@ -442,7 +442,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
Miroslav Lichvar e11a36
 		datalen = sizeof(*gsn);
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	case TLV_SUBSCRIBE_EVENTS_NP:
Miroslav Lichvar e11a36
-		if (p != c->uds_port) {
Miroslav Lichvar e11a36
+		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
 			/* Only the UDS port allowed. */
Miroslav Lichvar e11a36
 			break;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
@@ -784,7 +784,7 @@ static int forwarding(struct clock *c, struct port *p)
Miroslav Lichvar e11a36
 	default:
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
-	if (p == c->uds_port && ps != PS_FAULTY) {
Miroslav Lichvar e11a36
+	if (p == c->uds_rw_port && ps != PS_FAULTY) {
Miroslav Lichvar e11a36
 		return 1;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	return 0;
Miroslav Lichvar e11a36
@@ -1044,20 +1044,20 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	/* Configure the UDS. */
Miroslav Lichvar e11a36
 	uds_ifname = config_get_string(config, NULL, "uds_address");
Miroslav Lichvar e11a36
-	c->udsif = interface_create(uds_ifname);
Miroslav Lichvar e11a36
-	if (config_set_section_int(config, interface_name(c->udsif),
Miroslav Lichvar e11a36
+	c->uds_rw_if = interface_create(uds_ifname);
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_rw_if),
Miroslav Lichvar e11a36
 				   "announceReceiptTimeout", 0)) {
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
-	if (config_set_section_int(config, interface_name(c->udsif),
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_rw_if),
Miroslav Lichvar e11a36
 				    "delay_mechanism", DM_AUTO)) {
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
-	if (config_set_section_int(config, interface_name(c->udsif),
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_rw_if),
Miroslav Lichvar e11a36
 				    "network_transport", TRANS_UDS)) {
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
-	if (config_set_section_int(config, interface_name(c->udsif),
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_rw_if),
Miroslav Lichvar e11a36
 				   "delay_filter_length", 1)) {
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
@@ -1180,14 +1180,15 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	/* Create the UDS interface. */
Miroslav Lichvar e11a36
-	c->uds_port = port_open(phc_device, phc_index, timestamping, 0, c->udsif, c);
Miroslav Lichvar e11a36
-	if (!c->uds_port) {
Miroslav Lichvar e11a36
+	c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
Miroslav Lichvar e11a36
+				   c->uds_rw_if, c);
Miroslav Lichvar e11a36
+	if (!c->uds_rw_port) {
Miroslav Lichvar e11a36
 		pr_err("failed to open the UDS port");
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	clock_fda_changed(c);
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	c->slave_event_monitor = monitor_create(config, c->uds_port);
Miroslav Lichvar e11a36
+	c->slave_event_monitor = monitor_create(config, c->uds_rw_port);
Miroslav Lichvar e11a36
 	if (!c->slave_event_monitor) {
Miroslav Lichvar e11a36
 		pr_err("failed to create slave event monitor");
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
@@ -1206,7 +1207,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 	LIST_FOREACH(p, &c->ports, list) {
Miroslav Lichvar e11a36
 		port_dispatch(p, EV_INITIALIZE, 0);
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
-	port_dispatch(c->uds_port, EV_INITIALIZE, 0);
Miroslav Lichvar e11a36
+	port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	return c;
Miroslav Lichvar e11a36
 }
Miroslav Lichvar e11a36
@@ -1314,7 +1315,7 @@ static void clock_check_pollfd(struct clock *c)
Miroslav Lichvar e11a36
 		clock_fill_pollfd(dest, p);
Miroslav Lichvar e11a36
 		dest += N_CLOCK_PFD;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
-	clock_fill_pollfd(dest, c->uds_port);
Miroslav Lichvar e11a36
+	clock_fill_pollfd(dest, c->uds_rw_port);
Miroslav Lichvar e11a36
 	c->pollfd_valid = 1;
Miroslav Lichvar e11a36
 }
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
@@ -1331,7 +1332,7 @@ static int clock_do_forward_mgmt(struct clock *c,
Miroslav Lichvar e11a36
 		return 0;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	/* Don't forward any requests to the UDS port. */
Miroslav Lichvar e11a36
-	if (out == c->uds_port) {
Miroslav Lichvar e11a36
+	if (out == c->uds_rw_port) {
Miroslav Lichvar e11a36
 		switch (management_action(msg)) {
Miroslav Lichvar e11a36
 		case GET:
Miroslav Lichvar e11a36
 		case SET:
Miroslav Lichvar e11a36
@@ -1362,7 +1363,7 @@ static void clock_forward_mgmt_msg(struct clock *c, struct port *p, struct ptp_m
Miroslav Lichvar e11a36
 				pr_err("port %d: management forward failed",
Miroslav Lichvar e11a36
 				       port_number(piter));
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
-		if (clock_do_forward_mgmt(c, p, c->uds_port, msg, &msg_ready))
Miroslav Lichvar e11a36
+		if (clock_do_forward_mgmt(c, p, c->uds_rw_port, msg, &msg_ready))
Miroslav Lichvar e11a36
 			pr_err("uds port: management forward failed");
Miroslav Lichvar e11a36
 		if (msg_ready) {
Miroslav Lichvar e11a36
 			msg_post_recv(msg, pdulen);
Miroslav Lichvar e11a36
@@ -1414,7 +1415,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_WRONG_LENGTH);
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
-		if (p != c->uds_port) {
Miroslav Lichvar e11a36
+		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
 			/* Sorry, only allowed on the UDS port. */
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
@@ -1423,7 +1424,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	case COMMAND:
Miroslav Lichvar e11a36
-		if (p != c->uds_port) {
Miroslav Lichvar e11a36
+		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
 			/* Sorry, only allowed on the UDS port. */
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
@@ -1435,7 +1436,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	switch (mgt->id) {
Miroslav Lichvar e11a36
 	case TLV_PORT_PROPERTIES_NP:
Miroslav Lichvar e11a36
-		if (p != c->uds_port) {
Miroslav Lichvar e11a36
+		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
 			/* Only the UDS port allowed. */
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
 			return 0;
Miroslav Lichvar e11a36
@@ -1500,7 +1501,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 void clock_notify_event(struct clock *c, enum notification event)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
-	struct port *uds = c->uds_port;
Miroslav Lichvar e11a36
+	struct port *uds = c->uds_rw_port;
Miroslav Lichvar e11a36
 	struct PortIdentity pid = port_identity(uds);
Miroslav Lichvar e11a36
 	struct ptp_message *msg;
Miroslav Lichvar e11a36
 	int id;
Miroslav Lichvar e11a36
@@ -1604,7 +1605,7 @@ int clock_poll(struct clock *c)
Miroslav Lichvar e11a36
 	/* Check the UDS port. */
Miroslav Lichvar e11a36
 	for (i = 0; i < N_POLLFD; i++) {
Miroslav Lichvar e11a36
 		if (cur[i].revents & (POLLIN|POLLPRI)) {
Miroslav Lichvar e11a36
-			event = port_event(c->uds_port, i);
Miroslav Lichvar e11a36
+			event = port_event(c->uds_rw_port, i);
Miroslav Lichvar e11a36
 			if (EV_STATE_DECISION_EVENT == event) {
Miroslav Lichvar e11a36
 				c->sde = 1;
Miroslav Lichvar e11a36
 			}
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
commit 1f74a16502b55ce8eaed3d7488542e5469ac8263
Miroslav Lichvar e11a36
Author: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Date:   Thu Feb 11 16:47:11 2021 +0100
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
    clock: Add read-only UDS port for monitoring.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Add a second UDS port to allow untrusted applications to monitor ptp4l.
Miroslav Lichvar e11a36
    On this "read-only" UDS port disable non-GET actions and forwarding.
Miroslav Lichvar e11a36
    The path can be configured with the uds_ro_address option (default is
Miroslav Lichvar e11a36
    /var/run/ptp4lro).
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Forwarding is disabled to limit the access to the local ptp4l instance.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Subscriptions are not enabled to prevent the applications from making a
Miroslav Lichvar e11a36
    large number of subscriptions or interfere with applications that have
Miroslav Lichvar e11a36
    access to the read-write UDS port.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
diff --git a/clock.c b/clock.c
Miroslav Lichvar e11a36
index d013b19..8592d29 100644
Miroslav Lichvar e11a36
--- a/clock.c
Miroslav Lichvar e11a36
+++ b/clock.c
Miroslav Lichvar e11a36
@@ -96,9 +96,10 @@ struct clock {
Miroslav Lichvar e11a36
 	struct ClockIdentity best_id;
Miroslav Lichvar e11a36
 	LIST_HEAD(ports_head, port) ports;
Miroslav Lichvar e11a36
 	struct port *uds_rw_port;
Miroslav Lichvar e11a36
+	struct port *uds_ro_port;
Miroslav Lichvar e11a36
 	struct pollfd *pollfd;
Miroslav Lichvar e11a36
 	int pollfd_valid;
Miroslav Lichvar e11a36
-	int nports; /* does not include the UDS port */
Miroslav Lichvar e11a36
+	int nports; /* does not include the two UDS ports */
Miroslav Lichvar e11a36
 	int last_port_number;
Miroslav Lichvar e11a36
 	int sde;
Miroslav Lichvar e11a36
 	int free_running;
Miroslav Lichvar e11a36
@@ -130,6 +131,7 @@ struct clock {
Miroslav Lichvar e11a36
 	int stats_interval;
Miroslav Lichvar e11a36
 	struct clockcheck *sanity_check;
Miroslav Lichvar e11a36
 	struct interface *uds_rw_if;
Miroslav Lichvar e11a36
+	struct interface *uds_ro_if;
Miroslav Lichvar e11a36
 	LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
Miroslav Lichvar e11a36
 	struct monitor *slave_event_monitor;
Miroslav Lichvar e11a36
 };
Miroslav Lichvar e11a36
@@ -268,12 +270,14 @@ void clock_destroy(struct clock *c)
Miroslav Lichvar e11a36
 	struct port *p, *tmp;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	interface_destroy(c->uds_rw_if);
Miroslav Lichvar e11a36
+	interface_destroy(c->uds_ro_if);
Miroslav Lichvar e11a36
 	clock_flush_subscriptions(c);
Miroslav Lichvar e11a36
 	LIST_FOREACH_SAFE(p, &c->ports, list, tmp) {
Miroslav Lichvar e11a36
 		clock_remove_port(c, p);
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	monitor_destroy(c->slave_event_monitor);
Miroslav Lichvar e11a36
 	port_close(c->uds_rw_port);
Miroslav Lichvar e11a36
+	port_close(c->uds_ro_port);
Miroslav Lichvar e11a36
 	free(c->pollfd);
Miroslav Lichvar e11a36
 	if (c->clkid != CLOCK_REALTIME) {
Miroslav Lichvar e11a36
 		phc_close(c->clkid);
Miroslav Lichvar e11a36
@@ -443,7 +447,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	case TLV_SUBSCRIBE_EVENTS_NP:
Miroslav Lichvar e11a36
 		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
-			/* Only the UDS port allowed. */
Miroslav Lichvar e11a36
+			/* Only the UDS-RW port allowed. */
Miroslav Lichvar e11a36
 			break;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
 		sen = (struct subscribe_events_np *)tlv->data;
Miroslav Lichvar e11a36
@@ -774,6 +778,10 @@ static int clock_utc_correct(struct clock *c, tmv_t ingress)
Miroslav Lichvar e11a36
 static int forwarding(struct clock *c, struct port *p)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	enum port_state ps = port_state(p);
Miroslav Lichvar e11a36
+
Miroslav Lichvar e11a36
+	if (p == c->uds_ro_port)
Miroslav Lichvar e11a36
+		return 0;
Miroslav Lichvar e11a36
+
Miroslav Lichvar e11a36
 	switch (ps) {
Miroslav Lichvar e11a36
 	case PS_MASTER:
Miroslav Lichvar e11a36
 	case PS_GRAND_MASTER:
Miroslav Lichvar e11a36
@@ -818,7 +826,7 @@ static int clock_add_port(struct clock *c, const char *phc_device,
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	struct port *p, *piter, *lastp = NULL;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	if (clock_resize_pollfd(c, c->nports + 1)) {
Miroslav Lichvar e11a36
+	if (clock_resize_pollfd(c, c->nports + 2)) {
Miroslav Lichvar e11a36
 		return -1;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	p = port_open(phc_device, phc_index, timestamping,
Miroslav Lichvar e11a36
@@ -1043,6 +1051,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	/* Configure the UDS. */
Miroslav Lichvar e11a36
+
Miroslav Lichvar e11a36
 	uds_ifname = config_get_string(config, NULL, "uds_address");
Miroslav Lichvar e11a36
 	c->uds_rw_if = interface_create(uds_ifname);
Miroslav Lichvar e11a36
 	if (config_set_section_int(config, interface_name(c->uds_rw_if),
Miroslav Lichvar e11a36
@@ -1062,6 +1071,25 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
+	uds_ifname = config_get_string(config, NULL, "uds_ro_address");
Miroslav Lichvar e11a36
+	c->uds_ro_if = interface_create(uds_ifname);
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_ro_if),
Miroslav Lichvar e11a36
+				   "announceReceiptTimeout", 0)) {
Miroslav Lichvar e11a36
+		return NULL;
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_ro_if),
Miroslav Lichvar e11a36
+				   "delay_mechanism", DM_AUTO)) {
Miroslav Lichvar e11a36
+		return NULL;
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_ro_if),
Miroslav Lichvar e11a36
+				   "network_transport", TRANS_UDS)) {
Miroslav Lichvar e11a36
+		return NULL;
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
+	if (config_set_section_int(config, interface_name(c->uds_ro_if),
Miroslav Lichvar e11a36
+				   "delay_filter_length", 1)) {
Miroslav Lichvar e11a36
+		return NULL;
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
+
Miroslav Lichvar e11a36
 	c->config = config;
Miroslav Lichvar e11a36
 	c->free_running = config_get_int(config, NULL, "free_running");
Miroslav Lichvar e11a36
 	c->freq_est_interval = config_get_int(config, NULL, "freq_est_interval");
Miroslav Lichvar e11a36
@@ -1179,11 +1207,18 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	/* Create the UDS interface. */
Miroslav Lichvar e11a36
+	/* Create the UDS interfaces. */
Miroslav Lichvar e11a36
+
Miroslav Lichvar e11a36
 	c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
Miroslav Lichvar e11a36
 				   c->uds_rw_if, c);
Miroslav Lichvar e11a36
 	if (!c->uds_rw_port) {
Miroslav Lichvar e11a36
-		pr_err("failed to open the UDS port");
Miroslav Lichvar e11a36
+		pr_err("failed to open the UDS-RW port");
Miroslav Lichvar e11a36
+		return NULL;
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
+	c->uds_ro_port = port_open(phc_device, phc_index, timestamping, 0,
Miroslav Lichvar e11a36
+				   c->uds_ro_if, c);
Miroslav Lichvar e11a36
+	if (!c->uds_ro_port) {
Miroslav Lichvar e11a36
+		pr_err("failed to open the UDS-RO port");
Miroslav Lichvar e11a36
 		return NULL;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	clock_fda_changed(c);
Miroslav Lichvar e11a36
@@ -1208,6 +1243,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar e11a36
 		port_dispatch(p, EV_INITIALIZE, 0);
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
Miroslav Lichvar e11a36
+	port_dispatch(c->uds_ro_port, EV_INITIALIZE, 0);
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	return c;
Miroslav Lichvar e11a36
 }
Miroslav Lichvar e11a36
@@ -1278,9 +1314,9 @@ static int clock_resize_pollfd(struct clock *c, int new_nports)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	struct pollfd *new_pollfd;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	/* Need to allocate one whole extra block of fds for UDS. */
Miroslav Lichvar e11a36
+	/* Need to allocate two whole extra blocks of fds for UDS ports. */
Miroslav Lichvar e11a36
 	new_pollfd = realloc(c->pollfd,
Miroslav Lichvar e11a36
-			     (new_nports + 1) * N_CLOCK_PFD *
Miroslav Lichvar e11a36
+			     (new_nports + 2) * N_CLOCK_PFD *
Miroslav Lichvar e11a36
 			     sizeof(struct pollfd));
Miroslav Lichvar e11a36
 	if (!new_pollfd) {
Miroslav Lichvar e11a36
 		return -1;
Miroslav Lichvar e11a36
@@ -1316,6 +1352,8 @@ static void clock_check_pollfd(struct clock *c)
Miroslav Lichvar e11a36
 		dest += N_CLOCK_PFD;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 	clock_fill_pollfd(dest, c->uds_rw_port);
Miroslav Lichvar e11a36
+	dest += N_CLOCK_PFD;
Miroslav Lichvar e11a36
+	clock_fill_pollfd(dest, c->uds_ro_port);
Miroslav Lichvar e11a36
 	c->pollfd_valid = 1;
Miroslav Lichvar e11a36
 }
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
@@ -1331,7 +1369,8 @@ static int clock_do_forward_mgmt(struct clock *c,
Miroslav Lichvar e11a36
 	if (in == out || !forwarding(c, out))
Miroslav Lichvar e11a36
 		return 0;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	/* Don't forward any requests to the UDS port. */
Miroslav Lichvar e11a36
+	/* Don't forward any requests to the UDS-RW port
Miroslav Lichvar e11a36
+	   (the UDS-RO port doesn't allow any forwarding). */
Miroslav Lichvar e11a36
 	if (out == c->uds_rw_port) {
Miroslav Lichvar e11a36
 		switch (management_action(msg)) {
Miroslav Lichvar e11a36
 		case GET:
Miroslav Lichvar e11a36
@@ -1416,7 +1455,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
 		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
-			/* Sorry, only allowed on the UDS port. */
Miroslav Lichvar e11a36
+			/* Sorry, only allowed on the UDS-RW port. */
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
@@ -1425,7 +1464,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 		break;
Miroslav Lichvar e11a36
 	case COMMAND:
Miroslav Lichvar e11a36
 		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
-			/* Sorry, only allowed on the UDS port. */
Miroslav Lichvar e11a36
+			/* Sorry, only allowed on the UDS-RW port. */
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
 			return changed;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
@@ -1437,7 +1476,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
Miroslav Lichvar e11a36
 	switch (mgt->id) {
Miroslav Lichvar e11a36
 	case TLV_PORT_PROPERTIES_NP:
Miroslav Lichvar e11a36
 		if (p != c->uds_rw_port) {
Miroslav Lichvar e11a36
-			/* Only the UDS port allowed. */
Miroslav Lichvar e11a36
+			/* Only the UDS-RW port allowed. */
Miroslav Lichvar e11a36
 			clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
Miroslav Lichvar e11a36
 			return 0;
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
@@ -1548,7 +1587,7 @@ int clock_poll(struct clock *c)
Miroslav Lichvar e11a36
 	struct port *p;
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	clock_check_pollfd(c);
Miroslav Lichvar e11a36
-	cnt = poll(c->pollfd, (c->nports + 1) * N_CLOCK_PFD, -1);
Miroslav Lichvar e11a36
+	cnt = poll(c->pollfd, (c->nports + 2) * N_CLOCK_PFD, -1);
Miroslav Lichvar e11a36
 	if (cnt < 0) {
Miroslav Lichvar e11a36
 		if (EINTR == errno) {
Miroslav Lichvar e11a36
 			return 0;
Miroslav Lichvar e11a36
@@ -1602,7 +1641,7 @@ int clock_poll(struct clock *c)
Miroslav Lichvar e11a36
 		cur += N_CLOCK_PFD;
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
-	/* Check the UDS port. */
Miroslav Lichvar e11a36
+	/* Check the UDS ports. */
Miroslav Lichvar e11a36
 	for (i = 0; i < N_POLLFD; i++) {
Miroslav Lichvar e11a36
 		if (cur[i].revents & (POLLIN|POLLPRI)) {
Miroslav Lichvar e11a36
 			event = port_event(c->uds_rw_port, i);
Miroslav Lichvar e11a36
@@ -1611,6 +1650,13 @@ int clock_poll(struct clock *c)
Miroslav Lichvar e11a36
 			}
Miroslav Lichvar e11a36
 		}
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36
+	cur += N_CLOCK_PFD;
Miroslav Lichvar e11a36
+	for (i = 0; i < N_POLLFD; i++) {
Miroslav Lichvar e11a36
+		if (cur[i].revents & (POLLIN|POLLPRI)) {
Miroslav Lichvar e11a36
+			event = port_event(c->uds_ro_port, i);
Miroslav Lichvar e11a36
+			/* sde is not expected on the UDS-RO port */
Miroslav Lichvar e11a36
+		}
Miroslav Lichvar e11a36
+	}
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 	if (c->sde) {
Miroslav Lichvar e11a36
 		handle_state_decision_event(c);
Miroslav Lichvar e11a36
diff --git a/config.c b/config.c
Miroslav Lichvar e11a36
index d237de9..96a5351 100644
Miroslav Lichvar e11a36
--- a/config.c
Miroslav Lichvar e11a36
+++ b/config.c
Miroslav Lichvar e11a36
@@ -323,6 +323,7 @@ struct config_item config_tab[] = {
Miroslav Lichvar e11a36
 	PORT_ITEM_INT("udp_ttl", 1, 1, 255),
Miroslav Lichvar e11a36
 	PORT_ITEM_INT("udp6_scope", 0x0E, 0x00, 0x0F),
Miroslav Lichvar e11a36
 	GLOB_ITEM_STR("uds_address", "/var/run/ptp4l"),
Miroslav Lichvar e11a36
+	GLOB_ITEM_STR("uds_ro_address", "/var/run/ptp4lro"),
Miroslav Lichvar e11a36
 	PORT_ITEM_INT("unicast_listen", 0, 0, 1),
Miroslav Lichvar e11a36
 	PORT_ITEM_INT("unicast_master_table", 0, 0, INT_MAX),
Miroslav Lichvar e11a36
 	PORT_ITEM_INT("unicast_req_duration", 3600, 10, INT_MAX),
Miroslav Lichvar e11a36
diff --git a/configs/default.cfg b/configs/default.cfg
Miroslav Lichvar e11a36
index 8c19129..d5bab7d 100644
Miroslav Lichvar e11a36
--- a/configs/default.cfg
Miroslav Lichvar e11a36
+++ b/configs/default.cfg
Miroslav Lichvar e11a36
@@ -90,6 +90,7 @@ p2p_dst_mac		01:80:C2:00:00:0E
Miroslav Lichvar e11a36
 udp_ttl			1
Miroslav Lichvar e11a36
 udp6_scope		0x0E
Miroslav Lichvar e11a36
 uds_address		/var/run/ptp4l
Miroslav Lichvar e11a36
+uds_ro_address		/var/run/ptp4lro
Miroslav Lichvar e11a36
 #
Miroslav Lichvar e11a36
 # Default interface options
Miroslav Lichvar e11a36
 #
Miroslav Lichvar e11a36
diff --git a/ptp4l.8 b/ptp4l.8
Miroslav Lichvar e11a36
index b179b81..f9bd228 100644
Miroslav Lichvar e11a36
--- a/ptp4l.8
Miroslav Lichvar e11a36
+++ b/ptp4l.8
Miroslav Lichvar e11a36
@@ -615,6 +615,12 @@ is only relevant with IPv6 transport.  See RFC 4291.  The default is
Miroslav Lichvar e11a36
 Specifies the address of the UNIX domain socket for receiving local
Miroslav Lichvar e11a36
 management messages. The default is /var/run/ptp4l.
Miroslav Lichvar e11a36
 .TP
Miroslav Lichvar e11a36
+.B uds_ro_address
Miroslav Lichvar e11a36
+Specifies the address of the second UNIX domain socket for receiving local
Miroslav Lichvar e11a36
+management messages, which is restricted to GET actions and does not forward
Miroslav Lichvar e11a36
+messages to other ports. Access to this socket can be given to untrusted
Miroslav Lichvar e11a36
+applications for monitoring purposes. The default is /var/run/ptp4lro.
Miroslav Lichvar e11a36
+.TP
Miroslav Lichvar e11a36
 .B dscp_event
Miroslav Lichvar e11a36
 Defines the Differentiated Services Codepoint (DSCP) to be used for PTP
Miroslav Lichvar e11a36
 event messages. Must be a value between 0 and 63. There are several media
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
commit d4c5343237588d265c605f3772337bc88cabe787
Miroslav Lichvar e11a36
Author: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Date:   Thu Feb 11 16:47:12 2021 +0100
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
    timemaster: Set uds_ro_address for ptp4l instances.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    This prevents conflicts on the new UDS-RO port.
Miroslav Lichvar e11a36
    
Miroslav Lichvar e11a36
    Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Miroslav Lichvar e11a36
Miroslav Lichvar e11a36
diff --git a/timemaster.c b/timemaster.c
Miroslav Lichvar e11a36
index 00db59f..02408d6 100644
Miroslav Lichvar e11a36
--- a/timemaster.c
Miroslav Lichvar e11a36
+++ b/timemaster.c
Miroslav Lichvar e11a36
@@ -712,7 +712,7 @@ static int add_ptp_source(struct ptp_domain *source,
Miroslav Lichvar e11a36
 			  char **ntp_config, struct script *script)
Miroslav Lichvar e11a36
 {
Miroslav Lichvar e11a36
 	struct config_file *config_file;
Miroslav Lichvar e11a36
-	char **command, *uds_path, **interfaces, *message_tag;
Miroslav Lichvar e11a36
+	char **command, *uds_path, *uds_path2, **interfaces, *message_tag;
Miroslav Lichvar e11a36
 	char ts_interface[IF_NAMESIZE];
Miroslav Lichvar e11a36
 	int i, j, num_interfaces, *phc, *phcs, hw_ts, sw_ts;
Miroslav Lichvar e11a36
 	struct sk_ts_info ts_info;
Miroslav Lichvar e11a36
@@ -809,6 +809,8 @@ static int add_ptp_source(struct ptp_domain *source,
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 		uds_path = string_newf("%s/ptp4l.%d.socket",
Miroslav Lichvar e11a36
 				       config->rundir, *shm_segment);
Miroslav Lichvar e11a36
+		uds_path2 = string_newf("%s/ptp4lro.%d.socket",
Miroslav Lichvar e11a36
+					config->rundir, *shm_segment);
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 		message_tag = string_newf("[%d", source->domain);
Miroslav Lichvar e11a36
 		for (j = 0; interfaces[j]; j++)
Miroslav Lichvar e11a36
@@ -832,8 +834,10 @@ static int add_ptp_source(struct ptp_domain *source,
Miroslav Lichvar e11a36
 			       "slaveOnly 1\n"
Miroslav Lichvar e11a36
 			       "domainNumber %d\n"
Miroslav Lichvar e11a36
 			       "uds_address %s\n"
Miroslav Lichvar e11a36
+			       "uds_ro_address %s\n"
Miroslav Lichvar e11a36
 			       "message_tag %s\n",
Miroslav Lichvar e11a36
-			       source->domain, uds_path, message_tag);
Miroslav Lichvar e11a36
+			       source->domain, uds_path, uds_path2,
Miroslav Lichvar e11a36
+			       message_tag);
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 		if (phcs[i] >= 0) {
Miroslav Lichvar e11a36
 			/* HW time stamping */
Miroslav Lichvar e11a36
@@ -868,6 +872,7 @@ static int add_ptp_source(struct ptp_domain *source,
Miroslav Lichvar e11a36
 
Miroslav Lichvar e11a36
 		free(message_tag);
Miroslav Lichvar e11a36
 		free(uds_path);
Miroslav Lichvar e11a36
+		free(uds_path2);
Miroslav Lichvar e11a36
 		free(interfaces);
Miroslav Lichvar e11a36
 	}
Miroslav Lichvar e11a36