Skip to contentSkip to conversation

net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)

PATCH Superseded Arvid Brodin 2 participants 4 messages Jun 24, 2013 – Jun 25, 2013

Subsystems (3)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)

High-availability Seamless Redundancy ("HSR") provides instant failover redundancy for Ethernet networks. It requires a special network topology where all nodes are connected in a ring (each node having two physical network interfaces). It is suited for applications that demand high availability and very short reaction time.

HSR acts on the Ethernet layer, using a registered Ethernet protocol type to send special HSR frames in both directions over the ring. The driver creates virtual network interfaces that can be used just like any ordinary Linux network interface, for IP/TCP/UDP traffic etc. All nodes in the network ring must be HSR capable.

This code is a "best effort" to comply with the HSR standard as described in IEC 62439-3:2010 (HSRv0).

---

This is a patch against net-next (2013-06-20).

The code has been statically analysed using sparse (no problems detected).

kmemleak has been used to detect memory leaks (no known leaks exist).

The code passes checkpatch.pl with the option --max-line-length=83, except for CamelCase warnings. CamelCase is used in the IEC standard to describe field names, and these names have been used in the code. This usage is intentional.

The code has been tested extensively on rings of up to 32 avr32-based nodes. Less intense testing has included an x86_64 (SMP) system, and running HSR over a USB-to-Ethernet device.

Earlier RFC:s:
RFC v1: http://www.spinics.net/lists/netdev/msg192817.html
RFC v2: http://www.spinics.net/lists/netdev/msg203397.html
RFC v3: http://www.spinics.net/lists/netdev/msg207816.html
RFC v4: http://www.spinics.net/lists/netdev/msg213309.html

Thanks to Stephen Hemminger, Joe Perches, and others for their comments on these RFC:s.

 include/uapi/linux/if_ether.h |   1 +
 include/uapi/linux/if_link.h  |  13 +
 net/Kconfig                   |   1 +
 net/Makefile                  |   1 +
 net/hsr/Kconfig               |  27 ++
 net/hsr/Makefile              |   7 +
 net/hsr/hsr_device.c          | 592 ++++++++++++++++++++++++++++++++++++++++++
 net/hsr/hsr_device.h          |  30 +++
 net/hsr/hsr_framereg.c        | 505 +++++++++++++++++++++++++++++++++++
 net/hsr/hsr_framereg.h        |  54 ++++
 net/hsr/hsr_main.c            | 457 ++++++++++++++++++++++++++++++++
 net/hsr/hsr_main.h            | 167 ++++++++++++
 net/hsr/hsr_netlink.c         | 458 ++++++++++++++++++++++++++++++++
 net/hsr/hsr_netlink.h         |  74 ++++++
 14 files changed, 2387 insertions(+)
 create mode 100644 net/hsr/Kconfig
 create mode 100644 net/hsr/Makefile
 create mode 100644 net/hsr/hsr_device.c
 create mode 100644 net/hsr/hsr_device.h
 create mode 100644 net/hsr/hsr_framereg.c
 create mode 100644 net/hsr/hsr_framereg.h
 create mode 100644 net/hsr/hsr_main.c
 create mode 100644 net/hsr/hsr_main.h
 create mode 100644 net/hsr/hsr_netlink.c
 create mode 100644 net/hsr/hsr_netlink.h
include/uapi/linux/if_ether.h +1 -0
index ade07f1..2ce0f6a 100644
@@ -85,6 +85,7 @@
 #define ETH_P_8021AH	0x88E7          /* 802.1ah Backbone Service Tag */
 #define ETH_P_MVRP	0x88F5          /* 802.1Q MVRP                  */
 #define ETH_P_1588	0x88F7		/* IEEE 1588 Timesync */
+#define ETH_P_PRP	0x88FB		/* IEC 62439-3 PRP/HSRv0	*/
 #define ETH_P_FCOE	0x8906		/* Fibre Channel over Ethernet  */
 #define ETH_P_TDLS	0x890D          /* TDLS */
 #define ETH_P_FIP	0x8914		/* FCoE Initialization Protocol */
