Skip to content

Commit 7072337

Browse files
T-Xsimonwunderlich
authored andcommitted
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: e9c0013 ("batman-adv: fix tt_global_entries flags update") Reported-by: Leonardo Mörlein <me@irrelefant.net> Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
1 parent 8ba0f9b commit 7072337

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

net/batman-adv/translation-table.c

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,21 +1538,28 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
15381538
* handled by a given originator
15391539
* @entry: the TT global entry to check
15401540
* @orig_node: the originator to search in the list
1541+
* @flags: a pointer to store TT flags for the given @entry received
1542+
* from @orig_node
15411543
*
15421544
* find out if an orig_node is already in the list of a tt_global_entry.
15431545
*
15441546
* Return: true if found, false otherwise
15451547
*/
15461548
static bool
15471549
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
1548-
const struct batadv_orig_node *orig_node)
1550+
const struct batadv_orig_node *orig_node,
1551+
u8 *flags)
15491552
{
15501553
struct batadv_tt_orig_list_entry *orig_entry;
15511554
bool found = false;
15521555

15531556
orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
15541557
if (orig_entry) {
15551558
found = true;
1559+
1560+
if (flags)
1561+
*flags = orig_entry->flags;
1562+
15561563
batadv_tt_orig_list_entry_put(orig_entry);
15571564
}
15581565

@@ -1731,7 +1738,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
17311738
if (!(common->flags & BATADV_TT_CLIENT_TEMP))
17321739
goto out;
17331740
if (batadv_tt_global_entry_has_orig(tt_global_entry,
1734-
orig_node))
1741+
orig_node, NULL))
17351742
goto out_remove;
17361743
batadv_tt_global_del_orig_list(tt_global_entry);
17371744
goto add_orig_entry;
@@ -2880,23 +2887,46 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
28802887
}
28812888

28822889
/**
2883-
* batadv_tt_local_valid() - verify that given tt entry is a valid one
2890+
* batadv_tt_local_valid() - verify local tt entry and get flags
28842891
* @entry_ptr: to be checked local tt entry
28852892
* @data_ptr: not used but definition required to satisfy the callback prototype
2893+
* @flags: a pointer to store TT flags for this client to
2894+
*
2895+
* Checks the validity of the given local TT entry. If it is, then the provided
2896+
* flags pointer is updated.
28862897
*
28872898
* Return: true if the entry is a valid, false otherwise.
28882899
*/
2889-
static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
2900+
static bool batadv_tt_local_valid(const void *entry_ptr,
2901+
const void *data_ptr,
2902+
u8 *flags)
28902903
{
28912904
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
28922905

28932906
if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
28942907
return false;
2908+
2909+
if (flags)
2910+
*flags = tt_common_entry->flags;
2911+
28952912
return true;
28962913
}
28972914

2915+
/**
2916+
* batadv_tt_global_valid() - verify global tt entry and get flags
2917+
* @entry_ptr: to be checked global tt entry
2918+
* @data_ptr: an orig_node object (may be NULL)
2919+
* @flags: a pointer to store TT flags for this client to
2920+
*
2921+
* Checks the validity of the given global TT entry. If it is, then the provided
2922+
* flags pointer is updated either with the common (summed) TT flags if data_ptr
2923+
* is NULL or the specific, per originator TT flags otherwise.
2924+
*
2925+
* Return: true if the entry is a valid, false otherwise.
2926+
*/
28982927
static bool batadv_tt_global_valid(const void *entry_ptr,
2899-
const void *data_ptr)
2928+
const void *data_ptr,
2929+
u8 *flags)
29002930
{
29012931
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
29022932
const struct batadv_tt_global_entry *tt_global_entry;
@@ -2910,7 +2940,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
29102940
struct batadv_tt_global_entry,
29112941
common);
29122942

2913-
return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
2943+
return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
2944+
flags);
29142945
}
29152946

29162947
/**
@@ -2920,25 +2951,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
29202951
* @hash: hash table containing the tt entries
29212952
* @tt_len: expected tvlv tt data buffer length in number of bytes
29222953
* @tvlv_buff: pointer to the buffer to fill with the TT data
2923-
* @valid_cb: function to filter tt change entries
2954+
* @valid_cb: function to filter tt change entries and to return TT flags
29242955
* @cb_data: data passed to the filter function as argument
2956+
*
2957+
* Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
2958+
* is not provided then this becomes a no-op.
29252959
*/
29262960
static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
29272961
struct batadv_hashtable *hash,
29282962
void *tvlv_buff, u16 tt_len,
29292963
bool (*valid_cb)(const void *,
2930-
const void *),
2964+
const void *,
2965+
u8 *flags),
29312966
void *cb_data)
29322967
{
29332968
struct batadv_tt_common_entry *tt_common_entry;
29342969
struct batadv_tvlv_tt_change *tt_change;
29352970
struct hlist_head *head;
29362971
u16 tt_tot, tt_num_entries = 0;
2972+
u8 flags;
2973+
bool ret;
29372974
u32 i;
29382975

29392976
tt_tot = batadv_tt_entries(tt_len);
29402977
tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
29412978

2979+
if (!valid_cb)
2980+
return;
2981+
29422982
rcu_read_lock();
29432983
for (i = 0; i < hash->size; i++) {
29442984
head = &hash->table[i];
@@ -2948,11 +2988,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
29482988
if (tt_tot == tt_num_entries)
29492989
break;
29502990

2951-
if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
2991+
ret = valid_cb(tt_common_entry, cb_data, &flags);
2992+
if (!ret)
29522993
continue;
29532994

29542995
ether_addr_copy(tt_change->addr, tt_common_entry->addr);
2955-
tt_change->flags = tt_common_entry->flags;
2996+
tt_change->flags = flags;
29562997
tt_change->vid = htons(tt_common_entry->vid);
29572998
memset(tt_change->reserved, 0,
29582999
sizeof(tt_change->reserved));

0 commit comments

Comments
 (0)