]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
batman-adv: Mark best gateway in transtable_global debugfs
authorSven Eckelmann <sven@narfation.org>
Sun, 7 Oct 2012 11:34:15 +0000 (13:34 +0200)
committerAntonio Quartulli <ordex@autistici.org>
Wed, 21 Nov 2012 11:34:48 +0000 (12:34 +0100)
The transtable_global debug file can show multiple entries for a single client
when multiple gateways exist. The chosen gateway isn't marked in the list and
therefore the user cannot easily debug the situation when there is a problem
with the currently used gateway.

The best gateway is now marked with "*" and secondary gateways are marked with
"+".

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
net/batman-adv/translation-table.c

index 582f13405df9286bc752b633ed61a3b9244d545f..cdad824a0014a4b0d9951cca0131419088776f66 100644 (file)
@@ -911,8 +911,44 @@ out:
        return ret;
 }
 
-/* print all orig nodes who announce the address for this global entry.
- * it is assumed that the caller holds rcu_read_lock();
+/* batadv_transtable_best_orig - Get best originator list entry from tt entry
+ * @tt_global_entry: global translation table entry to be analyzed
+ *
+ * This functon assumes the caller holds rcu_read_lock().
+ * Returns best originator list entry or NULL on errors.
+ */
+static struct batadv_tt_orig_list_entry *
+batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
+{
+       struct batadv_neigh_node *router = NULL;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
+       int best_tq = 0;
+
+       head = &tt_global_entry->orig_list;
+       hlist_for_each_entry_rcu(orig_entry, node, head, list) {
+               router = batadv_orig_node_get_router(orig_entry->orig_node);
+               if (!router)
+                       continue;
+
+               if (router->tq_avg > best_tq) {
+                       best_entry = orig_entry;
+                       best_tq = router->tq_avg;
+               }
+
+               batadv_neigh_node_free_ref(router);
+       }
+
+       return best_entry;
+}
+
+/* batadv_tt_global_print_entry - print all orig nodes who announce the address
+ * for this global entry
+ * @tt_global_entry: global translation table entry to be printed
+ * @seq: debugfs table seq_file struct
+ *
+ * This functon assumes the caller holds rcu_read_lock().
  */
 static void
 batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
@@ -920,21 +956,37 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
 {
        struct hlist_head *head;
        struct hlist_node *node;
-       struct batadv_tt_orig_list_entry *orig_entry;
+       struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
        struct batadv_tt_common_entry *tt_common_entry;
        uint16_t flags;
        uint8_t last_ttvn;
 
        tt_common_entry = &tt_global_entry->common;
+       flags = tt_common_entry->flags;
+
+       best_entry = batadv_transtable_best_orig(tt_global_entry);
+       if (best_entry) {
+               last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
+               seq_printf(seq, " %c %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
+                          '*', tt_global_entry->common.addr,
+                          best_entry->ttvn, best_entry->orig_node->orig,
+                          last_ttvn,
+                          (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
+                          (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
+                          (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
+       }
 
        head = &tt_global_entry->orig_list;
 
        hlist_for_each_entry_rcu(orig_entry, node, head, list) {
-               flags = tt_common_entry->flags;
+               if (best_entry == orig_entry)
+                       continue;
+
                last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
-               seq_printf(seq, " * %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
-                          tt_global_entry->common.addr, orig_entry->ttvn,
-                          orig_entry->orig_node->orig, last_ttvn,
+               seq_printf(seq, " %c %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
+                          '+', tt_global_entry->common.addr,
+                          orig_entry->ttvn, orig_entry->orig_node->orig,
+                          last_ttvn,
                           (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
                           (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
                           (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
@@ -1280,11 +1332,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
        struct batadv_tt_local_entry *tt_local_entry = NULL;
        struct batadv_tt_global_entry *tt_global_entry = NULL;
        struct batadv_orig_node *orig_node = NULL;
-       struct batadv_neigh_node *router = NULL;
-       struct hlist_head *head;
-       struct hlist_node *node;
-       struct batadv_tt_orig_list_entry *orig_entry;
-       int best_tq;
+       struct batadv_tt_orig_list_entry *best_entry;
 
        if (src && atomic_read(&bat_priv->ap_isolation)) {
                tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
@@ -1304,25 +1352,15 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
            _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
                goto out;
 
-       best_tq = 0;
-
        rcu_read_lock();
-       head = &tt_global_entry->orig_list;
-       hlist_for_each_entry_rcu(orig_entry, node, head, list) {
-               router = batadv_orig_node_get_router(orig_entry->orig_node);
-               if (!router)
-                       continue;
-
-               if (router->tq_avg > best_tq) {
-                       orig_node = orig_entry->orig_node;
-                       best_tq = router->tq_avg;
-               }
-               batadv_neigh_node_free_ref(router);
-       }
+       best_entry = batadv_transtable_best_orig(tt_global_entry);
        /* found anything? */
+       if (best_entry)
+               orig_node = best_entry->orig_node;
        if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
                orig_node = NULL;
        rcu_read_unlock();
+
 out:
        if (tt_global_entry)
                batadv_tt_global_entry_free_ref(tt_global_entry);