lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sun, 2 Jul 2023 14:07:28 +0530
From: Abhiram V <abhi.raa.man.v@...il.com>
To: netdev@...r.kernel.org
Subject: Custom Kernel Module for PRP (https://github.com/ramv33/prp) -
 problem with removal of RCT using skb_trim

Hi

I am implementing the Parallel Redundancy Protocol (PRP, IEC standard
62439-3) as a kernel module for a project of mine. The code for the
module can be found at: https://github.com/ramv33/prp. I have used the
code for the HSR module which implements PRP, as a reference for my
implementation since I have no prior experience with kernel
programming. Even though a lot of the design is different, I have used
the module as a reference for how to implement PRP. I asked on the
kernelnewbies mailing list and was told to come here for help.

The module is nearly complete. 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 (as given in the HSR module):

             skb_trim(skb, skb->len - PRP_RCTLEN /* 6 */);

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:
https://github.com/ramv33/prp. 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() from the RTNL newlink.

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 :)

Abhiram

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