net/hsr: Added support for HSR v1
Subsystems (3)
PATCH 1/1 net/hsr: Added support for HSR v1
This patch adds support for the newer version 1 of the HSR networking standard. Version 0 is still default and the new version has to be selected via iproute2.
Main changes are in the supervision frame handling and its ethertype field.
--- include/uapi/linux/if_ether.h | 1 + include/uapi/linux/if_link.h | 1 + net/hsr/Kconfig | 5 +-- net/hsr/hsr_device.c | 80 +++++++++++++++++++++++++------------------ net/hsr/hsr_device.h | 2 +- net/hsr/hsr_forward.c | 43 +++++++++++++++++------ net/hsr/hsr_framereg.c | 30 ++++++++++------ net/hsr/hsr_main.h | 13 ++++++- net/hsr/hsr_netlink.c | 10 ++++-- net/hsr/hsr_slave.c | 4 ++- 10 files changed, 126 insertions(+), 63 deletions(-)
include/uapi/linux/if_ether.h +1 -0
@@ -92,6 +92,7 @@#define ETH_P_TDLS 0x890D/* TDLS */ #define ETH_P_FIP 0x8914/* FCoE Initialization Protocol */ #define ETH_P_80221 0x8917/* IEEE 802.21 Media Independent Handover Protocol */ +#define ETH_P_HSR 0x892F/* IEC 62439-3 HSRv1 */ #define ETH_P_LOOPBACK 0x9000/* Ethernet loopback packet, per IEEE 802.3 */ #define ETH_P_QINQ1 0x9100/* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_QINQ2 0x9200/* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
include/uapi/linux/if_link.h +1 -0
@@ -773,6 +773,7 @@ enum {IFLA_HSR_SLAVE1 ,IFLA_HSR_SLAVE2 ,IFLA_HSR_MULTICAST_SPEC ,/* Last byte of supervision addr */ +IFLA_HSR_VERSION ,/* HSR version */ IFLA_HSR_SUPERVISION_ADDR ,/* Supervision frame multicast addr */ IFLA_HSR_SEQ_NR , __IFLA_HSR_MAX,
net/hsr/Kconfig +3 -2
@@ -18,8 +18,9 @@ config HSR 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. + described in IEC 62439-3:2010 (HSRv0) and IEC 62439-3:2012 (HSRv1), + but no compliancy tests have been made. Use iproute2 to select + the version you desire. You need to perform any and all necessary tests yourself before relying on this code in a safety critical system!
net/hsr/hsr_device.c +46 -34
154 lines not on this page · raw message
net/hsr/hsr_device.h +1 -1
@@ -17,7 +17,7 @@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); +unsigned char multicast_spec,u8 protocol_version);void hsr_check_carrier_and_operstate (struct hsr_priv *hsr);bool is_hsr_master (struct net_device *dev);int hsr_get_max_mtu (struct hsr_priv *hsr);
net/hsr/hsr_forward.c +32 -11
81 lines not on this page · raw message
net/hsr/hsr_framereg.c +19 -11
@@ -177,17 +177,17 @@ struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,return node; } -if (!is_sup) -return NULL ;/* Only supervision frame may create node entry */ +/* Everyone may create a node entry, connected node to a HSR device. */ -if (ethhdr->h_proto ==htons (ETH_P_PRP )) { +if (ethhdr->h_proto ==htons (ETH_P_PRP ) + || ethhdr->h_proto ==htons (ETH_P_HSR )) {/* Use the existing sequence_nr from the tag as starting point * for filtering duplicate frames. */ seq_out =hsr_get_skb_sequence_nr (skb) -1 ; }else {WARN_ONCE (1 ,"%s: Non-HSR frame\n" , __func__); - seq_out =0 ; + seq_out =HSR_SEQNR_START ; }return hsr_add_node (node_db, ethhdr->h_source, seq_out);
@@ -200,17 +200,25 @@ struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,void hsr_handle_sup_frame (struct sk_buff *skb,struct hsr_node *node_curr,struct hsr_port *port_rcv) { +struct ethhdr *ethhdr;struct hsr_node *node_real;struct hsr_sup_payload *hsr_sp;struct list_head *node_db;int i; -skb_pull (skb,sizeof (struct hsr_ethhdr_sp )); - hsr_sp = (struct hsr_sup_payload *) skb->data; + ethhdr = (struct ethhdr *)skb_mac_header (skb); -if (ether_addr_equal (eth_hdr (skb)->h_source, hsr_sp->MacAddressA)) -/* Not sent from MacAddressB of a PICS_SUBS capable node */ - goto done; +/* Leave the ethernet header. */ +skb_pull (skb,sizeof (struct ethhdr )); + +/* And leave the HSR tag. */ +if (ethhdr->h_proto ==htons (ETH_P_HSR )) +skb_pull (skb,sizeof (struct hsr_tag )); + +/* And leave the HSR sup tag. */ +skb_pull (skb,sizeof (struct hsr_sup_tag )); + + hsr_sp = (struct hsr_sup_payload *) skb->data;/* Merge node_curr (registered on MacAddressB) into node_real */ node_db = &port_rcv->hsr->node_db;
@@ -225,7 +233,7 @@ void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr,/* Node has already been merged */ goto done; -ether_addr_copy (node_real->MacAddressB,eth_hdr (skb)->h_source); +ether_addr_copy (node_real->MacAddressB, ethhdr->h_source);for (i =0 ; i <HSR_PT_PORTS ; i++) {if (!node_curr->time_in_stale[i] &&time_after (node_curr->time_in[i], node_real->time_in[i])) {
@@ -241,7 +249,7 @@ void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr,kfree_rcu (node_curr, rcu_head); done: -skb_push (skb,sizeof (struct hsr_ethhdr_sp )); +skb_push (skb,sizeof (struct hsrv1_ethhdr_sp )); }
net/hsr/hsr_main.h +12 -1
@@ -30,6 +30,7 @@*/ #define MAX_SLAVE_DIFF 3000/* ms */ #define HSR_SEQNR_START (USHRT_MAX - 1024) +#define HSR_SUP_SEQNR_START (HSR_SEQNR_START / 2)/* How often shall we check for broken ring and remove node entries older than
@@ -58,6 +59,8 @@ struct hsr_tag {#define HSR_HLEN 6 +#define HSR_V1_SUP_LSDUSIZE 52 +/* The helper functions below assumes that 'path' occupies the 4 most * significant bits of the 16-bit field shared by 'path' and 'LSDU_size' (or * equivalently, the 4 most significant bits of HSR tag byte 14).
@@ -131,8 +134,14 @@ static inline void set_hsr_stag_HSR_Ver(struct hsr_sup_tag *hst, u16 HSR_Ver)set_hsr_tag_LSDU_size ((struct hsr_tag *) hst, HSR_Ver); } -struct hsr_ethhdr_sp { +struct hsrv0_ethhdr_sp { +struct ethhdr ethhdr; +struct hsr_sup_tag hsr_sup; +} __packed; + +struct hsrv1_ethhdr_sp {struct ethhdr ethhdr; +struct hsr_tag hsr;struct hsr_sup_tag hsr_sup; } __packed;
@@ -162,6 +171,8 @@ struct hsr_priv {struct timer_list prune_timer;int announce_count;u16 sequence_nr; +u16 sup_sequence_nr;/* For HSRv1 separate seq_nr for supervision */ +u8 protVersion;/* Indicate if HSRv0 or HSRv1. */ spinlock_t seqnr_lock;/* locking for sequence_nr */ unsigned char sup_multicast_addr[ETH_ALEN ]; };
net/hsr/hsr_netlink.c +8 -2
@@ -23,6 +23,7 @@ static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = { [IFLA_HSR_SLAVE1] = { .type = NLA_U32 }, [IFLA_HSR_SLAVE2] = { .type = NLA_U32 }, [IFLA_HSR_MULTICAST_SPEC] = { .type = NLA_U8 }, + [IFLA_HSR_VERSION] = { .type = NLA_U8 }, [IFLA_HSR_SUPERVISION_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN }, [IFLA_HSR_SEQ_NR] = { .type = NLA_U16 }, };
@@ -35,7 +36,7 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct net_device *link[2]; -unsigned char multicast_spec; +unsigned char multicast_spec, hsr_version;if (!data) {netdev_info (dev,"HSR: No slave devices specified\n" );
@@ -62,7 +63,12 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,else multicast_spec =nla_get_u8 (data[IFLA_HSR_MULTICAST_SPEC ]); -return hsr_dev_finalize (dev, link, multicast_spec); +if (!data[IFLA_HSR_VERSION ]) + hsr_version =0 ; +else + hsr_version =nla_get_u8 (data[IFLA_HSR_VERSION ]); + +return hsr_dev_finalize (dev, link, multicast_spec, hsr_version); }static int hsr_fill_info (struct sk_buff *skb,const struct net_device *dev)
net/hsr/hsr_slave.c +3 -1
@@ -22,6 +22,7 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) {struct sk_buff *skb = *pskb;struct hsr_port *port; +u16 protocol;if (!skb_mac_header_was_set (skb)) {WARN_ONCE (1 ,"%s: skb invalid" , __func__);
@@ -37,7 +38,8 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) goto finish_consume; } -if (eth_hdr (skb)->h_proto !=htons (ETH_P_PRP )) + protocol =eth_hdr (skb)->h_proto; +if (protocol !=htons (ETH_P_PRP ) && protocol !=htons (ETH_P_HSR )) goto finish_pass;skb_push (skb,ETH_HLEN );
Signature · 1 line
2.5.0
From: Peter Heise <[email protected]>
Date: Wed, 13 Apr 2016 13:52:22 +0200
Quoted 8 lines
This patch adds support for the newer version 1 of the HSR networking standard. Version 0 is still default and the new version has to be selected via iproute2.
Main changes are in the supervision frame handling and its ethertype field.
Signed-off-by Peter Heise <[email protected]>
Applied.
include/uapi/linux/if_link.h enum { · line 778
Quoted 11 lines · On Wed, 13 Apr 2016 13:52:22 +0200 Peter Heise <[email protected]> wrote:
include/uapi/linux/if_link.h +1
-0@@ -773,6 +773,7 @@ enum {IFLA_HSR_SLAVE1 ,IFLA_HSR_SLAVE2 ,IFLA_HSR_MULTICAST_SPEC ,/* Last byte of supervision addr */ +IFLA_HSR_VERSION ,/* HSR version */ IFLA_HSR_SUPERVISION_ADDR ,/* Supervision frame multicast addr */ IFLA_HSR_SEQ_NR,
You added a new value into the middle of an enumeration field. This breaks kernel ABI. Older applications (like iproute) would see the wrong values.
Please submit a new change which moves HSR_VERSION to the end of the enum
David Miller
maintainerFrom: Stephen Hemminger <[email protected]>
Date: Tue, 19 Apr 2016 08:21:00 -0700
Quoted 19 lines
include/uapi/linux/if_link.h enum { · line 778
Quoted 11 lines · On Wed, 13 Apr 2016 13:52:22 +0200 Peter Heise <[email protected]> wrote:
include/uapi/linux/if_link.h +1
-0@@ -773,6 +773,7 @@ enum {IFLA_HSR_SLAVE1 ,IFLA_HSR_SLAVE2 ,IFLA_HSR_MULTICAST_SPEC ,/* Last byte of supervision addr */ +IFLA_HSR_VERSION ,/* HSR version */ IFLA_HSR_SUPERVISION_ADDR ,/* Supervision frame multicast addr */ IFLA_HSR_SEQ_NR,You added a new value into the middle of an enumeration field. This breaks kernel ABI. Older applications (like iproute) would see the wrong values.
Quoted 1 line
Please submit a new change which moves
HSR_VERSIONto the end of the enum
Good catch, Stephen.
A message that is not in the archive (sent off-list or not yet received): 8104_1461082351_571658EF_8104_4642_1_20160419.121227.1437003570791513649.davem@davemloft.net
Thanks for the advice Stephen, new patch submitted!
-----Ursprüngliche Nachricht-----
Von: David Miller [mailto:[email protected]]
Gesendet: Dienstag, 19. April 2016 18:12
An: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Heise, Peter
Betreff: Re: [PATCH net-next] net/hsr: Added support for HSR v1
From: Stephen Hemminger <[email protected]>
Date: Tue, 19 Apr 2016 08:21:00 -0700
Quoted 19 lines
include/uapi/linux/if_link.h enum { · line 778
Quoted 11 lines · On Wed, 13 Apr 2016 13:52:22 +0200 Peter Heise <[email protected]> wrote:
(quoted diff) +0
-0
b/include/uapi/linux/if_link.hindex 9427f17..bb3a90b 100644include/uapi/linux/if_link.h +1
-0@@ -773,6 +773,7 @@ enum {IFLA_HSR_SLAVE1 ,IFLA_HSR_SLAVE2 ,IFLA_HSR_MULTICAST_SPEC ,/* Last byte of supervision addr */ +IFLA_HSR_VERSION ,/* HSR version */ IFLA_HSR_SUPERVISION_ADDR ,/* Supervision frame multicast addr */ IFLA_HSR_SEQ_NR,You added a new value into the middle of an enumeration field. This breaks kernel ABI. Older applications (like iproute) would see the wrong values.
Quoted 2 lines
Please submit a new change which moves
HSR_VERSIONto the end of the enum
Good catch, Stephen.
This mail has originated outside your organization, either from an external partner or the Global Internet. Keep this in mind if you answer this message.
The information in this e-mail is confidential. The contents may not be disclosed or used by anyone other than the addressee. Access to this e-mail by anyone else is unauthorised.
If you are not the intended recipient, please notify Airbus immediately and delete this e-mail.
Airbus cannot accept any responsibility for the accuracy or completeness of this e-mail as it has been sent over public networks. If you have any concerns over the content of this message or its Accuracy or Integrity, please contact Airbus immediately. All outgoing e-mails from Airbus are checked using regularly updated virus scanning software but you should take whatever measures you deem to be appropriate to ensure that this message and any attachments are virus free.