Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-12-03 Thread Richard Cochran
On Sun, Dec 03, 2023 at 06:15:52PM -0800, Kishen Maloor wrote:
> On 12/1/23 10:07 PM, Richard Cochran wrote:
> > Does the standard require that either ALL the nodes in a network use
> > CMLDS, or none do at all?
> > 
> 
> When the time-aware system supports multiple domains, IEEE
> 802.1as-2020/11.2.17 mandates CMLDS and the COMMON_P2P DM.

Very narrow minded and short sighted.

Oh well, I wouldn't expect 802.1as to actually be practical.

Pass me the crazy sauce, please!

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-12-03 Thread Kishen Maloor

On 12/1/23 10:07 PM, Richard Cochran wrote:

On Thu, Nov 30, 2023 at 04:52:44PM -0800, Kishen Maloor wrote:


CMLDS ptp4l process would be configured with
transportSpecific/domain=0x2/0.


Question about the spec:

How on earth is this going to work?

I mean, if the link partner is not also using CMLDS, then it won't
reply because of the majorSdoId mismatch.


Yes, as we understand, that is indeed the case. IEEE 
1588-2019/16.6.3.1/Note 3 emphasizes this point and 16.6.3.2 specifies 
the wire protocol variations for CMLDS. So yeah, the link partner is

expected to run an instance of the service and they would interoperate.



Does the standard require that either ALL the nodes in a network use
CMLDS, or none do at all?



When the time-aware system supports multiple domains, IEEE 
802.1as-2020/11.2.17 mandates CMLDS and the COMMON_P2P DM.


Thanks,
-Kishen.


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-12-01 Thread Richard Cochran
On Thu, Nov 30, 2023 at 04:52:44PM -0800, Kishen Maloor wrote:

> CMLDS ptp4l process would be configured with
> transportSpecific/domain=0x2/0.

Question about the spec:

How on earth is this going to work?

I mean, if the link partner is not also using CMLDS, then it won't
reply because of the majorSdoId mismatch.

Does the standard require that either ALL the nodes in a network use
CMLDS, or none do at all?

This is messed up, IMO.

Thanks,
Richard




___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-12-01 Thread Richard Cochran
On Thu, Nov 30, 2023 at 04:52:44PM -0800, Kishen Maloor wrote:

> If serviceMeasurementValid=true, then we set both peer_portid_valid and
> p->nrate.ratio_valid to true so that port_capable() could evaluate to true.

Even simpler: include asCapable from the CMLDS Link Port in the TLV,
and just assign asCapable directly in the cleint.

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-11-30 Thread Richard Cochran
On Thu, Nov 30, 2023 at 04:52:44PM -0800, Kishen Maloor wrote:

> > +   p->cmlds_pmc = pmc_create(cfg, TRANS_UDS,
> > + config_get_string(cfg, p->name, 
> > "cmlds_client_address"),
> > + config_get_string(cfg, p->name, 
> > "cmlds_server_address"),
> > + hops,
> > + config_get_int(cfg, NULL, "domainNumber"),
> > + config_get_int(cfg, p->name, 
> > "transportSpecific") << 4,
> 
> I haven't studied the flow here, but using the P2P_COMMON instance's
> transportSpecific and domainNumber above might cause the CMLDS server's
> port_ignore() to drop this message as the
> CMLDS ptp4l process would be configured with
> transportSpecific/domain=0x2/0.
> 
> Perhaps just passing 0x2/0 above will fix things? This is assuming that
> there are no transportSpecific/domainNumber checks on the receive path
> for CMLDS events (which seemed to be the case looking at the code).

Right, those two fields must match.  So I think:

- we'll need options for those two, and

- this is another reason to use a separate pmc instance for cmlds
  rather than reusing the uds port.

> > Right, so the next TODO is to enable FD_DELAY_TIMER for P2P_COMMON
> > mode and let it 1) renew the push subscription and 2) catch the case
> > when the push notification does not arrive on time.
> > 
> 
> Yes, in our series CMLDS queries were performed synchronously at the Pdelay
> request cadence. If serviceMeasurementValid=false then port->pdr_missing was
> incremented and immediately followed by a call to port_capable(). This was
> necessary as I recollect there was a related Avnu test case.
> 
> If serviceMeasurementValid=true, then we set both peer_portid_valid and
> p->nrate.ratio_valid to true so that port_capable() could evaluate to true.

