hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/batman-adv/translation-table.c
....@@ -1,19 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors:
2
+/* Copyright (C) 2007-2020 B.A.T.M.A.N. contributors:
33 *
44 * Marek Lindner, Simon Wunderlich, Antonio Quartulli
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of version 2 of the GNU General Public
8
- * License as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but
11
- * WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
175 */
186
197 #include "translation-table.h"
....@@ -205,7 +193,7 @@
205193 * Return: a pointer to the corresponding tt_global_entry struct if the client
206194 * is found, NULL otherwise.
207195 */
208
-static struct batadv_tt_global_entry *
196
+struct batadv_tt_global_entry *
209197 batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
210198 unsigned short vid)
211199 {
....@@ -260,6 +248,9 @@
260248 static void
261249 batadv_tt_local_entry_put(struct batadv_tt_local_entry *tt_local_entry)
262250 {
251
+ if (!tt_local_entry)
252
+ return;
253
+
263254 kref_put(&tt_local_entry->common.refcount,
264255 batadv_tt_local_entry_release);
265256 }
....@@ -283,7 +274,7 @@
283274 * queue for free after rcu grace period
284275 * @ref: kref pointer of the nc_node
285276 */
286
-static void batadv_tt_global_entry_release(struct kref *ref)
277
+void batadv_tt_global_entry_release(struct kref *ref)
287278 {
288279 struct batadv_tt_global_entry *tt_global_entry;
289280
....@@ -296,25 +287,13 @@
296287 }
297288
298289 /**
299
- * batadv_tt_global_entry_put() - decrement the tt_global_entry refcounter and
300
- * possibly release it
301
- * @tt_global_entry: tt_global_entry to be free'd
302
- */
303
-static void
304
-batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry)
305
-{
306
- kref_put(&tt_global_entry->common.refcount,
307
- batadv_tt_global_entry_release);
308
-}
309
-
310
-/**
311290 * batadv_tt_global_hash_count() - count the number of orig entries
312291 * @bat_priv: the bat priv with all the soft interface information
313292 * @addr: the mac address of the client to count entries for
314293 * @vid: VLAN identifier
315294 *
316295 * Return: the number of originators advertising the given address/data
317
- * (excluding ourself).
296
+ * (excluding our self).
318297 */
319298 int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
320299 const u8 *addr, unsigned short vid)
....@@ -466,6 +445,9 @@
466445 static void
467446 batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry *orig_entry)
468447 {
448
+ if (!orig_entry)
449
+ return;
450
+
469451 kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release);
470452 }
471453
....@@ -793,7 +775,6 @@
793775 if (roamed_back) {
794776 batadv_tt_global_free(bat_priv, tt_global,
795777 "Roaming canceled");
796
- tt_global = NULL;
797778 } else {
798779 /* The global entry has to be marked as ROAMING and
799780 * has to be kept for consistency purpose
....@@ -855,7 +836,7 @@
855836 * table. In case of success the value is updated with the real amount of
856837 * reserved bytes
857838 * Allocate the needed amount of memory for the entire TT TVLV and write its
858
- * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
839
+ * header made up of one tvlv_tt_data object and a series of tvlv_tt_vlan_data
859840 * objects, one per active VLAN served by the originator node.
860841 *
861842 * Return: the size of the allocated buffer or 0 in case of failure.
....@@ -875,7 +856,7 @@
875856 u8 *tt_change_ptr;
876857
877858 spin_lock_bh(&orig_node->vlan_list_lock);
878
- hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
859
+ hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
879860 num_vlan++;
880861 num_entries += atomic_read(&vlan->tt.num_entries);
881862 }
....@@ -901,7 +882,7 @@
901882 (*tt_data)->num_vlan = htons(num_vlan);
902883
903884 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
904
- hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
885
+ hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
905886 tt_vlan->vid = htons(vlan->vid);
906887 tt_vlan->crc = htonl(vlan->tt.crc);
907888 tt_vlan->reserved = 0;
....@@ -951,7 +932,7 @@
951932 int change_offset;
952933
953934 spin_lock_bh(&bat_priv->softif_vlan_list_lock);
954
- hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
935
+ hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) {
955936 vlan_entries = atomic_read(&vlan->tt.num_entries);
956937 if (vlan_entries < 1)
957938 continue;
....@@ -981,7 +962,7 @@
981962 (*tt_data)->num_vlan = htons(num_vlan);
982963
983964 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
984
- hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
965
+ hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) {
985966 vlan_entries = atomic_read(&vlan->tt.num_entries);
986967 if (vlan_entries < 1)
987968 continue;
....@@ -1159,14 +1140,15 @@
11591140 * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
11601141 * @msg :Netlink message to dump into
11611142 * @portid: Port making netlink request
1162
- * @seq: Sequence number of netlink message
1143
+ * @cb: Control block containing additional options
11631144 * @bat_priv: The bat priv with all the soft interface information
11641145 * @common: tt local & tt global common data
11651146 *
11661147 * Return: Error code, or 0 on success
11671148 */
11681149 static int
1169
-batadv_tt_local_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
1150
+batadv_tt_local_dump_entry(struct sk_buff *msg, u32 portid,
1151
+ struct netlink_callback *cb,
11701152 struct batadv_priv *bat_priv,
11711153 struct batadv_tt_common_entry *common)
11721154 {
....@@ -1187,11 +1169,13 @@
11871169
11881170 batadv_softif_vlan_put(vlan);
11891171
1190
- hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
1191
- NLM_F_MULTI,
1172
+ hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
1173
+ &batadv_netlink_family, NLM_F_MULTI,
11921174 BATADV_CMD_GET_TRANSTABLE_LOCAL);
11931175 if (!hdr)
11941176 return -ENOBUFS;
1177
+
1178
+ genl_dump_check_consistent(cb, hdr);
11951179
11961180 if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) ||
11971181 nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
....@@ -1215,34 +1199,39 @@
12151199 * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
12161200 * @msg: Netlink message to dump into
12171201 * @portid: Port making netlink request
1218
- * @seq: Sequence number of netlink message
1202
+ * @cb: Control block containing additional options
12191203 * @bat_priv: The bat priv with all the soft interface information
1220
- * @head: Pointer to the list containing the local tt entries
1204
+ * @hash: hash to dump
1205
+ * @bucket: bucket index to dump
12211206 * @idx_s: Number of entries to skip
12221207 *
12231208 * Return: Error code, or 0 on success
12241209 */
12251210 static int
1226
-batadv_tt_local_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1211
+batadv_tt_local_dump_bucket(struct sk_buff *msg, u32 portid,
1212
+ struct netlink_callback *cb,
12271213 struct batadv_priv *bat_priv,
1228
- struct hlist_head *head, int *idx_s)
1214
+ struct batadv_hashtable *hash, unsigned int bucket,
1215
+ int *idx_s)
12291216 {
12301217 struct batadv_tt_common_entry *common;
12311218 int idx = 0;
12321219
1233
- rcu_read_lock();
1234
- hlist_for_each_entry_rcu(common, head, hash_entry) {
1220
+ spin_lock_bh(&hash->list_locks[bucket]);
1221
+ cb->seq = atomic_read(&hash->generation) << 1 | 1;
1222
+
1223
+ hlist_for_each_entry(common, &hash->table[bucket], hash_entry) {
12351224 if (idx++ < *idx_s)
12361225 continue;
12371226
1238
- if (batadv_tt_local_dump_entry(msg, portid, seq, bat_priv,
1227
+ if (batadv_tt_local_dump_entry(msg, portid, cb, bat_priv,
12391228 common)) {
1240
- rcu_read_unlock();
1229
+ spin_unlock_bh(&hash->list_locks[bucket]);
12411230 *idx_s = idx - 1;
12421231 return -EMSGSIZE;
12431232 }
12441233 }
1245
- rcu_read_unlock();
1234
+ spin_unlock_bh(&hash->list_locks[bucket]);
12461235
12471236 *idx_s = 0;
12481237 return 0;
....@@ -1262,7 +1251,6 @@
12621251 struct batadv_priv *bat_priv;
12631252 struct batadv_hard_iface *primary_if = NULL;
12641253 struct batadv_hashtable *hash;
1265
- struct hlist_head *head;
12661254 int ret;
12671255 int ifindex;
12681256 int bucket = cb->args[0];
....@@ -1290,10 +1278,8 @@
12901278 hash = bat_priv->tt.local_hash;
12911279
12921280 while (bucket < hash->size) {
1293
- head = &hash->table[bucket];
1294
-
1295
- if (batadv_tt_local_dump_bucket(msg, portid, cb->nlh->nlmsg_seq,
1296
- bat_priv, head, &idx))
1281
+ if (batadv_tt_local_dump_bucket(msg, portid, cb, bat_priv,
1282
+ hash, bucket, &idx))
12971283 break;
12981284
12991285 bucket++;
....@@ -1684,7 +1670,7 @@
16841670 * the function argument.
16851671 * If a TT local entry exists for this non-mesh client remove it.
16861672 *
1687
- * The caller must hold orig_node refcount.
1673
+ * The caller must hold the orig_node refcount.
16881674 *
16891675 * Return: true if the new entry has been added, false otherwise
16901676 */
....@@ -1849,7 +1835,7 @@
18491835 * @bat_priv: the bat priv with all the soft interface information
18501836 * @tt_global_entry: global translation table entry to be analyzed
18511837 *
1852
- * This functon assumes the caller holds rcu_read_lock().
1838
+ * This function assumes the caller holds rcu_read_lock().
18531839 * Return: best originator list entry or NULL on errors.
18541840 */
18551841 static struct batadv_tt_orig_list_entry *
....@@ -1897,7 +1883,7 @@
18971883 * @tt_global_entry: global translation table entry to be printed
18981884 * @seq: debugfs table seq_file struct
18991885 *
1900
- * This functon assumes the caller holds rcu_read_lock().
1886
+ * This function assumes the caller holds rcu_read_lock().
19011887 */
19021888 static void
19031889 batadv_tt_global_print_entry(struct batadv_priv *bat_priv,
....@@ -2826,6 +2812,9 @@
28262812 */
28272813 static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
28282814 {
2815
+ if (!tt_req_node)
2816
+ return;
2817
+
28292818 kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
28302819 }
28312820