aboutsummaryrefslogtreecommitdiffstats
path: root/net/hsr
diff options
context:
space:
mode:
authorArvid Brodin <arvid.brodin@alten.se>2014-07-04 17:41:03 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 14:35:31 -0400
commitf266a683a4804dc499efc6c2206ef68efed029d0 (patch)
tree8af16a2a5dc8d101e0f1aa4681452a939179c957 /net/hsr
parent4c3477dca2fde1e3ab748387d736d40afe0df21d (diff)
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. Signed-off-by: Arvid Brodin <arvid.brodin@alten.se> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/hsr')
-rw-r--r--net/hsr/Makefile4
-rw-r--r--net/hsr/hsr_device.c170
-rw-r--r--net/hsr/hsr_forward.c368
-rw-r--r--net/hsr/hsr_forward.h20
-rw-r--r--net/hsr/hsr_framereg.c318
-rw-r--r--net/hsr/hsr_framereg.h25
-rw-r--r--net/hsr/hsr_main.c20
-rw-r--r--net/hsr/hsr_main.h16
-rw-r--r--net/hsr/hsr_netlink.c2
-rw-r--r--net/hsr/hsr_slave.c287
-rw-r--r--net/hsr/hsr_slave.h12
11 files changed, 656 insertions, 586 deletions
diff --git a/net/hsr/Makefile b/net/hsr/Makefile
index b533b243a48b..9ae972a820f4 100644
--- a/net/hsr/Makefile
+++ b/net/hsr/Makefile
@@ -4,5 +4,5 @@
4 4
5obj-$(CONFIG_HSR) += hsr.o 5obj-$(CONFIG_HSR) += hsr.o
6 6
7hsr-y := hsr_main.o hsr_framereg.o hsr_device.o hsr_netlink.o \ 7hsr-y := hsr_main.o hsr_framereg.o hsr_device.o \
8 hsr_slave.o 8 hsr_netlink.o hsr_slave.o hsr_forward.o
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index c2ae54924a0f..a138d75751df 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -21,6 +21,7 @@
21#include "hsr_slave.h" 21#include "hsr_slave.h"
22#include "hsr_framereg.h" 22#include "hsr_framereg.h"
23#include "hsr_main.h" 23#include "hsr_main.h"
24#include "hsr_forward.h"
24 25
25 26
26static bool is_admin_up(struct net_device *dev) 27static bool is_admin_up(struct net_device *dev)
@@ -231,141 +232,21 @@ static netdev_features_t hsr_fix_features(struct net_device *dev,
231} 232}
232 233
233 234
234static void hsr_fill_tag(struct hsr_ethhdr *hsr_ethhdr, struct hsr_priv *hsr)
235{
236 unsigned long irqflags;
237
238 /* IEC 62439-1:2010, p 48, says the 4-bit "path" field can take values
239 * between 0001-1001 ("ring identifier", for regular HSR frames),
240 * or 1111 ("HSR management", supervision frames). Unfortunately, the
241 * spec writers forgot to explain what a "ring identifier" is, or
242 * how it is used. So we just set this to 0001 for regular frames,
243 * and 1111 for supervision frames.
244 */
245 set_hsr_tag_path(&hsr_ethhdr->hsr_tag, 0x1);
246
247 /* IEC 62439-1:2010, p 12: "The link service data unit in an Ethernet
248 * frame is the content of the frame located between the Length/Type
249 * field and the Frame Check Sequence."
250 *
251 * IEC 62439-3, p 48, specifies the "original LPDU" to include the
252 * original "LT" field (what "LT" means is not explained anywhere as
253 * far as I can see - perhaps "Length/Type"?). So LSDU_size might
254 * equal original length + 2.
255 * Also, the fact that this field is not used anywhere (might be used
256 * by a RedBox connecting HSR and PRP nets?) means I cannot test its
257 * correctness. Instead of guessing, I set this to 0 here, to make any
258 * problems immediately apparent. Anyone using this driver with PRP/HSR
259 * RedBoxes might need to fix this...
260 */
261 set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, 0);
262
263 spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
264 hsr_ethhdr->hsr_tag.sequence_nr = htons(hsr->sequence_nr);
265 hsr->sequence_nr++;
266 spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
267
268 hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
269
270 hsr_ethhdr->ethhdr.h_proto = htons(ETH_P_PRP);
271}
272
273static int slave_xmit(struct hsr_priv *hsr, struct sk_buff *skb,
274 enum hsr_port_type type)
275{
276 struct hsr_port *port;
277 struct hsr_ethhdr *hsr_ethhdr;
278
279 hsr_ethhdr = (struct hsr_ethhdr *) skb->data;
280
281 rcu_read_lock();
282 port = hsr_port_get_hsr(hsr, type);
283 if (!port) {
284 rcu_read_unlock();
285 return NET_XMIT_DROP;
286 }
287 skb->dev = port->dev;
288
289 hsr_addr_subst_dest(port->hsr, &hsr_ethhdr->ethhdr, port);
290 rcu_read_unlock();
291
292 /* Address substitution (IEC62439-3 pp 26, 50): replace mac
293 * address of outgoing frame with that of the outgoing slave's.
294 */
295 ether_addr_copy(hsr_ethhdr->ethhdr.h_source, skb->dev->dev_addr);
296
297 return dev_queue_xmit(skb);
298}
299
300static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) 235static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
301{ 236{
302 struct hsr_priv *hsr; 237 struct hsr_priv *hsr = netdev_priv(dev);
303 struct hsr_port *master; 238 struct hsr_port *master;
304 struct hsr_ethhdr *hsr_ethhdr;
305 struct sk_buff *skb2;
306 int res1, res2;
307
308 hsr = netdev_priv(dev);
309 hsr_ethhdr = (struct hsr_ethhdr *) skb->data;
310
311 if ((skb->protocol != htons(ETH_P_PRP)) ||
312 (hsr_ethhdr->ethhdr.h_proto != htons(ETH_P_PRP))) {
313 hsr_fill_tag(hsr_ethhdr, hsr);
314 skb->protocol = htons(ETH_P_PRP);
315 }
316 239
317 skb2 = pskb_copy(skb, GFP_ATOMIC);
318
319 res1 = slave_xmit(hsr, skb, HSR_PT_SLAVE_A);
320 if (skb2)
321 res2 = slave_xmit(hsr, skb2, HSR_PT_SLAVE_B);
322 else
323 res2 = NET_XMIT_DROP;
324
325 rcu_read_lock();
326 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); 240 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
327 if (likely(res1 == NET_XMIT_SUCCESS || res1 == NET_XMIT_CN || 241 skb->dev = master->dev;
328 res2 == NET_XMIT_SUCCESS || res2 == NET_XMIT_CN)) { 242 hsr_forward_skb(skb, master);
329 master->dev->stats.tx_packets++;
330 master->dev->stats.tx_bytes += skb->len;
331 } else {
332 master->dev->stats.tx_dropped++;
333 }
334 rcu_read_unlock();
335 243
336 return NETDEV_TX_OK; 244 return NETDEV_TX_OK;
337} 245}
338 246
339 247
340static int hsr_header_create(struct sk_buff *skb, struct net_device *dev,
341 unsigned short type, const void *daddr,
342 const void *saddr, unsigned int len)
343{
344 int res;
345
346 /* Make room for the HSR tag now. We will fill it in later (in
347 * hsr_dev_xmit)
348 */
349 if (skb_headroom(skb) < HSR_HLEN + ETH_HLEN)
350 return -ENOBUFS;
351 skb_push(skb, HSR_HLEN);
352
353 /* To allow VLAN/HSR combos we should probably use
354 * res = dev_hard_header(skb, dev, type, daddr, saddr, len + HSR_HLEN);
355 * here instead. It would require other changes too, though - e.g.
356 * separate headers for each slave etc...
357 */
358 res = eth_header(skb, dev, type, daddr, saddr, len + HSR_HLEN);
359 if (res <= 0)
360 return res;
361 skb_reset_mac_header(skb);
362
363 return res + HSR_HLEN;
364}
365
366
367static const struct header_ops hsr_header_ops = { 248static const struct header_ops hsr_header_ops = {
368 .create = hsr_header_create, 249 .create = eth_header,
369 .parse = eth_header_parse, 250 .parse = eth_header_parse,
370}; 251};
371 252
@@ -382,19 +263,13 @@ static int hsr_pad(int size)
382 return min_size; 263 return min_size;
383} 264}
384 265
385static void send_hsr_supervision_frame(struct net_device *hsr_dev, u8 type) 266static void send_hsr_supervision_frame(struct hsr_port *master, u8 type)
386{ 267{
387 struct hsr_priv *hsr;
388 struct hsr_port *master;
389 struct sk_buff *skb; 268 struct sk_buff *skb;
390 int hlen, tlen; 269 int hlen, tlen;
391 struct hsr_sup_tag *hsr_stag; 270 struct hsr_sup_tag *hsr_stag;
392 struct hsr_sup_payload *hsr_sp; 271 struct hsr_sup_payload *hsr_sp;
393 unsigned long irqflags; 272 unsigned long irqflags;
394 int res;
395
396 hsr = netdev_priv(hsr_dev);
397 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
398 273
399 hlen = LL_RESERVED_SPACE(master->dev); 274 hlen = LL_RESERVED_SPACE(master->dev);
400 tlen = master->dev->needed_tailroom; 275 tlen = master->dev->needed_tailroom;
@@ -410,33 +285,30 @@ static void send_hsr_supervision_frame(struct net_device *hsr_dev, u8 type)
410 skb->protocol = htons(ETH_P_PRP); 285 skb->protocol = htons(ETH_P_PRP);
411 skb->priority = TC_PRIO_CONTROL; 286 skb->priority = TC_PRIO_CONTROL;
412 287
413 res = dev_hard_header(skb, skb->dev, ETH_P_PRP, 288 if (dev_hard_header(skb, skb->dev, ETH_P_PRP,
414 hsr->sup_multicast_addr, 289 master->hsr->sup_multicast_addr,
415 skb->dev->dev_addr, skb->len); 290 skb->dev->dev_addr, skb->len) <= 0)
416 if (res <= 0)
417 goto out; 291 goto out;
292 skb_reset_mac_header(skb);
418 293
419 skb_pull(skb, sizeof(struct ethhdr)); 294 hsr_stag = (typeof(hsr_stag)) skb_put(skb, sizeof(*hsr_stag));
420 hsr_stag = (typeof(hsr_stag)) skb->data;
421 295
422 set_hsr_stag_path(hsr_stag, 0xf); 296 set_hsr_stag_path(hsr_stag, 0xf);
423 set_hsr_stag_HSR_Ver(hsr_stag, 0); 297 set_hsr_stag_HSR_Ver(hsr_stag, 0);
424 298
425 spin_lock_irqsave(&hsr->seqnr_lock, irqflags); 299 spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
426 hsr_stag->sequence_nr = htons(hsr->sequence_nr); 300 hsr_stag->sequence_nr = htons(master->hsr->sequence_nr);
427 hsr->sequence_nr++; 301 master->hsr->sequence_nr++;
428 spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags); 302 spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
429 303
430 hsr_stag->HSR_TLV_Type = type; 304 hsr_stag->HSR_TLV_Type = type;
431 hsr_stag->HSR_TLV_Length = 12; 305 hsr_stag->HSR_TLV_Length = 12;
432 306
433 skb_push(skb, sizeof(struct ethhdr));
434
435 /* Payload: MacAddressA */ 307 /* Payload: MacAddressA */
436 hsr_sp = (typeof(hsr_sp)) skb_put(skb, sizeof(*hsr_sp)); 308 hsr_sp = (typeof(hsr_sp)) skb_put(skb, sizeof(*hsr_sp));
437 ether_addr_copy(hsr_sp->MacAddressA, master->dev->dev_addr); 309 ether_addr_copy(hsr_sp->MacAddressA, master->dev->dev_addr);
438 310
439 dev_queue_xmit(skb); 311 hsr_forward_skb(skb, master);
440 return; 312 return;
441 313
442out: 314out:
@@ -453,13 +325,15 @@ static void hsr_announce(unsigned long data)
453 struct hsr_port *master; 325 struct hsr_port *master;
454 326
455 hsr = (struct hsr_priv *) data; 327 hsr = (struct hsr_priv *) data;
328
329 rcu_read_lock();
456 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); 330 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
457 331
458 if (hsr->announce_count < 3) { 332 if (hsr->announce_count < 3) {
459 send_hsr_supervision_frame(master->dev, HSR_TLV_ANNOUNCE); 333 send_hsr_supervision_frame(master, HSR_TLV_ANNOUNCE);
460 hsr->announce_count++; 334 hsr->announce_count++;
461 } else { 335 } else {
462 send_hsr_supervision_frame(master->dev, HSR_TLV_LIFE_CHECK); 336 send_hsr_supervision_frame(master, HSR_TLV_LIFE_CHECK);
463 } 337 }
464 338
465 if (hsr->announce_count < 3) 339 if (hsr->announce_count < 3)
@@ -471,6 +345,8 @@ static void hsr_announce(unsigned long data)
471 345
472 if (is_admin_up(master->dev)) 346 if (is_admin_up(master->dev))
473 add_timer(&hsr->announce_timer); 347 add_timer(&hsr->announce_timer);
348
349 rcu_read_unlock();
474} 350}
475 351
476 352
@@ -570,7 +446,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
570 446
571 spin_lock_init(&hsr->seqnr_lock); 447 spin_lock_init(&hsr->seqnr_lock);
572 /* Overflow soon to find bugs easier: */ 448 /* Overflow soon to find bugs easier: */
573 hsr->sequence_nr = USHRT_MAX - 1024; 449 hsr->sequence_nr = HSR_SEQNR_START;
574 450
575 init_timer(&hsr->announce_timer); 451 init_timer(&hsr->announce_timer);
576 hsr->announce_timer.function = hsr_announce; 452 hsr->announce_timer.function = hsr_announce;
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
new file mode 100644
index 000000000000..7871ed6d3825
--- /dev/null
+++ b/net/hsr/hsr_forward.c
@@ -0,0 +1,368 @@
1/* Copyright 2011-2014 Autronica Fire and Security AS
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation; either version 2 of the License, or (at your option)
6 * any later version.
7 *
8 * Author(s):
9 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
10 */
11
12#include "hsr_forward.h"
13#include <linux/types.h>
14#include <linux/skbuff.h>
15#include <linux/etherdevice.h>
16#include <linux/if_vlan.h>
17#include "hsr_main.h"
18#include "hsr_framereg.h"
19
20
21struct hsr_node;
22
23struct hsr_frame_info {
24 struct sk_buff *skb_std;
25 struct sk_buff *skb_hsr;
26 struct hsr_port *port_rcv;
27 struct hsr_node *node_src;
28 u16 sequence_nr;
29 bool is_supervision;
30 bool is_vlan;
31 bool is_local_dest;
32 bool is_local_exclusive;
33};
34
35
36/* The uses I can see for these HSR supervision frames are:
37 * 1) Use the frames that are sent after node initialization ("HSR_TLV.Type =
38 * 22") to reset any sequence_nr counters belonging to that node. Useful if
39 * the other node's counter has been reset for some reason.
40 * --
41 * Or not - resetting the counter and bridging the frame would create a
42 * loop, unfortunately.
43 *
44 * 2) Use the LifeCheck frames to detect ring breaks. I.e. if no LifeCheck
45 * frame is received from a particular node, we know something is wrong.
46 * We just register these (as with normal frames) and throw them away.
47 *
48 * 3) Allow different MAC addresses for the two slave interfaces, using the
49 * MacAddressA field.
50 */
51static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
52{
53 struct hsr_ethhdr_sp *hdr;
54
55 WARN_ON_ONCE(!skb_mac_header_was_set(skb));
56 hdr = (struct hsr_ethhdr_sp *) skb_mac_header(skb);
57
58 if (!ether_addr_equal(hdr->ethhdr.h_dest,
59 hsr->sup_multicast_addr))
60 return false;
61
62 if (get_hsr_stag_path(&hdr->hsr_sup) != 0x0f)
63 return false;
64 if ((hdr->hsr_sup.HSR_TLV_Type != HSR_TLV_ANNOUNCE) &&
65 (hdr->hsr_sup.HSR_TLV_Type != HSR_TLV_LIFE_CHECK))
66 return false;
67 if (hdr->hsr_sup.HSR_TLV_Length != 12)
68 return false;
69
70 return true;
71}
72
73
74static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in,
75 struct hsr_frame_info *frame)
76{
77 struct sk_buff *skb;
78 int copylen;
79 unsigned char *dst, *src;
80
81 skb_pull(skb_in, HSR_HLEN);
82 skb = __pskb_copy(skb_in, skb_headroom(skb_in) - HSR_HLEN, GFP_ATOMIC);
83 skb_push(skb_in, HSR_HLEN);
84 if (skb == NULL)
85 return NULL;
86
87 skb_reset_mac_header(skb);
88
89 if (skb->ip_summed == CHECKSUM_PARTIAL)
90 skb->csum_start -= HSR_HLEN;
91
92 copylen = 2*ETH_ALEN;
93 if (frame->is_vlan)
94 copylen += VLAN_HLEN;
95 src = skb_mac_header(skb_in);
96 dst = skb_mac_header(skb);
97 memcpy(dst, src, copylen);
98
99 skb->protocol = eth_hdr(skb)->h_proto;
100 return skb;
101}
102
103static struct sk_buff *frame_get_stripped_skb(struct hsr_frame_info *frame,
104 struct hsr_port *port)
105{
106 if (!frame->skb_std)
107 frame->skb_std = create_stripped_skb(frame->skb_hsr, frame);
108 return skb_clone(frame->skb_std, GFP_ATOMIC);
109}
110
111
112static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame,
113 struct hsr_port *port)
114{
115 struct hsr_ethhdr *hsr_ethhdr;
116 int lane_id;
117 int lsdu_size;
118
119 if (port->type == HSR_PT_SLAVE_A)
120 lane_id = 0;
121 else
122 lane_id = 1;
123
124 lsdu_size = skb->len - 14;
125 if (frame->is_vlan)
126 lsdu_size -= 4;
127
128 hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb);
129
130 set_hsr_tag_path(&hsr_ethhdr->hsr_tag, lane_id);
131 set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size);
132 hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr);
133 hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
134 hsr_ethhdr->ethhdr.h_proto = htons(ETH_P_PRP);
135}
136
137static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
138 struct hsr_frame_info *frame,
139 struct hsr_port *port)
140{
141 int movelen;
142 unsigned char *dst, *src;
143 struct sk_buff *skb;
144
145 /* Create the new skb with enough headroom to fit the HSR tag */
146 skb = __pskb_copy(skb_o, skb_headroom(skb_o) + HSR_HLEN, GFP_ATOMIC);
147 if (skb == NULL)
148 return NULL;
149 skb_reset_mac_header(skb);
150
151 if (skb->ip_summed == CHECKSUM_PARTIAL)
152 skb->csum_start += HSR_HLEN;
153
154 movelen = ETH_HLEN;
155 if (frame->is_vlan)
156 movelen += VLAN_HLEN;
157
158 src = skb_mac_header(skb);
159 dst = skb_push(skb, HSR_HLEN);
160 memmove(dst, src, movelen);
161 skb_reset_mac_header(skb);
162
163 hsr_fill_tag(skb, frame, port);
164
165 return skb;
166}
167
168/* If the original frame was an HSR tagged frame, just clone it to be sent
169 * unchanged. Otherwise, create a private frame especially tagged for 'port'.
170 */
171static struct sk_buff *frame_get_tagged_skb(struct hsr_frame_info *frame,
172 struct hsr_port *port)
173{
174 if (frame->skb_hsr)
175 return skb_clone(frame->skb_hsr, GFP_ATOMIC);
176
177 if ((port->type != HSR_PT_SLAVE_A) && (port->type != HSR_PT_SLAVE_B)) {
178 WARN_ONCE(1, "HSR: Bug: trying to create a tagged frame for a non-ring port");
179 return NULL;
180 }
181
182 return create_tagged_skb(frame->skb_std, frame, port);
183}
184
185
186static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev,
187 struct hsr_node *node_src)
188{
189 bool was_multicast_frame;
190 int res;
191
192 was_multicast_frame = (skb->pkt_type == PACKET_MULTICAST);
193 hsr_addr_subst_source(node_src, skb);
194 skb_pull(skb, ETH_HLEN);
195 res = netif_rx(skb);
196 if (res == NET_RX_DROP) {
197 dev->stats.rx_dropped++;
198 } else {
199 dev->stats.rx_packets++;
200 dev->stats.rx_bytes += skb->len;
201 if (was_multicast_frame)
202 dev->stats.multicast++;
203 }
204}
205
206static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port,
207 struct hsr_frame_info *frame)
208{
209 if (frame->port_rcv->type == HSR_PT_MASTER) {
210 hsr_addr_subst_dest(frame->node_src, skb, port);
211
212 /* Address substitution (IEC62439-3 pp 26, 50): replace mac
213 * address of outgoing frame with that of the outgoing slave's.
214 */
215 ether_addr_copy(eth_hdr(skb)->h_source, port->dev->dev_addr);
216 }
217 return dev_queue_xmit(skb);
218}
219
220
221/* Forward the frame through all devices except:
222 * - Back through the receiving device
223 * - If it's a HSR frame: through a device where it has passed before
224 * - To the local HSR master only if the frame is directly addressed to it, or
225 * a non-supervision multicast or broadcast frame.
226 *
227 * HSR slave devices should insert a HSR tag into the frame, or forward the
228 * frame unchanged if it's already tagged. Interlink devices should strip HSR
229 * tags if they're of the non-HSR type (but only after duplicate discard). The
230 * master device always strips HSR tags.
231 */
232static void hsr_forward_do(struct hsr_frame_info *frame)
233{
234 struct hsr_port *port;
235 struct sk_buff *skb;
236
237 hsr_for_each_port(frame->port_rcv->hsr, port) {
238 /* Don't send frame back the way it came */
239 if (port == frame->port_rcv)
240 continue;
241
242 /* Don't deliver locally unless we should */
243 if ((port->type == HSR_PT_MASTER) && !frame->is_local_dest)
244 continue;
245
246 /* Deliver frames directly addressed to us to master only */
247 if ((port->type != HSR_PT_MASTER) && frame->is_local_exclusive)
248 continue;
249
250 /* Don't send frame over port where it has been sent before */
251 if (hsr_register_frame_out(port, frame->node_src,
252 frame->sequence_nr))
253 continue;
254
255 if (frame->is_supervision && (port->type == HSR_PT_MASTER)) {
256 hsr_handle_sup_frame(frame->skb_hsr,
257 frame->node_src,
258 frame->port_rcv);
259 continue;
260 }
261
262 if (port->type != HSR_PT_MASTER)
263 skb = frame_get_tagged_skb(frame, port);
264 else
265 skb = frame_get_stripped_skb(frame, port);
266 if (skb == NULL) {
267 /* FIXME: Record the dropped frame? */
268 continue;
269 }
270
271 skb->dev = port->dev;
272 if (port->type == HSR_PT_MASTER)
273 hsr_deliver_master(skb, port->dev, frame->node_src);
274 else
275 hsr_xmit(skb, port, frame);
276 }
277}
278
279
280static void check_local_dest(struct hsr_priv *hsr, struct sk_buff *skb,
281 struct hsr_frame_info *frame)
282{
283 struct net_device *master_dev;
284
285 master_dev = hsr_port_get_hsr(hsr, HSR_PT_MASTER)->dev;
286
287 if (hsr_addr_is_self(hsr, eth_hdr(skb)->h_dest)) {
288 frame->is_local_exclusive = true;
289 skb->pkt_type = PACKET_HOST;
290 } else {
291 frame->is_local_exclusive = false;
292 }
293
294 if ((skb->pkt_type == PACKET_HOST) ||
295 (skb->pkt_type == PACKET_MULTICAST) ||
296 (skb->pkt_type == PACKET_BROADCAST)) {
297 frame->is_local_dest = true;
298 } else {
299 frame->is_local_dest = false;
300 }
301}
302
303
304static int hsr_fill_frame_info(struct hsr_frame_info *frame,
305 struct sk_buff *skb, struct hsr_port *port)
306{
307 struct ethhdr *ethhdr;
308 unsigned long irqflags;
309
310 frame->is_supervision = is_supervision_frame(port->hsr, skb);
311 frame->node_src = hsr_get_node(&port->hsr->node_db, skb,
312 frame->is_supervision);
313 if (frame->node_src == NULL)
314 return -1; /* Unknown node and !is_supervision, or no mem */
315
316 ethhdr = (struct ethhdr *) skb_mac_header(skb);
317 frame->is_vlan = false;
318 if (ethhdr->h_proto == htons(ETH_P_8021Q)) {
319 frame->is_vlan = true;
320 /* FIXME: */
321 WARN_ONCE(1, "HSR: VLAN not yet supported");
322 }
323 if (ethhdr->h_proto == htons(ETH_P_PRP)) {
324 frame->skb_std = NULL;
325 frame->skb_hsr = skb;
326 frame->sequence_nr = hsr_get_skb_sequence_nr(skb);
327 } else {
328 frame->skb_std = skb;
329 frame->skb_hsr = NULL;
330 /* Sequence nr for the master node */
331 spin_lock_irqsave(&port->hsr->seqnr_lock, irqflags);
332 frame->sequence_nr = port->hsr->sequence_nr;
333 port->hsr->sequence_nr++;
334 spin_unlock_irqrestore(&port->hsr->seqnr_lock, irqflags);
335 }
336
337 frame->port_rcv = port;
338 check_local_dest(port->hsr, skb, frame);
339
340 return 0;
341}
342
343/* Must be called holding rcu read lock (because of the port parameter) */
344void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
345{
346 struct hsr_frame_info frame;
347
348 if (skb_mac_header(skb) != skb->data) {
349 WARN_ONCE(1, "%s:%d: Malformed frame (port_src %s)\n",
350 __FILE__, __LINE__, port->dev->name);
351 goto out_drop;
352 }
353
354 if (hsr_fill_frame_info(&frame, skb, port) < 0)
355 goto out_drop;
356 hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
357 hsr_forward_do(&frame);
358
359 if (frame.skb_hsr != NULL)
360 kfree_skb(frame.skb_hsr);
361 if (frame.skb_std != NULL)
362 kfree_skb(frame.skb_std);
363 return;
364
365out_drop:
366 port->dev->stats.tx_dropped++;
367 kfree_skb(skb);
368}
diff --git a/net/hsr/hsr_forward.h b/net/hsr/hsr_forward.h
new file mode 100644
index 000000000000..5c5bc4b6b75f
--- /dev/null
+++ b/net/hsr/hsr_forward.h
@@ -0,0 +1,20 @@
1/* Copyright 2011-2014 Autronica Fire and Security AS
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation; either version 2 of the License, or (at your option)
6 * any later version.
7 *
8 * Author(s):
9 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
10 */
11
12#ifndef __HSR_FORWARD_H
13#define __HSR_FORWARD_H
14
15#include <linux/netdevice.h>
16#include "hsr_main.h"
17
18void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port);
19
20#endif /* __HSR_FORWARD_H */
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index c9b78c52c75b..c709c13842cb 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -35,58 +35,56 @@ struct hsr_node {
35 struct rcu_head rcu_head; 35 struct rcu_head rcu_head;
36}; 36};
37 37
38/* TODO: use hash lists for mac addresses (linux/jhash.h)? */
39 38
39/* TODO: use hash lists for mac addresses (linux/jhash.h)? */
40 40
41 41
42/* Search for mac entry. Caller must hold rcu read lock. 42/* seq_nr_after(a, b) - return true if a is after (higher in sequence than) b,
43 * false otherwise.
43 */ 44 */
44static struct hsr_node *find_node_by_AddrA(struct list_head *node_db, 45static bool seq_nr_after(u16 a, u16 b)
45 const unsigned char addr[ETH_ALEN])
46{ 46{
47 struct hsr_node *node; 47 /* Remove inconsistency where
48 48 * seq_nr_after(a, b) == seq_nr_before(a, b)
49 list_for_each_entry_rcu(node, node_db, mac_list) { 49 */
50 if (ether_addr_equal(node->MacAddressA, addr)) 50 if ((int) b - a == 32768)
51 return node; 51 return false;
52 }
53 52
54 return NULL; 53 return (((s16) (b - a)) < 0);
55} 54}
55#define seq_nr_before(a, b) seq_nr_after((b), (a))
56#define seq_nr_after_or_eq(a, b) (!seq_nr_before((a), (b)))
57#define seq_nr_before_or_eq(a, b) (!seq_nr_after((a), (b)))
56 58
57 59
58/* Search for mac entry. Caller must hold rcu read lock. 60bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr)
59 */
60static struct hsr_node *find_node_by_AddrB(struct list_head *node_db,
61 const unsigned char addr[ETH_ALEN])
62{ 61{
63 struct hsr_node *node; 62 struct hsr_node *node;
64 63
65 list_for_each_entry_rcu(node, node_db, mac_list) { 64 node = list_first_or_null_rcu(&hsr->self_node_db, struct hsr_node,
66 if (ether_addr_equal(node->MacAddressB, addr)) 65 mac_list);
67 return node; 66 if (!node) {
67 WARN_ONCE(1, "HSR: No self node\n");
68 return false;
68 } 69 }
69 70
70 return NULL; 71 if (ether_addr_equal(addr, node->MacAddressA))
71} 72 return true;
73 if (ether_addr_equal(addr, node->MacAddressB))
74 return true;
72 75
76 return false;
77}
73 78
74/* Search for mac entry. Caller must hold rcu read lock. 79/* Search for mac entry. Caller must hold rcu read lock.
75 */ 80 */
76struct hsr_node *hsr_find_node(struct list_head *node_db, struct sk_buff *skb) 81static struct hsr_node *find_node_by_AddrA(struct list_head *node_db,
82 const unsigned char addr[ETH_ALEN])
77{ 83{
78 struct hsr_node *node; 84 struct hsr_node *node;
79 struct ethhdr *ethhdr;
80
81 if (!skb_mac_header_was_set(skb))
82 return NULL;
83
84 ethhdr = (struct ethhdr *) skb_mac_header(skb);
85 85
86 list_for_each_entry_rcu(node, node_db, mac_list) { 86 list_for_each_entry_rcu(node, node_db, mac_list) {
87 if (ether_addr_equal(node->MacAddressA, ethhdr->h_source)) 87 if (ether_addr_equal(node->MacAddressA, addr))
88 return node;
89 if (ether_addr_equal(node->MacAddressB, ethhdr->h_source))
90 return node; 88 return node;
91 } 89 }
92 90
@@ -127,90 +125,22 @@ int hsr_create_self_node(struct list_head *self_node_db,
127} 125}
128 126
129 127
130/* Add/merge node to the database of nodes. 'skb' must contain an HSR 128/* Allocate an hsr_node and add it to node_db. 'addr' is the node's AddressA;
131 * supervision frame. 129 * seq_out is used to initialize filtering of outgoing duplicate frames
132 * - If the supervision header's MacAddressA field is not yet in the database, 130 * originating from the newly added node.
133 * this frame is from an hitherto unknown node - add it to the database.
134 * - If the sender's MAC address is not the same as its MacAddressA address,
135 * the node is using PICS_SUBS (address substitution). Record the sender's
136 * address as the node's MacAddressB.
137 *
138 * This function needs to work even if the sender node has changed one of its
139 * slaves' MAC addresses. In this case, there are four different cases described
140 * by (Addr-changed, received-from) pairs as follows. Note that changing the
141 * SlaveA address is equal to changing the node's own address:
142 *
143 * - (AddrB, SlaveB): The new AddrB will be recorded by PICS_SUBS code since
144 * node == NULL.
145 * - (AddrB, SlaveA): Will work as usual (the AddrB change won't be detected
146 * from this frame).
147 *
148 * - (AddrA, SlaveB): The old node will be found. We need to detect this and
149 * remove the node.
150 * - (AddrA, SlaveA): A new node will be registered (non-PICS_SUBS at first).
151 * The old one will be pruned after HSR_NODE_FORGET_TIME.
152 *
153 * We also need to detect if the sender's SlaveA and SlaveB cables have been
154 * swapped.
155 */ 131 */
156struct hsr_node *hsr_merge_node(struct hsr_node *node, struct sk_buff *skb, 132struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[],
157 struct hsr_port *port) 133 u16 seq_out)
158{ 134{
159 struct hsr_priv *hsr; 135 struct hsr_node *node;
160 struct hsr_sup_payload *hsr_sp;
161 struct hsr_ethhdr_sp *hsr_ethsup;
162 int i;
163 unsigned long now; 136 unsigned long now;
164 137 int i;
165 hsr_ethsup = (struct hsr_ethhdr_sp *) skb_mac_header(skb);
166 hsr_sp = (struct hsr_sup_payload *) skb->data;
167 hsr = port->hsr;
168
169 if (node && !ether_addr_equal(node->MacAddressA, hsr_sp->MacAddressA)) {
170 /* Node has changed its AddrA, frame was received from SlaveB */
171 list_del_rcu(&node->mac_list);
172 kfree_rcu(node, rcu_head);
173 node = NULL;
174 }
175
176 if (node && (port->type == node->AddrB_port) &&
177 !ether_addr_equal(node->MacAddressB, hsr_ethsup->ethhdr.h_source)) {
178 /* Cables have been swapped */
179 list_del_rcu(&node->mac_list);
180 kfree_rcu(node, rcu_head);
181 node = NULL;
182 }
183
184 if (node && (port->type != node->AddrB_port) &&
185 (node->AddrB_port != HSR_PT_NONE) &&
186 !ether_addr_equal(node->MacAddressA, hsr_ethsup->ethhdr.h_source)) {
187 /* Cables have been swapped */
188 list_del_rcu(&node->mac_list);
189 kfree_rcu(node, rcu_head);
190 node = NULL;
191 }
192
193 if (node)
194 return node;
195
196 node = find_node_by_AddrA(&hsr->node_db, hsr_sp->MacAddressA);
197 if (node) {
198 /* Node is known, but frame was received from an unknown
199 * address. Node is PICS_SUBS capable; merge its AddrB.
200 */
201 ether_addr_copy(node->MacAddressB, hsr_ethsup->ethhdr.h_source);
202 node->AddrB_port = port->type;
203 return node;
204 }
205 138
206 node = kzalloc(sizeof(*node), GFP_ATOMIC); 139 node = kzalloc(sizeof(*node), GFP_ATOMIC);
207 if (!node) 140 if (!node)
208 return NULL; 141 return NULL;
209 142
210 ether_addr_copy(node->MacAddressA, hsr_sp->MacAddressA); 143 ether_addr_copy(node->MacAddressA, addr);
211 ether_addr_copy(node->MacAddressB, hsr_ethsup->ethhdr.h_source);
212 if (!ether_addr_equal(hsr_sp->MacAddressA, hsr_ethsup->ethhdr.h_source))
213 node->AddrB_port = port->type;
214 144
215 /* We are only interested in time diffs here, so use current jiffies 145 /* We are only interested in time diffs here, so use current jiffies
216 * as initialization. (0 could trigger an spurious ring error warning). 146 * as initialization. (0 could trigger an spurious ring error warning).
@@ -219,41 +149,120 @@ struct hsr_node *hsr_merge_node(struct hsr_node *node, struct sk_buff *skb,
219 for (i = 0; i < HSR_PT_PORTS; i++) 149 for (i = 0; i < HSR_PT_PORTS; i++)
220 node->time_in[i] = now; 150 node->time_in[i] = now;
221 for (i = 0; i < HSR_PT_PORTS; i++) 151 for (i = 0; i < HSR_PT_PORTS; i++)
222 node->seq_out[i] = ntohs(hsr_ethsup->hsr_sup.sequence_nr) - 1; 152 node->seq_out[i] = seq_out;
223 153
224 list_add_tail_rcu(&node->mac_list, &hsr->node_db); 154 list_add_tail_rcu(&node->mac_list, node_db);
225 155
226 return node; 156 return node;
227} 157}
228 158
159/* Get the hsr_node from which 'skb' was sent.
160 */
161struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,
162 bool is_sup)
163{
164 struct hsr_node *node;
165 struct ethhdr *ethhdr;
166 u16 seq_out;
167
168 if (!skb_mac_header_was_set(skb))
169 return NULL;
170
171 ethhdr = (struct ethhdr *) skb_mac_header(skb);
172
173 list_for_each_entry_rcu(node, node_db, mac_list) {
174 if (ether_addr_equal(node->MacAddressA, ethhdr->h_source))
175 return node;
176 if (ether_addr_equal(node->MacAddressB, ethhdr->h_source))
177 return node;
178 }
179
180 if (!is_sup)
181 return NULL; /* Only supervision frame may create node entry */
182
183 if (ethhdr->h_proto == htons(ETH_P_PRP)) {
184 /* Use the existing sequence_nr from the tag as starting point
185 * for filtering duplicate frames.
186 */
187 seq_out = hsr_get_skb_sequence_nr(skb) - 1;
188 } else {
189 WARN_ONCE(1, "%s: Non-HSR frame\n", __func__);
190 seq_out = 0;
191 }
192
193 return hsr_add_node(node_db, ethhdr->h_source, seq_out);
194}
195
196/* Use the Supervision frame's info about an eventual MacAddressB for merging
197 * nodes that has previously had their MacAddressB registered as a separate
198 * node.
199 */
200void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr,
201 struct hsr_port *port_rcv)
202{
203 struct hsr_node *node_real;
204 struct hsr_sup_payload *hsr_sp;
205 struct list_head *node_db;
206 int i;
207
208 skb_pull(skb, sizeof(struct hsr_ethhdr_sp));
209 hsr_sp = (struct hsr_sup_payload *) skb->data;
210
211 if (ether_addr_equal(eth_hdr(skb)->h_source, hsr_sp->MacAddressA))
212 /* Not sent from MacAddressB of a PICS_SUBS capable node */
213 goto done;
214
215 /* Merge node_curr (registered on MacAddressB) into node_real */
216 node_db = &port_rcv->hsr->node_db;
217 node_real = find_node_by_AddrA(node_db, hsr_sp->MacAddressA);
218 if (!node_real)
219 /* No frame received from AddrA of this node yet */
220 node_real = hsr_add_node(node_db, hsr_sp->MacAddressA,
221 HSR_SEQNR_START - 1);
222 if (!node_real)
223 goto done; /* No mem */
224 if (node_real == node_curr)
225 /* Node has already been merged */
226 goto done;
227
228 ether_addr_copy(node_real->MacAddressB, eth_hdr(skb)->h_source);
229 for (i = 0; i < HSR_PT_PORTS; i++) {
230 if (!node_curr->time_in_stale[i] &&
231 time_after(node_curr->time_in[i], node_real->time_in[i])) {
232 node_real->time_in[i] = node_curr->time_in[i];
233 node_real->time_in_stale[i] = node_curr->time_in_stale[i];
234 }
235 if (seq_nr_after(node_curr->seq_out[i], node_real->seq_out[i]))
236 node_real->seq_out[i] = node_curr->seq_out[i];
237 }
238 node_real->AddrB_port = port_rcv->type;
239
240 list_del_rcu(&node_curr->mac_list);
241 kfree_rcu(node_curr, rcu_head);
242
243done:
244 skb_push(skb, sizeof(struct hsr_ethhdr_sp));
245}
246
229 247
230/* 'skb' is a frame meant for this host, that is to be passed to upper layers. 248/* 'skb' is a frame meant for this host, that is to be passed to upper layers.
231 * 249 *
232 * If the frame was sent by a node's B interface, replace the sender 250 * If the frame was sent by a node's B interface, replace the source
233 * address with that node's "official" address (MacAddressA) so that upper 251 * address with that node's "official" address (MacAddressA) so that upper
234 * layers recognize where it came from. 252 * layers recognize where it came from.
235 */ 253 */
236void hsr_addr_subst_source(struct hsr_priv *hsr, struct sk_buff *skb) 254void hsr_addr_subst_source(struct hsr_node *node, struct sk_buff *skb)
237{ 255{
238 struct ethhdr *ethhdr;
239 struct hsr_node *node;
240
241 if (!skb_mac_header_was_set(skb)) { 256 if (!skb_mac_header_was_set(skb)) {
242 WARN_ONCE(1, "%s: Mac header not set\n", __func__); 257 WARN_ONCE(1, "%s: Mac header not set\n", __func__);
243 return; 258 return;
244 } 259 }
245 ethhdr = (struct ethhdr *) skb_mac_header(skb);
246 260
247 rcu_read_lock(); 261 memcpy(&eth_hdr(skb)->h_source, node->MacAddressA, ETH_ALEN);
248 node = find_node_by_AddrB(&hsr->node_db, ethhdr->h_source);
249 if (node)
250 ether_addr_copy(ethhdr->h_source, node->MacAddressA);
251 rcu_read_unlock();
252} 262}
253 263
254
255/* 'skb' is a frame meant for another host. 264/* 'skb' is a frame meant for another host.
256 * 'hsr_dev_idx' is the HSR index of the outgoing device 265 * 'port' is the outgoing interface
257 * 266 *
258 * Substitute the target (dest) MAC address if necessary, so the it matches the 267 * Substitute the target (dest) MAC address if necessary, so the it matches the
259 * recipient interface MAC address, regardless of whether that is the 268 * recipient interface MAC address, regardless of whether that is the
@@ -261,44 +270,49 @@ void hsr_addr_subst_source(struct hsr_priv *hsr, struct sk_buff *skb)
261 * This is needed to keep the packets flowing through switches that learn on 270 * This is needed to keep the packets flowing through switches that learn on
262 * which "side" the different interfaces are. 271 * which "side" the different interfaces are.
263 */ 272 */
264void hsr_addr_subst_dest(struct hsr_priv *hsr, struct ethhdr *ethhdr, 273void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
265 struct hsr_port *port) 274 struct hsr_port *port)
266{ 275{
267 struct hsr_node *node; 276 struct hsr_node *node_dst;
268 277
269 rcu_read_lock(); 278 if (!skb_mac_header_was_set(skb)) {
270 node = find_node_by_AddrA(&hsr->node_db, ethhdr->h_dest); 279 WARN_ONCE(1, "%s: Mac header not set\n", __func__);
271 if (node && (node->AddrB_port == port->type)) 280 return;
272 ether_addr_copy(ethhdr->h_dest, node->MacAddressB); 281 }
273 rcu_read_unlock();
274}
275 282
283 if (!is_unicast_ether_addr(eth_hdr(skb)->h_dest))
284 return;
276 285
277/* seq_nr_after(a, b) - return true if a is after (higher in sequence than) b, 286 node_dst = find_node_by_AddrA(&port->hsr->node_db, eth_hdr(skb)->h_dest);
278 * false otherwise. 287 if (!node_dst) {
279 */ 288 WARN_ONCE(1, "%s: Unknown node\n", __func__);
280static bool seq_nr_after(u16 a, u16 b) 289 return;
281{ 290 }
282 /* Remove inconsistency where 291 if (port->type != node_dst->AddrB_port)
283 * seq_nr_after(a, b) == seq_nr_before(a, b) 292 return;
284 */ 293 if (!node_dst->MacAddressB) {
285 if ((int) b - a == 32768) 294 WARN_ONCE(1, "%s: No MacAddressB\n", __func__);
286 return false; 295 return;
296 }
287 297
288 return (((s16) (b - a)) < 0); 298 ether_addr_copy(eth_hdr(skb)->h_dest, node_dst->MacAddressB);
289} 299}
290#define seq_nr_before(a, b) seq_nr_after((b), (a))
291#define seq_nr_after_or_eq(a, b) (!seq_nr_before((a), (b)))
292#define seq_nr_before_or_eq(a, b) (!seq_nr_after((a), (b)))
293 300
294 301
295void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port) 302void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
303 u16 sequence_nr)
296{ 304{
305 /* Don't register incoming frames without a valid sequence number. This
306 * ensures entries of restarted nodes gets pruned so that they can
307 * re-register and resume communications.
308 */
309 if (seq_nr_before(sequence_nr, node->seq_out[port->type]))
310 return;
311
297 node->time_in[port->type] = jiffies; 312 node->time_in[port->type] = jiffies;
298 node->time_in_stale[port->type] = false; 313 node->time_in_stale[port->type] = false;
299} 314}
300 315
301
302/* 'skb' is a HSR Ethernet frame (with a HSR tag inserted), with a valid 316/* 'skb' is a HSR Ethernet frame (with a HSR tag inserted), with a valid
303 * ethhdr->h_source address and skb->mac_header set. 317 * ethhdr->h_source address and skb->mac_header set.
304 * 318 *
@@ -307,19 +321,9 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port)
307 * 0 otherwise, or 321 * 0 otherwise, or
308 * negative error code on error 322 * negative error code on error
309 */ 323 */
310int hsr_register_frame_out(struct hsr_node *node, struct hsr_port *port, 324int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node,
311 struct sk_buff *skb) 325 u16 sequence_nr)
312{ 326{
313 struct hsr_ethhdr *hsr_ethhdr;
314 u16 sequence_nr;
315
316 if (!skb_mac_header_was_set(skb)) {
317 WARN_ONCE(1, "%s: Mac header not set\n", __func__);
318 return -EINVAL;
319 }
320 hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb);
321
322 sequence_nr = ntohs(hsr_ethhdr->hsr_tag.sequence_nr);
323 if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type])) 327 if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type]))
324 return 1; 328 return 1;
325 329
diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
index c87f36fc154c..438b40f98f5a 100644
--- a/net/hsr/hsr_framereg.h
+++ b/net/hsr/hsr_framereg.h
@@ -16,19 +16,22 @@
16 16
17struct hsr_node; 17struct hsr_node;
18 18
19struct hsr_node *hsr_find_node(struct list_head *node_db, struct sk_buff *skb); 19struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[],
20 20 u16 seq_out);
21struct hsr_node *hsr_merge_node(struct hsr_node *node, struct sk_buff *skb, 21struct hsr_node *hsr_get_node(struct list_head *node_db, struct sk_buff *skb,
22 struct hsr_port *port); 22 bool is_sup);
23 23void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr,
24void hsr_addr_subst_source(struct hsr_priv *hsr, struct sk_buff *skb); 24 struct hsr_port *port);
25void hsr_addr_subst_dest(struct hsr_priv *hsr, struct ethhdr *ethhdr, 25bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr);
26
27void hsr_addr_subst_source(struct hsr_node *node, struct sk_buff *skb);
28void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
26 struct hsr_port *port); 29 struct hsr_port *port);
27 30
28void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port); 31void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
29 32 u16 sequence_nr);
30int hsr_register_frame_out(struct hsr_node *node, struct hsr_port *port, 33int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node,
31 struct sk_buff *skb); 34 u16 sequence_nr);
32 35
33void hsr_prune_nodes(unsigned long data); 36void hsr_prune_nodes(unsigned long data);
34 37
diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
index a06cab57ab68..779d28b65417 100644
--- a/net/hsr/hsr_main.c
+++ b/net/hsr/hsr_main.c
@@ -20,26 +20,6 @@
20#include "hsr_slave.h" 20#include "hsr_slave.h"
21 21
22 22
23/* List of all registered virtual HSR devices */
24static LIST_HEAD(hsr_list);
25
26void register_hsr_master(struct hsr_priv *hsr)
27{
28 list_add_tail_rcu(&hsr->hsr_list, &hsr_list);
29}
30
31void unregister_hsr_master(struct hsr_priv *hsr)
32{
33 struct hsr_priv *hsr_it;
34
35 list_for_each_entry(hsr_it, &hsr_list, hsr_list)
36 if (hsr_it == hsr) {
37 list_del_rcu(&hsr_it->hsr_list);
38 return;
39 }
40}
41
42
43static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event, 23static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
44 void *ptr) 24 void *ptr)
45{ 25{
diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
index e31c3069fdf8..5a9c69962ded 100644
--- a/net/hsr/hsr_main.h
+++ b/net/hsr/hsr_main.h
@@ -29,6 +29,7 @@
29 * each node differ before we notify of communication problem? 29 * each node differ before we notify of communication problem?
30 */ 30 */
31#define MAX_SLAVE_DIFF 3000 /* ms */ 31#define MAX_SLAVE_DIFF 3000 /* ms */
32#define HSR_SEQNR_START (USHRT_MAX - 1024)
32 33
33 34
34/* How often shall we check for broken ring and remove node entries older than 35/* How often shall we check for broken ring and remove node entries older than
@@ -153,10 +154,9 @@ struct hsr_port {
153}; 154};
154 155
155struct hsr_priv { 156struct hsr_priv {
156 struct list_head hsr_list; /* List of hsr devices */
157 struct rcu_head rcu_head; 157 struct rcu_head rcu_head;
158 struct list_head ports; 158 struct list_head ports;
159 struct list_head node_db; /* Other HSR nodes */ 159 struct list_head node_db; /* Known HSR nodes */
160 struct list_head self_node_db; /* MACs of slaves */ 160 struct list_head self_node_db; /* MACs of slaves */
161 struct timer_list announce_timer; /* Supervision frame dispatch */ 161 struct timer_list announce_timer; /* Supervision frame dispatch */
162 struct timer_list prune_timer; 162 struct timer_list prune_timer;
@@ -166,6 +166,18 @@ struct hsr_priv {
166 unsigned char sup_multicast_addr[ETH_ALEN]; 166 unsigned char sup_multicast_addr[ETH_ALEN];
167}; 167};
168 168
169#define hsr_for_each_port(hsr, port) \
170 list_for_each_entry_rcu((port), &(hsr)->ports, port_list)
171
169struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt); 172struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt);
170 173
174/* Caller must ensure skb is a valid HSR frame */
175static inline u16 hsr_get_skb_sequence_nr(struct sk_buff *skb)
176{
177 struct hsr_ethhdr *hsr_ethhdr;
178
179 hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb);
180 return ntohs(hsr_ethhdr->hsr_tag.sequence_nr);
181}
182
171#endif /* __HSR_PRIVATE_H */ 183#endif /* __HSR_PRIVATE_H */
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 67082453928c..fbdf53f1d874 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -358,7 +358,7 @@ fail:
358 return res; 358 return res;
359} 359}
360 360
361/* Get a list of MacAddressA of all nodes known to this node (other than self). 361/* Get a list of MacAddressA of all nodes known to this node (including self).
362 */ 362 */
363static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) 363static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
364{ 364{
diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
index 23817d0b765b..a348dcbcd683 100644
--- a/net/hsr/hsr_slave.c
+++ b/net/hsr/hsr_slave.c
@@ -14,9 +14,51 @@
14#include <linux/if_arp.h> 14#include <linux/if_arp.h>
15#include "hsr_main.h" 15#include "hsr_main.h"
16#include "hsr_device.h" 16#include "hsr_device.h"
17#include "hsr_forward.h"
17#include "hsr_framereg.h" 18#include "hsr_framereg.h"
18 19
19 20
21static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)
22{
23 struct sk_buff *skb = *pskb;
24 struct hsr_port *port;
25
26 if (!skb_mac_header_was_set(skb)) {
27 WARN_ONCE(1, "%s: skb invalid", __func__);
28 return RX_HANDLER_PASS;
29 }
30
31 rcu_read_lock(); /* hsr->node_db, hsr->ports */
32 port = hsr_port_get_rcu(skb->dev);
33
34 if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) {
35 /* Directly kill frames sent by ourselves */
36 kfree_skb(skb);
37 goto finish_consume;
38 }
39
40 if (eth_hdr(skb)->h_proto != htons(ETH_P_PRP))
41 goto finish_pass;
42
43 skb_push(skb, ETH_HLEN);
44
45 hsr_forward_skb(skb, port);
46
47finish_consume:
48 rcu_read_unlock(); /* hsr->node_db, hsr->ports */
49 return RX_HANDLER_CONSUMED;
50
51finish_pass:
52 rcu_read_unlock(); /* hsr->node_db, hsr->ports */
53 return RX_HANDLER_PASS;
54}
55
56bool hsr_port_exists(const struct net_device *dev)
57{
58 return rcu_access_pointer(dev->rx_handler) == hsr_handle_frame;
59}
60
61
20static int hsr_check_dev_ok(struct net_device *dev) 62static int hsr_check_dev_ok(struct net_device *dev)
21{ 63{
22 /* Don't allow HSR on non-ethernet like devices */ 64 /* Don't allow HSR on non-ethernet like devices */
@@ -42,6 +84,11 @@ static int hsr_check_dev_ok(struct net_device *dev)
42 return -EINVAL; 84 return -EINVAL;
43 } 85 }
44 86
87 if (dev->priv_flags & IFF_DONT_BRIDGE) {
88 netdev_info(dev, "This device does not support bridging.\n");
89 return -EOPNOTSUPP;
90 }
91
45 /* HSR over bonded devices has not been tested, but I'm not sure it 92 /* HSR over bonded devices has not been tested, but I'm not sure it
46 * won't work... 93 * won't work...
47 */ 94 */
@@ -50,232 +97,6 @@ static int hsr_check_dev_ok(struct net_device *dev)
50} 97}
51 98
52 99
53static struct sk_buff *hsr_pull_tag(struct sk_buff *skb)
54{
55 struct hsr_tag *hsr_tag;
56 struct sk_buff *skb2;
57
58 skb2 = skb_share_check(skb, GFP_ATOMIC);
59 if (unlikely(!skb2))
60 goto err_free;
61 skb = skb2;
62
63 if (unlikely(!pskb_may_pull(skb, HSR_HLEN)))
64 goto err_free;
65
66 hsr_tag = (struct hsr_tag *) skb->data;
67 skb->protocol = hsr_tag->encap_proto;
68 skb_pull(skb, HSR_HLEN);
69
70 return skb;
71
72err_free:
73 kfree_skb(skb);
74 return NULL;
75}
76
77
78/* The uses I can see for these HSR supervision frames are:
79 * 1) Use the frames that are sent after node initialization ("HSR_TLV.Type =
80 * 22") to reset any sequence_nr counters belonging to that node. Useful if
81 * the other node's counter has been reset for some reason.
82 * --
83 * Or not - resetting the counter and bridging the frame would create a
84 * loop, unfortunately.
85 *
86 * 2) Use the LifeCheck frames to detect ring breaks. I.e. if no LifeCheck
87 * frame is received from a particular node, we know something is wrong.
88 * We just register these (as with normal frames) and throw them away.
89 *
90 * 3) Allow different MAC addresses for the two slave interfaces, using the
91 * MacAddressA field.
92 */
93static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
94{
95 struct hsr_sup_tag *hsr_stag;
96
97 if (!ether_addr_equal(eth_hdr(skb)->h_dest,
98 hsr->sup_multicast_addr))
99 return false;
100
101 hsr_stag = (struct hsr_sup_tag *) skb->data;
102 if (get_hsr_stag_path(hsr_stag) != 0x0f)
103 return false;
104 if ((hsr_stag->HSR_TLV_Type != HSR_TLV_ANNOUNCE) &&
105 (hsr_stag->HSR_TLV_Type != HSR_TLV_LIFE_CHECK))
106 return false;
107 if (hsr_stag->HSR_TLV_Length != 12)
108 return false;
109
110 return true;
111}
112
113
114/* Implementation somewhat according to IEC-62439-3, p. 43
115 */
116rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)
117{
118 struct sk_buff *skb = *pskb;
119 struct hsr_port *port, *other_port, *master;
120 struct hsr_priv *hsr;
121 struct hsr_node *node;
122 bool deliver_to_self;
123 struct sk_buff *skb_deliver;
124 bool dup_out;
125 int ret;
126
127 if (eth_hdr(skb)->h_proto != htons(ETH_P_PRP))
128 return RX_HANDLER_PASS;
129
130 rcu_read_lock(); /* ports & node */
131
132 port = hsr_port_get_rcu(skb->dev);
133 hsr = port->hsr;
134 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
135
136 node = hsr_find_node(&hsr->self_node_db, skb);
137 if (node) {
138 /* Always kill frames sent by ourselves */
139 kfree_skb(skb);
140 ret = RX_HANDLER_CONSUMED;
141 goto finish;
142 }
143
144 /* Is this frame a candidate for local reception? */
145 deliver_to_self = false;
146 if ((skb->pkt_type == PACKET_HOST) ||
147 (skb->pkt_type == PACKET_MULTICAST) ||
148 (skb->pkt_type == PACKET_BROADCAST))
149 deliver_to_self = true;
150 else if (ether_addr_equal(eth_hdr(skb)->h_dest,
151 master->dev->dev_addr)) {
152 skb->pkt_type = PACKET_HOST;
153 deliver_to_self = true;
154 }
155
156 node = hsr_find_node(&hsr->node_db, skb);
157
158 if (is_supervision_frame(hsr, skb)) {
159 skb_pull(skb, sizeof(struct hsr_sup_tag));
160 node = hsr_merge_node(node, skb, port);
161 if (!node) {
162 kfree_skb(skb);
163 master->dev->stats.rx_dropped++;
164 ret = RX_HANDLER_CONSUMED;
165 goto finish;
166 }
167 skb_push(skb, sizeof(struct hsr_sup_tag));
168 deliver_to_self = false;
169 }
170
171 if (!node) {
172 /* Source node unknown; this might be a HSR frame from
173 * another net (different multicast address). Ignore it.
174 */
175 kfree_skb(skb);
176 ret = RX_HANDLER_CONSUMED;
177 goto finish;
178 }
179
180 if (port->type == HSR_PT_SLAVE_A)
181 other_port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
182 else
183 other_port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
184
185 /* Register ALL incoming frames as outgoing through the other interface.
186 * This allows us to register frames as incoming only if they are valid
187 * for the receiving interface, without using a specific counter for
188 * incoming frames.
189 */
190 if (other_port)
191 dup_out = hsr_register_frame_out(node, other_port, skb);
192 else
193 dup_out = 0;
194 if (!dup_out)
195 hsr_register_frame_in(node, port);
196
197 /* Forward this frame? */
198 if (dup_out || (skb->pkt_type == PACKET_HOST))
199 other_port = NULL;
200
201 if (hsr_register_frame_out(node, master, skb))
202 deliver_to_self = false;
203
204 if (!deliver_to_self && !other_port) {
205 kfree_skb(skb);
206 /* Circulated frame; silently remove it. */
207 ret = RX_HANDLER_CONSUMED;
208 goto finish;
209 }
210
211 skb_deliver = skb;
212 if (deliver_to_self && other_port) {
213 /* skb_clone() is not enough since we will strip the hsr tag
214 * and do address substitution below
215 */
216 skb_deliver = pskb_copy(skb, GFP_ATOMIC);
217 if (!skb_deliver) {
218 deliver_to_self = false;
219 master->dev->stats.rx_dropped++;
220 }
221 }
222
223 if (deliver_to_self) {
224 bool multicast_frame;
225
226 skb_deliver = hsr_pull_tag(skb_deliver);
227 if (!skb_deliver) {
228 master->dev->stats.rx_dropped++;
229 goto forward;
230 }
231#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
232 /* Move everything in the header that is after the HSR tag,
233 * to work around alignment problems caused by the 6-byte HSR
234 * tag. In practice, this removes/overwrites the HSR tag in
235 * the header and restores a "standard" packet.
236 */
237 memmove(skb_deliver->data - HSR_HLEN, skb_deliver->data,
238 skb_headlen(skb_deliver));
239
240 /* Adjust skb members so they correspond with the move above.
241 * This cannot possibly underflow skb->data since hsr_pull_tag()
242 * above succeeded.
243 * At this point in the protocol stack, the transport and
244 * network headers have not been set yet, and we haven't touched
245 * the mac header nor the head. So we only need to adjust data
246 * and tail:
247 */
248 skb_deliver->data -= HSR_HLEN;
249 skb_deliver->tail -= HSR_HLEN;
250#endif
251 skb_deliver->dev = master->dev;
252 hsr_addr_subst_source(hsr, skb_deliver);
253 multicast_frame = (skb_deliver->pkt_type == PACKET_MULTICAST);
254 ret = netif_rx(skb_deliver);
255 if (ret == NET_RX_DROP) {
256 master->dev->stats.rx_dropped++;
257 } else {
258 master->dev->stats.rx_packets++;
259 master->dev->stats.rx_bytes += skb->len;
260 if (multicast_frame)
261 master->dev->stats.multicast++;
262 }
263 }
264
265forward:
266 if (other_port) {
267 skb_push(skb, ETH_HLEN);
268 skb->dev = other_port->dev;
269 dev_queue_xmit(skb);
270 }
271
272 ret = RX_HANDLER_CONSUMED;
273
274finish:
275 rcu_read_unlock();
276 return ret;
277}
278
279/* Setup device to be added to the HSR bridge. */ 100/* Setup device to be added to the HSR bridge. */
280static int hsr_portdev_setup(struct net_device *dev, struct hsr_port *port) 101static int hsr_portdev_setup(struct net_device *dev, struct hsr_port *port)
281{ 102{
@@ -285,16 +106,17 @@ static int hsr_portdev_setup(struct net_device *dev, struct hsr_port *port)
285 res = dev_set_promiscuity(dev, 1); 106 res = dev_set_promiscuity(dev, 1);
286 if (res) 107 if (res)
287 goto fail_promiscuity; 108 goto fail_promiscuity;
288 res = netdev_rx_handler_register(dev, hsr_handle_frame, port);
289 if (res)
290 goto fail_rx_handler;
291 dev_disable_lro(dev);
292 109
293 /* FIXME: 110 /* FIXME:
294 * What does net device "adjacency" mean? Should we do 111 * What does net device "adjacency" mean? Should we do
295 * res = netdev_master_upper_dev_link(port->dev, port->hsr->dev); ? 112 * res = netdev_master_upper_dev_link(port->dev, port->hsr->dev); ?
296 */ 113 */
297 114
115 res = netdev_rx_handler_register(dev, hsr_handle_frame, port);
116 if (res)
117 goto fail_rx_handler;
118 dev_disable_lro(dev);
119
298 return 0; 120 return 0;
299 121
300fail_rx_handler: 122fail_rx_handler:
@@ -339,11 +161,6 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev,
339 synchronize_rcu(); 161 synchronize_rcu();
340 162
341 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); 163 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
342
343 /* Set required header length */
344 if (dev->hard_header_len + HSR_HLEN > master->dev->hard_header_len)
345 master->dev->hard_header_len = dev->hard_header_len + HSR_HLEN;
346
347 netdev_update_features(master->dev); 164 netdev_update_features(master->dev);
348 dev_set_mtu(master->dev, hsr_get_max_mtu(hsr)); 165 dev_set_mtu(master->dev, hsr_get_max_mtu(hsr));
349 166
diff --git a/net/hsr/hsr_slave.h b/net/hsr/hsr_slave.h
index 3055022eddb3..3ccfbf71c92e 100644
--- a/net/hsr/hsr_slave.h
+++ b/net/hsr/hsr_slave.h
@@ -20,17 +20,7 @@
20int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, 20int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev,
21 enum hsr_port_type pt); 21 enum hsr_port_type pt);
22void hsr_del_port(struct hsr_port *port); 22void hsr_del_port(struct hsr_port *port);
23rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb); 23bool hsr_port_exists(const struct net_device *dev);
24
25
26#define hsr_for_each_port(hsr, port) \
27 list_for_each_entry_rcu((port), &(hsr)->ports, port_list)
28
29
30static inline bool hsr_port_exists(const struct net_device *dev)
31{
32 return dev->rx_handler == hsr_handle_frame;
33}
34 24
35static inline struct hsr_port *hsr_port_get_rtnl(const struct net_device *dev) 25static inline struct hsr_port *hsr_port_get_rtnl(const struct net_device *dev)
36{ 26{