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

net: prp: add packet handling support

DAN-P (Dual Attached Nodes PRP) nodes are expected to receive
traditional IP packets as well as PRP (Parallel Redundancy
Protocol) tagged (trailer) packets. PRP trailer is 6 bytes
of PRP protocol unit called RCT, Redundancy Control Trailer
(RCT) similar to HSR tag. PRP network can have traditional
devices such as bridges/switches or PC attached to it and
should be able to communicate. Regular Ethernet devices treat
the RCT as pads. This patch adds logic to format L2 frames
from network stack to add a trailer (RCT) and send it as
duplicates over the slave interfaces when the protocol is
PRP as per IEC 62439-3. At the ingress, it strips the trailer,
do duplicate detection and rejection and forward a stripped
frame up the network stack. PRP device should accept frames
from Singly Attached Nodes (SAN) and thus the driver mark
the link where the frame came from in the node table.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Murali Karicheri and committed by
David S. Miller
451d8123 fa4dc895

+433 -88
+14 -6
net/hsr/hsr_device.c
··· 443 443 .create_tagged_frame = hsr_create_tagged_frame, 444 444 .get_untagged_frame = hsr_get_untagged_frame, 445 445 .fill_frame_info = hsr_fill_frame_info, 446 + .invalid_dan_ingress_frame = hsr_invalid_dan_ingress_frame, 446 447 }; 447 448 448 449 static struct hsr_proto_ops prp_ops = { 449 450 .send_sv_frame = send_prp_supervision_frame, 451 + .create_tagged_frame = prp_create_tagged_frame, 452 + .get_untagged_frame = prp_get_untagged_frame, 453 + .drop_frame = prp_drop_frame, 454 + .fill_frame_info = prp_fill_frame_info, 455 + .handle_san_frame = prp_handle_san_frame, 456 + .update_san_info = prp_update_san_info, 450 457 }; 451 458 452 459 void hsr_dev_setup(struct net_device *dev) ··· 515 508 516 509 ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); 517 510 518 - /* currently PRP is not supported */ 519 - if (protocol_version == PRP_V1) 520 - return -EPROTONOSUPPORT; 521 - 522 511 /* initialize protocol specific functions */ 523 - if (protocol_version == PRP_V1) 512 + if (protocol_version == PRP_V1) { 513 + /* For PRP, lan_id has most significant 3 bits holding 514 + * the net_id of PRP_LAN_ID 515 + */ 516 + hsr->net_id = PRP_LAN_ID << 1; 524 517 hsr->proto_ops = &prp_ops; 525 - else 518 + } else { 526 519 hsr->proto_ops = &hsr_ops; 520 + } 527 521 528 522 /* Make sure we recognize frames from ourselves in hsr_rcv() */ 529 523 res = hsr_create_self_node(hsr, hsr_dev->dev_addr,
+215 -57
net/hsr/hsr_forward.c
··· 17 17 18 18 struct hsr_node; 19 19 20 - struct hsr_frame_info { 21 - struct sk_buff *skb_std; 22 - struct sk_buff *skb_hsr; 23 - struct hsr_port *port_rcv; 24 - struct hsr_node *node_src; 25 - u16 sequence_nr; 26 - bool is_supervision; 27 - bool is_vlan; 28 - bool is_local_dest; 29 - bool is_local_exclusive; 30 - }; 31 - 32 20 /* The uses I can see for these HSR supervision frames are: 33 21 * 1) Use the frames that are sent after node initialization ("HSR_TLV.Type = 34 22 * 22") to reset any sequence_nr counters belonging to that node. Useful if ··· 75 87 return true; 76 88 } 77 89 78 - static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, 79 - struct hsr_frame_info *frame) 90 + static struct sk_buff *create_stripped_skb_hsr(struct sk_buff *skb_in, 91 + struct hsr_frame_info *frame) 80 92 { 81 93 struct sk_buff *skb; 82 94 int copylen; ··· 107 119 struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, 108 120 struct hsr_port *port) 109 121 { 110 - if (!frame->skb_std) 111 - frame->skb_std = create_stripped_skb(frame->skb_hsr, frame); 122 + if (!frame->skb_std) { 123 + if (frame->skb_hsr) { 124 + frame->skb_std = 125 + create_stripped_skb_hsr(frame->skb_hsr, frame); 126 + } else { 127 + /* Unexpected */ 128 + WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", 129 + __FILE__, __LINE__, port->dev->name); 130 + return NULL; 131 + } 132 + } 133 + 112 134 return skb_clone(frame->skb_std, GFP_ATOMIC); 135 + } 136 + 137 + struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame, 138 + struct hsr_port *port) 139 + { 140 + if (!frame->skb_std) { 141 + if (frame->skb_prp) { 142 + /* trim the skb by len - HSR_HLEN to exclude RCT */ 143 + skb_trim(frame->skb_prp, 144 + frame->skb_prp->len - HSR_HLEN); 145 + frame->skb_std = 146 + __pskb_copy(frame->skb_prp, 147 + skb_headroom(frame->skb_prp), 148 + GFP_ATOMIC); 149 + } else { 150 + /* Unexpected */ 151 + WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", 152 + __FILE__, __LINE__, port->dev->name); 153 + return NULL; 154 + } 155 + } 156 + 157 + return skb_clone(frame->skb_std, GFP_ATOMIC); 158 + } 159 + 160 + static void prp_set_lan_id(struct prp_rct *trailer, 161 + struct hsr_port *port) 162 + { 163 + int lane_id; 164 + 165 + if (port->type == HSR_PT_SLAVE_A) 166 + lane_id = 0; 167 + else 168 + lane_id = 1; 169 + 170 + /* Add net_id in the upper 3 bits of lane_id */ 171 + lane_id |= port->hsr->net_id; 172 + set_prp_lan_id(trailer, lane_id); 173 + } 174 + 175 + /* Tailroom for PRP rct should have been created before calling this */ 176 + static struct sk_buff *prp_fill_rct(struct sk_buff *skb, 177 + struct hsr_frame_info *frame, 178 + struct hsr_port *port) 179 + { 180 + struct prp_rct *trailer; 181 + int min_size = ETH_ZLEN; 182 + int lsdu_size; 183 + 184 + if (!skb) 185 + return skb; 186 + 187 + if (frame->is_vlan) 188 + min_size = VLAN_ETH_ZLEN; 189 + 190 + if (skb_put_padto(skb, min_size)) 191 + return NULL; 192 + 193 + trailer = (struct prp_rct *)skb_put(skb, HSR_HLEN); 194 + lsdu_size = skb->len - 14; 195 + if (frame->is_vlan) 196 + lsdu_size -= 4; 197 + prp_set_lan_id(trailer, port); 198 + set_prp_LSDU_size(trailer, lsdu_size); 199 + trailer->sequence_nr = htons(frame->sequence_nr); 200 + trailer->PRP_suffix = htons(ETH_P_PRP); 201 + 202 + return skb; 203 + } 204 + 205 + static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr, 206 + struct hsr_port *port) 207 + { 208 + int path_id; 209 + 210 + if (port->type == HSR_PT_SLAVE_A) 211 + path_id = 0; 212 + else 213 + path_id = 1; 214 + 215 + set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id); 113 216 } 114 217 115 218 static struct sk_buff *hsr_fill_tag(struct sk_buff *skb, ··· 208 129 struct hsr_port *port, u8 proto_version) 209 130 { 210 131 struct hsr_ethhdr *hsr_ethhdr; 211 - int lane_id; 212 132 int lsdu_size; 213 133 214 134 /* pad to minimum packet size which is 60 + 6 (HSR tag) */ 215 135 if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) 216 136 return NULL; 217 - 218 - if (port->type == HSR_PT_SLAVE_A) 219 - lane_id = 0; 220 - else 221 - lane_id = 1; 222 137 223 138 lsdu_size = skb->len - 14; 224 139 if (frame->is_vlan) ··· 220 147 221 148 hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb); 222 149 223 - set_hsr_tag_path(&hsr_ethhdr->hsr_tag, lane_id); 150 + hsr_set_path_id(hsr_ethhdr, port); 224 151 set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size); 225 152 hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr); 226 153 hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; ··· 230 157 return skb; 231 158 } 232 159 233 - static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, 234 - struct hsr_frame_info *frame, 235 - struct hsr_port *port) 160 + /* If the original frame was an HSR tagged frame, just clone it to be sent 161 + * unchanged. Otherwise, create a private frame especially tagged for 'port'. 162 + */ 163 + struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, 164 + struct hsr_port *port) 236 165 { 237 - int movelen; 238 166 unsigned char *dst, *src; 239 167 struct sk_buff *skb; 168 + int movelen; 169 + 170 + if (frame->skb_hsr) { 171 + struct hsr_ethhdr *hsr_ethhdr = 172 + (struct hsr_ethhdr *)skb_mac_header(frame->skb_hsr); 173 + 174 + /* set the lane id properly */ 175 + hsr_set_path_id(hsr_ethhdr, port); 176 + return skb_clone(frame->skb_hsr, GFP_ATOMIC); 177 + } 240 178 241 179 /* Create the new skb with enough headroom to fit the HSR tag */ 242 - skb = __pskb_copy(skb_o, skb_headroom(skb_o) + HSR_HLEN, GFP_ATOMIC); 180 + skb = __pskb_copy(frame->skb_std, 181 + skb_headroom(frame->skb_std) + HSR_HLEN, GFP_ATOMIC); 243 182 if (!skb) 244 183 return NULL; 245 184 skb_reset_mac_header(skb); ··· 274 189 return hsr_fill_tag(skb, frame, port, port->hsr->prot_version); 275 190 } 276 191 277 - /* If the original frame was an HSR tagged frame, just clone it to be sent 278 - * unchanged. Otherwise, create a private frame especially tagged for 'port'. 279 - */ 280 - struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, 192 + struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame, 281 193 struct hsr_port *port) 282 194 { 283 - if (frame->skb_hsr) 284 - return skb_clone(frame->skb_hsr, GFP_ATOMIC); 195 + struct sk_buff *skb; 285 196 286 - if (port->type != HSR_PT_SLAVE_A && port->type != HSR_PT_SLAVE_B) { 287 - WARN_ONCE(1, "HSR: Bug: trying to create a tagged frame for a non-ring port"); 288 - return NULL; 197 + if (frame->skb_prp) { 198 + struct prp_rct *trailer = skb_get_PRP_rct(frame->skb_prp); 199 + 200 + if (trailer) { 201 + prp_set_lan_id(trailer, port); 202 + } else { 203 + WARN_ONCE(!trailer, "errored PRP skb"); 204 + return NULL; 205 + } 206 + return skb_clone(frame->skb_prp, GFP_ATOMIC); 289 207 } 290 208 291 - return create_tagged_skb(frame->skb_std, frame, port); 209 + skb = skb_copy_expand(frame->skb_std, 0, 210 + skb_tailroom(frame->skb_std) + HSR_HLEN, 211 + GFP_ATOMIC); 212 + prp_fill_rct(skb, frame, port); 213 + 214 + return skb; 292 215 } 293 216 294 217 static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev, ··· 333 240 return dev_queue_xmit(skb); 334 241 } 335 242 243 + bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port) 244 + { 245 + return ((frame->port_rcv->type == HSR_PT_SLAVE_A && 246 + port->type == HSR_PT_SLAVE_B) || 247 + (frame->port_rcv->type == HSR_PT_SLAVE_B && 248 + port->type == HSR_PT_SLAVE_A)); 249 + } 250 + 336 251 /* Forward the frame through all devices except: 337 252 * - Back through the receiving device 338 253 * - If it's a HSR frame: through a device where it has passed before 254 + * - if it's a PRP frame: through another PRP slave device (no bridge) 339 255 * - To the local HSR master only if the frame is directly addressed to it, or 340 256 * a non-supervision multicast or broadcast frame. 341 257 * ··· 372 270 if (port->type != HSR_PT_MASTER && frame->is_local_exclusive) 373 271 continue; 374 272 375 - /* Don't send frame over port where it has been sent before */ 376 - if (hsr_register_frame_out(port, frame->node_src, 273 + /* Don't send frame over port where it has been sent before. 274 + * Also fro SAN, this shouldn't be done. 275 + */ 276 + if (!frame->is_from_san && 277 + hsr_register_frame_out(port, frame->node_src, 377 278 frame->sequence_nr)) 378 279 continue; 379 280 380 281 if (frame->is_supervision && port->type == HSR_PT_MASTER) { 381 - hsr_handle_sup_frame(frame->skb_hsr, 382 - frame->node_src, 383 - frame->port_rcv); 282 + hsr_handle_sup_frame(frame); 384 283 continue; 385 284 } 285 + 286 + /* Check if frame is to be dropped. Eg. for PRP no forward 287 + * between ports. 288 + */ 289 + if (hsr->proto_ops->drop_frame && 290 + hsr->proto_ops->drop_frame(frame, port)) 291 + continue; 386 292 387 293 if (port->type != HSR_PT_MASTER) 388 294 skb = hsr->proto_ops->create_tagged_frame(frame, port); ··· 398 288 skb = hsr->proto_ops->get_untagged_frame(frame, port); 399 289 400 290 if (!skb) { 401 - /* FIXME: Record the dropped frame? */ 291 + frame->port_rcv->dev->stats.rx_dropped++; 402 292 continue; 403 293 } 404 294 ··· 429 319 } 430 320 } 431 321 432 - void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, 433 - struct hsr_frame_info *frame) 322 + static void handle_std_frame(struct sk_buff *skb, 323 + struct hsr_frame_info *frame) 434 324 { 435 - struct hsr_priv *hsr = frame->port_rcv->hsr; 325 + struct hsr_port *port = frame->port_rcv; 326 + struct hsr_priv *hsr = port->hsr; 436 327 unsigned long irqflags; 437 328 438 - if (proto == htons(ETH_P_PRP) || proto == htons(ETH_P_HSR)) { 439 - frame->skb_std = NULL; 440 - frame->skb_hsr = skb; 441 - frame->sequence_nr = hsr_get_skb_sequence_nr(skb); 329 + frame->skb_hsr = NULL; 330 + frame->skb_prp = NULL; 331 + frame->skb_std = skb; 332 + 333 + if (port->type != HSR_PT_MASTER) { 334 + frame->is_from_san = true; 442 335 } else { 443 - frame->skb_std = skb; 444 - frame->skb_hsr = NULL; 445 336 /* Sequence nr for the master node */ 446 337 spin_lock_irqsave(&hsr->seqnr_lock, irqflags); 447 338 frame->sequence_nr = hsr->sequence_nr; ··· 451 340 } 452 341 } 453 342 343 + void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, 344 + struct hsr_frame_info *frame) 345 + { 346 + if (proto == htons(ETH_P_PRP) || 347 + proto == htons(ETH_P_HSR)) { 348 + /* HSR tagged frame :- Data or Supervision */ 349 + frame->skb_std = NULL; 350 + frame->skb_prp = NULL; 351 + frame->skb_hsr = skb; 352 + frame->sequence_nr = hsr_get_skb_sequence_nr(skb); 353 + return; 354 + } 355 + 356 + /* Standard frame or PRP from master port */ 357 + handle_std_frame(skb, frame); 358 + } 359 + 360 + void prp_fill_frame_info(__be16 proto, struct sk_buff *skb, 361 + struct hsr_frame_info *frame) 362 + { 363 + /* Supervision frame */ 364 + struct prp_rct *rct = skb_get_PRP_rct(skb); 365 + 366 + if (rct && 367 + prp_check_lsdu_size(skb, rct, frame->is_supervision)) { 368 + frame->skb_hsr = NULL; 369 + frame->skb_std = NULL; 370 + frame->skb_prp = skb; 371 + frame->sequence_nr = prp_get_skb_sequence_nr(rct); 372 + return; 373 + } 374 + handle_std_frame(skb, frame); 375 + } 376 + 454 377 static int fill_frame_info(struct hsr_frame_info *frame, 455 378 struct sk_buff *skb, struct hsr_port *port) 456 379 { 457 380 struct hsr_priv *hsr = port->hsr; 381 + struct hsr_vlan_ethhdr *vlan_hdr; 458 382 struct ethhdr *ethhdr; 459 383 __be16 proto; 460 384 385 + memset(frame, 0, sizeof(*frame)); 461 386 frame->is_supervision = is_supervision_frame(port->hsr, skb); 462 - frame->node_src = hsr_get_node(port, skb, frame->is_supervision); 387 + frame->node_src = hsr_get_node(port, &hsr->node_db, skb, 388 + frame->is_supervision, 389 + port->type); 463 390 if (!frame->node_src) 464 391 return -1; /* Unknown node and !is_supervision, or no mem */ 465 392 466 393 ethhdr = (struct ethhdr *)skb_mac_header(skb); 467 394 frame->is_vlan = false; 468 - if (ethhdr->h_proto == htons(ETH_P_8021Q)) { 395 + proto = ethhdr->h_proto; 396 + 397 + if (proto == htons(ETH_P_8021Q)) 469 398 frame->is_vlan = true; 399 + 400 + if (frame->is_vlan) { 401 + vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; 402 + proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; 470 403 /* FIXME: */ 471 404 netdev_warn_once(skb->dev, "VLAN not yet supported"); 472 405 } 473 - proto = ethhdr->h_proto; 406 + 407 + frame->is_from_san = false; 474 408 frame->port_rcv = port; 475 409 hsr->proto_ops->fill_frame_info(proto, skb, frame); 476 - check_local_dest(hsr, skb, frame); 410 + check_local_dest(port->hsr, skb, frame); 477 411 478 412 return 0; 479 413 } ··· 536 380 537 381 if (fill_frame_info(&frame, skb, port) < 0) 538 382 goto out_drop; 383 + 539 384 hsr_register_frame_in(frame.node_src, port, frame.sequence_nr); 540 385 hsr_forward_do(&frame); 541 386 /* Gets called for ingress frames as well as egress from master port. ··· 548 391 } 549 392 550 393 kfree_skb(frame.skb_hsr); 394 + kfree_skb(frame.skb_prp); 551 395 kfree_skb(frame.skb_std); 552 396 return; 553 397
+7
net/hsr/hsr_forward.h
··· 14 14 #include "hsr_main.h" 15 15 16 16 void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port); 17 + struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame, 18 + struct hsr_port *port); 17 19 struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, 18 20 struct hsr_port *port); 19 21 struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, 20 22 struct hsr_port *port); 23 + struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame, 24 + struct hsr_port *port); 25 + bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port); 26 + void prp_fill_frame_info(__be16 proto, struct sk_buff *skb, 27 + struct hsr_frame_info *frame); 21 28 void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, 22 29 struct hsr_frame_info *frame); 23 30 #endif /* __HSR_FORWARD_H */
+75 -19
net/hsr/hsr_framereg.c
··· 127 127 kfree(node); 128 128 } 129 129 130 + void prp_handle_san_frame(bool san, enum hsr_port_type port, 131 + struct hsr_node *node) 132 + { 133 + /* Mark if the SAN node is over LAN_A or LAN_B */ 134 + if (port == HSR_PT_SLAVE_A) { 135 + node->san_a = true; 136 + return; 137 + } 138 + 139 + if (port == HSR_PT_SLAVE_B) 140 + node->san_b = true; 141 + } 142 + 130 143 /* Allocate an hsr_node and add it to node_db. 'addr' is the node's address_A; 131 144 * seq_out is used to initialize filtering of outgoing duplicate frames 132 145 * originating from the newly added node. ··· 147 134 static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, 148 135 struct list_head *node_db, 149 136 unsigned char addr[], 150 - u16 seq_out) 137 + u16 seq_out, bool san, 138 + enum hsr_port_type rx_port) 151 139 { 152 140 struct hsr_node *new_node, *node; 153 141 unsigned long now; ··· 169 155 for (i = 0; i < HSR_PT_PORTS; i++) 170 156 new_node->seq_out[i] = seq_out; 171 157 158 + if (san && hsr->proto_ops->handle_san_frame) 159 + hsr->proto_ops->handle_san_frame(san, rx_port, new_node); 160 + 172 161 spin_lock_bh(&hsr->list_lock); 173 162 list_for_each_entry_rcu(node, node_db, mac_list, 174 163 lockdep_is_held(&hsr->list_lock)) { ··· 189 172 return node; 190 173 } 191 174 175 + void prp_update_san_info(struct hsr_node *node, bool is_sup) 176 + { 177 + if (!is_sup) 178 + return; 179 + 180 + node->san_a = false; 181 + node->san_b = false; 182 + } 183 + 192 184 /* Get the hsr_node from which 'skb' was sent. 193 185 */ 194 - struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, 195 - bool is_sup) 186 + struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db, 187 + struct sk_buff *skb, bool is_sup, 188 + enum hsr_port_type rx_port) 196 189 { 197 - struct list_head *node_db = &port->hsr->node_db; 198 190 struct hsr_priv *hsr = port->hsr; 199 191 struct hsr_node *node; 200 192 struct ethhdr *ethhdr; 193 + struct prp_rct *rct; 194 + bool san = false; 201 195 u16 seq_out; 202 196 203 197 if (!skb_mac_header_was_set(skb)) ··· 217 189 ethhdr = (struct ethhdr *)skb_mac_header(skb); 218 190 219 191 list_for_each_entry_rcu(node, node_db, mac_list) { 220 - if (ether_addr_equal(node->macaddress_A, ethhdr->h_source)) 192 + if (ether_addr_equal(node->macaddress_A, ethhdr->h_source)) { 193 + if (hsr->proto_ops->update_san_info) 194 + hsr->proto_ops->update_san_info(node, is_sup); 221 195 return node; 222 - if (ether_addr_equal(node->macaddress_B, ethhdr->h_source)) 196 + } 197 + if (ether_addr_equal(node->macaddress_B, ethhdr->h_source)) { 198 + if (hsr->proto_ops->update_san_info) 199 + hsr->proto_ops->update_san_info(node, is_sup); 223 200 return node; 201 + } 224 202 } 225 203 226 - /* Everyone may create a node entry, connected node to a HSR device. */ 227 - 204 + /* Everyone may create a node entry, connected node to a HSR/PRP 205 + * device. 206 + */ 228 207 if (ethhdr->h_proto == htons(ETH_P_PRP) || 229 208 ethhdr->h_proto == htons(ETH_P_HSR)) { 230 209 /* Use the existing sequence_nr from the tag as starting point ··· 239 204 */ 240 205 seq_out = hsr_get_skb_sequence_nr(skb) - 1; 241 206 } else { 242 - /* this is called also for frames from master port and 243 - * so warn only for non master ports 244 - */ 245 - if (port->type != HSR_PT_MASTER) 246 - WARN_ONCE(1, "%s: Non-HSR frame\n", __func__); 247 - seq_out = HSR_SEQNR_START; 207 + rct = skb_get_PRP_rct(skb); 208 + if (rct && prp_check_lsdu_size(skb, rct, is_sup)) { 209 + seq_out = prp_get_skb_sequence_nr(rct); 210 + } else { 211 + if (rx_port != HSR_PT_MASTER) 212 + san = true; 213 + seq_out = HSR_SEQNR_START; 214 + } 248 215 } 249 216 250 - return hsr_add_node(hsr, node_db, ethhdr->h_source, seq_out); 217 + return hsr_add_node(hsr, node_db, ethhdr->h_source, seq_out, 218 + san, rx_port); 251 219 } 252 220 253 221 /* Use the Supervision frame's info about an eventual macaddress_B for merging 254 222 * nodes that has previously had their macaddress_B registered as a separate 255 223 * node. 256 224 */ 257 - void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, 258 - struct hsr_port *port_rcv) 225 + void hsr_handle_sup_frame(struct hsr_frame_info *frame) 259 226 { 227 + struct hsr_node *node_curr = frame->node_src; 228 + struct hsr_port *port_rcv = frame->port_rcv; 260 229 struct hsr_priv *hsr = port_rcv->hsr; 261 230 struct hsr_sup_payload *hsr_sp; 262 231 struct hsr_node *node_real; 232 + struct sk_buff *skb = NULL; 263 233 struct list_head *node_db; 264 234 struct ethhdr *ethhdr; 265 235 int i; 236 + 237 + /* Here either frame->skb_hsr or frame->skb_prp should be 238 + * valid as supervision frame always will have protocol 239 + * header info. 240 + */ 241 + if (frame->skb_hsr) 242 + skb = frame->skb_hsr; 243 + else if (frame->skb_prp) 244 + skb = frame->skb_prp; 245 + if (!skb) 246 + return; 266 247 267 248 ethhdr = (struct ethhdr *)skb_mac_header(skb); 268 249 ··· 300 249 if (!node_real) 301 250 /* No frame received from AddrA of this node yet */ 302 251 node_real = hsr_add_node(hsr, node_db, hsr_sp->macaddress_A, 303 - HSR_SEQNR_START - 1); 252 + HSR_SEQNR_START - 1, true, 253 + port_rcv->type); 304 254 if (!node_real) 305 255 goto done; /* No mem */ 306 256 if (node_real == node_curr) ··· 327 275 kfree_rcu(node_curr, rcu_head); 328 276 329 277 done: 330 - skb_push(skb, sizeof(struct hsrv1_ethhdr_sp)); 278 + /* PRP uses v0 header */ 279 + if (ethhdr->h_proto == htons(ETH_P_HSR)) 280 + skb_push(skb, sizeof(struct hsrv1_ethhdr_sp)); 281 + else 282 + skb_push(skb, sizeof(struct hsrv0_ethhdr_sp)); 331 283 } 332 284 333 285 /* 'skb' is a frame meant for this host, that is to be passed to upper layers.
+25 -4
net/hsr/hsr_framereg.h
··· 14 14 15 15 struct hsr_node; 16 16 17 + struct hsr_frame_info { 18 + struct sk_buff *skb_std; 19 + struct sk_buff *skb_hsr; 20 + struct sk_buff *skb_prp; 21 + struct hsr_port *port_rcv; 22 + struct hsr_node *node_src; 23 + u16 sequence_nr; 24 + bool is_supervision; 25 + bool is_vlan; 26 + bool is_local_dest; 27 + bool is_local_exclusive; 28 + bool is_from_san; 29 + }; 30 + 17 31 void hsr_del_self_node(struct hsr_priv *hsr); 18 32 void hsr_del_nodes(struct list_head *node_db); 19 - struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, 20 - bool is_sup); 21 - void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, 22 - struct hsr_port *port); 33 + struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db, 34 + struct sk_buff *skb, bool is_sup, 35 + enum hsr_port_type rx_port); 36 + void hsr_handle_sup_frame(struct hsr_frame_info *frame); 23 37 bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr); 24 38 25 39 void hsr_addr_subst_source(struct hsr_node *node, struct sk_buff *skb); ··· 63 49 int *if2_age, 64 50 u16 *if2_seq); 65 51 52 + void prp_handle_san_frame(bool san, enum hsr_port_type port, 53 + struct hsr_node *node); 54 + void prp_update_san_info(struct hsr_node *node, bool is_sup); 55 + 66 56 struct hsr_node { 67 57 struct list_head mac_list; 68 58 unsigned char macaddress_A[ETH_ALEN]; ··· 75 57 enum hsr_port_type addr_B_port; 76 58 unsigned long time_in[HSR_PT_PORTS]; 77 59 bool time_in_stale[HSR_PT_PORTS]; 60 + /* if the node is a SAN */ 61 + bool san_a; 62 + bool san_b; 78 63 u16 seq_out[HSR_PT_PORTS]; 79 64 struct rcu_head rcu_head; 80 65 };
+72 -1
net/hsr/hsr_main.h
··· 12 12 13 13 #include <linux/netdevice.h> 14 14 #include <linux/list.h> 15 + #include <linux/if_vlan.h> 15 16 16 17 /* Time constants as specified in the HSR specification (IEC-62439-3 2010) 17 18 * Table 8. ··· 87 86 struct hsr_tag hsr_tag; 88 87 } __packed; 89 88 90 - /* HSR Supervision Frame data types. 89 + struct hsr_vlan_ethhdr { 90 + struct vlan_ethhdr vlanhdr; 91 + struct hsr_tag hsr_tag; 92 + } __packed; 93 + 94 + /* HSR/PRP Supervision Frame data types. 91 95 * Field names as defined in the IEC:2010 standard for HSR. 92 96 */ 93 97 struct hsr_sup_tag { ··· 148 142 __be16 PRP_suffix; 149 143 } __packed; 150 144 145 + static inline u16 get_prp_LSDU_size(struct prp_rct *rct) 146 + { 147 + return ntohs(rct->lan_id_and_LSDU_size) & 0x0FFF; 148 + } 149 + 150 + static inline void set_prp_lan_id(struct prp_rct *rct, u16 lan_id) 151 + { 152 + rct->lan_id_and_LSDU_size = htons((ntohs(rct->lan_id_and_LSDU_size) & 153 + 0x0FFF) | (lan_id << 12)); 154 + } 151 155 static inline void set_prp_LSDU_size(struct prp_rct *rct, u16 LSDU_size) 152 156 { 153 157 rct->lan_id_and_LSDU_size = htons((ntohs(rct->lan_id_and_LSDU_size) & ··· 179 163 }; 180 164 181 165 struct hsr_frame_info; 166 + struct hsr_node; 182 167 183 168 struct hsr_proto_ops { 184 169 /* format and send supervision frame */ 185 170 void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval); 171 + void (*handle_san_frame)(bool san, enum hsr_port_type port, 172 + struct hsr_node *node); 173 + bool (*drop_frame)(struct hsr_frame_info *frame, struct hsr_port *port); 186 174 struct sk_buff * (*get_untagged_frame)(struct hsr_frame_info *frame, 187 175 struct hsr_port *port); 188 176 struct sk_buff * (*create_tagged_frame)(struct hsr_frame_info *frame, 189 177 struct hsr_port *port); 190 178 void (*fill_frame_info)(__be16 proto, struct sk_buff *skb, 191 179 struct hsr_frame_info *frame); 180 + bool (*invalid_dan_ingress_frame)(__be16 protocol); 181 + void (*update_san_info)(struct hsr_node *node, bool is_sup); 192 182 }; 193 183 194 184 struct hsr_priv { ··· 211 189 spinlock_t seqnr_lock; /* locking for sequence_nr */ 212 190 spinlock_t list_lock; /* locking for node list */ 213 191 struct hsr_proto_ops *proto_ops; 192 + #define PRP_LAN_ID 0x5 /* 0x1010 for A and 0x1011 for B. Bit 0 is set 193 + * based on SLAVE_A or SLAVE_B 194 + */ 195 + u8 net_id; /* for PRP, it occupies most significant 3 bits 196 + * of lan_id 197 + */ 214 198 unsigned char sup_multicast_addr[ETH_ALEN]; 215 199 #ifdef CONFIG_DEBUG_FS 216 200 struct dentry *node_tbl_root; ··· 235 207 236 208 hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb); 237 209 return ntohs(hsr_ethhdr->hsr_tag.sequence_nr); 210 + } 211 + 212 + static inline struct prp_rct *skb_get_PRP_rct(struct sk_buff *skb) 213 + { 214 + unsigned char *tail = skb_tail_pointer(skb) - HSR_HLEN; 215 + 216 + struct prp_rct *rct = (struct prp_rct *)tail; 217 + 218 + if (rct->PRP_suffix == htons(ETH_P_PRP)) 219 + return rct; 220 + 221 + return NULL; 222 + } 223 + 224 + /* Assume caller has confirmed this skb is PRP suffixed */ 225 + static inline u16 prp_get_skb_sequence_nr(struct prp_rct *rct) 226 + { 227 + return ntohs(rct->sequence_nr); 228 + } 229 + 230 + static inline u16 get_prp_lan_id(struct prp_rct *rct) 231 + { 232 + return ntohs(rct->lan_id_and_LSDU_size) >> 12; 233 + } 234 + 235 + /* assume there is a valid rct */ 236 + static inline bool prp_check_lsdu_size(struct sk_buff *skb, 237 + struct prp_rct *rct, 238 + bool is_sup) 239 + { 240 + struct ethhdr *ethhdr; 241 + int expected_lsdu_size; 242 + 243 + if (is_sup) { 244 + expected_lsdu_size = HSR_V1_SUP_LSDUSIZE; 245 + } else { 246 + ethhdr = (struct ethhdr *)skb_mac_header(skb); 247 + expected_lsdu_size = skb->len - 14; 248 + if (ethhdr->h_proto == htons(ETH_P_8021Q)) 249 + expected_lsdu_size -= 4; 250 + } 251 + 252 + return (expected_lsdu_size == get_prp_LSDU_size(rct)); 238 253 } 239 254 240 255 #if IS_ENABLED(CONFIG_DEBUG_FS)
+23 -1
net/hsr/hsr_slave.c
··· 16 16 #include "hsr_forward.h" 17 17 #include "hsr_framereg.h" 18 18 19 + bool hsr_invalid_dan_ingress_frame(__be16 protocol) 20 + { 21 + return (protocol != htons(ETH_P_PRP) && protocol != htons(ETH_P_HSR)); 22 + } 23 + 19 24 static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) 20 25 { 21 26 struct sk_buff *skb = *pskb; 22 27 struct hsr_port *port; 28 + struct hsr_priv *hsr; 23 29 __be16 protocol; 30 + 31 + /* Packets from dev_loopback_xmit() do not have L2 header, bail out */ 32 + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) 33 + return RX_HANDLER_PASS; 24 34 25 35 if (!skb_mac_header_was_set(skb)) { 26 36 WARN_ONCE(1, "%s: skb invalid", __func__); ··· 40 30 port = hsr_port_get_rcu(skb->dev); 41 31 if (!port) 42 32 goto finish_pass; 33 + hsr = port->hsr; 43 34 44 35 if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) { 45 36 /* Directly kill frames sent by ourselves */ ··· 48 37 goto finish_consume; 49 38 } 50 39 40 + /* For HSR, only tagged frames are expected, but for PRP 41 + * there could be non tagged frames as well from Single 42 + * attached nodes (SANs). 43 + */ 51 44 protocol = eth_hdr(skb)->h_proto; 52 - if (protocol != htons(ETH_P_PRP) && protocol != htons(ETH_P_HSR)) 45 + if (hsr->proto_ops->invalid_dan_ingress_frame && 46 + hsr->proto_ops->invalid_dan_ingress_frame(protocol)) 53 47 goto finish_pass; 54 48 55 49 skb_push(skb, ETH_HLEN); 50 + 51 + if (skb_mac_header(skb) != skb->data) { 52 + WARN_ONCE(1, "%s:%d: Malformed frame at source port %s)\n", 53 + __func__, __LINE__, port->dev->name); 54 + goto finish_consume; 55 + } 56 56 57 57 hsr_forward_skb(skb, port); 58 58
+2
net/hsr/hsr_slave.h
··· 32 32 rcu_dereference(dev->rx_handler_data) : NULL; 33 33 } 34 34 35 + bool hsr_invalid_dan_ingress_frame(__be16 protocol); 36 + 35 37 #endif /* __HSR_SLAVE_H */