I think that logic can be implemented without any service Measurement
Valid field in the TLV.

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-11-30 Thread Kishen Maloor

Hi Richard,

Firstly, thanks so much for your reviews and efforts to get
this done.

I'll just rehash a couple of points also raised by Andrew.

On this change below:

> +static int port_cmlds_initialize(struct port *p)
> +{
> +  struct config *cfg = clock_config(p->clock);
> +  struct subscribe_events_np sen = {0};
> +  const int zero_datalen = 1;
> +  const UInteger8 hops = 0;
> +
> +  p->cmlds_port = config_get_int(cfg, p->name, "cmlds_port");
> +  p->cmlds_pmc = pmc_create(cfg, TRANS_UDS,
> +config_get_string(cfg, p->name, 
"cmlds_client_address"),
> +config_get_string(cfg, p->name, 
"cmlds_server_address"),
> +hops,
> +config_get_int(cfg, NULL, "domainNumber"),
> +config_get_int(cfg, p->name, "transportSpecific") 
<< 4,

I haven't studied the flow here, but using the P2P_COMMON instance's
transportSpecific and domainNumber above might cause the CMLDS server's 
port_ignore() to drop this message as the

CMLDS ptp4l process would be configured with
transportSpecific/domain=0x2/0.

Perhaps just passing 0x2/0 above will fix things? This is assuming that
there are no transportSpecific/domainNumber checks on the receive path
for CMLDS events (which seemed to be the case looking at the code).

On 11/30/23 11:28 AM, Richard Cochran wrote:
...

serviceMeasurementValid is implicit, because if you get a PUSH
notification, it is valid.


Right, serviceMeasurementValid == true is implicit but
serviceMeasurementValid == false is useful for the .port_id_valid /
.pdr_missing logic to work.  The timeout logic is disabled with
P2P_COMMON.


Right, so the next TODO is to enable FD_DELAY_TIMER for P2P_COMMON
mode and let it 1) renew the push subscription and 2) catch the case
when the push notification does not arrive on time.



Yes, in our series CMLDS queries were performed synchronously at the 
Pdelay request cadence. If serviceMeasurementValid=false then 
port->pdr_missing was incremented and immediately followed by a call to 
port_capable(). This was necessary as I recollect there was a related 
Avnu test case.


If serviceMeasurementValid=true, then we set both peer_portid_valid and 
p->nrate.ratio_valid to true so that port_capable() could evaluate to true.



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-11-30 Thread Richard Cochran
On Thu, Nov 30, 2023 at 07:12:54PM +0100, Andrew Zaborowski wrote:
> On Thu, 30 Nov 2023 at 17:44, Richard Cochran  
> wrote:
> > On Thu, Nov 30, 2023 at 04:32:20PM +0100, Andrew Zaborowski wrote:
> > > > +   PORT_ITEM_STR("cmlds_client_address", "/var/run/cmlds_cleint"),
> > >
> > > I assume the use of this is simply to set unique names for per-port
> > > sockets.  Maybe something like tempnam() could be used instead.
> >
> > No, it has to be under user control, because the path might be under a
> > security policy.
> 
> Do you mean that the user might want it to be under a security policy?

Yes.

>  Otherwise it could be in /tmp.

The top down path has to be the user's choice,
 /tmp/... or
 /var/run/... or
 /whatever/...

and so there must be a configuration option in any case.  It seems
silly to restrict the option to the leading path and not include the
socket file name.

