net: prp: add packet handling support

DAN-P (Dual Attached Nodes PRP) nodes are expected to receive
traditional IP packets as well as PRP (Parallel Redundancy
Protocol) tagged (trailer) packets. PRP trailer is 6 bytes
of PRP protocol unit called RCT, Redundancy Control Trailer
(RCT) similar to HSR tag. PRP network can have traditional
devices such as bridges/switches or PC attached to it and
should be able to communicate. Regular Ethernet devices treat
the RCT as pads.  This patch adds logic to format L2 frames
from network stack to add a trailer (RCT) and send it as
duplicates over the slave interfaces when the protocol is
PRP as per IEC 62439-3. At the ingress, it strips the trailer,
do duplicate detection and rejection and forward a stripped
frame up the network stack. PRP device should accept frames
from Singly Attached Nodes (SAN) and thus the driver mark
the link where the frame came from in the node table.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Murali Karicheri
2020-07-22 10:40:21 -04:00
committed by David S. Miller
parent fa4dc89531
commit 451d8123f8
8 changed files with 433 additions and 88 deletions

View File

@@ -16,12 +16,22 @@
#include "hsr_forward.h"
#include "hsr_framereg.h"
bool hsr_invalid_dan_ingress_frame(__be16 protocol)
{
return (protocol != htons(ETH_P_PRP) && protocol != htons(ETH_P_HSR));
}
static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
struct hsr_port *port;
struct hsr_priv *hsr;
__be16 protocol;
/* Packets from dev_loopback_xmit() do not have L2 header, bail out */
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
return RX_HANDLER_PASS;
if (!skb_mac_header_was_set(skb)) {
WARN_ONCE(1, "%s: skb invalid", __func__);
return RX_HANDLER_PASS;
@@ -30,6 +40,7 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)
port = hsr_port_get_rcu(skb->dev);
if (!port)
goto finish_pass;
hsr = port->hsr;
if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) {
/* Directly kill frames sent by ourselves */
@@ -37,12 +48,23 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)
goto finish_consume;
}
/* For HSR, only tagged frames are expected, but for PRP
* there could be non tagged frames as well from Single
* attached nodes (SANs).
*/
protocol = eth_hdr(skb)->h_proto;
if (protocol != htons(ETH_P_PRP) && protocol != htons(ETH_P_HSR))
if (hsr->proto_ops->invalid_dan_ingress_frame &&
hsr->proto_ops->invalid_dan_ingress_frame(protocol))
goto finish_pass;
skb_push(skb, ETH_HLEN);
if (skb_mac_header(skb) != skb->data) {
WARN_ONCE(1, "%s:%d: Malformed frame at source port %s)\n",
__func__, __LINE__, port->dev->name);
goto finish_consume;
}
hsr_forward_skb(skb, port);
finish_consume: