@@ -33,7 +33,6 @@
#include <net/arp.h>
#include <linux/if_vlan.h>
-static const uint8_t claim_dest[6] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
static const uint8_t announce_mac[6] = {0x43, 0x05, 0x43, 0x05, 0x00, 0x00};
static void bla_periodic_work(struct work_struct *work);
@@ -255,7 +254,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
if (!primary_if)
return;
- memcpy(&local_claim_dest, claim_dest,
+ memcpy(&local_claim_dest, &bat_priv->claim_dest,
sizeof(local_claim_dest));
local_claim_dest.type = claimtype;
@@ -268,8 +267,9 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
NULL, /* Ethernet DST: Broadcast */
primary_if->net_dev->dev_addr, /* Ethernet SRC/HW SRC:
* originator mac */
- (uint8_t *)&local_claim_dest /* HW DST: FF:43:05:XX:00:00
- * with XX = claim type */
+ (uint8_t *)&local_claim_dest /* HW DST: FF:43:05:XX:YY:YY
+ * with XX = claim type
+ * and YY:YY = group id */
);
if (!skb)
@@ -701,6 +701,82 @@ static int handle_claim(struct bat_priv *bat_priv,
return 1;
}
+/**
+ *
+ * @bat_priv: the bat priv with all the soft interface information
+ * @hw_src: the Hardware source in the ARP Header
+ * @hw_dst: the Hardware destination in the ARP Header
+ * @ethhdr: pointer to the Ethernet header of the claim frame
+ *
+ * checks if it is a claim packet and if its on the same group.
+ * This function also applies the group ID of the sender
+ * if it is in the same mesh.
+ *
+ * returns:
+ * 2 - if it is a claim packet and on the same group
+ * 1 - if is a claim packet from another group
+ * 0 - if it is not a claim packet
+ */
+static int check_claim_group(struct bat_priv *bat_priv,
+ uint8_t *hw_src, uint8_t *hw_dst, struct ethhdr *ethhdr)
+{
+ uint8_t *backbone_addr;
+ struct orig_node *orig_node;
+ struct bla_claim_dst *bla_dst, *bla_dst_own;
+
+ bla_dst = (struct bla_claim_dst *) hw_dst;
+ bla_dst_own = &bat_priv->claim_dest;
+
+ /* check if it is a claim packet in general */
+ if (memcmp(bla_dst->magic, bla_dst_own->magic,
+ sizeof(bla_dst->magic)) != 0)
+ return 0;
+
+ /* if announcement packet, use the source,
+ * otherwise assume it is in the hw_src */
+ switch (bla_dst->type) {
+ case CLAIM_TYPE_ADD:
+ backbone_addr = hw_src;
+ break;
+ case CLAIM_TYPE_REQUEST:
+ case CLAIM_TYPE_ANNOUNCE:
+ case CLAIM_TYPE_DEL:
+ backbone_addr = ethhdr->h_source;
+ break;
+ default:
+ return 0;
+ }
+
+ /* don't accept claim frames from ourselves */
+ if (compare_eth(backbone_addr, bat_priv->own_orig))
+ return 0;
+
+ /* if its already the same group, it is fine. */
+ if (bla_dst->group == bla_dst_own->group)
+ return 2;
+
+ /* lets see if this originator is in our mesh */
+ orig_node = orig_hash_find(bat_priv, backbone_addr);
+
+ /* dont accept claims from gateways which are not in
+ * the same mesh or group. */
+ if (!orig_node)
+ return 1;
+
+ /* if our mesh friends mac is bigger, use it for ourselves. */
+ if (ntohs(bla_dst->group) > ntohs(bla_dst_own->group)) {
+ bat_dbg(DBG_BLA, bat_priv,
+ "taking other backbones claim group: %04x\n",
+ ntohs(bla_dst->group));
+ bla_dst_own->group = bla_dst->group;
+ }
+
+ orig_node_free_ref(orig_node);
+
+ return 2;
+}
+
+
/*
* @bat_priv: the bat priv with all the soft interface information
* @skb: the frame to be checked
@@ -721,6 +797,7 @@ static int bla_process_claim(struct bat_priv *bat_priv, struct sk_buff *skb)
uint16_t proto;
int headlen;
short vid = -1;
+ int ret;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
@@ -761,8 +838,15 @@ static int bla_process_claim(struct bat_priv *bat_priv, struct sk_buff *skb)
bla_dst = (struct bla_claim_dst *) hw_dst;
/* check if it is a claim frame. */
- if (memcmp(hw_dst, claim_dest, 3) != 0)
- return 0;
+ ret = check_claim_group(bat_priv, hw_src, hw_dst, ethhdr);
+ if (ret == 1)
+ bat_dbg(DBG_BLA, bat_priv, "bla_process_claim(): received "
+ "a claim frame from another group. From: "
+ "%pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
+ ethhdr->h_source, vid, hw_src, hw_dst);
+
+ if (ret < 2)
+ return ret;
/* become a backbone gw ourselves on this vlan if not happened yet */
bla_update_own_backbone_gw(bat_priv, vid);
@@ -806,6 +890,9 @@ void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr)
struct hashtable_t *hash;
int i;
+ /* reset bridge loop avoidance group id */
+ bat_priv->claim_dest.group = htons(crc16(0, newaddr, ETH_ALEN));
+
hash = bat_priv->backbone_hash;
if (!hash)
return;
@@ -971,9 +1058,16 @@ timer:
int bla_init(struct bat_priv *bat_priv)
{
int i;
+ uint8_t claim_dest[6] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n");
+ /* setting claim destination address */
+ memcpy(&bat_priv->claim_dest.magic, claim_dest, 3);
+ bat_priv->claim_dest.type = 0;
+ bat_priv->claim_dest.group =
+ htons(crc16(0, bat_priv->own_orig, ETH_ALEN));
+
/* initialize the duplicate list */
for (i = 0; i < DUPLIST_SIZE; i++)
bat_priv->bcast_duplist[i].entrytime =
@@ -1390,8 +1484,9 @@ int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
}
seq_printf(seq, "Claims announced for the mesh %s "
- "(orig %pM)\n",
- net_dev->name, bat_priv->own_orig);
+ "(orig %pM, group id %04x)\n",
+ net_dev->name, bat_priv->own_orig,
+ ntohs(bat_priv->claim_dest.group));
seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n",
"Client", "VID", "Originator", "CRC");
for (i = 0; i < hash->size; i++) {
@@ -192,6 +192,7 @@ struct bat_priv {
struct hashtable_t *vis_hash;
struct bcast_duplist_entry bcast_duplist[DUPLIST_SIZE];
int bcast_duplist_curr;
+ struct bla_claim_dst claim_dest;
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
spinlock_t forw_bcast_list_lock; /* protects */
spinlock_t tt_changes_list_lock; /* protects tt_changes */