> > > > @@ -1868,6 +1869,33 @@ static void port_clear_fda(struct port *p, int 
> > > > count)
> > > > p->fda.fd[i] = -1;
> > > >  }
> > > >
> > > > +static int port_cmlds_initialize(struct port *p)
> > > > +{
> > > > +   struct config *cfg = clock_config(p->clock);
> > > > +   struct subscribe_events_np sen = {0};
> > > > +   const int zero_datalen = 1;
> > > > +   const UInteger8 hops = 0;
> > > > +
> > > > +   p->cmlds_port = config_get_int(cfg, p->name, "cmlds_port");
> > >
> > > Should this fall back to port_number(p)?
> >
> > I don't see how, since there is always a default for each
> > configuration option.
> 
> Right, it'd need to default to, say, -1 which would be checked here.

Okay, sure.  That will reduce configuration burden for normal setups.

> > Also, I understood from you guys that the port
> > number _has_ to be different to pass compliance tests. For that, I
> > thought adding a "starting port number" option would do the trick
> 
> The port identity (clock identity + port number) has to be unique.  As
> long as the clock identity is unique, which it has to be, I don't
> think the port number *has* to be different.

Got it.

> > serviceMeasurementValid is implicit, because if you get a PUSH
> > notification, it is valid.
> 
> Right, serviceMeasurementValid == true is implicit but
> serviceMeasurementValid == false is useful for the .port_id_valid /
> .pdr_missing logic to work.  The timeout logic is disabled with
> P2P_COMMON.

Right, so the next TODO is to enable FD_DELAY_TIMER for P2P_COMMON
mode and let it 1) renew the push subscription and 2) catch the case
when the push notification does not arrive on time.

Thoughts?

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-11-30 Thread Andrew Zaborowski
On Thu, 30 Nov 2023 at 17:44, Richard Cochran  wrote:
> On Thu, Nov 30, 2023 at 04:32:20PM +0100, Andrew Zaborowski wrote:
> > > +   PORT_ITEM_STR("cmlds_client_address", "/var/run/cmlds_cleint"),
> >
> > I assume the use of this is simply to set unique names for per-port
> > sockets.  Maybe something like tempnam() could be used instead.
>
> No, it has to be under user control, because the path might be under a
> security policy.

Do you mean that the user might want it to be under a security policy?
 Otherwise it could be in /tmp.

