Kernel module for a network interface - remove trailer from sk_buff on reception

Alison Schofield alison.schofield at
Fri Jun 30 15:12:53 EDT 2023

On Wed, Jun 28, 2023 at 04:15:36PM +0530, Abhiram V wrote:
> I am implementing the Parallel Redundancy Protocol (PRP, IEC standard
> 62439-3) as a kernel module for a school project of mine. The code for the
> module can be found at: I have used the code
> for the HSR module which implements PRP as a reference for my
> implementation since I have zero prior experience with kernel programming.
> Even though a lot of the design is different, I have used the module as a
> reference for what to do and how to do it.

Hi Abhiram,

Sounds like an interesting project. This list may not have the reach
you need. Here are some other places where you may find the specific
help you need.

There is a netdev mailing list:

If you modeled after, drivers/net/dsa/xrs700x/*, perhaps just send
a message to George McCollister <george.mccollister at> and
CC the netdev mailing list. Folks really like to keep things on the
mailing list - as you've done here. (If I've got the wrong driver,
look in the MAINTAINERS file for the correct one.)

Another access point is the IRC channel. The netdev folks probably
hang out on #netdev on

Good luck with your presentation!


> Let me provide a brief description of what PRP is and what it does. PRP is
> used to provide hitless redundancy (zero recovery time). It does this by
> having two parallel and independent Ethernet networks. A device is
> connected to both these networks (LAN_A and LAN_B).
> Whenever a frame is sent by the device, it duplicates the frame and appends
> a trailer (Redundancy Control Trailer - RCT) which contains a sequence
> number, LAN_Id (LAN_A=0xA or LAN_B=0xB) and an LSDU_size (Link Service Data
> Unit, i.e, Ethernet payload size minus the RCT), and a PRP_Suffix (0x88FB)
> for a total of 6 octets.
> On reception, the sequence number is used to detect and discard the
> duplicates, removes the RCT, and forwards the frames to the upper layers
> for processing.
> The duplication on transmission, discarding and removal of RCT on reception
> is done by the kernel module which acts as the Link Redundancy Entity (LRE)
> as specified in the standard. The LRE is implemented as a virtual network
> interface using a kernel module. The transmission is done by defining the
> ndo_start_xmit function in the netdev_ops structure of my net_device.
> The *problem* I have is on reception, specifically with the *removal of the
> RCT*. The receive handler is registered on device creation using
> netdev_rx_handler_register and netdev_upper_dev_link.
> The receive handler  when it detects that the RCT is well-formed (correct
> PRP_Suffix, LSDU_size, LAN_ID for the NIC through which it was received),
> tries to strip the RCT before calling netif_rx() on the skb to forward it
> to the upper layers for processing.
> To strip the RCT, I call *skb_trim* as follows:
>        skb_trim(skb, skb->len - PRP_RCTLEN /* 6 */);
> as given in the HSR module.
> I have used skb_dump both before and after the call to skb_trim and
> verified that the length is being reduced and that the tailroom is
> increased by 6 bytes. The problem is that when I call skb_trim, the packet
> is not received by the upper layers. Without calling skb_trim, the packet
> is received correctly but the RCT is consumed by the applications which
> should not be the case.
> I used wireshark to inspect the frames at both the sender and the receiver
> side on the two physical devices and observed the following:
>    1. At the receiver side - The IP payload length is different for the
>    same frame received through LAN_A and LAN_B. The one received through LAN_B
>    has a payload length 6 greater  than that for LAN_A (*6 is the size of
>    the RCT*). On checking the ip_rcv_core function, invalid IP payload
>    length is one reason that the packet can be dropped.
>    2. At the sender side - The entire packet is the same minus the RCT's
>    LAN_ID field for a frame-pair. The IP payload length is correct when I
>    capture outgoing frames on the two physical devices.
> As mentioned at the top, the code is available at:
> Here is a brief overview of the code
>    1. The transmission is defined in *prp_tx.c* in *prp_send_skb* which is
>    called by *prp_dev_xmit* function defined in *prp_dev.c*
>    2. The code that sets up the two slave devices to forward frames
>    received to the virtual interface is defined in *prp_dev.c* in the
>    function *prp_port_setup*. It is called by *prp_add_ports*, which is
>    called by *prp_dev_finalize* which is called by the RTNL newlnk callback,
>    3. The receive handler that is defined in *prp_rx.c, *the function is
>    *prp_recv_frame.* It checks if the frame has a valid RCT, duplicates
>    discards, and then strips the RCT by calling *strip_rct *before calling
>    *prp_net_if* which removes the Ethernet header and calls *netif_rx*
> Hope you can help me find a solution to the removal of the RCT. Point out
> any mistakes that I am making. Thank you in advance :)

> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at

More information about the Kernelnewbies mailing list