batman-adv: don't let backbone gateways exchange tt entries
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>
Sun, 22 Jan 2012 19:00:23 +0000 (20:00 +0100)
committerAntonio Quartulli <ordex@autistici.org>
Wed, 11 Apr 2012 12:28:59 +0000 (14:28 +0200)
As the backbone gateways are connected to the same backbone, they
should announce the same clients on the backbone non-exclusively.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/bridge_loop_avoidance.h
net/batman-adv/routing.c
net/batman-adv/translation-table.c

index 56b9b4924763adf39bf9ddfe61b912a74fb79510..6186f6e92e3393689b184926626a559e5d57ce30 100644 (file)
@@ -24,6 +24,7 @@
 #include "hard-interface.h"
 #include "originator.h"
 #include "bridge_loop_avoidance.h"
+#include "translation-table.h"
 #include "send.h"
 
 #include <linux/etherdevice.h>
@@ -359,6 +360,7 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
                                               uint8_t *orig, short vid)
 {
        struct backbone_gw *entry;
+       struct orig_node *orig_node;
        int hash_added;
 
        entry = backbone_hash_find(bat_priv, orig, vid);
@@ -393,6 +395,13 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
                return NULL;
        }
 
+       /* this is a gateway now, remove any tt entries */
+       orig_node = orig_hash_find(bat_priv, orig);
+       if (orig_node) {
+               tt_global_del_orig(bat_priv, orig_node,
+                                  "became a backbone gateway");
+               orig_node_free_ref(orig_node);
+       }
        return entry;
 }
 
@@ -1049,6 +1058,47 @@ int bla_init(struct bat_priv *bat_priv)
        return 1;
 }
 
+/**
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: originator mac address
+ *
+ * check if the originator is a gateway for any VLAN ID.
+ *
+ * returns 1 if it is found, 0 otherwise
+ *
+ */
+
+int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig)
+{
+       struct hashtable_t *hash = bat_priv->backbone_hash;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct backbone_gw *backbone_gw;
+       int i;
+
+       if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+               return 0;
+
+       if (!hash)
+               return 0;
+
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+
+               rcu_read_lock();
+               hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
+                       if (compare_eth(backbone_gw->orig, orig)) {
+                               rcu_read_unlock();
+                               return 1;
+                       }
+               }
+               rcu_read_unlock();
+       }
+
+       return 0;
+}
+
+
 /**
  * @skb: the frame to be checked
  * @orig_node: the orig_node of the frame
index d9e34803a4657e9c5c29f88fb86f9c3637c704cb..b74940f09baf8df75fde75256b0578dcd3b7565f 100644 (file)
@@ -27,6 +27,7 @@ int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
 int bla_is_backbone_gw(struct sk_buff *skb,
                       struct orig_node *orig_node, int hdr_size);
 int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
+int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig);
 void bla_update_orig_address(struct bat_priv *bat_priv,
                             struct hard_iface *primary_if,
                             struct hard_iface *oldif);
index a1d8c9b0f90284765629531f8742dee13f049f80..1d1fd04c9c3a0b9570127cb0e2241914a0b5c4a8 100644 (file)
@@ -673,6 +673,13 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
        if (!is_my_mac(roam_adv_packet->dst))
                return route_unicast_packet(skb, recv_if);
 
+       /* check if it is a backbone gateway. we don't accept
+        * roaming advertisement from it, as it has the same
+        * entries as we have.
+        */
+       if (bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src))
+               goto out;
+
        orig_node = orig_hash_find(bat_priv, roam_adv_packet->src);
        if (!orig_node)
                goto out;
index 9648b0dc57ef959a2d13e7e6b2f5d8e027bc8669..e16a3690bdb24d606326ec0735daa9d754650e1e 100644 (file)
@@ -27,6 +27,7 @@
 #include "hash.h"
 #include "originator.h"
 #include "routing.h"
+#include "bridge_loop_avoidance.h"
 
 #include <linux/crc16.h>
 
@@ -1615,10 +1616,15 @@ out:
 bool send_tt_response(struct bat_priv *bat_priv,
                      struct tt_query_packet *tt_request)
 {
-       if (is_my_mac(tt_request->dst))
+       if (is_my_mac(tt_request->dst)) {
+               /* don't answer backbone gws! */
+               if (bla_is_backbone_gw_orig(bat_priv, tt_request->src))
+                       return true;
+
                return send_my_tt_response(bat_priv, tt_request);
-       else
+       } else {
                return send_other_tt_response(bat_priv, tt_request);
+       }
 }
 
 static void _tt_update_changes(struct bat_priv *bat_priv,
@@ -1722,6 +1728,10 @@ void handle_tt_response(struct bat_priv *bat_priv,
                tt_response->src, tt_response->ttvn, tt_response->tt_data,
                (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
 
+       /* we should have never asked a backbone gw */
+       if (bla_is_backbone_gw_orig(bat_priv, tt_response->src))
+               goto out;
+
        orig_node = orig_hash_find(bat_priv, tt_response->src);
        if (!orig_node)
                goto out;
@@ -2052,6 +2062,10 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
        uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
        bool full_table = true;
 
+       /* don't care about a backbone gateways updates. */
+       if (bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
+               return;
+
        /* orig table not initialised AND first diff is in the OGM OR the ttvn
         * increased by one -> we can apply the attached changes */
        if ((!orig_node->tt_initialised && ttvn == 1) ||