aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/bridge_loop_avoidance.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/bridge_loop_avoidance.c')
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 5bb58d7bdd56..28eb5e6d0a02 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -411,10 +411,10 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
411 return NULL; 411 return NULL;
412 } 412 }
413 413
414 /* this is a gateway now, remove any tt entries */ 414 /* this is a gateway now, remove any TT entry on this VLAN */
415 orig_node = batadv_orig_hash_find(bat_priv, orig); 415 orig_node = batadv_orig_hash_find(bat_priv, orig);
416 if (orig_node) { 416 if (orig_node) {
417 batadv_tt_global_del_orig(bat_priv, orig_node, 417 batadv_tt_global_del_orig(bat_priv, orig_node, vid,
418 "became a backbone gateway"); 418 "became a backbone gateway");
419 batadv_orig_node_free_ref(orig_node); 419 batadv_orig_node_free_ref(orig_node);
420 } 420 }
@@ -858,27 +858,25 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
858 struct batadv_hard_iface *primary_if, 858 struct batadv_hard_iface *primary_if,
859 struct sk_buff *skb) 859 struct sk_buff *skb)
860{ 860{
861 struct ethhdr *ethhdr; 861 struct batadv_bla_claim_dst *bla_dst;
862 uint8_t *hw_src, *hw_dst;
862 struct vlan_ethhdr *vhdr; 863 struct vlan_ethhdr *vhdr;
864 struct ethhdr *ethhdr;
863 struct arphdr *arphdr; 865 struct arphdr *arphdr;
864 uint8_t *hw_src, *hw_dst; 866 unsigned short vid;
865 struct batadv_bla_claim_dst *bla_dst;
866 __be16 proto; 867 __be16 proto;
867 int headlen; 868 int headlen;
868 unsigned short vid = BATADV_NO_FLAGS;
869 int ret; 869 int ret;
870 870
871 vid = batadv_get_vid(skb, 0);
871 ethhdr = eth_hdr(skb); 872 ethhdr = eth_hdr(skb);
872 873
873 if (ethhdr->h_proto == htons(ETH_P_8021Q)) { 874 proto = ethhdr->h_proto;
875 headlen = ETH_HLEN;
876 if (vid & BATADV_VLAN_HAS_TAG) {
874 vhdr = (struct vlan_ethhdr *)ethhdr; 877 vhdr = (struct vlan_ethhdr *)ethhdr;
875 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
876 vid |= BATADV_VLAN_HAS_TAG;
877 proto = vhdr->h_vlan_encapsulated_proto; 878 proto = vhdr->h_vlan_encapsulated_proto;
878 headlen = sizeof(*vhdr); 879 headlen += VLAN_HLEN;
879 } else {
880 proto = ethhdr->h_proto;
881 headlen = ETH_HLEN;
882 } 880 }
883 881
884 if (proto != htons(ETH_P_ARP)) 882 if (proto != htons(ETH_P_ARP))
@@ -1317,12 +1315,14 @@ out:
1317 1315
1318/* @bat_priv: the bat priv with all the soft interface information 1316/* @bat_priv: the bat priv with all the soft interface information
1319 * @orig: originator mac address 1317 * @orig: originator mac address
1318 * @vid: VLAN identifier
1320 * 1319 *
1321 * check if the originator is a gateway for any VLAN ID. 1320 * Check if the originator is a gateway for the VLAN identified by vid.
1322 * 1321 *
1323 * returns 1 if it is found, 0 otherwise 1322 * Returns true if orig is a backbone for this vid, false otherwise.
1324 */ 1323 */
1325int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) 1324bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig,
1325 unsigned short vid)
1326{ 1326{
1327 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; 1327 struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
1328 struct hlist_head *head; 1328 struct hlist_head *head;
@@ -1330,25 +1330,26 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1330 int i; 1330 int i;
1331 1331
1332 if (!atomic_read(&bat_priv->bridge_loop_avoidance)) 1332 if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1333 return 0; 1333 return false;
1334 1334
1335 if (!hash) 1335 if (!hash)
1336 return 0; 1336 return false;
1337 1337
1338 for (i = 0; i < hash->size; i++) { 1338 for (i = 0; i < hash->size; i++) {
1339 head = &hash->table[i]; 1339 head = &hash->table[i];
1340 1340
1341 rcu_read_lock(); 1341 rcu_read_lock();
1342 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) { 1342 hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
1343 if (batadv_compare_eth(backbone_gw->orig, orig)) { 1343 if (batadv_compare_eth(backbone_gw->orig, orig) &&
1344 backbone_gw->vid == vid) {
1344 rcu_read_unlock(); 1345 rcu_read_unlock();
1345 return 1; 1346 return true;
1346 } 1347 }
1347 } 1348 }
1348 rcu_read_unlock(); 1349 rcu_read_unlock();
1349 } 1350 }
1350 1351
1351 return 0; 1352 return false;
1352} 1353}
1353 1354
1354 1355
@@ -1365,10 +1366,8 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
1365int batadv_bla_is_backbone_gw(struct sk_buff *skb, 1366int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1366 struct batadv_orig_node *orig_node, int hdr_size) 1367 struct batadv_orig_node *orig_node, int hdr_size)
1367{ 1368{
1368 struct ethhdr *ethhdr;
1369 struct vlan_ethhdr *vhdr;
1370 struct batadv_bla_backbone_gw *backbone_gw; 1369 struct batadv_bla_backbone_gw *backbone_gw;
1371 unsigned short vid = BATADV_NO_FLAGS; 1370 unsigned short vid;
1372 1371
1373 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance)) 1372 if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1374 return 0; 1373 return 0;
@@ -1377,16 +1376,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
1377 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN)) 1376 if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
1378 return 0; 1377 return 0;
1379 1378
1380 ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size); 1379 vid = batadv_get_vid(skb, hdr_size);
1381
1382 if (ethhdr->h_proto == htons(ETH_P_8021Q)) {
1383 if (!pskb_may_pull(skb, hdr_size + VLAN_ETH_HLEN))
1384 return 0;
1385
1386 vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size);
1387 vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
1388 vid |= BATADV_VLAN_HAS_TAG;
1389 }
1390 1380
1391 /* see if this originator is a backbone gw for this VLAN */ 1381 /* see if this originator is a backbone gw for this VLAN */
1392 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv, 1382 backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,