hsr_framereg.c (e5451c8f8330e03ad3cfa16048b4daf961af434f) | hsr_framereg.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): --- 163 unchanged lines hidden (view full) --- 172 173 list_for_each_entry_rcu(node, node_db, mac_list) { 174 if (ether_addr_equal(node->MacAddressA, ethhdr->h_source)) 175 return node; 176 if (ether_addr_equal(node->MacAddressB, ethhdr->h_source)) 177 return node; 178 } 179 | 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): --- 163 unchanged lines hidden (view full) --- 172 173 list_for_each_entry_rcu(node, node_db, mac_list) { 174 if (ether_addr_equal(node->MacAddressA, ethhdr->h_source)) 175 return node; 176 if (ether_addr_equal(node->MacAddressB, ethhdr->h_source)) 177 return node; 178 } 179 |
180 if (!is_sup) 181 return NULL; /* Only supervision frame may create node entry */ | 180 /* Everyone may create a node entry, connected node to a HSR device. */ |
182 | 181 |
183 if (ethhdr->h_proto == htons(ETH_P_PRP)) { | 182 if (ethhdr->h_proto == htons(ETH_P_PRP) 183 || ethhdr->h_proto == htons(ETH_P_HSR)) { |
184 /* Use the existing sequence_nr from the tag as starting point 185 * for filtering duplicate frames. 186 */ 187 seq_out = hsr_get_skb_sequence_nr(skb) - 1; 188 } else { 189 WARN_ONCE(1, "%s: Non-HSR frame\n", __func__); | 184 /* Use the existing sequence_nr from the tag as starting point 185 * for filtering duplicate frames. 186 */ 187 seq_out = hsr_get_skb_sequence_nr(skb) - 1; 188 } else { 189 WARN_ONCE(1, "%s: Non-HSR frame\n", __func__); |
190 seq_out = 0; | 190 seq_out = HSR_SEQNR_START; |
191 } 192 193 return hsr_add_node(node_db, ethhdr->h_source, seq_out); 194} 195 196/* Use the Supervision frame's info about an eventual MacAddressB for merging 197 * nodes that has previously had their MacAddressB registered as a separate 198 * node. 199 */ 200void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, 201 struct hsr_port *port_rcv) 202{ | 191 } 192 193 return hsr_add_node(node_db, ethhdr->h_source, seq_out); 194} 195 196/* Use the Supervision frame's info about an eventual MacAddressB for merging 197 * nodes that has previously had their MacAddressB registered as a separate 198 * node. 199 */ 200void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, 201 struct hsr_port *port_rcv) 202{ |
203 struct ethhdr *ethhdr; |
|
203 struct hsr_node *node_real; 204 struct hsr_sup_payload *hsr_sp; 205 struct list_head *node_db; 206 int i; 207 | 204 struct hsr_node *node_real; 205 struct hsr_sup_payload *hsr_sp; 206 struct list_head *node_db; 207 int i; 208 |
208 skb_pull(skb, sizeof(struct hsr_ethhdr_sp)); 209 hsr_sp = (struct hsr_sup_payload *) skb->data; | 209 ethhdr = (struct ethhdr *) skb_mac_header(skb); |
210 | 210 |
211 if (ether_addr_equal(eth_hdr(skb)->h_source, hsr_sp->MacAddressA)) 212 /* Not sent from MacAddressB of a PICS_SUBS capable node */ 213 goto done; | 211 /* Leave the ethernet header. */ 212 skb_pull(skb, sizeof(struct ethhdr)); |
214 | 213 |
214 /* And leave the HSR tag. */ 215 if (ethhdr->h_proto == htons(ETH_P_HSR)) 216 skb_pull(skb, sizeof(struct hsr_tag)); 217 218 /* And leave the HSR sup tag. */ 219 skb_pull(skb, sizeof(struct hsr_sup_tag)); 220 221 hsr_sp = (struct hsr_sup_payload *) skb->data; 222 |
|
215 /* Merge node_curr (registered on MacAddressB) into node_real */ 216 node_db = &port_rcv->hsr->node_db; 217 node_real = find_node_by_AddrA(node_db, hsr_sp->MacAddressA); 218 if (!node_real) 219 /* No frame received from AddrA of this node yet */ 220 node_real = hsr_add_node(node_db, hsr_sp->MacAddressA, 221 HSR_SEQNR_START - 1); 222 if (!node_real) 223 goto done; /* No mem */ 224 if (node_real == node_curr) 225 /* Node has already been merged */ 226 goto done; 227 | 223 /* Merge node_curr (registered on MacAddressB) into node_real */ 224 node_db = &port_rcv->hsr->node_db; 225 node_real = find_node_by_AddrA(node_db, hsr_sp->MacAddressA); 226 if (!node_real) 227 /* No frame received from AddrA of this node yet */ 228 node_real = hsr_add_node(node_db, hsr_sp->MacAddressA, 229 HSR_SEQNR_START - 1); 230 if (!node_real) 231 goto done; /* No mem */ 232 if (node_real == node_curr) 233 /* Node has already been merged */ 234 goto done; 235 |
228 ether_addr_copy(node_real->MacAddressB, eth_hdr(skb)->h_source); | 236 ether_addr_copy(node_real->MacAddressB, ethhdr->h_source); |
229 for (i = 0; i < HSR_PT_PORTS; i++) { 230 if (!node_curr->time_in_stale[i] && 231 time_after(node_curr->time_in[i], node_real->time_in[i])) { 232 node_real->time_in[i] = node_curr->time_in[i]; 233 node_real->time_in_stale[i] = node_curr->time_in_stale[i]; 234 } 235 if (seq_nr_after(node_curr->seq_out[i], node_real->seq_out[i])) 236 node_real->seq_out[i] = node_curr->seq_out[i]; 237 } 238 node_real->AddrB_port = port_rcv->type; 239 240 list_del_rcu(&node_curr->mac_list); 241 kfree_rcu(node_curr, rcu_head); 242 243done: | 237 for (i = 0; i < HSR_PT_PORTS; i++) { 238 if (!node_curr->time_in_stale[i] && 239 time_after(node_curr->time_in[i], node_real->time_in[i])) { 240 node_real->time_in[i] = node_curr->time_in[i]; 241 node_real->time_in_stale[i] = node_curr->time_in_stale[i]; 242 } 243 if (seq_nr_after(node_curr->seq_out[i], node_real->seq_out[i])) 244 node_real->seq_out[i] = node_curr->seq_out[i]; 245 } 246 node_real->AddrB_port = port_rcv->type; 247 248 list_del_rcu(&node_curr->mac_list); 249 kfree_rcu(node_curr, rcu_head); 250 251done: |
244 skb_push(skb, sizeof(struct hsr_ethhdr_sp)); | 252 skb_push(skb, sizeof(struct hsrv1_ethhdr_sp)); |
245} 246 247 248/* 'skb' is a frame meant for this host, that is to be passed to upper layers. 249 * 250 * If the frame was sent by a node's B interface, replace the source 251 * address with that node's "official" address (MacAddressA) so that upper 252 * layers recognize where it came from. --- 238 unchanged lines hidden --- | 253} 254 255 256/* 'skb' is a frame meant for this host, that is to be passed to upper layers. 257 * 258 * If the frame was sent by a node's B interface, replace the source 259 * address with that node's "official" address (MacAddressA) so that upper 260 * layers recognize where it came from. --- 238 unchanged lines hidden --- |