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.c121
1 files changed, 115 insertions, 6 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 4f6b44a5b12..1cf18ac44ba 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -33,7 +33,6 @@
33#include <net/arp.h> 33#include <net/arp.h>
34#include <linux/if_vlan.h> 34#include <linux/if_vlan.h>
35 35
36static const uint8_t claim_dest[6] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
37static const uint8_t announce_mac[4] = {0x43, 0x05, 0x43, 0x05}; 36static const uint8_t announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
38 37
39static void bla_periodic_work(struct work_struct *work); 38static void bla_periodic_work(struct work_struct *work);
@@ -265,7 +264,8 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
265 if (!primary_if) 264 if (!primary_if)
266 return; 265 return;
267 266
268 memcpy(&local_claim_dest, claim_dest, sizeof(local_claim_dest)); 267 memcpy(&local_claim_dest, &bat_priv->claim_dest,
268 sizeof(local_claim_dest));
269 local_claim_dest.type = claimtype; 269 local_claim_dest.type = claimtype;
270 270
271 soft_iface = primary_if->soft_iface; 271 soft_iface = primary_if->soft_iface;
@@ -282,6 +282,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
282 primary_if->net_dev->dev_addr, 282 primary_if->net_dev->dev_addr,
283 /* HW DST: FF:43:05:XX:00:00 283 /* HW DST: FF:43:05:XX:00:00
284 * with XX = claim type 284 * with XX = claim type
285 * and YY:YY = group id
285 */ 286 */
286 (uint8_t *)&local_claim_dest); 287 (uint8_t *)&local_claim_dest);
287 288
@@ -734,6 +735,86 @@ static int handle_claim(struct bat_priv *bat_priv,
734 735
735/** 736/**
736 * @bat_priv: the bat priv with all the soft interface information 737 * @bat_priv: the bat priv with all the soft interface information
738 * @bat_priv: the bat priv with all the soft interface information
739 * @hw_src: the Hardware source in the ARP Header
740 * @hw_dst: the Hardware destination in the ARP Header
741 * @ethhdr: pointer to the Ethernet header of the claim frame
742 *
743 * checks if it is a claim packet and if its on the same group.
744 * This function also applies the group ID of the sender
745 * if it is in the same mesh.
746 *
747 * returns:
748 * 2 - if it is a claim packet and on the same group
749 * 1 - if is a claim packet from another group
750 * 0 - if it is not a claim packet
751 */
752static int check_claim_group(struct bat_priv *bat_priv,
753 struct hard_iface *primary_if,
754 uint8_t *hw_src, uint8_t *hw_dst,
755 struct ethhdr *ethhdr)
756{
757 uint8_t *backbone_addr;
758 struct orig_node *orig_node;
759 struct bla_claim_dst *bla_dst, *bla_dst_own;
760
761 bla_dst = (struct bla_claim_dst *)hw_dst;
762 bla_dst_own = &bat_priv->claim_dest;
763
764 /* check if it is a claim packet in general */
765 if (memcmp(bla_dst->magic, bla_dst_own->magic,
766 sizeof(bla_dst->magic)) != 0)
767 return 0;
768
769 /* if announcement packet, use the source,
770 * otherwise assume it is in the hw_src
771 */
772 switch (bla_dst->type) {
773 case CLAIM_TYPE_ADD:
774 backbone_addr = hw_src;
775 break;
776 case CLAIM_TYPE_REQUEST:
777 case CLAIM_TYPE_ANNOUNCE:
778 case CLAIM_TYPE_DEL:
779 backbone_addr = ethhdr->h_source;
780 break;
781 default:
782 return 0;
783 }
784
785 /* don't accept claim frames from ourselves */
786 if (compare_eth(backbone_addr, primary_if->net_dev->dev_addr))
787 return 0;
788
789 /* if its already the same group, it is fine. */
790 if (bla_dst->group == bla_dst_own->group)
791 return 2;
792
793 /* lets see if this originator is in our mesh */
794 orig_node = orig_hash_find(bat_priv, backbone_addr);
795
796 /* dont accept claims from gateways which are not in
797 * the same mesh or group.
798 */
799 if (!orig_node)
800 return 1;
801
802 /* if our mesh friends mac is bigger, use it for ourselves. */
803 if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
804 bat_dbg(DBG_BLA, bat_priv,
805 "taking other backbones claim group: %04x\n",
806 ntohs(bla_dst->group));
807 bla_dst_own->group = bla_dst->group;
808 }
809
810 orig_node_free_ref(orig_node);
811
812 return 2;
813}
814
815
816/**
817 * @bat_priv: the bat priv with all the soft interface information
737 * @skb: the frame to be checked 818 * @skb: the frame to be checked
738 * 819 *
739 * Check if this is a claim frame, and process it accordingly. 820 * Check if this is a claim frame, and process it accordingly.
@@ -753,6 +834,7 @@ static int bla_process_claim(struct bat_priv *bat_priv,
753 uint16_t proto; 834 uint16_t proto;
754 int headlen; 835 int headlen;
755 short vid = -1; 836 short vid = -1;
837 int ret;
756 838
757 ethhdr = (struct ethhdr *)skb_mac_header(skb); 839 ethhdr = (struct ethhdr *)skb_mac_header(skb);
758 840
@@ -796,8 +878,14 @@ static int bla_process_claim(struct bat_priv *bat_priv,
796 bla_dst = (struct bla_claim_dst *)hw_dst; 878 bla_dst = (struct bla_claim_dst *)hw_dst;
797 879
798 /* check if it is a claim frame. */ 880 /* check if it is a claim frame. */
799 if (memcmp(hw_dst, claim_dest, 3) != 0) 881 ret = check_claim_group(bat_priv, primary_if, hw_src, hw_dst, ethhdr);
800 return 0; 882 if (ret == 1)
883 bat_dbg(DBG_BLA, bat_priv,
884 "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
885 ethhdr->h_source, vid, hw_src, hw_dst);
886
887 if (ret < 2)
888 return ret;
801 889
802 /* become a backbone gw ourselves on this vlan if not happened yet */ 890 /* become a backbone gw ourselves on this vlan if not happened yet */
803 bla_update_own_backbone_gw(bat_priv, primary_if, vid); 891 bla_update_own_backbone_gw(bat_priv, primary_if, vid);
@@ -944,6 +1032,10 @@ void bla_update_orig_address(struct bat_priv *bat_priv,
944 struct hashtable_t *hash; 1032 struct hashtable_t *hash;
945 int i; 1033 int i;
946 1034
1035 /* reset bridge loop avoidance group id */
1036 bat_priv->claim_dest.group =
1037 htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
1038
947 if (!oldif) { 1039 if (!oldif) {
948 bla_purge_claims(bat_priv, NULL, 1); 1040 bla_purge_claims(bat_priv, NULL, 1);
949 bla_purge_backbone_gw(bat_priv, 1); 1041 bla_purge_backbone_gw(bat_priv, 1);
@@ -1042,9 +1134,24 @@ out:
1042int bla_init(struct bat_priv *bat_priv) 1134int bla_init(struct bat_priv *bat_priv)
1043{ 1135{
1044 int i; 1136 int i;
1137 uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
1138 struct hard_iface *primary_if;
1045 1139
1046 bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n"); 1140 bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n");
1047 1141
1142 /* setting claim destination address */
1143 memcpy(&bat_priv->claim_dest.magic, claim_dest, 3);
1144 bat_priv->claim_dest.type = 0;
1145 primary_if = primary_if_get_selected(bat_priv);
1146 if (primary_if) {
1147 bat_priv->claim_dest.group =
1148 htons(crc16(0, primary_if->net_dev->dev_addr,
1149 ETH_ALEN));
1150 hardif_free_ref(primary_if);
1151 } else {
1152 bat_priv->claim_dest.group = 0; /* will be set later */
1153 }
1154
1048 /* initialize the duplicate list */ 1155 /* initialize the duplicate list */
1049 for (i = 0; i < DUPLIST_SIZE; i++) 1156 for (i = 0; i < DUPLIST_SIZE; i++)
1050 bat_priv->bcast_duplist[i].entrytime = 1157 bat_priv->bcast_duplist[i].entrytime =
@@ -1448,8 +1555,10 @@ int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
1448 goto out; 1555 goto out;
1449 } 1556 }
1450 1557
1451 seq_printf(seq, "Claims announced for the mesh %s (orig %pM)\n", 1558 seq_printf(seq,
1452 net_dev->name, primary_if->net_dev->dev_addr); 1559 "Claims announced for the mesh %s (orig %pM, group id %04x)\n",
1560 net_dev->name, primary_if->net_dev->dev_addr,
1561 ntohs(bat_priv->claim_dest.group));
1453 seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", 1562 seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n",
1454 "Client", "VID", "Originator", "CRC"); 1563 "Client", "VID", "Originator", "CRC");
1455 for (i = 0; i < hash->size; i++) { 1564 for (i = 0; i < hash->size; i++) {