diff options
Diffstat (limited to 'net/batman-adv/bridge_loop_avoidance.c')
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.c | 58 |
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 | */ |
1325 | int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) | 1324 | bool 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) | |||
1365 | int batadv_bla_is_backbone_gw(struct sk_buff *skb, | 1366 | int 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, |