<div dir="ltr"><div>Hi Alison and Greg</div><div><br></div><div>Thanks for the help and best wishes. I will try asking on the kernel netdev mailing list.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jul 1, 2023 at 12:42 AM Alison Schofield <<a href="mailto:alison.schofield@intel.com">alison.schofield@intel.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Jun 28, 2023 at 04:15:36PM +0530, Abhiram V wrote:<br>
> I am implementing the Parallel Redundancy Protocol (PRP, IEC standard<br>
> 62439-3) as a kernel module for a school project of mine. The code for the<br>
> module can be found at: <a href="https://github.com/ramv33/prp" rel="noreferrer" target="_blank">https://github.com/ramv33/prp</a>. I have used the code<br>
> for the HSR module which implements PRP as a reference for my<br>
> implementation since I have zero prior experience with kernel programming.<br>
> Even though a lot of the design is different, I have used the module as a<br>
> reference for what to do and how to do it.<br>
<br>
Hi Abhiram,<br>
<br>
Sounds like an interesting project. This list may not have the reach<br>
you need. Here are some other places where you may find the specific<br>
help you need.<br>
<br>
There is a netdev mailing list:<br>
<a href="https://lore.kernel.org/netdev/" rel="noreferrer" target="_blank">https://lore.kernel.org/netdev/</a><br>
<br>
If you modeled after, drivers/net/dsa/xrs700x/*, perhaps just send<br>
a message to George McCollister <<a href="mailto:george.mccollister@gmail.com" target="_blank">george.mccollister@gmail.com</a>> and<br>
CC the netdev mailing list. Folks really like to keep things on the<br>
mailing list - as you've done here. (If I've got the wrong driver,<br>
look in the MAINTAINERS file for the correct one.)<br>
<br>
Another access point is the IRC channel. The netdev folks probably<br>
hang out on #netdev on <a href="http://oftc.net" rel="noreferrer" target="_blank">oftc.net</a><br>
<br>
Good luck with your presentation!<br>
<br>
Alison<br>
<br>
> <br>
> Let me provide a brief description of what PRP is and what it does. PRP is<br>
> used to provide hitless redundancy (zero recovery time). It does this by<br>
> having two parallel and independent Ethernet networks. A device is<br>
> connected to both these networks (LAN_A and LAN_B).<br>
> Whenever a frame is sent by the device, it duplicates the frame and appends<br>
> a trailer (Redundancy Control Trailer - RCT) which contains a sequence<br>
> number, LAN_Id (LAN_A=0xA or LAN_B=0xB) and an LSDU_size (Link Service Data<br>
> Unit, i.e, Ethernet payload size minus the RCT), and a PRP_Suffix (0x88FB)<br>
> for a total of 6 octets.<br>
> On reception, the sequence number is used to detect and discard the<br>
> duplicates, removes the RCT, and forwards the frames to the upper layers<br>
> for processing.<br>
> The duplication on transmission, discarding and removal of RCT on reception<br>
> is done by the kernel module which acts as the Link Redundancy Entity (LRE)<br>
> as specified in the standard. The LRE is implemented as a virtual network<br>
> interface using a kernel module. The transmission is done by defining the<br>
> ndo_start_xmit function in the netdev_ops structure of my net_device.<br>
> <br>
> The *problem* I have is on reception, specifically with the *removal of the<br>
> RCT*. The receive handler is registered on device creation using<br>
> netdev_rx_handler_register and netdev_upper_dev_link.<br>
> The receive handler  when it detects that the RCT is well-formed (correct<br>
> PRP_Suffix, LSDU_size, LAN_ID for the NIC through which it was received),<br>
> tries to strip the RCT before calling netif_rx() on the skb to forward it<br>
> to the upper layers for processing.<br>
> To strip the RCT, I call *skb_trim* as follows:<br>
>        skb_trim(skb, skb->len - PRP_RCTLEN /* 6 */);<br>
> as given in the HSR module.<br>
> <br>
> I have used skb_dump both before and after the call to skb_trim and<br>
> verified that the length is being reduced and that the tailroom is<br>
> increased by 6 bytes. The problem is that when I call skb_trim, the packet<br>
> is not received by the upper layers. Without calling skb_trim, the packet<br>
> is received correctly but the RCT is consumed by the applications which<br>
> should not be the case.<br>
> <br>
> I used wireshark to inspect the frames at both the sender and the receiver<br>
> side on the two physical devices and observed the following:<br>
> <br>
>    1. At the receiver side - The IP payload length is different for the<br>
>    same frame received through LAN_A and LAN_B. The one received through LAN_B<br>
>    has a payload length 6 greater  than that for LAN_A (*6 is the size of<br>
>    the RCT*). On checking the ip_rcv_core function, invalid IP payload<br>
>    length is one reason that the packet can be dropped.<br>
>    2. At the sender side - The entire packet is the same minus the RCT's<br>
>    LAN_ID field for a frame-pair. The IP payload length is correct when I<br>
>    capture outgoing frames on the two physical devices.<br>
> <br>
> As mentioned at the top, the code is available at:<br>
> <a href="https://github.com/ramv33/prp" rel="noreferrer" target="_blank">https://github.com/ramv33/prp</a>. Here is a brief overview of the code<br>
> <br>
>    1. The transmission is defined in *prp_tx.c* in *prp_send_skb* which is<br>
>    called by *prp_dev_xmit* function defined in *prp_dev.c*<br>
>    2. The code that sets up the two slave devices to forward frames<br>
>    received to the virtual interface is defined in *prp_dev.c* in the<br>
>    function *prp_port_setup*. It is called by *prp_add_ports*, which is<br>
>    called by *prp_dev_finalize* which is called by the RTNL newlnk callback,<br>
>    3. The receive handler that is defined in *prp_rx.c, *the function is<br>
>    *prp_recv_frame.* It checks if the frame has a valid RCT, duplicates<br>
>    discards, and then strips the RCT by calling *strip_rct *before calling<br>
>    *prp_net_if* which removes the Ethernet header and calls *netif_rx*<br>
> <br>
> Hope you can help me find a solution to the removal of the RCT. Point out<br>
> any mistakes that I am making. Thank you in advance :)<br>
<br>
> _______________________________________________<br>
> Kernelnewbies mailing list<br>
> <a href="mailto:Kernelnewbies@kernelnewbies.org" target="_blank">Kernelnewbies@kernelnewbies.org</a><br>
> <a href="https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" rel="noreferrer" target="_blank">https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
<br>
</blockquote></div>