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 check_slave_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 (is_hsr_slave(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 net_device
*dev
= skb
->dev
;
120 struct hsr_priv
*hsr
;
121 struct net_device
*other_slave
;
122 struct hsr_node
*node
;
123 bool deliver_to_self
;
124 struct sk_buff
*skb_deliver
;
125 enum hsr_dev_idx dev_in_idx
, dev_other_idx
;
129 if (eth_hdr(skb
)->h_proto
!= htons(ETH_P_PRP
))
130 return RX_HANDLER_PASS
;
132 hsr
= get_hsr_master(dev
);
135 return RX_HANDLER_PASS
;
138 if (dev
== hsr
->slave
[0]) {
139 dev_in_idx
= HSR_DEV_SLAVE_A
;
140 dev_other_idx
= HSR_DEV_SLAVE_B
;
142 dev_in_idx
= HSR_DEV_SLAVE_B
;
143 dev_other_idx
= HSR_DEV_SLAVE_A
;
146 node
= hsr_find_node(&hsr
->self_node_db
, skb
);
148 /* Always kill frames sent by ourselves */
150 return RX_HANDLER_CONSUMED
;
153 /* Is this frame a candidate for local reception? */
154 deliver_to_self
= false;
155 if ((skb
->pkt_type
== PACKET_HOST
) ||
156 (skb
->pkt_type
== PACKET_MULTICAST
) ||
157 (skb
->pkt_type
== PACKET_BROADCAST
))
158 deliver_to_self
= true;
159 else if (ether_addr_equal(eth_hdr(skb
)->h_dest
, hsr
->dev
->dev_addr
)) {
160 skb
->pkt_type
= PACKET_HOST
;
161 deliver_to_self
= true;
165 rcu_read_lock(); /* node_db */
166 node
= hsr_find_node(&hsr
->node_db
, skb
);
168 if (is_supervision_frame(hsr
, skb
)) {
169 skb_pull(skb
, sizeof(struct hsr_sup_tag
));
170 node
= hsr_merge_node(hsr
, node
, skb
, dev_in_idx
);
172 rcu_read_unlock(); /* node_db */
174 hsr
->dev
->stats
.rx_dropped
++;
175 return RX_HANDLER_CONSUMED
;
177 skb_push(skb
, sizeof(struct hsr_sup_tag
));
178 deliver_to_self
= false;
182 /* Source node unknown; this might be a HSR frame from
183 * another net (different multicast address). Ignore it.
185 rcu_read_unlock(); /* node_db */
187 return RX_HANDLER_CONSUMED
;
190 /* Register ALL incoming frames as outgoing through the other interface.
191 * This allows us to register frames as incoming only if they are valid
192 * for the receiving interface, without using a specific counter for
195 dup_out
= hsr_register_frame_out(node
, dev_other_idx
, skb
);
197 hsr_register_frame_in(node
, dev_in_idx
);
199 /* Forward this frame? */
200 if (!dup_out
&& (skb
->pkt_type
!= PACKET_HOST
))
201 other_slave
= get_other_slave(hsr
, dev
);
205 if (hsr_register_frame_out(node
, HSR_DEV_MASTER
, skb
))
206 deliver_to_self
= false;
208 rcu_read_unlock(); /* node_db */
210 if (!deliver_to_self
&& !other_slave
) {
212 /* Circulated frame; silently remove it. */
213 return RX_HANDLER_CONSUMED
;
217 if (deliver_to_self
&& other_slave
) {
218 /* skb_clone() is not enough since we will strip the hsr tag
219 * and do address substitution below
221 skb_deliver
= pskb_copy(skb
, GFP_ATOMIC
);
223 deliver_to_self
= false;
224 hsr
->dev
->stats
.rx_dropped
++;
228 if (deliver_to_self
) {
229 bool multicast_frame
;
231 skb_deliver
= hsr_pull_tag(skb_deliver
);
233 hsr
->dev
->stats
.rx_dropped
++;
236 #if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
237 /* Move everything in the header that is after the HSR tag,
238 * to work around alignment problems caused by the 6-byte HSR
239 * tag. In practice, this removes/overwrites the HSR tag in
240 * the header and restores a "standard" packet.
242 memmove(skb_deliver
->data
- HSR_HLEN
, skb_deliver
->data
,
243 skb_headlen(skb_deliver
));
245 /* Adjust skb members so they correspond with the move above.
246 * This cannot possibly underflow skb->data since hsr_pull_tag()
248 * At this point in the protocol stack, the transport and
249 * network headers have not been set yet, and we haven't touched
250 * the mac header nor the head. So we only need to adjust data
253 skb_deliver
->data
-= HSR_HLEN
;
254 skb_deliver
->tail
-= HSR_HLEN
;
256 skb_deliver
->dev
= hsr
->dev
;
257 hsr_addr_subst_source(hsr
, skb_deliver
);
258 multicast_frame
= (skb_deliver
->pkt_type
== PACKET_MULTICAST
);
259 ret
= netif_rx(skb_deliver
);
260 if (ret
== NET_RX_DROP
) {
261 hsr
->dev
->stats
.rx_dropped
++;
263 hsr
->dev
->stats
.rx_packets
++;
264 hsr
->dev
->stats
.rx_bytes
+= skb
->len
;
266 hsr
->dev
->stats
.multicast
++;
272 skb_push(skb
, ETH_HLEN
);
273 skb
->dev
= other_slave
;
277 return RX_HANDLER_CONSUMED
;
280 int hsr_add_slave(struct hsr_priv
*hsr
, struct net_device
*dev
, int idx
)
286 res
= check_slave_ok(dev
);
290 res
= dev_set_promiscuity(dev
, 1);
294 res
= netdev_rx_handler_register(dev
, hsr_handle_frame
, hsr
);
296 goto fail_rx_handler
;
299 hsr
->slave
[idx
] = dev
;
301 /* Set required header length */
302 if (dev
->hard_header_len
+ HSR_HLEN
> hsr
->dev
->hard_header_len
)
303 hsr
->dev
->hard_header_len
= dev
->hard_header_len
+ HSR_HLEN
;
305 dev_set_mtu(hsr
->dev
, hsr_get_max_mtu(hsr
));
310 dev_set_promiscuity(dev
, -1);
317 void hsr_del_slave(struct hsr_priv
*hsr
, int idx
)
319 struct net_device
*slave
;
321 slave
= hsr
->slave
[idx
];
322 hsr
->slave
[idx
] = NULL
;
324 netdev_update_features(hsr
->dev
);
325 dev_set_mtu(hsr
->dev
, hsr_get_max_mtu(hsr
));
328 netdev_rx_handler_unregister(slave
);
329 dev_set_promiscuity(slave
, -1);
This page took 0.039171 seconds and 6 git commands to generate.