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

Reply via email to