aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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));