In certain scenarios it is useful to know whether a remote port is synchronized, for example when the local system is the PTP master and we are trying to send time-synchronized data to a slave.
Introduce a new option in ptp4l, which defaults to false, and which allows the following: - a remote PMC agent to subscribe to a given data set - the clock API to push notifications towards a non-local subscriber The only SET that is supported is adding a subscription, no clock state can be modified remotely. Nonetheless, there is no authentication implemented, so the option should be used with care. Signed-off-by: Vladimir Oltean <olte...@gmail.com> --- clock.c | 22 +++++++++++++++------- config.c | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/clock.c b/clock.c index d1c85ec5a7b1..0689360db410 100644 --- a/clock.c +++ b/clock.c @@ -76,6 +76,7 @@ struct clock_subscriber { struct address addr; UInteger16 sequenceId; time_t expiration; + struct port *port; }; struct clock { @@ -152,8 +153,9 @@ static void remove_subscriber(struct clock_subscriber *s) free(s); } -static void clock_update_subscription(struct clock *c, struct ptp_message *req, - uint8_t *bitmask, uint16_t duration) +static void clock_update_subscription(struct clock *c, struct port *p, + struct ptp_message *req, uint8_t *bitmask, + uint16_t duration) { struct clock_subscriber *s, *tmp; struct timespec now; @@ -175,6 +177,7 @@ static void clock_update_subscription(struct clock *c, struct ptp_message *req, memcpy(s->events, bitmask, EVENT_BITMASK_CNT); clock_gettime(CLOCK_MONOTONIC, &now); s->expiration = now.tv_sec + duration; + s->port = p; } else { remove_subscriber(s); } @@ -195,6 +198,7 @@ static void clock_update_subscription(struct clock *c, struct ptp_message *req, clock_gettime(CLOCK_MONOTONIC, &now); s->expiration = now.tv_sec + duration; s->sequenceId = 0; + s->port = p; LIST_INSERT_HEAD(&c->subscribers, s, list); } @@ -248,10 +252,11 @@ static void clock_prune_subscriptions(struct clock *c) void clock_send_notification(struct clock *c, struct ptp_message *msg, enum notification event) { - struct port *uds = c->uds_rw_port; struct clock_subscriber *s; LIST_FOREACH(s, &c->subscribers, list) { + struct port *port = s->port ? s->port : c->uds_rw_port; + if (!event_bitmask_get(s->events, event)) continue; /* send event */ @@ -262,7 +267,7 @@ void clock_send_notification(struct clock *c, struct ptp_message *msg, msg->management.targetPortIdentity.portNumber = htons(s->targetPortIdentity.portNumber); msg->address = s->addr; - port_forward_to(uds, msg); + port_forward_to(port, msg); } } @@ -532,7 +537,7 @@ static int clock_management_set(struct clock *c, struct port *p, break; case MID_SUBSCRIBE_EVENTS_NP: sen = (struct subscribe_events_np *)tlv->data; - clock_update_subscription(c, req, sen->bitmask, sen->duration); + clock_update_subscription(c, p, req, sen->bitmask, sen->duration); respond = 1; break; case MID_SYNCHRONIZATION_UNCERTAIN_NP: @@ -1436,6 +1441,7 @@ tmv_t clock_ingress_time(struct clock *c) int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) { + bool allow_remote_subscriptions = config_get_int(c->config, NULL, "allow_remote_subscriptions"); int changed = 0, res, answers; struct port *piter; struct management_tlv *mgt; @@ -1472,7 +1478,9 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) clock_management_send_error(p, msg, MID_WRONG_LENGTH); return changed; } - if (p != c->uds_rw_port) { + if (p != c->uds_rw_port && + (!allow_remote_subscriptions || + mgt->id != MID_SUBSCRIBE_EVENTS_NP)) { /* Sorry, only allowed on the UDS-RW port. */ clock_management_send_error(p, msg, MID_NOT_SUPPORTED); return changed; @@ -1493,7 +1501,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg) switch (mgt->id) { case MID_PORT_PROPERTIES_NP: - if (p != c->uds_rw_port) { + if (p != c->uds_rw_port && !allow_remote_subscriptions) { /* Only the UDS-RW port allowed. */ clock_management_send_error(p, msg, MID_NOT_SUPPORTED); return 0; diff --git a/config.c b/config.c index 760d0e12b0b6..6ee46b448adc 100644 --- a/config.c +++ b/config.c @@ -221,6 +221,7 @@ static struct config_enum bmca_enu[] = { }; struct config_item config_tab[] = { + PORT_ITEM_INT("allow_remote_subscriptions", 0, 0, 1), PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX), PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu), GLOB_ITEM_INT("assume_two_step", 0, 0, 1), -- 2.25.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel