aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@c0d3.blue>2018-05-10 13:44:28 -0400
committerSimon Wunderlich <sw@simonwunderlich.de>2018-05-12 12:52:19 -0400
commit7072337e52b3e9d5460500d8dc9cbc1ba2db084c (patch)
treef0b0b7de59238eee7d118b49864f50081d2b7e10 /net
parent8ba0f9bd3bdea1058c2b2676bec7905724418e40 (diff)
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: e9c00136a475 ("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>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/translation-table.c61
1 files changed, 51 insertions, 10 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 7fa3a0a0524a..23f9c212ab1e 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,
1538 * handled by a given originator 1538 * handled by a given originator
1539 * @entry: the TT global entry to check 1539 * @entry: the TT global entry to check
1540 * @orig_node: the originator to search in the list 1540 * @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
1541 * 1543 *
1542 * find out if an orig_node is already in the list of a tt_global_entry. 1544 * find out if an orig_node is already in the list of a tt_global_entry.
1543 * 1545 *
@@ -1545,7 +1547,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
1545 */ 1547 */
1546static bool 1548static bool
1547batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, 1549batadv_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)
1549{ 1552{
1550 struct batadv_tt_orig_list_entry *orig_entry; 1553 struct batadv_tt_orig_list_entry *orig_entry;
1551 bool found = false; 1554 bool found = false;
@@ -1553,6 +1556,10 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
1553 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); 1556 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
1554 if (orig_entry) { 1557 if (orig_entry) {
1555 found = true; 1558 found = true;
1559
1560 if (flags)
1561 *flags = orig_entry->flags;
1562
1556 batadv_tt_orig_list_entry_put(orig_entry); 1563 batadv_tt_orig_list_entry_put(orig_entry);
1557 } 1564 }
1558 1565
@@ -1731,7 +1738,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
1731 if (!(common->flags & BATADV_TT_CLIENT_TEMP)) 1738 if (!(common->flags & BATADV_TT_CLIENT_TEMP))
1732 goto out; 1739 goto out;
1733 if (batadv_tt_global_entry_has_orig(tt_global_entry, 1740 if (batadv_tt_global_entry_has_orig(tt_global_entry,
1734 orig_node)) 1741 orig_node, NULL))
1735 goto out_remove; 1742 goto out_remove;
1736 batadv_tt_global_del_orig_list(tt_global_entry); 1743 batadv_tt_global_del_orig_list(tt_global_entry);
1737 goto add_orig_entry; 1744 goto add_orig_entry;
@@ -2880,23 +2887,46 @@ unlock:
2880} 2887}
2881 2888
2882/** 2889/**
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
2884 * @entry_ptr: to be checked local tt entry 2891 * @entry_ptr: to be checked local tt entry
2885 * @data_ptr: not used but definition required to satisfy the callback prototype 2892 * @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.
2886 * 2897 *
2887 * Return: true if the entry is a valid, false otherwise. 2898 * Return: true if the entry is a valid, false otherwise.
2888 */ 2899 */
2889static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr) 2900static bool batadv_tt_local_valid(const void *entry_ptr,
2901 const void *data_ptr,
2902 u8 *flags)
2890{ 2903{
2891 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 2904 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2892 2905
2893 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) 2906 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
2894 return false; 2907 return false;
2908
2909 if (flags)
2910 *flags = tt_common_entry->flags;
2911
2895 return true; 2912 return true;
2896} 2913}
2897 2914
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 */
2898static bool batadv_tt_global_valid(const void *entry_ptr, 2927static bool batadv_tt_global_valid(const void *entry_ptr,
2899 const void *data_ptr) 2928 const void *data_ptr,
2929 u8 *flags)
2900{ 2930{
2901 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; 2931 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2902 const struct batadv_tt_global_entry *tt_global_entry; 2932 const struct batadv_tt_global_entry *tt_global_entry;
@@ -2910,7 +2940,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
2910 struct batadv_tt_global_entry, 2940 struct batadv_tt_global_entry,
2911 common); 2941 common);
2912 2942
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);
2914} 2945}
2915 2946
2916/** 2947/**
@@ -2920,25 +2951,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
2920 * @hash: hash table containing the tt entries 2951 * @hash: hash table containing the tt entries
2921 * @tt_len: expected tvlv tt data buffer length in number of bytes 2952 * @tt_len: expected tvlv tt data buffer length in number of bytes
2922 * @tvlv_buff: pointer to the buffer to fill with the TT data 2953 * @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
2924 * @cb_data: data passed to the filter function as argument 2955 * @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.
2925 */ 2959 */
2926static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, 2960static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2927 struct batadv_hashtable *hash, 2961 struct batadv_hashtable *hash,
2928 void *tvlv_buff, u16 tt_len, 2962 void *tvlv_buff, u16 tt_len,
2929 bool (*valid_cb)(const void *, 2963 bool (*valid_cb)(const void *,
2930 const void *), 2964 const void *,
2965 u8 *flags),
2931 void *cb_data) 2966 void *cb_data)
2932{ 2967{
2933 struct batadv_tt_common_entry *tt_common_entry; 2968 struct batadv_tt_common_entry *tt_common_entry;
2934 struct batadv_tvlv_tt_change *tt_change; 2969 struct batadv_tvlv_tt_change *tt_change;
2935 struct hlist_head *head; 2970 struct hlist_head *head;
2936 u16 tt_tot, tt_num_entries = 0; 2971 u16 tt_tot, tt_num_entries = 0;
2972 u8 flags;
2973 bool ret;
2937 u32 i; 2974 u32 i;
2938 2975
2939 tt_tot = batadv_tt_entries(tt_len); 2976 tt_tot = batadv_tt_entries(tt_len);
2940 tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff; 2977 tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
2941 2978
2979 if (!valid_cb)
2980 return;
2981
2942 rcu_read_lock(); 2982 rcu_read_lock();
2943 for (i = 0; i < hash->size; i++) { 2983 for (i = 0; i < hash->size; i++) {
2944 head = &hash->table[i]; 2984 head = &hash->table[i];
@@ -2948,11 +2988,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2948 if (tt_tot == tt_num_entries) 2988 if (tt_tot == tt_num_entries)
2949 break; 2989 break;
2950 2990
2951 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) 2991 ret = valid_cb(tt_common_entry, cb_data, &flags);
2992 if (!ret)
2952 continue; 2993 continue;
2953 2994
2954 ether_addr_copy(tt_change->addr, tt_common_entry->addr); 2995 ether_addr_copy(tt_change->addr, tt_common_entry->addr);
2955 tt_change->flags = tt_common_entry->flags; 2996 tt_change->flags = flags;
2956 tt_change->vid = htons(tt_common_entry->vid); 2997 tt_change->vid = htons(tt_common_entry->vid);
2957 memset(tt_change->reserved, 0, 2998 memset(tt_change->reserved, 0,
2958 sizeof(tt_change->reserved)); 2999 sizeof(tt_change->reserved));