Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Arvid Brodin and committed by
David S. Miller
f266a683 4c3477dc

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