aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/translation-table.c
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2012-10-07 07:34:15 -0400
committerAntonio Quartulli <ordex@autistici.org>2012-11-21 06:34:48 -0500
commit981d8900291108eebf187fd77736f751e99b6ffd (patch)
tree5a32475dd3be14bfa96a06366d3cf17066dc676d /net/batman-adv/translation-table.c
parentde4594a51c904ddcd6c3a6cdd100f7c1d94d3239 (diff)
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: Sven Eckelmann <sven@narfation.org> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r--net/batman-adv/translation-table.c90
1 files changed, 64 insertions, 26 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 582f13405df9..cdad824a0014 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -911,8 +911,44 @@ out:
911 return ret; 911 return ret;
912} 912}
913 913
914/* print all orig nodes who announce the address for this global entry. 914/* batadv_transtable_best_orig - Get best originator list entry from tt entry
915 * it is assumed that the caller holds rcu_read_lock(); 915 * @tt_global_entry: global translation table entry to be analyzed
916 *
917 * This functon assumes the caller holds rcu_read_lock().
918 * Returns best originator list entry or NULL on errors.
919 */
920static struct batadv_tt_orig_list_entry *
921batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
922{
923 struct batadv_neigh_node *router = NULL;
924 struct hlist_head *head;
925 struct hlist_node *node;
926 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
927 int best_tq = 0;
928
929 head = &tt_global_entry->orig_list;
930 hlist_for_each_entry_rcu(orig_entry, node, head, list) {
931 router = batadv_orig_node_get_router(orig_entry->orig_node);
932 if (!router)
933 continue;
934
935 if (router->tq_avg > best_tq) {
936 best_entry = orig_entry;
937 best_tq = router->tq_avg;
938 }
939
940 batadv_neigh_node_free_ref(router);
941 }
942
943 return best_entry;
944}
945
946/* batadv_tt_global_print_entry - print all orig nodes who announce the address
947 * for this global entry
948 * @tt_global_entry: global translation table entry to be printed
949 * @seq: debugfs table seq_file struct
950 *
951 * This functon assumes the caller holds rcu_read_lock().
916 */ 952 */
917static void 953static void
918batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, 954batadv_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{ 956{
921 struct hlist_head *head; 957 struct hlist_head *head;
922 struct hlist_node *node; 958 struct hlist_node *node;
923 struct batadv_tt_orig_list_entry *orig_entry; 959 struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
924 struct batadv_tt_common_entry *tt_common_entry; 960 struct batadv_tt_common_entry *tt_common_entry;
925 uint16_t flags; 961 uint16_t flags;
926 uint8_t last_ttvn; 962 uint8_t last_ttvn;
927 963
928 tt_common_entry = &tt_global_entry->common; 964 tt_common_entry = &tt_global_entry->common;
965 flags = tt_common_entry->flags;
966
967 best_entry = batadv_transtable_best_orig(tt_global_entry);
968 if (best_entry) {
969 last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
970 seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n",
971 '*', tt_global_entry->common.addr,
972 best_entry->ttvn, best_entry->orig_node->orig,
973 last_ttvn,
974 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
975 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
976 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
977 }
929 978
930 head = &tt_global_entry->orig_list; 979 head = &tt_global_entry->orig_list;
931 980
932 hlist_for_each_entry_rcu(orig_entry, node, head, list) { 981 hlist_for_each_entry_rcu(orig_entry, node, head, list) {
933 flags = tt_common_entry->flags; 982 if (best_entry == orig_entry)
983 continue;
984
934 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); 985 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
935 seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n", 986 seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n",
936 tt_global_entry->common.addr, orig_entry->ttvn, 987 '+', tt_global_entry->common.addr,
937 orig_entry->orig_node->orig, last_ttvn, 988 orig_entry->ttvn, orig_entry->orig_node->orig,
989 last_ttvn,
938 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 990 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
939 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), 991 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
940 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); 992 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
@@ -1280,11 +1332,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1280 struct batadv_tt_local_entry *tt_local_entry = NULL; 1332 struct batadv_tt_local_entry *tt_local_entry = NULL;
1281 struct batadv_tt_global_entry *tt_global_entry = NULL; 1333 struct batadv_tt_global_entry *tt_global_entry = NULL;
1282 struct batadv_orig_node *orig_node = NULL; 1334 struct batadv_orig_node *orig_node = NULL;
1283 struct batadv_neigh_node *router = NULL; 1335 struct batadv_tt_orig_list_entry *best_entry;
1284 struct hlist_head *head;
1285 struct hlist_node *node;
1286 struct batadv_tt_orig_list_entry *orig_entry;
1287 int best_tq;
1288 1336
1289 if (src && atomic_read(&bat_priv->ap_isolation)) { 1337 if (src && atomic_read(&bat_priv->ap_isolation)) {
1290 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src); 1338 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 _batadv_is_ap_isolated(tt_local_entry, tt_global_entry)) 1352 _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
1305 goto out; 1353 goto out;
1306 1354
1307 best_tq = 0;
1308
1309 rcu_read_lock(); 1355 rcu_read_lock();
1310 head = &tt_global_entry->orig_list; 1356 best_entry = batadv_transtable_best_orig(tt_global_entry);
1311 hlist_for_each_entry_rcu(orig_entry, node, head, list) {
1312 router = batadv_orig_node_get_router(orig_entry->orig_node);
1313 if (!router)
1314 continue;
1315
1316 if (router->tq_avg > best_tq) {
1317 orig_node = orig_entry->orig_node;
1318 best_tq = router->tq_avg;
1319 }
1320 batadv_neigh_node_free_ref(router);
1321 }
1322 /* found anything? */ 1357 /* found anything? */
1358 if (best_entry)
1359 orig_node = best_entry->orig_node;
1323 if (orig_node && !atomic_inc_not_zero(&orig_node->refcount)) 1360 if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
1324 orig_node = NULL; 1361 orig_node = NULL;
1325 rcu_read_unlock(); 1362 rcu_read_unlock();
1363
1326out: 1364out:
1327 if (tt_global_entry) 1365 if (tt_global_entry)
1328 batadv_tt_global_entry_free_ref(tt_global_entry); 1366 batadv_tt_global_entry_free_ref(tt_global_entry);