hsr_forward.c (e5451c8f8330e03ad3cfa16048b4daf961af434f) | hsr_forward.c (ee1c27977284907d40f7f72c2d078d709f15811f) |
---|---|
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): --- 36 unchanged lines hidden (view full) --- 45 * frame is received from a particular node, we know something is wrong. 46 * We just register these (as with normal frames) and throw them away. 47 * 48 * 3) Allow different MAC addresses for the two slave interfaces, using the 49 * MacAddressA field. 50 */ 51static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb) 52{ | 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): --- 36 unchanged lines hidden (view full) --- 45 * frame is received from a particular node, we know something is wrong. 46 * We just register these (as with normal frames) and throw them away. 47 * 48 * 3) Allow different MAC addresses for the two slave interfaces, using the 49 * MacAddressA field. 50 */ 51static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb) 52{ |
53 struct hsr_ethhdr_sp *hdr; | 53 struct ethhdr *ethHdr; 54 struct hsr_sup_tag *hsrSupTag; 55 struct hsrv1_ethhdr_sp *hsrV1Hdr; |
54 55 WARN_ON_ONCE(!skb_mac_header_was_set(skb)); | 56 57 WARN_ON_ONCE(!skb_mac_header_was_set(skb)); |
56 hdr = (struct hsr_ethhdr_sp *) skb_mac_header(skb); | 58 ethHdr = (struct ethhdr *) skb_mac_header(skb); |
57 | 59 |
58 if (!ether_addr_equal(hdr->ethhdr.h_dest, | 60 /* Correct addr? */ 61 if (!ether_addr_equal(ethHdr->h_dest, |
59 hsr->sup_multicast_addr)) 60 return false; 61 | 62 hsr->sup_multicast_addr)) 63 return false; 64 |
62 if (get_hsr_stag_path(&hdr->hsr_sup) != 0x0f) | 65 /* Correct ether type?. */ 66 if (!(ethHdr->h_proto == htons(ETH_P_PRP) 67 || ethHdr->h_proto == htons(ETH_P_HSR))) |
63 return false; | 68 return false; |
64 if ((hdr->hsr_sup.HSR_TLV_Type != HSR_TLV_ANNOUNCE) && 65 (hdr->hsr_sup.HSR_TLV_Type != HSR_TLV_LIFE_CHECK)) | 69 70 /* Get the supervision header from correct location. */ 71 if (ethHdr->h_proto == htons(ETH_P_HSR)) { /* Okay HSRv1. */ 72 hsrV1Hdr = (struct hsrv1_ethhdr_sp *) skb_mac_header(skb); 73 if (hsrV1Hdr->hsr.encap_proto != htons(ETH_P_PRP)) 74 return false; 75 76 hsrSupTag = &hsrV1Hdr->hsr_sup; 77 } else { 78 hsrSupTag = &((struct hsrv0_ethhdr_sp *) skb_mac_header(skb))->hsr_sup; 79 } 80 81 if ((hsrSupTag->HSR_TLV_Type != HSR_TLV_ANNOUNCE) && 82 (hsrSupTag->HSR_TLV_Type != HSR_TLV_LIFE_CHECK)) |
66 return false; | 83 return false; |
67 if (hdr->hsr_sup.HSR_TLV_Length != 12) | 84 if ((hsrSupTag->HSR_TLV_Length != 12) && 85 (hsrSupTag->HSR_TLV_Length != 86 sizeof(struct hsr_sup_payload))) |
68 return false; 69 70 return true; 71} 72 73 74static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, 75 struct hsr_frame_info *frame) --- 29 unchanged lines hidden (view full) --- 105{ 106 if (!frame->skb_std) 107 frame->skb_std = create_stripped_skb(frame->skb_hsr, frame); 108 return skb_clone(frame->skb_std, GFP_ATOMIC); 109} 110 111 112static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame, | 87 return false; 88 89 return true; 90} 91 92 93static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, 94 struct hsr_frame_info *frame) --- 29 unchanged lines hidden (view full) --- 124{ 125 if (!frame->skb_std) 126 frame->skb_std = create_stripped_skb(frame->skb_hsr, frame); 127 return skb_clone(frame->skb_std, GFP_ATOMIC); 128} 129 130 131static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame, |
113 struct hsr_port *port) | 132 struct hsr_port *port, u8 protoVersion) |
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 --- 4 unchanged lines hidden (view full) --- 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; | 133{ 134 struct hsr_ethhdr *hsr_ethhdr; 135 int lane_id; 136 int lsdu_size; 137 138 if (port->type == HSR_PT_SLAVE_A) 139 lane_id = 0; 140 else --- 4 unchanged lines hidden (view full) --- 145 lsdu_size -= 4; 146 147 hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb); 148 149 set_hsr_tag_path(&hsr_ethhdr->hsr_tag, lane_id); 150 set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size); 151 hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr); 152 hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; |
134 hsr_ethhdr->ethhdr.h_proto = htons(ETH_P_PRP); | 153 hsr_ethhdr->ethhdr.h_proto = htons(protoVersion ? 154 ETH_P_HSR : ETH_P_PRP); |
135} 136 137static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, 138 struct hsr_frame_info *frame, 139 struct hsr_port *port) 140{ 141 int movelen; 142 unsigned char *dst, *src; --- 12 unchanged lines hidden (view full) --- 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 | 155} 156 157static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, 158 struct hsr_frame_info *frame, 159 struct hsr_port *port) 160{ 161 int movelen; 162 unsigned char *dst, *src; --- 12 unchanged lines hidden (view full) --- 175 if (frame->is_vlan) 176 movelen += VLAN_HLEN; 177 178 src = skb_mac_header(skb); 179 dst = skb_push(skb, HSR_HLEN); 180 memmove(dst, src, movelen); 181 skb_reset_mac_header(skb); 182 |
163 hsr_fill_tag(skb, frame, port); | 183 hsr_fill_tag(skb, frame, port, port->hsr->protVersion); |
164 165 return skb; 166} 167 168/* If the original frame was an HSR tagged frame, just clone it to be sent 169 * unchanged. Otherwise, create a private frame especially tagged for 'port'. 170 */ 171static struct sk_buff *frame_get_tagged_skb(struct hsr_frame_info *frame, --- 143 unchanged lines hidden (view full) --- 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 } | 184 185 return skb; 186} 187 188/* If the original frame was an HSR tagged frame, just clone it to be sent 189 * unchanged. Otherwise, create a private frame especially tagged for 'port'. 190 */ 191static struct sk_buff *frame_get_tagged_skb(struct hsr_frame_info *frame, --- 143 unchanged lines hidden (view full) --- 335 336 ethhdr = (struct ethhdr *) skb_mac_header(skb); 337 frame->is_vlan = false; 338 if (ethhdr->h_proto == htons(ETH_P_8021Q)) { 339 frame->is_vlan = true; 340 /* FIXME: */ 341 WARN_ONCE(1, "HSR: VLAN not yet supported"); 342 } |
323 if (ethhdr->h_proto == htons(ETH_P_PRP)) { | 343 if (ethhdr->h_proto == htons(ETH_P_PRP) 344 || ethhdr->h_proto == htons(ETH_P_HSR)) { |
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); --- 37 unchanged lines hidden --- | 345 frame->skb_std = NULL; 346 frame->skb_hsr = skb; 347 frame->sequence_nr = hsr_get_skb_sequence_nr(skb); 348 } else { 349 frame->skb_std = skb; 350 frame->skb_hsr = NULL; 351 /* Sequence nr for the master node */ 352 spin_lock_irqsave(&port->hsr->seqnr_lock, irqflags); --- 37 unchanged lines hidden --- |