Hi, Any more review comments related to this patch or is there a chance it could be accepted?
BR, Magnus Armholt > -----Original Message----- > From: Magnus Armholt <magnus.armh...@gmail.com> > Sent: tiistai 9. elokuuta 2022 8.26 > To: linuxptp-devel@lists.sourceforge.net > Cc: Magnus Armholt <magnus.armh...@fi.abb.com> > Subject: [PATCH v5] Strip Parallel Redundancy Protocol (PRP) trailer > > BeSecure! This email comes from outside of ABB. Make sure you verify > the sender before clicking any links or downloading/opening attachments. > If this email looks suspicious, report it by clicking 'Report Phishing' > button in > Outlook or raising a ticket on MyIS. > > > 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. > > The PRP trailer is normally removed by the PRP implementation and invisible > to the rest of the stack. > If a PRP HW implementation is used the trailer won't be there. > When the SW PRP implementataion introduction in linux kernel 5.9 is used, > the trailer will be there. > In short, PRP uses dual lines to send the same information, LAN A and LAN B, > the first arriving packet is handled and the duplicate from the other > interface > is dropped. > PTP over PRP can't mix the information from the 2 lines (path delay might be > different) so it is needed to run a ptp4l instance on each interface instead > of > on the combined > prp0 interface created by the kernel. > Hence, the PRP trailer will still be there in PTP packages received directly > from the interfaces, the PRP stack hasn't had the chance to remove it (which > it would if traffic is read from prp0). > > Signed-off-by: Magnus Armholt <magnus.armh...@fi.abb.com> > --- > raw.c | 69 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 67 insertions(+), 2 deletions(-) > > diff --git a/raw.c b/raw.c > index ce64684..7fa2287 100644 > --- a/raw.c > +++ b/raw.c > @@ -23,6 +23,7 @@ > #include <net/if.h> > #include <netinet/in.h> > #include <netpacket/packet.h> > +#include <stdbool.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > @@ -65,6 +66,9 @@ struct raw { > #define N_RAW_FILTER 12 > #define RAW_FILTER_TEST 9 > > +#define PRP_MIN_PACKET_LEN 70 > +#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 +210,64 @@ static void addr_to_mac(void *mac, struct address > *addr) > memcpy(mac, &addr->sll.sll_addr, MAC_LEN); } > > +/* Determines if the packet has Parallel Redundancy Protocol (PRP) > +trailer. */ static bool has_prp_trailer(unsigned char *ptr, int cnt, > +int eth_hlen) { > + unsigned short suffix_id, lane_size_field, lsdu_size; > + int ptp_msg_len, trailer_start, padding_len; > + struct ptp_header *hdr; > + > + /* try to parse like a PTP message to find out the message length */ > + if (cnt < sizeof(struct ptp_header)) > + return false; > + > + hdr = (struct ptp_header *)ptr; > + if ((hdr->ver & MAJOR_VERSION_MASK) != PTP_MAJOR_VERSION) > + return false; > + > + ptp_msg_len = ntohs(hdr->messageLength); > + > + /* PRP requires ethernet packets to be minimum 70 bytes, including > trailer */ > + trailer_start = ptp_msg_len; > + padding_len = 0; > + if ((eth_hlen + ptp_msg_len + PRP_TRAILER_LEN) < > PRP_MIN_PACKET_LEN) > + { > + padding_len = PRP_MIN_PACKET_LEN - (eth_hlen + ptp_msg_len + > PRP_TRAILER_LEN); > + trailer_start += padding_len; > + } > + > + if (cnt < (trailer_start + PRP_TRAILER_LEN)) > + return false; > + > + /* 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 that the size in the RCT matches. > + Size is the lower 12 bits > + */ > + lane_size_field = ntohs(*(unsigned short*)(ptr + trailer_start + 2)); > + lsdu_size = lane_size_field & 0x0FFF; > + if (lsdu_size != cnt) > + return false; > + > + /* Verify the suffix */ > + suffix_id = ntohs(*(unsigned short*)(ptr + trailer_start + 4)); > + if (suffix_id == ETH_P_PRP) > + { > + return true; > + } > + > + return false; > +} > + > static int raw_open(struct transport *t, struct interface *iface, > struct fdarray *fda, enum timestamp_type ts_type) { @@ > -266,10 > +328,10 @@ no_mac: > static int raw_recv(struct transport *t, int fd, void *buf, int buflen, > struct address *addr, struct hw_timestamp *hwts) { > - int cnt, hlen; > + struct raw *raw = container_of(t, struct raw, t); > unsigned char *ptr = buf; > struct eth_hdr *hdr; > - struct raw *raw = container_of(t, struct raw, t); > + int cnt, hlen; > > if (raw->vlan) { > hlen = sizeof(struct vlan_hdr); @@ -287,6 +349,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, hlen)) > + 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