include/uapi/linux/if_link.h +13 -0
index 03f6170..5b164b4 100644
@@ -467,4 +467,17 @@ enum {
 
 #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
 
+
+/* HSR section */
+
+enum {
+	IFLA_HSR_UNSPEC,
+	IFLA_HSR_SLAVE1,
+	IFLA_HSR_SLAVE2,
+	IFLA_HSR_MULTICAST_SPEC,
+	__IFLA_HSR_MAX,
+};
+
+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+
 #endif /* _UAPI_LINUX_IF_LINK_H */
net/Kconfig +1 -0
index 51da839..e0c621a 100644
@@ -219,6 +219,7 @@ source "net/openvswitch/Kconfig"
 source "net/vmw_vsock/Kconfig"
 source "net/netlink/Kconfig"
 source "net/mpls/Kconfig"
+source "net/hsr/Kconfig"
 
 config RPS
 	boolean
net/Makefile +1 -0
index 9492e8c..8fa2f91 100644
@@ -71,3 +71,4 @@ obj-$(CONFIG_NFC)		+= nfc/
 obj-$(CONFIG_OPENVSWITCH)	+= openvswitch/
 obj-$(CONFIG_VSOCKETS)	+= vmw_vsock/
 obj-$(CONFIG_NET_MPLS_GSO)	+= mpls/
+obj-$(CONFIG_HSR)		+= hsr/
net/hsr/Kconfig new file +27 -0
new file mode 100644
index 0000000..0d3d709
@@ -0,0 +1,27 @@
+#
+# IEC 62439-3 High-availability Seamless Redundancy
+#
+
+config HSR
+	tristate "High-availability Seamless Redundancy (HSR)"
+	---help---
+	  If you say Y here, then your Linux box will be able to act as a
+	  DANH ("Doubly attached node implementing HSR"). For this to work,
+	  your Linux box needs (at least) two physical Ethernet interfaces,
+	  and it must be connected as a node in a ring network together with
+	  other HSR capable nodes.
+
+	  All Ethernet frames sent over the hsr device will be sent in both
+	  directions on the ring (over both slave ports), giving a redundant,
+	  instant fail-over network. Each HSR node in the ring acts like a
+	  bridge for HSR frames, but filters frames that have been forwarded
+	  earlier.
+
+	  This code is a "best effort" to comply with the HSR standard as
+	  described in IEC 62439-3:2010 (HSRv0), but no compliancy tests have
+	  been made.
+
+	  You need to perform any and all necessary tests yourself before
+	  relying on this code in a safety critical system!
+
+	  If unsure, say N.
net/hsr/Makefile new file +7 -0
new file mode 100644
index 0000000..b68359f
@@ -0,0 +1,7 @@
+#
+# Makefile for HSR
+#
+
+obj-$(CONFIG_HSR)	+= hsr.o
+
+hsr-y			:= hsr_main.o hsr_framereg.o hsr_device.o hsr_netlink.o
net/hsr/hsr_device.c new file +592 -0

592 lines not on this page · raw message

net/hsr/hsr_device.h new file +30 -0
new file mode 100644
index 0000000..549436a
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2011-2013 Autronica Fire and Security AS
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * Author(s):
+ *	2011-2013 Arvid Brodin, [email protected]
+ */
+
+#ifndef __HSR_DEVICE_H
+#define __HSR_DEVICE_H
+
+#include <linux/netdevice.h>
+#include "hsr_main.h"
+
+void hsr_dev_setup(struct net_device *dev);
+int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
+		     unsigned char multicast_spec);
+void hsr_set_operstate(struct net_device *hsr_dev, struct net_device *slave1,
+		       struct net_device *slave2);
+void hsr_set_carrier(struct net_device *hsr_dev, struct net_device *slave1,
+		     struct net_device *slave2);
+void hsr_check_announce(struct net_device *hsr_dev, int old_operstate);
+bool is_hsr_master(struct net_device *dev);
+int hsr_get_max_mtu(struct hsr_priv *hsr_priv);
+
+#endif /* __HSR_DEVICE_H */
net/hsr/hsr_framereg.c new file +505 -0

505 lines not on this page · raw message

net/hsr/hsr_framereg.h new file +54 -0

54 lines not on this page · raw message

net/hsr/hsr_main.c new file +457 -0

457 lines not on this page · raw message

net/hsr/hsr_main.h new file +167 -0

167 lines not on this page · raw message

net/hsr/hsr_netlink.c new file +458 -0

458 lines not on this page · raw message

net/hsr/hsr_netlink.h new file +74 -0

74 lines not on this page · raw message

--
1.8.1.5

Signature · 2 lines
Arvid Brodin | Consultant (Linux)
XDIN AB | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden | xdin.com
#1 lore raw
Quoted 5 lines · Arvid Brodin

High-availability Seamless Redundancy ("HSR") provides instant failover redundancy for Ethernet networks. It requires a special network topology where all nodes are connected in a ring (each node having two physical network interfaces). It is suited for applications that demand high availability and very short reaction time.

trivia:

You should probably use checkpatch.pl --strict for files in net. It will suggest aligning arguments in the more common net style.

Quoted 4 lines
 net/hsr/hsr_device.h          |  30 +++
 net/hsr/hsr_framereg.h        |  54 ++++
 net/hsr/hsr_main.h            | 167 ++++++++++++
 net/hsr/hsr_netlink.h         |  74 ++++++

Maybe some of these .h files should go into include/net/...

