@@ -862,7 +862,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
862
862
struct batadv_orig_node_vlan * vlan ;
863
863
u8 * tt_change_ptr ;
864
864
865
- rcu_read_lock ( );
865
+ spin_lock_bh ( & orig_node -> vlan_list_lock );
866
866
hlist_for_each_entry_rcu (vlan , & orig_node -> vlan_list , list ) {
867
867
num_vlan ++ ;
868
868
num_entries += atomic_read (& vlan -> tt .num_entries );
@@ -900,7 +900,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
900
900
* tt_change = (struct batadv_tvlv_tt_change * )tt_change_ptr ;
901
901
902
902
out :
903
- rcu_read_unlock ( );
903
+ spin_unlock_bh ( & orig_node -> vlan_list_lock );
904
904
return tvlv_len ;
905
905
}
906
906
@@ -931,23 +931,28 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
931
931
struct batadv_tvlv_tt_vlan_data * tt_vlan ;
932
932
struct batadv_softif_vlan * vlan ;
933
933
u16 num_vlan = 0 ;
934
- u16 num_entries = 0 ;
934
+ u16 vlan_entries = 0 ;
935
+ u16 total_entries = 0 ;
935
936
u16 tvlv_len ;
936
937
u8 * tt_change_ptr ;
937
938
int change_offset ;
938
939
939
- rcu_read_lock ( );
940
+ spin_lock_bh ( & bat_priv -> softif_vlan_list_lock );
940
941
hlist_for_each_entry_rcu (vlan , & bat_priv -> softif_vlan_list , list ) {
942
+ vlan_entries = atomic_read (& vlan -> tt .num_entries );
943
+ if (vlan_entries < 1 )
944
+ continue ;
945
+
941
946
num_vlan ++ ;
942
- num_entries += atomic_read ( & vlan -> tt . num_entries ) ;
947
+ total_entries += vlan_entries ;
943
948
}
944
949
945
950
change_offset = sizeof (* * tt_data );
946
951
change_offset += num_vlan * sizeof (* tt_vlan );
947
952
948
953
/* if tt_len is negative, allocate the space needed by the full table */
949
954
if (* tt_len < 0 )
950
- * tt_len = batadv_tt_len (num_entries );
955
+ * tt_len = batadv_tt_len (total_entries );
951
956
952
957
tvlv_len = * tt_len ;
953
958
tvlv_len += change_offset ;
@@ -964,6 +969,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
964
969
965
970
tt_vlan = (struct batadv_tvlv_tt_vlan_data * )(* tt_data + 1 );
966
971
hlist_for_each_entry_rcu (vlan , & bat_priv -> softif_vlan_list , list ) {
972
+ vlan_entries = atomic_read (& vlan -> tt .num_entries );
973
+ if (vlan_entries < 1 )
974
+ continue ;
975
+
967
976
tt_vlan -> vid = htons (vlan -> vid );
968
977
tt_vlan -> crc = htonl (vlan -> tt .crc );
969
978
@@ -974,7 +983,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
974
983
* tt_change = (struct batadv_tvlv_tt_change * )tt_change_ptr ;
975
984
976
985
out :
977
- rcu_read_unlock ( );
986
+ spin_unlock_bh ( & bat_priv -> softif_vlan_list_lock );
978
987
return tvlv_len ;
979
988
}
980
989
@@ -1538,21 +1547,28 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
1538
1547
* handled by a given originator
1539
1548
* @entry: the TT global entry to check
1540
1549
* @orig_node: the originator to search in the list
1550
+ * @flags: a pointer to store TT flags for the given @entry received
1551
+ * from @orig_node
1541
1552
*
1542
1553
* find out if an orig_node is already in the list of a tt_global_entry.
1543
1554
*
1544
1555
* Return: true if found, false otherwise
1545
1556
*/
1546
1557
static bool
1547
1558
batadv_tt_global_entry_has_orig (const struct batadv_tt_global_entry * entry ,
1548
- const struct batadv_orig_node * orig_node )
1559
+ const struct batadv_orig_node * orig_node ,
1560
+ u8 * flags )
1549
1561
{
1550
1562
struct batadv_tt_orig_list_entry * orig_entry ;
1551
1563
bool found = false;
1552
1564
1553
1565
orig_entry = batadv_tt_global_orig_entry_find (entry , orig_node );
1554
1566
if (orig_entry ) {
1555
1567
found = true;
1568
+
1569
+ if (flags )
1570
+ * flags = orig_entry -> flags ;
1571
+
1556
1572
batadv_tt_orig_list_entry_put (orig_entry );
1557
1573
}
1558
1574
@@ -1731,7 +1747,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
1731
1747
if (!(common -> flags & BATADV_TT_CLIENT_TEMP ))
1732
1748
goto out ;
1733
1749
if (batadv_tt_global_entry_has_orig (tt_global_entry ,
1734
- orig_node ))
1750
+ orig_node , NULL ))
1735
1751
goto out_remove ;
1736
1752
batadv_tt_global_del_orig_list (tt_global_entry );
1737
1753
goto add_orig_entry ;
@@ -2880,23 +2896,46 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
2880
2896
}
2881
2897
2882
2898
/**
2883
- * batadv_tt_local_valid() - verify that given tt entry is a valid one
2899
+ * batadv_tt_local_valid() - verify local tt entry and get flags
2884
2900
* @entry_ptr: to be checked local tt entry
2885
2901
* @data_ptr: not used but definition required to satisfy the callback prototype
2902
+ * @flags: a pointer to store TT flags for this client to
2903
+ *
2904
+ * Checks the validity of the given local TT entry. If it is, then the provided
2905
+ * flags pointer is updated.
2886
2906
*
2887
2907
* Return: true if the entry is a valid, false otherwise.
2888
2908
*/
2889
- static bool batadv_tt_local_valid (const void * entry_ptr , const void * data_ptr )
2909
+ static bool batadv_tt_local_valid (const void * entry_ptr ,
2910
+ const void * data_ptr ,
2911
+ u8 * flags )
2890
2912
{
2891
2913
const struct batadv_tt_common_entry * tt_common_entry = entry_ptr ;
2892
2914
2893
2915
if (tt_common_entry -> flags & BATADV_TT_CLIENT_NEW )
2894
2916
return false;
2917
+
2918
+ if (flags )
2919
+ * flags = tt_common_entry -> flags ;
2920
+
2895
2921
return true;
2896
2922
}
2897
2923
2924
+ /**
2925
+ * batadv_tt_global_valid() - verify global tt entry and get flags
2926
+ * @entry_ptr: to be checked global tt entry
2927
+ * @data_ptr: an orig_node object (may be NULL)
2928
+ * @flags: a pointer to store TT flags for this client to
2929
+ *
2930
+ * Checks the validity of the given global TT entry. If it is, then the provided
2931
+ * flags pointer is updated either with the common (summed) TT flags if data_ptr
2932
+ * is NULL or the specific, per originator TT flags otherwise.
2933
+ *
2934
+ * Return: true if the entry is a valid, false otherwise.
2935
+ */
2898
2936
static bool batadv_tt_global_valid (const void * entry_ptr ,
2899
- const void * data_ptr )
2937
+ const void * data_ptr ,
2938
+ u8 * flags )
2900
2939
{
2901
2940
const struct batadv_tt_common_entry * tt_common_entry = entry_ptr ;
2902
2941
const struct batadv_tt_global_entry * tt_global_entry ;
@@ -2910,7 +2949,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
2910
2949
struct batadv_tt_global_entry ,
2911
2950
common );
2912
2951
2913
- return batadv_tt_global_entry_has_orig (tt_global_entry , orig_node );
2952
+ return batadv_tt_global_entry_has_orig (tt_global_entry , orig_node ,
2953
+ flags );
2914
2954
}
2915
2955
2916
2956
/**
@@ -2920,25 +2960,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
2920
2960
* @hash: hash table containing the tt entries
2921
2961
* @tt_len: expected tvlv tt data buffer length in number of bytes
2922
2962
* @tvlv_buff: pointer to the buffer to fill with the TT data
2923
- * @valid_cb: function to filter tt change entries
2963
+ * @valid_cb: function to filter tt change entries and to return TT flags
2924
2964
* @cb_data: data passed to the filter function as argument
2965
+ *
2966
+ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
2967
+ * is not provided then this becomes a no-op.
2925
2968
*/
2926
2969
static void batadv_tt_tvlv_generate (struct batadv_priv * bat_priv ,
2927
2970
struct batadv_hashtable * hash ,
2928
2971
void * tvlv_buff , u16 tt_len ,
2929
2972
bool (* valid_cb )(const void * ,
2930
- const void * ),
2973
+ const void * ,
2974
+ u8 * flags ),
2931
2975
void * cb_data )
2932
2976
{
2933
2977
struct batadv_tt_common_entry * tt_common_entry ;
2934
2978
struct batadv_tvlv_tt_change * tt_change ;
2935
2979
struct hlist_head * head ;
2936
2980
u16 tt_tot , tt_num_entries = 0 ;
2981
+ u8 flags ;
2982
+ bool ret ;
2937
2983
u32 i ;
2938
2984
2939
2985
tt_tot = batadv_tt_entries (tt_len );
2940
2986
tt_change = (struct batadv_tvlv_tt_change * )tvlv_buff ;
2941
2987
2988
+ if (!valid_cb )
2989
+ return ;
2990
+
2942
2991
rcu_read_lock ();
2943
2992
for (i = 0 ; i < hash -> size ; i ++ ) {
2944
2993
head = & hash -> table [i ];
@@ -2948,11 +2997,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2948
2997
if (tt_tot == tt_num_entries )
2949
2998
break ;
2950
2999
2951
- if ((valid_cb ) && (!valid_cb (tt_common_entry , cb_data )))
3000
+ ret = valid_cb (tt_common_entry , cb_data , & flags );
3001
+ if (!ret )
2952
3002
continue ;
2953
3003
2954
3004
ether_addr_copy (tt_change -> addr , tt_common_entry -> addr );
2955
- tt_change -> flags = tt_common_entry -> flags ;
3005
+ tt_change -> flags = flags ;
2956
3006
tt_change -> vid = htons (tt_common_entry -> vid );
2957
3007
memset (tt_change -> reserved , 0 ,
2958
3008
sizeof (tt_change -> reserved ));
0 commit comments