Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hsr: enhance netlink socket interface to support PRP

Parallel Redundancy Protocol (PRP) is another redundancy protocol
introduced by IEC 63439 standard. It is similar to HSR in many
aspects:-

- Use a pair of Ethernet interfaces to created the PRP device
- Use a 6 byte redundancy protocol part (RCT, Redundancy Check
Trailer) similar to HSR Tag.
- Has Link Redundancy Entity (LRE) that works with RCT to implement
redundancy.

Key difference is that the protocol unit is a trailer instead of a
prefix as in HSR. That makes it inter-operable with tradition network
components such as bridges/switches which treat it as pad bytes,
whereas HSR nodes requires some kind of translators (Called redbox) to
talk to regular network devices. This features allows regular linux box
to be converted to a DAN-P box. DAN-P stands for Dual Attached Node - PRP
similar to DAN-H (Dual Attached Node - HSR).

Add a comment at the header/source code to explicitly state that the
driver files also handles PRP protocol as well.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Murali Karicheri and committed by
David S. Miller
8f4c0e01 1775da47

+100 -26
+1 -1
include/uapi/linux/hsr_netlink.h
··· 17 17 /* Generic Netlink HSR family definition 18 18 */ 19 19 20 - /* attributes */ 20 + /* attributes for HSR or PRP node */ 21 21 enum { 22 22 HSR_A_UNSPEC, 23 23 HSR_A_NODE_ADDR,
+11 -1
include/uapi/linux/if_link.h
··· 907 907 #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) 908 908 909 909 910 - /* HSR section */ 910 + /* HSR/PRP section, both uses same interface */ 911 + 912 + /* Different redundancy protocols for hsr device */ 913 + enum { 914 + HSR_PROTOCOL_HSR, 915 + HSR_PROTOCOL_PRP, 916 + HSR_PROTOCOL_MAX, 917 + }; 911 918 912 919 enum { 913 920 IFLA_HSR_UNSPEC, ··· 924 917 IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ 925 918 IFLA_HSR_SEQ_NR, 926 919 IFLA_HSR_VERSION, /* HSR version */ 920 + IFLA_HSR_PROTOCOL, /* Indicate different protocol than 921 + * HSR. For example PRP. 922 + */ 927 923 __IFLA_HSR_MAX, 928 924 }; 929 925
+24 -13
net/hsr/Kconfig
··· 4 4 # 5 5 6 6 config HSR 7 - tristate "High-availability Seamless Redundancy (HSR)" 7 + tristate "High-availability Seamless Redundancy (HSR & PRP)" 8 8 help 9 - If you say Y here, then your Linux box will be able to act as a 10 - DANH ("Doubly attached node implementing HSR"). For this to work, 11 - your Linux box needs (at least) two physical Ethernet interfaces, 12 - and it must be connected as a node in a ring network together with 13 - other HSR capable nodes. 9 + This enables IEC 62439 defined High-availability Seamless 10 + Redundancy (HSR) and Parallel Redundancy Protocol (PRP). 14 11 15 - All Ethernet frames sent over the hsr device will be sent in both 16 - directions on the ring (over both slave ports), giving a redundant, 17 - instant fail-over network. Each HSR node in the ring acts like a 18 - bridge for HSR frames, but filters frames that have been forwarded 19 - earlier. 12 + If you say Y here, then your Linux box will be able to act as a 13 + DANH ("Doubly attached node implementing HSR") or DANP ("Doubly 14 + attached node implementing PRP"). For this to work, your Linux box 15 + needs (at least) two physical Ethernet interfaces. 16 + 17 + For DANH, it must be connected as a node in a ring network together 18 + with other HSR capable nodes. All Ethernet frames sent over the HSR 19 + device will be sent in both directions on the ring (over both slave 20 + ports), giving a redundant, instant fail-over network. Each HSR node 21 + in the ring acts like a bridge for HSR frames, but filters frames 22 + that have been forwarded earlier. 23 + 24 + For DANP, it must be connected as a node connecting to two 25 + separate networks over the two slave interfaces. Like HSR, Ethernet 26 + frames sent over the PRP device will be sent to both networks giving 27 + a redundant, instant fail-over network. Unlike HSR, PRP networks 28 + can have Singly Attached Nodes (SAN) such as PC, printer, bridges 29 + etc and will be able to communicate with DANP nodes. 20 30 21 31 This code is a "best effort" to comply with the HSR standard as 22 32 described in IEC 62439-3:2010 (HSRv0) and IEC 62439-3:2012 (HSRv1), 23 - but no compliancy tests have been made. Use iproute2 to select 24 - the version you desire. 33 + and PRP standard described in IEC 62439-4:2012 (PRP), but no 34 + compliancy tests have been made. Use iproute2 to select the protocol 35 + you would like to use. 25 36 26 37 You need to perform any and all necessary tests yourself before 27 38 relying on this code in a safety critical system!
+1 -1
net/hsr/hsr_debugfs.c
··· 1 1 /* 2 - * hsr_debugfs code 2 + * debugfs code for HSR & PRP 3 3 * Copyright (C) 2019 Texas Instruments Incorporated 4 4 * 5 5 * Author(s):
+5 -2
net/hsr/hsr_device.c
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 - * 7 6 * This file contains device methods for creating, using and destroying 8 - * virtual HSR devices. 7 + * virtual HSR or PRP devices. 9 8 */ 10 9 11 10 #include <linux/netdevice.h> ··· 425 426 spin_lock_init(&hsr->list_lock); 426 427 427 428 ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); 429 + 430 + /* currently PRP is not supported */ 431 + if (protocol_version == PRP_V1) 432 + return -EPROTONOSUPPORT; 428 433 429 434 /* Make sure we recognize frames from ourselves in hsr_rcv() */ 430 435 res = hsr_create_self_node(hsr, hsr_dev->dev_addr,
+2
net/hsr/hsr_device.h
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * include file for HSR and PRP. 6 8 */ 7 9 8 10 #ifndef __HSR_DEVICE_H
+2
net/hsr/hsr_forward.c
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * Frame router for HSR and PRP. 6 8 */ 7 9 8 10 #include "hsr_forward.h"
+2
net/hsr/hsr_forward.h
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * include file for HSR and PRP. 6 8 */ 7 9 8 10 #ifndef __HSR_FORWARD_H
+1
net/hsr/hsr_framereg.c
··· 8 8 * interface. A frame is identified by its source MAC address and its HSR 9 9 * sequence number. This code keeps track of senders and their sequence numbers 10 10 * to allow filtering of duplicate frames, and to detect HSR ring errors. 11 + * Same code handles filtering of duplicates for PRP as well. 11 12 */ 12 13 13 14 #include <linux/if_ether.h>
+2
net/hsr/hsr_framereg.h
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * include file for HSR and PRP. 6 8 */ 7 9 8 10 #ifndef __HSR_FRAMEREG_H
+2
net/hsr/hsr_main.c
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * Event handling for HSR and PRP devices. 6 8 */ 7 9 8 10 #include <linux/netdevice.h>
+10 -1
net/hsr/hsr_main.h
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * include file for HSR and PRP. 6 8 */ 7 9 8 10 #ifndef __HSR_PRIVATE_H ··· 133 131 enum hsr_port_type type; 134 132 }; 135 133 134 + /* used by driver internally to differentiate various protocols */ 135 + enum hsr_version { 136 + HSR_V0 = 0, 137 + HSR_V1, 138 + PRP_V1, 139 + }; 140 + 136 141 struct hsr_priv { 137 142 struct rcu_head rcu_head; 138 143 struct list_head ports; ··· 150 141 int announce_count; 151 142 u16 sequence_nr; 152 143 u16 sup_sequence_nr; /* For HSRv1 separate seq_nr for supervision */ 153 - u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ 144 + enum hsr_version prot_version; /* Indicate if HSRv0, HSRv1 or PRPv1 */ 154 145 spinlock_t seqnr_lock; /* locking for sequence_nr */ 155 146 spinlock_t list_lock; /* locking for node list */ 156 147 unsigned char sup_multicast_addr[ETH_ALEN];
+31 -7
net/hsr/hsr_netlink.c
··· 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 6 * 7 - * Routines for handling Netlink messages for HSR. 7 + * Routines for handling Netlink messages for HSR and PRP. 8 8 */ 9 9 10 10 #include "hsr_netlink.h" ··· 22 22 [IFLA_HSR_VERSION] = { .type = NLA_U8 }, 23 23 [IFLA_HSR_SUPERVISION_ADDR] = { .len = ETH_ALEN }, 24 24 [IFLA_HSR_SEQ_NR] = { .type = NLA_U16 }, 25 + [IFLA_HSR_PROTOCOL] = { .type = NLA_U8 }, 25 26 }; 26 27 27 28 /* Here, it seems a netdevice has already been allocated for us, and the ··· 32 31 struct nlattr *tb[], struct nlattr *data[], 33 32 struct netlink_ext_ack *extack) 34 33 { 34 + enum hsr_version proto_version; 35 + unsigned char multicast_spec; 36 + u8 proto = HSR_PROTOCOL_HSR; 35 37 struct net_device *link[2]; 36 - unsigned char multicast_spec, hsr_version; 37 38 38 39 if (!data) { 39 40 NL_SET_ERR_MSG_MOD(extack, "No slave devices specified"); ··· 72 69 else 73 70 multicast_spec = nla_get_u8(data[IFLA_HSR_MULTICAST_SPEC]); 74 71 72 + if (data[IFLA_HSR_PROTOCOL]) 73 + proto = nla_get_u8(data[IFLA_HSR_PROTOCOL]); 74 + 75 + if (proto >= HSR_PROTOCOL_MAX) { 76 + NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol\n"); 77 + return -EINVAL; 78 + } 79 + 75 80 if (!data[IFLA_HSR_VERSION]) { 76 - hsr_version = 0; 81 + proto_version = HSR_V0; 77 82 } else { 78 - hsr_version = nla_get_u8(data[IFLA_HSR_VERSION]); 79 - if (hsr_version > 1) { 83 + if (proto == HSR_PROTOCOL_PRP) { 84 + NL_SET_ERR_MSG_MOD(extack, "PRP version unsupported\n"); 85 + return -EINVAL; 86 + } 87 + 88 + proto_version = nla_get_u8(data[IFLA_HSR_VERSION]); 89 + if (proto_version > HSR_V1) { 80 90 NL_SET_ERR_MSG_MOD(extack, 81 - "Only versions 0..1 are supported"); 91 + "Only HSR version 0/1 supported\n"); 82 92 return -EINVAL; 83 93 } 84 94 } 85 95 86 - return hsr_dev_finalize(dev, link, multicast_spec, hsr_version, extack); 96 + if (proto == HSR_PROTOCOL_PRP) 97 + proto_version = PRP_V1; 98 + 99 + return hsr_dev_finalize(dev, link, multicast_spec, proto_version, extack); 87 100 } 88 101 89 102 static void hsr_dellink(struct net_device *dev, struct list_head *head) ··· 121 102 static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev) 122 103 { 123 104 struct hsr_priv *hsr = netdev_priv(dev); 105 + u8 proto = HSR_PROTOCOL_HSR; 124 106 struct hsr_port *port; 125 107 126 108 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A); ··· 139 119 if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN, 140 120 hsr->sup_multicast_addr) || 141 121 nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr->sequence_nr)) 122 + goto nla_put_failure; 123 + if (hsr->prot_version == PRP_V1) 124 + proto = HSR_PROTOCOL_PRP; 125 + if (nla_put_u8(skb, IFLA_HSR_PROTOCOL, proto)) 142 126 goto nla_put_failure; 143 127 144 128 return 0;
+2
net/hsr/hsr_netlink.h
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * include file for HSR and PRP. 6 8 */ 7 9 8 10 #ifndef __HSR_NETLINK_H
+2
net/hsr/hsr_slave.c
··· 3 3 * 4 4 * Author(s): 5 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 + * 7 + * Frame handler other utility functions for HSR and PRP. 6 8 */ 7 9 8 10 #include "hsr_slave.h"
+2
net/hsr/hsr_slave.h
··· 2 2 /* Copyright 2011-2014 Autronica Fire and Security AS 3 3 * 4 4 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 5 + * 6 + * include file for HSR and PRP. 5 7 */ 6 8 7 9 #ifndef __HSR_SLAVE_H