Commit 981d8900 authored by Sven Eckelmann's avatar Sven Eckelmann Committed by Antonio Quartulli

batman-adv: Mark best gateway in transtable_global debugfs

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: default avatarSven Eckelmann <sven@narfation.org>
Signed-off-by: default avatarMarek Lindner <lindner_marek@yahoo.de>
Signed-off-by: default avatarAntonio Quartulli <ordex@autistici.org>
parent de4594a5
...@@ -911,8 +911,44 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, ...@@ -911,8 +911,44 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
return ret; return ret;
} }
/* print all orig nodes who announce the address for this global entry. /* batadv_transtable_best_orig - Get best originator list entry from tt entry
* it is assumed that the caller holds rcu_read_lock(); * @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 static void
batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, 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, ...@@ -920,21 +956,37 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
{ {
struct hlist_head *head; struct hlist_head *head;
struct hlist_node *node; 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; struct batadv_tt_common_entry *tt_common_entry;
uint16_t flags; uint16_t flags;
uint8_t last_ttvn; uint8_t last_ttvn;
tt_common_entry = &tt_global_entry->common; 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; head = &tt_global_entry->orig_list;
hlist_for_each_entry_rcu(orig_entry, node, head, 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); last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n", seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n",
tt_global_entry->common.addr, orig_entry->ttvn, '+', tt_global_entry->common.addr,
orig_entry->orig_node->orig, last_ttvn, orig_entry->ttvn, orig_entry->orig_node->orig,
last_ttvn,
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
...@@ -1280,11 +1332,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, ...@@ -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_local_entry *tt_local_entry = NULL;
struct batadv_tt_global_entry *tt_global_entry = NULL; struct batadv_tt_global_entry *tt_global_entry = NULL;
struct batadv_orig_node *orig_node = NULL; struct batadv_orig_node *orig_node = NULL;
struct batadv_neigh_node *router = NULL; struct batadv_tt_orig_list_entry *best_entry;
struct hlist_head *head;
struct hlist_node *node;
struct batadv_tt_orig_list_entry *orig_entry;
int best_tq;
if (src && atomic_read(&bat_priv->ap_isolation)) { if (src && atomic_read(&bat_priv->ap_isolation)) {
tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); 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, ...@@ -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)) _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
goto out; goto out;
best_tq = 0;
rcu_read_lock(); rcu_read_lock();
head = &tt_global_entry->orig_list; best_entry = batadv_transtable_best_orig(tt_global_entry);
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);
}
/* found anything? */ /* found anything? */
if (best_entry)
orig_node = best_entry->orig_node;
if (orig_node && !atomic_inc_not_zero(&orig_node->refcount)) if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
orig_node = NULL; orig_node = NULL;
rcu_read_unlock(); rcu_read_unlock();
out: out:
if (tt_global_entry) if (tt_global_entry)
batadv_tt_global_entry_free_ref(tt_global_entry); batadv_tt_global_entry_free_ref(tt_global_entry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment