[Linuxptp-devel] [RFC PATCH v1 5/8] Add port_cmlds_ignore()
PTP IEEE 1588 stack for Linux
                
                Brought to you by:
                
                    rcochran
                    
                
            
            
        
        
        
    | 
      
      
      From: Kishen M. <kis...@in...> - 2023-03-20 02:37:21
      
     | 
| port_cmlds_ignore() assesses incoming messages per the following
policy:
* All messages that bear the CMLDS sdoid/domainNumber are directed
to a CMLDS Link Port context and processed by this function. All other
messages go through the regular flow (i.e. port_ignore() and beyond)
based on the the ptp4l instance configuration.
* PDELAY_REQ, PDELAY_RESP, PDELAY_RESP_FOLLOW_UP and management
messages for MID_CMLDS_INFO_NP are the only expected message types
at a CMLDS Link Port. All other received messages at a CMLDS Link Port
(i.e., bearing the CMLDS sdoid/domainNumber) are ignored.
Signed-off-by: Kishen Maloor <kis...@in...>
---
 port.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/port.c b/port.c
index e632316aa492..9040453fb2dc 100644
--- a/port.c
+++ b/port.c
@@ -772,9 +772,62 @@ int port_clr_tmo(int fd)
 	return timerfd_settime(fd, 0, &tmo, NULL);
 }
 
+static int port_cmlds_ignore(struct port *p, struct ptp_message *m)
+{
+	struct management_tlv *mgt = (struct management_tlv *)
+					m->management.suffix;
+
+	/* Messages that do not bear the CMLDS sdoid/domainNumber
+	 * are unrelated to CMLDS.
+	 */
+	if (msg_transport_specific(m) != CMLDS_TRANSPORTSPECIFIC ||
+	    m->header.domainNumber != CMLDS_DOMAINNUMBER) {
+		/* MID_CMLDS_INFO_NP may only be accessed using the CMLDS
+		 * sdoid/domainNumber.
+		 */
+		if (msg_type(m) == MANAGEMENT &&
+		    mgt->id == MID_CMLDS_INFO_NP) {
+			return -1;
+		}
+		return 0;
+	}
+
+	/* CMLDS messages */
+	if (msg_transport_specific(m) == CMLDS_TRANSPORTSPECIFIC) {
+		/* Only MID_CMLDS_INFO_NP may be accessed using the CMLDS
+		 * sdoid/domainNumber. Ignore anything else.
+		 */
+		if (msg_type(m) == MANAGEMENT &&
+		    mgt->id != MID_CMLDS_INFO_NP)
+			return -1;
+
+		/* Ignore CMLDS messages received at a port that does
+		 * not expose CMLDS.
+		 * Note: Messages across ptp4l instacnes to/from
+		 * MID_CMLDS_INFO_NP currently propagate over the UDS.
+		 */
+		if (!port_is_uds(p) && !port_cmlds_enabled(p)) {
+			return -1;
+		}
+
+		/* Only the following message types are permitted to/from
+		 * the CMLDS. Ignore anything else.
+		 */
+		if (msg_type(m) != MANAGEMENT &&
+		    msg_type(m) != PDELAY_REQ &&
+		    msg_type(m) != PDELAY_RESP &&
+		    msg_type(m) != PDELAY_RESP_FOLLOW_UP) {
+			return -1;
+		}
+	}
+	/* This is a permitted CMLDS PDELAY or MANAGEMENT message */
+	return 1;
+}
+
 static int port_ignore(struct port *p, struct ptp_message *m)
 {
 	struct ClockIdentity c1, c2;
+	int cmlds = 0;
 
 	if (port_is_uds(p) && msg_type(m) != MANAGEMENT) {
 		return 1;
@@ -785,14 +838,24 @@ static int port_ignore(struct port *p, struct ptp_message *m)
 	if (path_trace_ignore(p, m)) {
 		return 1;
 	}
-	if (p->match_transport_specific &&
+
+	/* Ignore non-permitted CMLDS messages */
+	if ((cmlds = port_cmlds_ignore(p, m)) == -1)
+		return 1;
+
+	/* Suppress transportSpecific/domainNumber matching below for
+	 * mesaages to/from the CMLDS as the requisite checks have
+	 * already been performed by port_cmlds_ignore()
+	 */
+	if (!cmlds && p->match_transport_specific &&
 	    msg_transport_specific(m) != p->transportSpecific) {
 		return 1;
 	}
 	if (pid_eq(&m->header.sourcePortIdentity, &p->portIdentity)) {
 		return 1;
 	}
-	if (m->header.domainNumber != clock_domain_number(p->clock)) {
+	if (!cmlds &&
+	    m->header.domainNumber != clock_domain_number(p->clock)) {
 		return 1;
 	}
 
-- 
2.31.1
 |