net/hsr: Better frame dispatch
Subsystems (3)
PATCH 9/10 net/hsr: Better frame dispatch
This patch removes the separate paths for frames coming from the outside, and frames sent from the HSR device, and instead makes all frames go through hsr_forward_skb() in hsr_forward.c. This greatly improves code readability and also opens up the possibility for future support of the HSR Interlink device that is the basis for HSR RedBoxes and HSR QuadBoxes, as well as VLAN compatibility.
Other improvements:
* A reduction in the number of times an skb is copied on machines without HAVE_EFFICIENT_UNALIGNED_ACCESS, which improves throughput somewhat.
* Headers are now created using the standard eth_header(), and using the standard hard_header_len.
* Each HSR slave now gets its own private skb, so slave-specific fields can be correctly set.
--- net/hsr/Makefile | 4 +- net/hsr/hsr_device.c | 170 ++++------------------- net/hsr/hsr_forward.c | 368 +++++++++++++++++++++++++++++++++++++++++++++++++ net/hsr/hsr_forward.h | 20 +++ net/hsr/hsr_framereg.c | 318 +++++++++++++++++++++--------------------- net/hsr/hsr_framereg.h | 25 ++-- net/hsr/hsr_main.c | 20 --- net/hsr/hsr_main.h | 16 ++- net/hsr/hsr_netlink.c | 2 +- net/hsr/hsr_slave.c | 287 +++++++------------------------------- net/hsr/hsr_slave.h | 12 +- 11 files changed, 656 insertions(+), 586 deletions(-) create mode 100644 net/hsr/hsr_forward.c create mode 100644 net/hsr/hsr_forward.h
net/hsr/Makefile +2 -2
@@ -4,5 +4,5 @@ obj-$(CONFIG_HSR) += hsr.o -hsr-y := hsr_main.o hsr_framereg.o hsr_device.o hsr_netlink.o \ - hsr_slave.o +hsr-y := hsr_main.o hsr_framereg.o hsr_device.o \ + hsr_netlink.o hsr_slave.o hsr_forward.o
net/hsr/hsr_device.c +23 -147
248 lines not on this page · raw message
net/hsr/hsr_forward.c new file +368 -0
368 lines not on this page · raw message
net/hsr/hsr_forward.h new file +20 -0
@@ -0,0 +1,20 @@ +/* Copyright 2011-2014 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-2014 Arvid Brodin, [email protected] +*/ + +#ifndef __HSR_FORWARD_H +#define __HSR_FORWARD_H + +#include <linux/netdevice.h> +#include "hsr_main.h" + +void hsr_forward_skb (struct sk_buff *skb,struct hsr_port *port); + +#endif /* __HSR_FORWARD_H */
net/hsr/hsr_framereg.c +161 -157
413 lines not on this page · raw message
net/hsr/hsr_framereg.h +14 -11
@@ -16,19 +16,22 @@struct hsr_node ; -struct hsr_node *hsr_find_node (struct list_head *node_db,struct sk_buff *skb); - -struct hsr_node *hsr_merge_node (struct hsr_node *node,struct sk_buff *skb, -struct hsr_port *port); - -void hsr_addr_subst_source (struct hsr_priv *hsr,struct sk_buff *skb); -void hsr_addr_subst_dest (struct hsr_priv *hsr,struct ethhdr *ethhdr, +struct hsr_node *hsr_add_node (struct list_head *node_db,unsigned char addr[], +u16 seq_out); +struct hsr_node *hsr_get_node (struct list_head *node_db,struct sk_buff *skb, +bool is_sup); +void hsr_handle_sup_frame (struct sk_buff *skb,struct hsr_node *node_curr, +struct hsr_port *port); +bool hsr_addr_is_self (struct hsr_priv *hsr,unsigned char *addr); + +void hsr_addr_subst_source (struct hsr_node *node,struct sk_buff *skb); +void hsr_addr_subst_dest (struct hsr_node *node_src,struct sk_buff *skb,struct hsr_port *port); -void hsr_register_frame_in (struct hsr_node *node,struct hsr_port *port); - -int hsr_register_frame_out (struct hsr_node *node,struct hsr_port *port, -struct sk_buff *skb); +void hsr_register_frame_in (struct hsr_node *node,struct hsr_port *port, +u16 sequence_nr); +int hsr_register_frame_out (struct hsr_port *port,struct hsr_node *node, +u16 sequence_nr);void hsr_prune_nodes (unsigned long data);
net/hsr/hsr_main.c +0 -20
@@ -20,26 +20,6 @@#include "hsr_slave.h" -/* List of all registered virtual HSR devices */ -static LIST_HEAD (hsr_list); - -void register_hsr_master (struct hsr_priv *hsr) -{ -list_add_tail_rcu (&hsr->hsr_list, &hsr_list); -} - -void unregister_hsr_master (struct hsr_priv *hsr) -{ -struct hsr_priv *hsr_it; - -list_for_each_entry (hsr_it, &hsr_list, hsr_list) -if (hsr_it == hsr) { -list_del_rcu (&hsr_it->hsr_list); -return ; - } -} - -static int hsr_netdev_notify (struct notifier_block *nb,unsigned long event,void *ptr) {
net/hsr/hsr_main.h +14 -2
@@ -29,6 +29,7 @@* each node differ before we notify of communication problem? */ #define MAX_SLAVE_DIFF 3000/* ms */ +#define HSR_SEQNR_START (USHRT_MAX - 1024)/* How often shall we check for broken ring and remove node entries older than
@@ -153,10 +154,9 @@ struct hsr_port { };struct hsr_priv { -struct list_head hsr_list;/* List of hsr devices */ struct rcu_head rcu_head;struct list_head ports; -struct list_head node_db;/* Other HSR nodes */ +struct list_head node_db;/* Known HSR nodes */ struct list_head self_node_db;/* MACs of slaves */ struct timer_list announce_timer;/* Supervision frame dispatch */ struct timer_list prune_timer;
@@ -166,6 +166,18 @@ struct hsr_priv { unsigned char sup_multicast_addr[ETH_ALEN]; }; +#define hsr_for_each_port (hsr, port) \ + list_for_each_entry_rcu((port), &(hsr)->ports, port_list) +struct hsr_port *hsr_port_get_hsr (struct hsr_priv *hsr,enum hsr_port_type pt); +/* Caller must ensure skb is a valid HSR frame */ +static inline u16 hsr_get_skb_sequence_nr (struct sk_buff *skb) +{ +struct hsr_ethhdr *hsr_ethhdr; + + hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header (skb); +return ntohs (hsr_ethhdr->hsr_tag.sequence_nr); +} +#endif /* __HSR_PRIVATE_H */
net/hsr/hsr_netlink.c +1 -1
@@ -358,7 +358,7 @@ fail:return res; } -/* Get a list of MacAddressA of all nodes known to this node (other than self). +/* Get a list of MacAddressA of all nodes known to this node (including self). */ static int hsr_get_node_list (struct sk_buff *skb_in,struct genl_info *info) {
net/hsr/hsr_slave.c +52 -235
326 lines not on this page · raw message
net/hsr/hsr_slave.h +1 -11
@@ -20,17 +20,7 @@int hsr_add_port (struct hsr_priv *hsr,struct net_device *dev,enum hsr_port_type pt);void hsr_del_port (struct hsr_port *port); -rx_handler_result_t hsr_handle_frame (struct sk_buff **pskb); - - -#define hsr_for_each_port (hsr, port) \ - list_for_each_entry_rcu((port), &(hsr)->ports, port_list) - - -static inline bool hsr_port_exists (const struct net_device *dev) -{ -return dev->rx_handler == hsr_handle_frame; -} +bool hsr_port_exists (const struct net_device *dev);static inline struct hsr_port *hsr_port_get_rtnl (const struct net_device *dev) {
Signature · 6 lines
1.8.3.2 -- Arvid Brodin | Consultant (Linux) ALTEN | Knarrarnäsgatan 7 | SE-164 40 Kista | Sweden [email protected] | www.alten.se/en/