>
> > > @@ -1868,6 +1869,33 @@ static void port_clear_fda(struct port *p, int 
> > > count)
> > > p->fda.fd[i] = -1;
> > >  }
> > >
> > > +static int port_cmlds_initialize(struct port *p)
> > > +{
> > > +   struct config *cfg = clock_config(p->clock);
> > > +   struct subscribe_events_np sen = {0};
> > > +   const int zero_datalen = 1;
> > > +   const UInteger8 hops = 0;
> > > +
> > > +   p->cmlds_port = config_get_int(cfg, p->name, "cmlds_port");
> >
> > Should this fall back to port_number(p)?
>
> I don't see how, since there is always a default for each
> configuration option.

Right, it'd need to default to, say, -1 which would be checked here.

> Also, I understood from you guys that the port
> number _has_ to be different to pass compliance tests. For that, I
> thought adding a "starting port number" option would do the trick

The port identity (clock identity + port number) has to be unique.  As
long as the clock identity is unique, which it has to be, I don't
think the port number *has* to be different.

>
> > In Kishen's patch series struct cmlds_info_np also had a
> > .serviceMeasurementValid which enabled the port_capable() logic to
> > work and IIRC that is important at least for 802.1AS compliance.  If
> > that was to be re-added, the event would need to be emitted in an
> > extra place in the CMLDS, perhaps where pdr_missing is incremented.
>
> serviceMeasurementValid is implicit, because if you get a PUSH
> notification, it is valid.

Right, serviceMeasurementValid == true is implicit but
serviceMeasurementValid == false is useful for the .port_id_valid /
.pdr_missing logic to work.  The timeout logic is disabled with
P2P_COMMON.

Best regards


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-11-30 Thread Richard Cochran
On Thu, Nov 30, 2023 at 04:32:20PM +0100, Andrew Zaborowski wrote:

> > @@ -249,6 +250,9 @@ struct config_item config_tab[] = {
> > 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),
> > +   PORT_ITEM_STR("cmlds_client_address", "/var/run/cmlds_cleint"),
> 
> I assume the use of this is simply to set unique names for per-port
> sockets.  Maybe something like tempnam() could be used instead.

No, it has to be under user control, because the path might be under a
security policy.
 
> > @@ -1868,6 +1869,33 @@ static void port_clear_fda(struct port *p, int count)
> > p->fda.fd[i] = -1;
> >  }
> >
> > +static int port_cmlds_initialize(struct port *p)
> > +{
> > +   struct config *cfg = clock_config(p->clock);
> > +   struct subscribe_events_np sen = {0};
> > +   const int zero_datalen = 1;
> > +   const UInteger8 hops = 0;
> > +
> > +   p->cmlds_port = config_get_int(cfg, p->name, "cmlds_port");
> 
> Should this fall back to port_number(p)?

I don't see how, since there is always a default for each
configuration option.  Also, I understood from you guys that the port
number _has_ to be different to pass compliance tests. For that, I
thought adding a "starting port number" option would do the trick.
 
> > +   p->cmlds_pmc = pmc_create(cfg, TRANS_UDS,
> > + config_get_string(cfg, p->name, 
> > "cmlds_client_address"),
> > + config_get_string(cfg, p->name, 
> > "cmlds_server_address"),
> > + hops,
> > + config_get_int(cfg, NULL, "domainNumber"),
> > + config_get_int(cfg, p->name, 
> > "transportSpecific") << 4,
> 
> The sdoId is (by either IEEE 1588 or 802.1AS) different for the CMLDS
> than for a P2P_COMMON port, I think a check in port_ignore will
> discard the messages as a result.  Maybe hardcode TS_CMLDS here? (with
> TS_CMLDS defined in msg.h next to TS_IEEE_8021AS)
> 
> Using pmc here surely works but I wonder if it's not actually more
> work than reusing c->uds_port.

I considered that, but I invite you to try implementing that to see
which one is simpler.

> > +   switch (mgt->id) {
> > +   case MID_CMLDS_INFO_NP:
> > +   if (msg->header.sourcePortIdentity.portNumber != 
> > p->cmlds_port) {
> > +   break;
> > +   }
> > +   cmlds = (struct cmlds_info_np *) mgt->data;
> > +   p->peer_delay = nanoseconds_to_tmv(cmlds->meanLinkDelay >> 
> > 16);
> > +   p->peerMeanPathDelay = tmv_to_TimeInterval(p->peer_delay);
> 
> cmlds->meanLinkDelay is already a TimeInterval in case you want to use that.

good point

> > +
> > +   if (p->state == PS_UNCALIBRATED || p->state == PS_SLAVE) {
> > +   const struct timestamp dummy = {0};
> > +   const tmv_t tx = timestamp_to_tmv(dummy);
> 
> tmv_zero() could also be used.

yeah

> > +   clock_peer_delay(p->clock, p->peer_delay, tx, tx,
> > +p->nrate.ratio);
> 
> p->nrate.ratio hasn't been set yet, I think a line similar to this is missing:
> 
> p->nrate.ratio = 1.0 + (double) cmlds->scaledNeighborRateRatio / POW2_41;

Right
 
> The CMLDS port will also need to ensure that the NRR is calculated
> because now it's done conditionally.

Huh, I didn't change that part?
 
> In Kishen's patch series struct cmlds_info_np also had a
> .serviceMeasurementValid which enabled the port_capable() logic to
> work and IIRC that is important at least for 802.1AS compliance.  If
> that was to be re-added, the event would need to be emitted in an
> extra place in the CMLDS, perhaps where pdr_missing is incremented.

serviceMeasurementValid is implicit, because if you get a PUSH
notification, it is valid.

Thanks,
Richard



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH v1 5/5] Implement the COMMON_P2P delay mechanism.

2023-11-30 Thread Andrew Zaborowski
Hi Richard,

I haven't tested this but here are some comments.

On Thu, 30 Nov 2023 at 08:58, Richard Cochran  wrote:
> From: Kishen Maloor 
>
> Signed-off-by: Richard Cochran 
> ---
>  config.c   |   4 ++
>  dm.h   |   3 +
>  fd.h   |   1 +
>  makefile   |   4 +-
>  port.c | 166 +++--
>  port_private.h |   3 +
>  6 files changed, 174 insertions(+), 7 deletions(-)
>
> diff --git a/config.c b/config.c
> index fe65b76..05ffd3c 100644
> --- a/config.c
> +++ b/config.c
> @@ -171,6 +171,7 @@ static struct config_enum delay_filter_enu[] = {
>
>  static struct config_enum delay_mech_enu[] = {
> { "Auto", DM_AUTO },
> +   { "COMMON_P2P", DM_COMMON_P2P },
> { "E2E",  DM_E2E },
> { "P2P",  DM_P2P },
> { "NONE", DM_NO_MECHANISM },
> @@ -249,6 +250,9 @@ struct config_item config_tab[] = {
> 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),
> +   PORT_ITEM_STR("cmlds_client_address", "/var/run/cmlds_cleint"),

I assume the use of this is simply to set unique names for per-port
sockets.  Maybe something like tempnam() could be used instead.

> +   PORT_ITEM_INT("cmlds_port", 1, 1, UINT16_MAX),
> +   PORT_ITEM_STR("cmlds_server_address", "/var/run/cmlds_server"),
> GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, 
> dataset_comp_enu),
> PORT_ITEM_INT("delayAsymmetry", 0, INT_MIN, INT_MAX),
> PORT_ITEM_ENU("delay_filter", FILTER_MOVING_MEDIAN, delay_filter_enu),
> diff --git a/dm.h b/dm.h
> index 47bd847..80d1ce5 100644
> --- a/dm.h
> +++ b/dm.h
> @@ -34,6 +34,9 @@ enum delay_mechanism {
> /** Peer delay mechanism. */
> DM_P2P,
>
> +   /** Peer delay as measured by CMLDS. */
> +   DM_COMMON_P2P,
> +
> /** No Delay Mechanism. */
> DM_NO_MECHANISM = 0xFE,
>  };
> diff --git a/fd.h b/fd.h
> index 16420d7..9a072ab 100644
> --- a/fd.h
> +++ b/fd.h
> @@ -39,6 +39,7 @@ enum {
> FD_SYNC_TX_TIMER,
> FD_UNICAST_REQ_TIMER,
> FD_UNICAST_SRV_TIMER,
> +   FD_CMLDS,
> FD_RTNL,
> N_POLLFD,
>  };
> diff --git a/makefile b/makefile
> index 7fc5f6f..e9c1ccc 100644
> --- a/makefile
> +++ b/makefile
> @@ -30,8 +30,8 @@ TS2PHC= ts2phc.o lstab.o nmea.o serial.o sock.o 
> ts2phc_generic_pps_source.o \
>   ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
> ts2phc_pps_source.o
>  OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
>   e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o monitor.o msg.o phc.o \
> - port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) \
> - sk.o stats.o tc.o $(TRANSP) telecom.o tlv.o tsproc.o unicast_client.o \
> + pmc_common.o port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o 
> rtnl.o \
> + $(SERVOS) sk.o stats.o tc.o $(TRANSP) telecom.o tlv.o tsproc.o 
> unicast_client.o \
>   unicast_fsm.o unicast_service.o util.o version.o
>
>  OBJECTS= $(OBJ) hwstamp_ctl.o nsm.o phc2sys.o phc_ctl.o pmc.o 
> pmc_agent.o \
> diff --git a/port.c b/port.c
> index 8afe1b2..75b4dd8 100644
> --- a/port.c
> +++ b/port.c
> @@ -963,7 +963,8 @@ static int port_management_fill_response(struct port 
> *target,
> ptp_text_copy(cd->userDescription, >userDescription);
> buf += sizeof(struct PTPText) + cd->userDescription->length;
>
> -   if (target->delayMechanism == DM_P2P) {
> +   if (target->delayMechanism == DM_P2P ||
> +   target->delayMechanism == DM_COMMON_P2P) {
> memcpy(buf, profile_id_p2p, PROFILE_ID_LEN);
> } else {
> struct config *cfg = clock_config(target->clock);
> @@ -1868,6 +1869,33 @@ static void port_clear_fda(struct port *p, int count)
> p->fda.fd[i] = -1;
>  }
>
> +static int port_cmlds_initialize(struct port *p)
> +{
> +   struct config *cfg = clock_config(p->clock);
> +   struct subscribe_events_np sen = {0};
> +   const int zero_datalen = 1;
> +   const UInteger8 hops = 0;
> +
> +   p->cmlds_port = config_get_int(cfg, p->name, "cmlds_port");

Should this fall back to port_number(p)?

> +   p->cmlds_pmc = pmc_create(cfg, TRANS_UDS,
> + config_get_string(cfg, p->name, 
> "cmlds_client_address"),
> + config_get_string(cfg, p->name, 
> "cmlds_server_address"),
> + hops,
> + config_get_int(cfg, NULL, "domainNumber"),
> + config_get_int(cfg, p->name, 
> "transportSpecific") << 4,

The sdoId is (by either IEEE 1588 or 802.1AS) different for the CMLDS
than for a