181 lines
6.7 KiB
Diff
181 lines
6.7 KiB
Diff
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
|
Date: Thu, 10 May 2018 19:44:28 +0200
|
|
Subject: [PATCH] batman-adv: Fix TT sync flags for intermediate TT responses
|
|
|
|
The previous TT sync fix so far only fixed TT responses issued by the
|
|
target node directly. So far, TT responses issued by intermediate nodes
|
|
still lead to the wrong flags being added, leading to CRC mismatches.
|
|
|
|
This behaviour was observed at Freifunk Hannover in a 800 nodes setup
|
|
where a considerable amount of nodes were still infected with 'WI'
|
|
TT flags even with (most) nodes having the previous TT sync fix applied.
|
|
|
|
I was able to reproduce the issue with intermediate TT responses in a
|
|
four node test setup and this patch fixes this issue by ensuring to
|
|
use the per originator instead of the summarized, OR'd ones.
|
|
|
|
Fixes: fa614fd04692 ("batman-adv: fix tt_global_entries flags update")
|
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
|
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d65daee8617b29c1ddcc949ce3a5ec24f7a1e1af
|
|
---
|
|
net/batman-adv/translation-table.c | 61 +++++++++++++++++++++++++-----
|
|
1 file changed, 51 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
|
|
index 7fa3a0a0524a1da63e92d081b443c302900bf0c3..23f9c212ab1e27be429645a85f7b5d6a02585de9 100644
|
|
--- a/net/batman-adv/translation-table.c
|
|
+++ b/net/batman-adv/translation-table.c
|
|
@@ -1538,6 +1538,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
|
|
* handled by a given originator
|
|
* @entry: the TT global entry to check
|
|
* @orig_node: the originator to search in the list
|
|
+ * @flags: a pointer to store TT flags for the given @entry received
|
|
+ * from @orig_node
|
|
*
|
|
* find out if an orig_node is already in the list of a tt_global_entry.
|
|
*
|
|
@@ -1545,7 +1547,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
|
|
*/
|
|
static bool
|
|
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
|
|
- const struct batadv_orig_node *orig_node)
|
|
+ const struct batadv_orig_node *orig_node,
|
|
+ u8 *flags)
|
|
{
|
|
struct batadv_tt_orig_list_entry *orig_entry;
|
|
bool found = false;
|
|
@@ -1553,6 +1556,10 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
|
|
orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
|
|
if (orig_entry) {
|
|
found = true;
|
|
+
|
|
+ if (flags)
|
|
+ *flags = orig_entry->flags;
|
|
+
|
|
batadv_tt_orig_list_entry_put(orig_entry);
|
|
}
|
|
|
|
@@ -1731,7 +1738,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
|
|
if (!(common->flags & BATADV_TT_CLIENT_TEMP))
|
|
goto out;
|
|
if (batadv_tt_global_entry_has_orig(tt_global_entry,
|
|
- orig_node))
|
|
+ orig_node, NULL))
|
|
goto out_remove;
|
|
batadv_tt_global_del_orig_list(tt_global_entry);
|
|
goto add_orig_entry;
|
|
@@ -2880,23 +2887,46 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
|
|
}
|
|
|
|
/**
|
|
- * batadv_tt_local_valid() - verify that given tt entry is a valid one
|
|
+ * batadv_tt_local_valid() - verify local tt entry and get flags
|
|
* @entry_ptr: to be checked local tt entry
|
|
* @data_ptr: not used but definition required to satisfy the callback prototype
|
|
+ * @flags: a pointer to store TT flags for this client to
|
|
+ *
|
|
+ * Checks the validity of the given local TT entry. If it is, then the provided
|
|
+ * flags pointer is updated.
|
|
*
|
|
* Return: true if the entry is a valid, false otherwise.
|
|
*/
|
|
-static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
|
|
+static bool batadv_tt_local_valid(const void *entry_ptr,
|
|
+ const void *data_ptr,
|
|
+ u8 *flags)
|
|
{
|
|
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
|
|
|
|
if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
|
|
return false;
|
|
+
|
|
+ if (flags)
|
|
+ *flags = tt_common_entry->flags;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
+/**
|
|
+ * batadv_tt_global_valid() - verify global tt entry and get flags
|
|
+ * @entry_ptr: to be checked global tt entry
|
|
+ * @data_ptr: an orig_node object (may be NULL)
|
|
+ * @flags: a pointer to store TT flags for this client to
|
|
+ *
|
|
+ * Checks the validity of the given global TT entry. If it is, then the provided
|
|
+ * flags pointer is updated either with the common (summed) TT flags if data_ptr
|
|
+ * is NULL or the specific, per originator TT flags otherwise.
|
|
+ *
|
|
+ * Return: true if the entry is a valid, false otherwise.
|
|
+ */
|
|
static bool batadv_tt_global_valid(const void *entry_ptr,
|
|
- const void *data_ptr)
|
|
+ const void *data_ptr,
|
|
+ u8 *flags)
|
|
{
|
|
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
|
|
const struct batadv_tt_global_entry *tt_global_entry;
|
|
@@ -2910,7 +2940,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
|
|
struct batadv_tt_global_entry,
|
|
common);
|
|
|
|
- return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
|
|
+ return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
|
|
+ flags);
|
|
}
|
|
|
|
/**
|
|
@@ -2920,25 +2951,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
|
|
* @hash: hash table containing the tt entries
|
|
* @tt_len: expected tvlv tt data buffer length in number of bytes
|
|
* @tvlv_buff: pointer to the buffer to fill with the TT data
|
|
- * @valid_cb: function to filter tt change entries
|
|
+ * @valid_cb: function to filter tt change entries and to return TT flags
|
|
* @cb_data: data passed to the filter function as argument
|
|
+ *
|
|
+ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
|
|
+ * is not provided then this becomes a no-op.
|
|
*/
|
|
static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
|
|
struct batadv_hashtable *hash,
|
|
void *tvlv_buff, u16 tt_len,
|
|
bool (*valid_cb)(const void *,
|
|
- const void *),
|
|
+ const void *,
|
|
+ u8 *flags),
|
|
void *cb_data)
|
|
{
|
|
struct batadv_tt_common_entry *tt_common_entry;
|
|
struct batadv_tvlv_tt_change *tt_change;
|
|
struct hlist_head *head;
|
|
u16 tt_tot, tt_num_entries = 0;
|
|
+ u8 flags;
|
|
+ bool ret;
|
|
u32 i;
|
|
|
|
tt_tot = batadv_tt_entries(tt_len);
|
|
tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
|
|
|
|
+ if (!valid_cb)
|
|
+ return;
|
|
+
|
|
rcu_read_lock();
|
|
for (i = 0; i < hash->size; i++) {
|
|
head = &hash->table[i];
|
|
@@ -2948,11 +2988,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
|
|
if (tt_tot == tt_num_entries)
|
|
break;
|
|
|
|
- if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
|
|
+ ret = valid_cb(tt_common_entry, cb_data, &flags);
|
|
+ if (!ret)
|
|
continue;
|
|
|
|
ether_addr_copy(tt_change->addr, tt_common_entry->addr);
|
|
- tt_change->flags = tt_common_entry->flags;
|
|
+ tt_change->flags = flags;
|
|
tt_change->vid = htons(tt_common_entry->vid);
|
|
memset(tt_change->reserved, 0,
|
|
sizeof(tt_change->reserved));
|