Strip the IEC62439-3 PRP trailer if it is present
to support PTP over PRP.
The implementation is very pedantic about
trailing bytes and will indicate bad message if the
PRP trailer bytes are present when parsing the PTP message.

Signed-off-by: Magnus Armholt <magnus.armh...@fi.abb.com>
---
 raw.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/raw.c b/raw.c
index ce64684..6c96028 100644
--- a/raw.c
+++ b/raw.c
@@ -65,6 +65,8 @@ struct raw {
 #define N_RAW_FILTER    12
 #define RAW_FILTER_TEST 9
 
+#define PRP_TRAILER_LEN 6
+
 static struct sock_filter raw_filter[N_RAW_FILTER] = {
        {OP_LDH,  0, 0, OFF_ETYPE   },
        {OP_JEQ,  0, 4, ETH_P_8021Q          }, /*f goto non-vlan block*/
@@ -206,6 +208,39 @@ static void addr_to_mac(void *mac, struct address *addr)
        memcpy(mac, &addr->sll.sll_addr, MAC_LEN);
 }
 
+static int has_prp_trailer(unsigned char *ptr, int cnt)
+{
+       unsigned short suffix_id, lane_size_field, lsdu_size;
+
+       if (cnt < PRP_TRAILER_LEN)
+               return -1;
+
+       /* PRP trailer (RCT) consists of 3 uint16.
+        * --------------------------------------------------------*
+        * SeqNr(0-15) | LanId(0-3) LSDUsize(4-15) | Suffix (0-15) *
+        * --------------------------------------------------------*
+        - Sequence number is a running number and can't be verified
+        - LanId should be 0x1010 or 0x1011 (but should not be used for 
verification)
+        - LSDUsize should match LSDU length
+          (including possible padding and the RCT itself)
+        - Suffix should be 0x88FB
+       */
+
+       /* verify the suffix first as it is the best identifier */
+       suffix_id = ntohs(*(unsigned short*)(ptr + (cnt - 2)));
+       if (suffix_id != ETH_P_PRP)
+               return -1;
+
+       /* verify also that the size in the RCT matches */
+       lane_size_field = ntohs(*(unsigned short*)(ptr + (cnt - 4)));
+       // size is lower 12 bits
+       lsdu_size = (lane_size_field & 0x0FFF);
+       if (lsdu_size == cnt)
+               return 0;
+
+       return -1;
+}
+
 static int raw_open(struct transport *t, struct interface *iface,
                    struct fdarray *fda, enum timestamp_type ts_type)
 {
@@ -287,6 +322,9 @@ static int raw_recv(struct transport *t, int fd, void *buf, 
int buflen,
        if (cnt < 0)
                return cnt;
 
+       if (has_prp_trailer(buf, cnt) == 0)
+               cnt -= PRP_TRAILER_LEN;
+
        if (raw->vlan) {
                if (ETH_P_1588 == ntohs(hdr->type)) {
                        pr_notice("raw: disabling VLAN mode");
-- 
2.25.1



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

Reply via email to