A future version of checkpatch may read all the include files and exempt any CamelCase defines/typedefs/functions from CamelCase warnings.

net/hsr/hsr_device.c line 220

Quoted 2 lines
net/hsr/hsr_device.c new file +2 -0
+	if ((skb->protocol != htons(ETH_P_PRP)) ||
+			(hsr_ethhdr->ethhdr.h_proto != htons(ETH_P_PRP))) {

Please align indents after the appropriate open parenthesis.

	if (foo ||
	    bar) {

net/hsr/hsr_device.c line 455

Quoted 10 lines
net/hsr/hsr_device.c new file +10 -0
+bool is_hsr_master(struct net_device *dev)
+{
+	if (!dev) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}
+	if (!dev->netdev_ops) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}

probably better to combine and give a textual reason

net/hsr/hsr_main.h

Quoted 1 line
net/hsr/hsr_main.h +0 -0

[]

net/hsr/hsr_main.h line 26

Quoted 3 lines
net/hsr/hsr_main.h +3 -0
+#define HSR_LIFE_CHECK_INTERVAL		 2000 /* ms */
+#define HSR_NODE_FORGET_TIME		60000 /* ms */
+#define HSR_ANNOUNCE_INTERVAL		  100 /* ms */

Odd alignment

net/hsr/hsr_netlink.c

Quoted 1 line
net/hsr/hsr_netlink.c +0 -0

[]

net/hsr/hsr_netlink.c line 81

Quoted 6 lines
net/hsr/hsr_netlink.c +6 -0
+static const struct nla_policy hsr_genl_policy[HSR_A_MAX + 1] = {
+	[HSR_A_NODE_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[HSR_A_NODE_ADDR_B] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[HSR_A_IFINDEX] = { .type = NLA_U32 },
+	[HSR_A_IF1_AGE] = { .type = NLA_U32 }, /* Actually signed 32-bit */
+	[HSR_A_IF2_AGE] = { .type = NLA_U32 }, /* Actually signed 32-bit */

Why not use NLA_S32?

#2 lore raw
Quoted 11 lines · Joe Perches
Quoted 5 lines · Arvid Brodin

High-availability Seamless Redundancy ("HSR") provides instant failover redundancy for Ethernet networks. It requires a special network topology where all nodes are connected in a ring (each node having two physical network interfaces). It is suited for applications that demand high availability and very short reaction time.

trivia:

You should probably use checkpatch.pl --strict for files in net. It will suggest aligning arguments in the more common net style.

Does this mean I should also remove spaces after casts (IMO this would reduce readability somewhat)?

Quoted 10 lines
Quoted 4 lines
 net/hsr/hsr_device.h          |  30 +++
 net/hsr/hsr_framereg.h        |  54 ++++
 net/hsr/hsr_main.h            | 167 ++++++++++++
 net/hsr/hsr_netlink.h         |  74 ++++++

Maybe some of these .h files should go into include/net/...

A future version of checkpatch may read all the include files and exempt any CamelCase defines/typedefs/functions from CamelCase warnings.

I cannot judge if these files should go into include/net/ or not. Where can I get a final say on this?

Some of the definitions in hsr_netlink.h are needed by userspace tools that want to listen for ring errors etc from the HSR driver, so it would be a good thing if this file could be part of the kernel headers install. How can I accomplish this?

Quoted 8 lines

net/hsr/hsr_device.c line 220

Quoted 2 lines
net/hsr/hsr_device.c new file +2 -0
+	if ((skb->protocol != htons(ETH_P_PRP)) ||
+			(hsr_ethhdr->ethhdr.h_proto != htons(ETH_P_PRP))) {

Please align indents after the appropriate open parenthesis.

	if (foo ||
	    bar) {
Quoted 12 lines

net/hsr/hsr_device.c line 455

Quoted 10 lines
net/hsr/hsr_device.c new file +10 -0
+bool is_hsr_master(struct net_device *dev)
+{
+	if (!dev) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}
+	if (!dev->netdev_ops) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}

probably better to combine and give a textual reason

Or perhaps better to remove them altogether? I guess you could call them debug statements...

Quoted 7 lines

net/hsr/hsr_main.h

Quoted 1 line
net/hsr/hsr_main.h +0 -0

[]

net/hsr/hsr_main.h line 26

Quoted 3 lines
net/hsr/hsr_main.h +3 -0
+#define HSR_LIFE_CHECK_INTERVAL		 2000 /* ms */
+#define HSR_NODE_FORGET_TIME		60000 /* ms */
+#define HSR_ANNOUNCE_INTERVAL		  100 /* ms */

Odd alignment

Only because of the plus chars added by diff. :)

Quoted 10 lines

net/hsr/hsr_netlink.c

Quoted 1 line
net/hsr/hsr_netlink.c +0 -0

[]

net/hsr/hsr_netlink.c line 81

Quoted 6 lines
net/hsr/hsr_netlink.c +6 -0
+static const struct nla_policy hsr_genl_policy[HSR_A_MAX + 1] = {
+	[HSR_A_NODE_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[HSR_A_NODE_ADDR_B] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[HSR_A_IFINDEX] = { .type = NLA_U32 },
+	[HSR_A_IF1_AGE] = { .type = NLA_U32 }, /* Actually signed 32-bit */
+	[HSR_A_IF2_AGE] = { .type = NLA_U32 }, /* Actually signed 32-bit */

Why not use NLA_S32?

We need the code to work on older kernels as well, where NLA_S32 does not exist. Actually, these values never become negative with the current code. During development we returned a negative value to mean "out of range" but we have switched to INT_MAX instead. So perhaps it's best just to remove these comments?

Signature · 3 lines
Arvid Brodin | Consultant (Linux)
T: +46-8-56254286 | M: +46-70-9714286 | [email protected]
XDIN AB | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden | xdin.com
#3 lore raw
Quoted 8 lines · Arvid Brodin
Quoted 7 lines · Joe Perches
Quoted 5 lines · Arvid Brodin

High-availability Seamless Redundancy ("HSR") provides instant failover redundancy for Ethernet networks. It requires a special network topology where all nodes are connected in a ring (each node having two physical network interfaces). It is suited for applications that demand high availability and very short reaction time.

Quoted 7 lines
Quoted 4 lines

trivia:

You should probably use checkpatch.pl --strict for files in net. It will suggest aligning arguments in the more common net style.

Does this mean I should also remove spaces after casts (IMO this would reduce readability somewhat)?

No. Don't do that adjustment if you don't want to. checkpatch is just a stupid little tool, it's not dicta. Weigh its recommendations according to your taste.

Quoted 2 lines

I cannot judge if these files should go into include/net/ or not. Where can I get a final say on this?

David Miller is the most likely arbiter.

Quoted 3 lines

Some of the definitions in hsr_netlink.h are needed by userspace tools that want to listen for ring errors etc from the HSR driver, so it would be a good thing if this file could be part of the kernel headers install. How can I accomplish this?

Maybe all those definitions are the CamelCase vars and should go into a uapi #include?

include/uapi/linux/hsr_netlink.h should work.

Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
net/hsr/hsr_device.c new file +4 -0
+bool is_hsr_master(struct net_device *dev)
+{
+	if (!dev) {
+		WARN_ON_ONCE(1);
Quoted 8 lines

net/hsr/hsr_device.c line 455

Quoted 6 lines
net/hsr/hsr_device.c new file +6 -0
+		return 0;
+	}
+	if (!dev->netdev_ops) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}

probably better to combine and give a textual reason

Quoted 1 line

Or perhaps better to remove them altogether? I guess you could call them debug statements...

Better still if you know it's not possible anymore.

Quoted 9 lines
Quoted 7 lines

net/hsr/hsr_main.h

Quoted 1 line
net/hsr/hsr_main.h +0 -0

[]

net/hsr/hsr_main.h line 26

Quoted 3 lines
net/hsr/hsr_main.h +3 -0
+#define HSR_LIFE_CHECK_INTERVAL		 2000 /* ms */
+#define HSR_NODE_FORGET_TIME		60000 /* ms */
+#define HSR_ANNOUNCE_INTERVAL		  100 /* ms */

Odd alignment

Only because of the plus chars added by diff. :)

Not really.
#defines don't generally try to right align numbers. It's up to you though.

Quoted 11 lines
Quoted 10 lines

net/hsr/hsr_netlink.c

Quoted 1 line
net/hsr/hsr_netlink.c +0 -0

[]

net/hsr/hsr_netlink.c line 81

Quoted 6 lines
net/hsr/hsr_netlink.c +6 -0
+static const struct nla_policy hsr_genl_policy[HSR_A_MAX + 1] = {
+	[HSR_A_NODE_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[HSR_A_NODE_ADDR_B] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[HSR_A_IFINDEX] = { .type = NLA_U32 },
+	[HSR_A_IF1_AGE] = { .type = NLA_U32 }, /* Actually signed 32-bit */
+	[HSR_A_IF2_AGE] = { .type = NLA_U32 }, /* Actually signed 32-bit */

Why not use NLA_S32?

Quoted 1 line

We need the code to work on older kernels as well, where NLA_S32 does not exist.

Not if it's newly going into 3.11 and higher.

Quoted 4 lines

Actually,
these values never become negative with the current code. During development we returned a negative value to mean "out of range" but we have switched to INT_MAX instead. So perhaps it's best just to remove these comments?

Probably. I thought it was unusual.

cheers, Joe