1 /* Copyright 2011-2014 Autronica Fire and Security AS
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)
9 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
12 #include "hsr_slave.h"
13 #include <linux/etherdevice.h>
14 #include <linux/if_arp.h>
16 #include "hsr_device.h"
17 #include "hsr_framereg.h"
20 static int hsr_check_dev_ok(struct net_device
*dev
)
22 /* Don't allow HSR on non-ethernet like devices */
23 if ((dev
->flags
& IFF_LOOPBACK
) || (dev
->type
!= ARPHRD_ETHER
) ||
24 (dev
->addr_len
!= ETH_ALEN
)) {
25 netdev_info(dev
, "Cannot use loopback or non-ethernet device as HSR slave.\n");
29 /* Don't allow enslaving hsr devices */
30 if (is_hsr_master(dev
)) {
31 netdev_info(dev
, "Cannot create trees of HSR devices.\n");
35 if (hsr_port_exists(dev
)) {
36 netdev_info(dev
, "This device is already a HSR slave.\n");
40 if (dev
->priv_flags
& IFF_802_1Q_VLAN
) {
41 netdev_info(dev
, "HSR on top of VLAN is not yet supported in this driver.\n");
45 /* HSR over bonded devices has not been tested, but I'm not sure it
53 static struct sk_buff
*hsr_pull_tag(struct sk_buff
*skb
)
55 struct hsr_tag
*hsr_tag
;
58 skb2
= skb_share_check(skb
, GFP_ATOMIC
);
63 if (unlikely(!pskb_may_pull(skb
, HSR_HLEN
)))
66 hsr_tag
= (struct hsr_tag
*) skb
->data
;
67 skb
->protocol
= hsr_tag
->encap_proto
;
68 skb_pull(skb
, HSR_HLEN
);
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.
83 * Or not - resetting the counter and bridging the frame would create a
84 * loop, unfortunately.
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.
90 * 3) Allow different MAC addresses for the two slave interfaces, using the
93 static bool is_supervision_frame(struct hsr_priv
*hsr
, struct sk_buff
*skb
)
95 struct hsr_sup_tag
*hsr_stag
;
97 if (!ether_addr_equal(eth_hdr(skb
)->h_dest
,
98 hsr
->sup_multicast_addr
))
101 hsr_stag
= (struct hsr_sup_tag
*) skb
->data
;
102 if (get_hsr_stag_path(hsr_stag
) != 0x0f)
104 if ((hsr_stag
->HSR_TLV_Type
!= HSR_TLV_ANNOUNCE
) &&
105 (hsr_stag
->HSR_TLV_Type
!= HSR_TLV_LIFE_CHECK
))
107 if (hsr_stag
->HSR_TLV_Length
!= 12)
114 /* Implementation somewhat according to IEC-62439-3, p. 43
116 rx_handler_result_t
hsr_handle_frame(struct sk_buff
**pskb
)
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
;
127 if (eth_hdr(skb
)->h_proto
!= htons(ETH_P_PRP
))
128 return RX_HANDLER_PASS
;
130 rcu_read_lock(); /* ports & node */
132 port
= hsr_port_get_rcu(skb
->dev
);
134 master
= hsr_port_get_hsr(hsr
, HSR_PT_MASTER
);
136 node
= hsr_find_node(&hsr
->self_node_db
, skb
);
138 /* Always kill frames sent by ourselves */
140 ret
= RX_HANDLER_CONSUMED
;
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;
156 node
= hsr_find_node(&hsr
->node_db
, skb
);
158 if (is_supervision_frame(hsr
, skb
)) {
159 skb_pull(skb
, sizeof(struct hsr_sup_tag
));
160 node
= hsr_merge_node(node
, skb
, port
);
163 master
->dev
->stats
.rx_dropped
++;
164 ret
= RX_HANDLER_CONSUMED
;
167 skb_push(skb
, sizeof(struct hsr_sup_tag
));
168 deliver_to_self
= false;
172 /* Source node unknown; this might be a HSR frame from
173 * another net (different multicast address). Ignore it.
176 ret
= RX_HANDLER_CONSUMED
;
180 if (port
->type
== HSR_PT_SLAVE_A
)
181 other_port
= hsr_port_get_hsr(hsr
, HSR_PT_SLAVE_B
);
183 other_port
= hsr_port_get_hsr(hsr
, HSR_PT_SLAVE_A
);
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
191 dup_out
= hsr_register_frame_out(node
, other_port
, skb
);
195 hsr_register_frame_in(node
, port
);
197 /* Forward this frame? */
198 if (dup_out
|| (skb
->pkt_type
== PACKET_HOST
))
201 if (hsr_register_frame_out(node
, master
, skb
))
202 deliver_to_self
= false;
204 if (!deliver_to_self
&& !other_port
) {
206 /* Circulated frame; silently remove it. */
207 ret
= RX_HANDLER_CONSUMED
;
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
216 skb_deliver
= pskb_copy(skb
, GFP_ATOMIC
);
218 deliver_to_self
= false;
219 master
->dev
->stats
.rx_dropped
++;
223 if (deliver_to_self
) {
224 bool multicast_frame
;
226 skb_deliver
= hsr_pull_tag(skb_deliver
);
228 master
->dev
->stats
.rx_dropped
++;
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.
237 memmove(skb_deliver
->data
- HSR_HLEN
, skb_deliver
->data
,
238 skb_headlen(skb_deliver
));
240 /* Adjust skb members so they correspond with the move above.
241 * This cannot possibly underflow skb->data since hsr_pull_tag()
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
248 skb_deliver
->data
-= HSR_HLEN
;
249 skb_deliver
->tail
-= HSR_HLEN
;
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
++;
258 master
->dev
->stats
.rx_packets
++;
259 master
->dev
->stats
.rx_bytes
+= skb
->len
;
261 master
->dev
->stats
.multicast
++;
267 skb_push(skb
, ETH_HLEN
);
268 skb
->dev
= other_port
->dev
;
272 ret
= RX_HANDLER_CONSUMED
;
279 /* Setup device to be added to the HSR bridge. */
280 static int hsr_portdev_setup(struct net_device
*dev
, struct hsr_port
*port
)
285 res
= dev_set_promiscuity(dev
, 1);
287 goto fail_promiscuity
;
288 res
= netdev_rx_handler_register(dev
, hsr_handle_frame
, port
);
290 goto fail_rx_handler
;
291 dev_disable_lro(dev
);
294 * What does net device "adjacency" mean? Should we do
295 * res = netdev_master_upper_dev_link(port->dev, port->hsr->dev); ?
301 dev_set_promiscuity(dev
, -1);
308 int hsr_add_port(struct hsr_priv
*hsr
, struct net_device
*dev
,
309 enum hsr_port_type type
)
311 struct hsr_port
*port
, *master
;
314 if (type
!= HSR_PT_MASTER
) {
315 res
= hsr_check_dev_ok(dev
);
320 port
= hsr_port_get_hsr(hsr
, type
);
322 return -EBUSY
; /* This port already exists */
324 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
328 if (type
!= HSR_PT_MASTER
) {
329 res
= hsr_portdev_setup(dev
, port
);
338 list_add_tail_rcu(&port
->port_list
, &hsr
->ports
);
341 master
= hsr_port_get_hsr(hsr
, HSR_PT_MASTER
);
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
;
347 dev_set_mtu(master
->dev
, hsr_get_max_mtu(hsr
));
356 void hsr_del_port(struct hsr_port
*port
)
358 struct hsr_priv
*hsr
;
359 struct hsr_port
*master
;
362 master
= hsr_port_get_hsr(hsr
, HSR_PT_MASTER
);
363 list_del_rcu(&port
->port_list
);
365 if (port
!= master
) {
366 dev_set_mtu(master
->dev
, hsr_get_max_mtu(hsr
));
367 netdev_rx_handler_unregister(port
->dev
);
368 dev_set_promiscuity(port
->dev
, -1);
372 * netdev_upper_dev_unlink(port->dev, port->hsr->dev);
This page took 0.048407 seconds and 5 git commands to generate.