xref: /linux/net/batman-adv/translation-table.c (revision 68993ced0f618e36cf33388f1e50223e5e6e78cc)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3  *
4  * Marek Lindner, Simon Wunderlich, Antonio Quartulli
5  */
6 
7 #include "translation-table.h"
8 #include "main.h"
9 
10 #include <linux/atomic.h>
11 #include <linux/bitops.h>
12 #include <linux/build_bug.h>
13 #include <linux/byteorder/generic.h>
14 #include <linux/cache.h>
15 #include <linux/compiler.h>
16 #include <linux/container_of.h>
17 #include <linux/crc32.h>
18 #include <linux/err.h>
19 #include <linux/errno.h>
20 #include <linux/etherdevice.h>
21 #include <linux/gfp.h>
22 #include <linux/if_ether.h>
23 #include <linux/init.h>
24 #include <linux/jhash.h>
25 #include <linux/jiffies.h>
26 #include <linux/kref.h>
27 #include <linux/list.h>
28 #include <linux/lockdep.h>
29 #include <linux/net.h>
30 #include <linux/netdevice.h>
31 #include <linux/netlink.h>
32 #include <linux/overflow.h>
33 #include <linux/rculist.h>
34 #include <linux/rcupdate.h>
35 #include <linux/skbuff.h>
36 #include <linux/slab.h>
37 #include <linux/spinlock.h>
38 #include <linux/stddef.h>
39 #include <linux/string.h>
40 #include <linux/workqueue.h>
41 #include <net/genetlink.h>
42 #include <net/netlink.h>
43 #include <uapi/linux/batadv_packet.h>
44 #include <uapi/linux/batman_adv.h>
45 
46 #include "bridge_loop_avoidance.h"
47 #include "hard-interface.h"
48 #include "hash.h"
49 #include "log.h"
50 #include "mesh-interface.h"
51 #include "netlink.h"
52 #include "originator.h"
53 #include "tvlv.h"
54 
55 static struct kmem_cache *batadv_tl_cache __read_mostly;
56 static struct kmem_cache *batadv_tg_cache __read_mostly;
57 static struct kmem_cache *batadv_tt_orig_cache __read_mostly;
58 static struct kmem_cache *batadv_tt_change_cache __read_mostly;
59 static struct kmem_cache *batadv_tt_req_cache __read_mostly;
60 static struct kmem_cache *batadv_tt_roam_cache __read_mostly;
61 
62 /* hash class keys */
63 static struct lock_class_key batadv_tt_local_hash_lock_class_key;
64 static struct lock_class_key batadv_tt_global_hash_lock_class_key;
65 
66 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, u8 *client,
67 				 unsigned short vid,
68 				 struct batadv_orig_node *orig_node);
69 static void batadv_tt_purge(struct work_struct *work);
70 static void
71 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
72 static void batadv_tt_global_del(struct batadv_priv *bat_priv,
73 				 struct batadv_orig_node *orig_node,
74 				 const unsigned char *addr,
75 				 unsigned short vid, const char *message,
76 				 bool roaming);
77 
78 /**
79  * batadv_compare_tt() - check if two TT entries are the same
80  * @node: the list element pointer of the first TT entry
81  * @data2: pointer to the tt_common_entry of the second TT entry
82  *
83  * Compare the MAC address and the VLAN ID of the two TT entries and check if
84  * they are the same TT client.
85  * Return: true if the two TT clients are the same, false otherwise
86  */
batadv_compare_tt(const struct hlist_node * node,const void * data2)87 static bool batadv_compare_tt(const struct hlist_node *node, const void *data2)
88 {
89 	const void *data1 = container_of(node, struct batadv_tt_common_entry,
90 					 hash_entry);
91 	const struct batadv_tt_common_entry *tt1 = data1;
92 	const struct batadv_tt_common_entry *tt2 = data2;
93 
94 	return (tt1->vid == tt2->vid) && batadv_compare_eth(data1, data2);
95 }
96 
97 /**
98  * batadv_choose_tt() - return the index of the tt entry in the hash table
99  * @data: pointer to the tt_common_entry object to map
100  * @size: the size of the hash table
101  *
102  * Return: the hash index where the object represented by 'data' should be
103  * stored at.
104  */
batadv_choose_tt(const void * data,u32 size)105 static inline u32 batadv_choose_tt(const void *data, u32 size)
106 {
107 	const struct batadv_tt_common_entry *tt;
108 	u32 hash = 0;
109 
110 	tt = data;
111 	hash = jhash(&tt->addr, ETH_ALEN, hash);
112 	hash = jhash(&tt->vid, sizeof(tt->vid), hash);
113 
114 	return hash % size;
115 }
116 
117 /**
118  * batadv_tt_hash_find() - look for a client in the given hash table
119  * @hash: the hash table to search
120  * @addr: the mac address of the client to look for
121  * @vid: VLAN identifier
122  *
123  * Return: a pointer to the tt_common struct belonging to the searched client if
124  * found, NULL otherwise.
125  */
126 static struct batadv_tt_common_entry *
batadv_tt_hash_find(struct batadv_hashtable * hash,const u8 * addr,unsigned short vid)127 batadv_tt_hash_find(struct batadv_hashtable *hash, const u8 *addr,
128 		    unsigned short vid)
129 {
130 	struct hlist_head *head;
131 	struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
132 	u32 index;
133 
134 	if (!hash)
135 		return NULL;
136 
137 	ether_addr_copy(to_search.addr, addr);
138 	to_search.vid = vid;
139 
140 	index = batadv_choose_tt(&to_search, hash->size);
141 	head = &hash->table[index];
142 
143 	rcu_read_lock();
144 	hlist_for_each_entry_rcu(tt, head, hash_entry) {
145 		if (!batadv_compare_eth(tt, addr))
146 			continue;
147 
148 		if (tt->vid != vid)
149 			continue;
150 
151 		if (!kref_get_unless_zero(&tt->refcount))
152 			continue;
153 
154 		tt_tmp = tt;
155 		break;
156 	}
157 	rcu_read_unlock();
158 
159 	return tt_tmp;
160 }
161 
162 /**
163  * batadv_tt_local_hash_find() - search the local table for a given client
164  * @bat_priv: the bat priv with all the mesh interface information
165  * @addr: the mac address of the client to look for
166  * @vid: VLAN identifier
167  *
168  * Return: a pointer to the corresponding tt_local_entry struct if the client is
169  * found, NULL otherwise.
170  */
171 static struct batadv_tt_local_entry *
batadv_tt_local_hash_find(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid)172 batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
173 			  unsigned short vid)
174 {
175 	struct batadv_tt_common_entry *tt_common_entry;
176 	struct batadv_tt_local_entry *tt_local_entry = NULL;
177 
178 	tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
179 					      vid);
180 	if (tt_common_entry)
181 		tt_local_entry = container_of(tt_common_entry,
182 					      struct batadv_tt_local_entry,
183 					      common);
184 	return tt_local_entry;
185 }
186 
187 /**
188  * batadv_tt_global_hash_find() - search the global table for a given client
189  * @bat_priv: the bat priv with all the mesh interface information
190  * @addr: the mac address of the client to look for
191  * @vid: VLAN identifier
192  *
193  * Return: a pointer to the corresponding tt_global_entry struct if the client
194  * is found, NULL otherwise.
195  */
196 struct batadv_tt_global_entry *
batadv_tt_global_hash_find(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid)197 batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
198 			   unsigned short vid)
199 {
200 	struct batadv_tt_common_entry *tt_common_entry;
201 	struct batadv_tt_global_entry *tt_global_entry = NULL;
202 
203 	tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
204 					      vid);
205 	if (tt_common_entry)
206 		tt_global_entry = container_of(tt_common_entry,
207 					       struct batadv_tt_global_entry,
208 					       common);
209 	return tt_global_entry;
210 }
211 
212 /**
213  * batadv_tt_local_entry_release() - release tt_local_entry from lists and queue
214  *  for free after rcu grace period
215  * @ref: kref pointer of the batadv_tt_local_entry
216  */
batadv_tt_local_entry_release(struct kref * ref)217 static void batadv_tt_local_entry_release(struct kref *ref)
218 {
219 	struct batadv_tt_local_entry *tt_local_entry;
220 
221 	tt_local_entry = container_of(ref, struct batadv_tt_local_entry,
222 				      common.refcount);
223 
224 	batadv_meshif_vlan_put(tt_local_entry->vlan);
225 
226 	kfree_rcu(tt_local_entry, common.rcu);
227 }
228 
229 /**
230  * batadv_tt_local_entry_put() - decrement the tt_local_entry refcounter and
231  *  possibly release it
232  * @tt_local_entry: tt_local_entry to be free'd
233  */
234 static void
batadv_tt_local_entry_put(struct batadv_tt_local_entry * tt_local_entry)235 batadv_tt_local_entry_put(struct batadv_tt_local_entry *tt_local_entry)
236 {
237 	if (!tt_local_entry)
238 		return;
239 
240 	kref_put(&tt_local_entry->common.refcount,
241 		 batadv_tt_local_entry_release);
242 }
243 
244 /**
245  * batadv_tt_global_entry_release() - release tt_global_entry from lists and
246  *  queue for free after rcu grace period
247  * @ref: kref pointer of the batadv_tt_global_entry
248  */
batadv_tt_global_entry_release(struct kref * ref)249 void batadv_tt_global_entry_release(struct kref *ref)
250 {
251 	struct batadv_tt_global_entry *tt_global_entry;
252 
253 	tt_global_entry = container_of(ref, struct batadv_tt_global_entry,
254 				       common.refcount);
255 
256 	batadv_tt_global_del_orig_list(tt_global_entry);
257 
258 	kfree_rcu(tt_global_entry, common.rcu);
259 }
260 
261 /**
262  * batadv_tt_global_hash_count() - count the number of orig entries
263  * @bat_priv: the bat priv with all the mesh interface information
264  * @addr: the mac address of the client to count entries for
265  * @vid: VLAN identifier
266  *
267  * Return: the number of originators advertising the given address/data
268  * (excluding our self).
269  */
batadv_tt_global_hash_count(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid)270 int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
271 				const u8 *addr, unsigned short vid)
272 {
273 	struct batadv_tt_global_entry *tt_global_entry;
274 	int count;
275 
276 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
277 	if (!tt_global_entry)
278 		return 0;
279 
280 	count = atomic_read(&tt_global_entry->orig_list_count);
281 	batadv_tt_global_entry_put(tt_global_entry);
282 
283 	return count;
284 }
285 
286 /**
287  * batadv_tt_local_size_mod() - change the size by v of the local table
288  *  identified by vid
289  * @bat_priv: the bat priv with all the mesh interface information
290  * @vid: the VLAN identifier of the sub-table to change
291  * @v: the amount to sum to the local table size
292  */
batadv_tt_local_size_mod(struct batadv_priv * bat_priv,unsigned short vid,int v)293 static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv,
294 				     unsigned short vid, int v)
295 {
296 	struct batadv_meshif_vlan *vlan;
297 
298 	vlan = batadv_meshif_vlan_get(bat_priv, vid);
299 	if (!vlan)
300 		return;
301 
302 	atomic_add(v, &vlan->tt.num_entries);
303 
304 	batadv_meshif_vlan_put(vlan);
305 }
306 
307 /**
308  * batadv_tt_local_size_inc() - increase by one the local table size for the
309  *  given vid
310  * @bat_priv: the bat priv with all the mesh interface information
311  * @vid: the VLAN identifier
312  */
batadv_tt_local_size_inc(struct batadv_priv * bat_priv,unsigned short vid)313 static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv,
314 				     unsigned short vid)
315 {
316 	batadv_tt_local_size_mod(bat_priv, vid, 1);
317 }
318 
319 /**
320  * batadv_tt_local_size_dec() - decrease by one the local table size for the
321  *  given vid
322  * @bat_priv: the bat priv with all the mesh interface information
323  * @vid: the VLAN identifier
324  */
batadv_tt_local_size_dec(struct batadv_priv * bat_priv,unsigned short vid)325 static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv,
326 				     unsigned short vid)
327 {
328 	batadv_tt_local_size_mod(bat_priv, vid, -1);
329 }
330 
331 /**
332  * batadv_tt_global_size_mod() - change the size by v of the global table
333  *  for orig_node identified by vid
334  * @orig_node: the originator for which the table has to be modified
335  * @vid: the VLAN identifier
336  * @v: the amount to sum to the global table size
337  */
batadv_tt_global_size_mod(struct batadv_orig_node * orig_node,unsigned short vid,int v)338 static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
339 				      unsigned short vid, int v)
340 {
341 	struct batadv_orig_node_vlan *vlan;
342 
343 	vlan = batadv_orig_node_vlan_new(orig_node, vid);
344 	if (!vlan)
345 		return;
346 
347 	if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
348 		spin_lock_bh(&orig_node->vlan_list_lock);
349 		if (!hlist_unhashed(&vlan->list)) {
350 			hlist_del_init_rcu(&vlan->list);
351 			batadv_orig_node_vlan_put(vlan);
352 		}
353 		spin_unlock_bh(&orig_node->vlan_list_lock);
354 	}
355 
356 	batadv_orig_node_vlan_put(vlan);
357 }
358 
359 /**
360  * batadv_tt_global_size_inc() - increase by one the global table size for the
361  *  given vid
362  * @orig_node: the originator which global table size has to be decreased
363  * @vid: the vlan identifier
364  */
batadv_tt_global_size_inc(struct batadv_orig_node * orig_node,unsigned short vid)365 static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node,
366 				      unsigned short vid)
367 {
368 	batadv_tt_global_size_mod(orig_node, vid, 1);
369 }
370 
371 /**
372  * batadv_tt_global_size_dec() - decrease by one the global table size for the
373  *  given vid
374  * @orig_node: the originator which global table size has to be decreased
375  * @vid: the vlan identifier
376  */
batadv_tt_global_size_dec(struct batadv_orig_node * orig_node,unsigned short vid)377 static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
378 				      unsigned short vid)
379 {
380 	batadv_tt_global_size_mod(orig_node, vid, -1);
381 }
382 
383 /**
384  * batadv_tt_orig_list_entry_release() - release tt orig entry from lists and
385  *  queue for free after rcu grace period
386  * @ref: kref pointer of the tt orig entry
387  */
batadv_tt_orig_list_entry_release(struct kref * ref)388 static void batadv_tt_orig_list_entry_release(struct kref *ref)
389 {
390 	struct batadv_tt_orig_list_entry *orig_entry;
391 
392 	orig_entry = container_of(ref, struct batadv_tt_orig_list_entry,
393 				  refcount);
394 
395 	batadv_orig_node_put(orig_entry->orig_node);
396 	kfree_rcu(orig_entry, rcu);
397 }
398 
399 /**
400  * batadv_tt_orig_list_entry_put() - decrement the tt orig entry refcounter and
401  *  possibly release it
402  * @orig_entry: tt orig entry to be free'd
403  */
404 static void
batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry * orig_entry)405 batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry *orig_entry)
406 {
407 	if (!orig_entry)
408 		return;
409 
410 	kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release);
411 }
412 
413 /**
414  * batadv_tt_local_event() - store a local TT event (ADD/DEL)
415  * @bat_priv: the bat priv with all the mesh interface information
416  * @tt_local_entry: the TT entry involved in the event
417  * @event_flags: flags to store in the event structure
418  */
batadv_tt_local_event(struct batadv_priv * bat_priv,struct batadv_tt_local_entry * tt_local_entry,u8 event_flags)419 static void batadv_tt_local_event(struct batadv_priv *bat_priv,
420 				  struct batadv_tt_local_entry *tt_local_entry,
421 				  u8 event_flags)
422 {
423 	struct batadv_tt_change_node *tt_change_node, *entry, *safe;
424 	struct batadv_tt_common_entry *common = &tt_local_entry->common;
425 	u8 flags = common->flags | event_flags;
426 	bool del_op_requested, del_op_entry;
427 	size_t changes;
428 
429 	tt_change_node = kmem_cache_alloc(batadv_tt_change_cache, GFP_ATOMIC);
430 	if (!tt_change_node)
431 		return;
432 
433 	tt_change_node->change.flags = flags;
434 	memset(tt_change_node->change.reserved, 0,
435 	       sizeof(tt_change_node->change.reserved));
436 	ether_addr_copy(tt_change_node->change.addr, common->addr);
437 	tt_change_node->change.vid = htons(common->vid);
438 
439 	del_op_requested = flags & BATADV_TT_CLIENT_DEL;
440 
441 	/* check for ADD+DEL, DEL+ADD, ADD+ADD or DEL+DEL events */
442 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
443 	changes = READ_ONCE(bat_priv->tt.local_changes);
444 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
445 				 list) {
446 		if (!batadv_compare_eth(entry->change.addr, common->addr))
447 			continue;
448 
449 		del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
450 		if (del_op_requested != del_op_entry) {
451 			/* DEL+ADD in the same orig interval have no effect and
452 			 * can be removed to avoid silly behaviour on the
453 			 * receiver side. The  other way around (ADD+DEL) can
454 			 * happen in case of roaming of  a client still in the
455 			 * NEW state. Roaming of NEW clients is now possible due
456 			 * to automatically recognition of "temporary" clients
457 			 */
458 			list_del(&entry->list);
459 			kmem_cache_free(batadv_tt_change_cache, entry);
460 			changes--;
461 		} else {
462 			/* this is a second add or del in the same originator
463 			 * interval. It could mean that flags have been changed
464 			 * (e.g. double add): update them
465 			 */
466 			entry->change.flags = flags;
467 		}
468 
469 		kmem_cache_free(batadv_tt_change_cache, tt_change_node);
470 		goto update_changes;
471 	}
472 
473 	/* track the change in the OGMinterval list */
474 	list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
475 	changes++;
476 
477 update_changes:
478 	WRITE_ONCE(bat_priv->tt.local_changes, changes);
479 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
480 }
481 
482 /**
483  * batadv_tt_len() - compute length in bytes of given number of tt changes
484  * @changes_num: number of tt changes
485  *
486  * Return: computed length in bytes.
487  */
batadv_tt_len(int changes_num)488 static int batadv_tt_len(int changes_num)
489 {
490 	return changes_num * sizeof(struct batadv_tvlv_tt_change);
491 }
492 
493 /**
494  * batadv_tt_entries() - compute the number of entries fitting in tt_len bytes
495  * @tt_len: available space
496  *
497  * Return: the number of entries.
498  */
batadv_tt_entries(u16 tt_len)499 static u16 batadv_tt_entries(u16 tt_len)
500 {
501 	return tt_len / batadv_tt_len(1);
502 }
503 
504 /**
505  * batadv_tt_local_table_transmit_size() - calculates the local translation
506  *  table size when transmitted over the air
507  * @bat_priv: the bat priv with all the mesh interface information
508  *
509  * Return: local translation table size in bytes.
510  */
batadv_tt_local_table_transmit_size(struct batadv_priv * bat_priv)511 static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
512 {
513 	u16 num_vlan = 0;
514 	u16 tt_local_entries = 0;
515 	struct batadv_meshif_vlan *vlan;
516 	int hdr_size;
517 
518 	rcu_read_lock();
519 	hlist_for_each_entry_rcu(vlan, &bat_priv->meshif_vlan_list, list) {
520 		num_vlan++;
521 		tt_local_entries += atomic_read(&vlan->tt.num_entries);
522 	}
523 	rcu_read_unlock();
524 
525 	/* header size of tvlv encapsulated tt response payload */
526 	hdr_size = sizeof(struct batadv_unicast_tvlv_packet);
527 	hdr_size += sizeof(struct batadv_tvlv_hdr);
528 	hdr_size += sizeof(struct batadv_tvlv_tt_data);
529 	hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data);
530 
531 	return hdr_size + batadv_tt_len(tt_local_entries);
532 }
533 
batadv_tt_local_init(struct batadv_priv * bat_priv)534 static int batadv_tt_local_init(struct batadv_priv *bat_priv)
535 {
536 	if (bat_priv->tt.local_hash)
537 		return 0;
538 
539 	bat_priv->tt.local_hash = batadv_hash_new(1024);
540 
541 	if (!bat_priv->tt.local_hash)
542 		return -ENOMEM;
543 
544 	batadv_hash_set_lock_class(bat_priv->tt.local_hash,
545 				   &batadv_tt_local_hash_lock_class_key);
546 
547 	return 0;
548 }
549 
batadv_tt_global_free(struct batadv_priv * bat_priv,struct batadv_tt_global_entry * tt_global,const char * message)550 static void batadv_tt_global_free(struct batadv_priv *bat_priv,
551 				  struct batadv_tt_global_entry *tt_global,
552 				  const char *message)
553 {
554 	struct batadv_tt_global_entry *tt_removed_entry;
555 	struct hlist_node *tt_removed_node;
556 
557 	batadv_dbg(BATADV_DBG_TT, bat_priv,
558 		   "Deleting global tt entry %pM (vid: %d): %s\n",
559 		   tt_global->common.addr,
560 		   batadv_print_vid(tt_global->common.vid), message);
561 
562 	tt_removed_node = batadv_hash_remove(bat_priv->tt.global_hash,
563 					     batadv_compare_tt,
564 					     batadv_choose_tt,
565 					     &tt_global->common);
566 	if (!tt_removed_node)
567 		return;
568 
569 	/* drop reference of remove hash entry */
570 	tt_removed_entry = hlist_entry(tt_removed_node,
571 				       struct batadv_tt_global_entry,
572 				       common.hash_entry);
573 	batadv_tt_global_entry_put(tt_removed_entry);
574 }
575 
576 /**
577  * batadv_tt_local_add() - add a new client to the local table or update an
578  *  existing client
579  * @mesh_iface: netdev struct of the mesh interface
580  * @addr: the mac address of the client to add
581  * @vid: VLAN identifier
582  * @ifindex: index of the interface where the client is connected to (useful to
583  *  identify wireless clients)
584  * @mark: the value contained in the skb->mark field of the received packet (if
585  *  any)
586  *
587  * Return: true if the client was successfully added, false otherwise.
588  */
batadv_tt_local_add(struct net_device * mesh_iface,const u8 * addr,unsigned short vid,int ifindex,u32 mark)589 bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
590 			 unsigned short vid, int ifindex, u32 mark)
591 {
592 	struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
593 	struct batadv_tt_local_entry *tt_local;
594 	struct batadv_tt_global_entry *tt_global = NULL;
595 	struct net *net = dev_net(mesh_iface);
596 	struct batadv_meshif_vlan *vlan;
597 	struct net_device *in_dev = NULL;
598 	struct batadv_hard_iface *in_hardif = NULL;
599 	struct hlist_head *head;
600 	struct batadv_tt_orig_list_entry *orig_entry;
601 	int hash_added, table_size, packet_size_max;
602 	bool ret = false;
603 	bool roamed_back = false;
604 	u8 remote_flags;
605 	u32 match_mark;
606 
607 	if (ifindex != BATADV_NULL_IFINDEX)
608 		in_dev = dev_get_by_index(net, ifindex);
609 
610 	if (in_dev)
611 		in_hardif = batadv_hardif_get_by_netdev(in_dev);
612 
613 	tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
614 
615 	if (!is_multicast_ether_addr(addr))
616 		tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
617 
618 	if (tt_local) {
619 		tt_local->last_seen = jiffies;
620 		if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
621 			batadv_dbg(BATADV_DBG_TT, bat_priv,
622 				   "Re-adding pending client %pM (vid: %d)\n",
623 				   addr, batadv_print_vid(vid));
624 			/* whatever the reason why the PENDING flag was set,
625 			 * this is a client which was enqueued to be removed in
626 			 * this orig_interval. Since it popped up again, the
627 			 * flag can be reset like it was never enqueued
628 			 */
629 			tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
630 			goto add_event;
631 		}
632 
633 		if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
634 			batadv_dbg(BATADV_DBG_TT, bat_priv,
635 				   "Roaming client %pM (vid: %d) came back to its original location\n",
636 				   addr, batadv_print_vid(vid));
637 			/* the ROAM flag is set because this client roamed away
638 			 * and the node got a roaming_advertisement message. Now
639 			 * that the client popped up again at its original
640 			 * location such flag can be unset
641 			 */
642 			tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
643 			roamed_back = true;
644 		}
645 		goto check_roaming;
646 	}
647 
648 	/* Ignore the client if we cannot send it in a full table response. */
649 	table_size = batadv_tt_local_table_transmit_size(bat_priv);
650 	table_size += batadv_tt_len(1);
651 	packet_size_max = atomic_read(&bat_priv->packet_size_max);
652 	if (table_size > packet_size_max) {
653 		net_ratelimited_function(batadv_info, mesh_iface,
654 					 "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
655 					 table_size, packet_size_max, addr);
656 		goto out;
657 	}
658 
659 	tt_local = kmem_cache_alloc(batadv_tl_cache, GFP_ATOMIC);
660 	if (!tt_local)
661 		goto out;
662 
663 	/* increase the refcounter of the related vlan */
664 	vlan = batadv_meshif_vlan_get(bat_priv, vid);
665 	if (!vlan) {
666 		net_ratelimited_function(batadv_info, mesh_iface,
667 					 "adding TT local entry %pM to non-existent VLAN %d\n",
668 					 addr, batadv_print_vid(vid));
669 		kmem_cache_free(batadv_tl_cache, tt_local);
670 		tt_local = NULL;
671 		goto out;
672 	}
673 
674 	batadv_dbg(BATADV_DBG_TT, bat_priv,
675 		   "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
676 		   addr, batadv_print_vid(vid),
677 		   (u8)atomic_read(&bat_priv->tt.vn));
678 
679 	ether_addr_copy(tt_local->common.addr, addr);
680 	/* The local entry has to be marked as NEW to avoid to send it in
681 	 * a full table response going out before the next ttvn increment
682 	 * (consistency check)
683 	 */
684 	tt_local->common.flags = BATADV_TT_CLIENT_NEW;
685 	tt_local->common.vid = vid;
686 	if (batadv_is_wifi_hardif(in_hardif))
687 		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
688 	kref_init(&tt_local->common.refcount);
689 	tt_local->last_seen = jiffies;
690 	tt_local->common.added_at = tt_local->last_seen;
691 	tt_local->vlan = vlan;
692 
693 	/* the batman interface mac and multicast addresses should never be
694 	 * purged
695 	 */
696 	if (batadv_compare_eth(addr, mesh_iface->dev_addr) ||
697 	    is_multicast_ether_addr(addr))
698 		tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
699 
700 	kref_get(&tt_local->common.refcount);
701 	hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
702 				     batadv_choose_tt, &tt_local->common,
703 				     &tt_local->common.hash_entry);
704 
705 	if (unlikely(hash_added != 0)) {
706 		/* remove the reference for the hash */
707 		batadv_tt_local_entry_put(tt_local);
708 		goto out;
709 	}
710 
711 add_event:
712 	batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
713 
714 check_roaming:
715 	/* Check whether it is a roaming, but don't do anything if the roaming
716 	 * process has already been handled
717 	 */
718 	if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
719 		/* These node are probably going to update their tt table */
720 		head = &tt_global->orig_list;
721 		rcu_read_lock();
722 		hlist_for_each_entry_rcu(orig_entry, head, list) {
723 			batadv_send_roam_adv(bat_priv, tt_global->common.addr,
724 					     tt_global->common.vid,
725 					     orig_entry->orig_node);
726 		}
727 		rcu_read_unlock();
728 		if (roamed_back) {
729 			batadv_tt_global_free(bat_priv, tt_global,
730 					      "Roaming canceled");
731 		} else {
732 			/* The global entry has to be marked as ROAMING and
733 			 * has to be kept for consistency purpose
734 			 */
735 			tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
736 			tt_global->roam_at = jiffies;
737 		}
738 	}
739 
740 	/* store the current remote flags before altering them. This helps
741 	 * understanding is flags are changing or not
742 	 */
743 	remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
744 
745 	if (batadv_is_wifi_hardif(in_hardif))
746 		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
747 	else
748 		tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
749 
750 	/* check the mark in the skb: if it's equal to the configured
751 	 * isolation_mark, it means the packet is coming from an isolated
752 	 * non-mesh client
753 	 */
754 	match_mark = (mark & bat_priv->isolation_mark_mask);
755 	if (bat_priv->isolation_mark_mask &&
756 	    match_mark == bat_priv->isolation_mark)
757 		tt_local->common.flags |= BATADV_TT_CLIENT_ISOLA;
758 	else
759 		tt_local->common.flags &= ~BATADV_TT_CLIENT_ISOLA;
760 
761 	/* if any "dynamic" flag has been modified, resend an ADD event for this
762 	 * entry so that all the nodes can get the new flags
763 	 */
764 	if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK))
765 		batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
766 
767 	ret = true;
768 out:
769 	batadv_hardif_put(in_hardif);
770 	dev_put(in_dev);
771 	batadv_tt_local_entry_put(tt_local);
772 	batadv_tt_global_entry_put(tt_global);
773 	return ret;
774 }
775 
776 /**
777  * batadv_tt_prepare_tvlv_global_data() - prepare the TVLV TT header to send
778  *  within a TT Response directed to another node
779  * @orig_node: originator for which the TT data has to be prepared
780  * @tt_data: uninitialised pointer to the address of the TVLV buffer
781  * @tt_change: uninitialised pointer to the address of the area where the TT
782  *  changed can be stored
783  * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
784  *  function reserves the amount of space needed to send the entire global TT
785  *  table. In case of success the value is updated with the real amount of
786  *  reserved bytes
787  * Allocate the needed amount of memory for the entire TT TVLV and write its
788  * header made up of one tvlv_tt_data object and a series of tvlv_tt_vlan_data
789  * objects, one per active VLAN served by the originator node.
790  *
791  * Return: the size of the allocated buffer or 0 in case of failure.
792  */
793 static u16
batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node * orig_node,struct batadv_tvlv_tt_data ** tt_data,struct batadv_tvlv_tt_change ** tt_change,s32 * tt_len)794 batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
795 				   struct batadv_tvlv_tt_data **tt_data,
796 				   struct batadv_tvlv_tt_change **tt_change,
797 				   s32 *tt_len)
798 {
799 	u16 num_vlan = 0;
800 	u16 tvlv_len = 0;
801 	unsigned int change_offset;
802 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
803 	struct batadv_orig_node_vlan *vlan;
804 	u16 total_entries = 0;
805 	u8 *tt_change_ptr;
806 	int vlan_entries;
807 	u16 sum_entries;
808 
809 	spin_lock_bh(&orig_node->vlan_list_lock);
810 	hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
811 		vlan_entries = atomic_read(&vlan->tt.num_entries);
812 
813 		if (check_add_overflow(vlan_entries, total_entries, &sum_entries)) {
814 			*tt_len = 0;
815 			goto out;
816 		}
817 
818 		total_entries = sum_entries;
819 		num_vlan++;
820 	}
821 
822 	change_offset = struct_size(*tt_data, vlan_data, num_vlan);
823 
824 	/* if tt_len is negative, allocate the space needed by the full table */
825 	if (*tt_len < 0)
826 		*tt_len = batadv_tt_len(total_entries);
827 
828 	if (change_offset > U16_MAX || *tt_len > U16_MAX - change_offset) {
829 		*tt_len = 0;
830 		goto out;
831 	}
832 
833 	tvlv_len = *tt_len;
834 	tvlv_len += change_offset;
835 
836 	*tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
837 	if (!*tt_data) {
838 		*tt_len = 0;
839 		goto out;
840 	}
841 
842 	(*tt_data)->flags = BATADV_NO_FLAGS;
843 	(*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
844 	(*tt_data)->num_vlan = htons(num_vlan);
845 
846 	tt_vlan = (*tt_data)->vlan_data;
847 	num_vlan = 0;
848 	hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
849 		vlan_entries = atomic_read(&vlan->tt.num_entries);
850 		if (vlan_entries < 1)
851 			continue;
852 
853 		tt_vlan->vid = htons(vlan->vid);
854 		tt_vlan->crc = htonl(vlan->tt.crc);
855 		tt_vlan->reserved = 0;
856 
857 		tt_vlan++;
858 		num_vlan++;
859 	}
860 
861 	/* recalculate in case number of VLANs reduced */
862 	change_offset = struct_size(*tt_data, vlan_data, num_vlan);
863 	tvlv_len = *tt_len + change_offset;
864 
865 	(*tt_data)->num_vlan = htons(num_vlan);
866 
867 	tt_change_ptr = (u8 *)*tt_data + change_offset;
868 	*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
869 
870 out:
871 	spin_unlock_bh(&orig_node->vlan_list_lock);
872 	return tvlv_len;
873 }
874 
875 /**
876  * batadv_tt_prepare_tvlv_local_data() - allocate and prepare the TT TVLV for
877  *  this node
878  * @bat_priv: the bat priv with all the mesh interface information
879  * @tt_data: uninitialised pointer to the address of the TVLV buffer
880  * @tt_change: uninitialised pointer to the address of the area where the TT
881  *  changes can be stored
882  * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
883  *  function reserves the amount of space needed to send the entire local TT
884  *  table. In case of success the value is updated with the real amount of
885  *  reserved bytes
886  *
887  * Allocate the needed amount of memory for the entire TT TVLV and write its
888  * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
889  * objects, one per active VLAN.
890  *
891  * Return: the size of the allocated buffer or 0 in case of failure.
892  */
893 static u16
batadv_tt_prepare_tvlv_local_data(struct batadv_priv * bat_priv,struct batadv_tvlv_tt_data ** tt_data,struct batadv_tvlv_tt_change ** tt_change,s32 * tt_len)894 batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
895 				  struct batadv_tvlv_tt_data **tt_data,
896 				  struct batadv_tvlv_tt_change **tt_change,
897 				  s32 *tt_len)
898 {
899 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
900 	struct batadv_meshif_vlan *vlan;
901 	size_t change_offset;
902 	u16 num_vlan = 0;
903 	u16 total_entries = 0;
904 	u16 tvlv_len;
905 	u8 *tt_change_ptr;
906 	int vlan_entries;
907 	u16 sum_entries;
908 
909 	spin_lock_bh(&bat_priv->meshif_vlan_list_lock);
910 	hlist_for_each_entry(vlan, &bat_priv->meshif_vlan_list, list) {
911 		vlan_entries = atomic_read(&vlan->tt.num_entries);
912 
913 		if (check_add_overflow(vlan_entries, total_entries, &sum_entries)) {
914 			tvlv_len = 0;
915 			goto out;
916 		}
917 
918 		total_entries = sum_entries;
919 		num_vlan++;
920 	}
921 
922 	change_offset = struct_size(*tt_data, vlan_data, num_vlan);
923 
924 	/* if tt_len is negative, allocate the space needed by the full table */
925 	if (*tt_len < 0)
926 		*tt_len = batadv_tt_len(total_entries);
927 
928 	if (check_add_overflow(*tt_len, change_offset, &tvlv_len)) {
929 		tvlv_len = 0;
930 		goto out;
931 	}
932 
933 	*tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
934 	if (!*tt_data) {
935 		tvlv_len = 0;
936 		goto out;
937 	}
938 
939 	(*tt_data)->flags = BATADV_NO_FLAGS;
940 	(*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn);
941 	(*tt_data)->num_vlan = htons(num_vlan);
942 
943 	tt_vlan = (*tt_data)->vlan_data;
944 	num_vlan = 0;
945 	hlist_for_each_entry(vlan, &bat_priv->meshif_vlan_list, list) {
946 		vlan_entries = atomic_read(&vlan->tt.num_entries);
947 		if (vlan_entries < 1)
948 			continue;
949 
950 		tt_vlan->vid = htons(vlan->vid);
951 		tt_vlan->crc = htonl(vlan->tt.crc);
952 		tt_vlan->reserved = 0;
953 
954 		tt_vlan++;
955 		num_vlan++;
956 	}
957 
958 	/* recalculate in case number of VLANs reduced */
959 	change_offset = struct_size(*tt_data, vlan_data, num_vlan);
960 	tvlv_len = *tt_len + change_offset;
961 
962 	(*tt_data)->num_vlan = htons(num_vlan);
963 
964 	tt_change_ptr = (u8 *)*tt_data + change_offset;
965 	*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
966 
967 out:
968 	spin_unlock_bh(&bat_priv->meshif_vlan_list_lock);
969 	return tvlv_len;
970 }
971 
972 /**
973  * batadv_tt_tvlv_container_update() - update the translation table tvlv
974  *  container after local tt changes have been committed
975  * @bat_priv: the bat priv with all the mesh interface information
976  */
batadv_tt_tvlv_container_update(struct batadv_priv * bat_priv)977 static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
978 {
979 	struct batadv_tt_change_node *entry, *safe;
980 	struct batadv_tvlv_tt_data *tt_data;
981 	struct batadv_tvlv_tt_change *tt_change;
982 	int tt_diff_len, tt_change_len = 0;
983 	int tt_diff_entries_num = 0;
984 	int tt_diff_entries_count = 0;
985 	bool drop_changes = false;
986 	size_t tt_extra_len = 0;
987 	u16 tvlv_len;
988 
989 	tt_diff_entries_num = READ_ONCE(bat_priv->tt.local_changes);
990 	tt_diff_len = batadv_tt_len(tt_diff_entries_num);
991 
992 	/* if we have too many changes for one packet don't send any
993 	 * and wait for the tt table request so we can reply with the full
994 	 * (fragmented) table.
995 	 *
996 	 * The local change history should still be cleaned up so the next
997 	 * TT round can start again with a clean state.
998 	 */
999 	if (tt_diff_len > bat_priv->mesh_iface->mtu) {
1000 		tt_diff_len = 0;
1001 		tt_diff_entries_num = 0;
1002 		drop_changes = true;
1003 	}
1004 
1005 	tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
1006 						     &tt_change, &tt_diff_len);
1007 	if (!tvlv_len)
1008 		return;
1009 
1010 	tt_data->flags = BATADV_TT_OGM_DIFF;
1011 
1012 	if (!drop_changes && tt_diff_len == 0)
1013 		goto container_register;
1014 
1015 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
1016 	WRITE_ONCE(bat_priv->tt.local_changes, 0);
1017 
1018 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
1019 				 list) {
1020 		if (tt_diff_entries_count < tt_diff_entries_num) {
1021 			memcpy(tt_change + tt_diff_entries_count,
1022 			       &entry->change,
1023 			       sizeof(struct batadv_tvlv_tt_change));
1024 			tt_diff_entries_count++;
1025 		}
1026 		list_del(&entry->list);
1027 		kmem_cache_free(batadv_tt_change_cache, entry);
1028 	}
1029 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
1030 
1031 	tt_extra_len = batadv_tt_len(tt_diff_entries_num -
1032 				     tt_diff_entries_count);
1033 
1034 	/* Keep the buffer for possible tt_request */
1035 	spin_lock_bh(&bat_priv->tt.last_changeset_lock);
1036 	kfree(bat_priv->tt.last_changeset);
1037 	bat_priv->tt.last_changeset_len = 0;
1038 	bat_priv->tt.last_changeset = NULL;
1039 	tt_change_len = batadv_tt_len(tt_diff_entries_count);
1040 	/* check whether this new OGM has no changes due to size problems */
1041 	if (tt_diff_entries_count > 0) {
1042 		tt_diff_len -= tt_extra_len;
1043 		/* if kmalloc() fails we will reply with the full table
1044 		 * instead of providing the diff
1045 		 */
1046 		bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
1047 		if (bat_priv->tt.last_changeset) {
1048 			memcpy(bat_priv->tt.last_changeset,
1049 			       tt_change, tt_change_len);
1050 			bat_priv->tt.last_changeset_len = tt_diff_len;
1051 		}
1052 	}
1053 	spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1054 
1055 	/* Remove extra packet space for OGM */
1056 	tvlv_len -= tt_extra_len;
1057 container_register:
1058 	batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
1059 				       tvlv_len);
1060 	kfree(tt_data);
1061 }
1062 
1063 /**
1064  * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
1065  * @msg :Netlink message to dump into
1066  * @portid: Port making netlink request
1067  * @cb: Control block containing additional options
1068  * @bat_priv: The bat priv with all the mesh interface information
1069  * @common: tt local & tt global common data
1070  *
1071  * Return: Error code, or 0 on success
1072  */
1073 static int
batadv_tt_local_dump_entry(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_tt_common_entry * common)1074 batadv_tt_local_dump_entry(struct sk_buff *msg, u32 portid,
1075 			   struct netlink_callback *cb,
1076 			   struct batadv_priv *bat_priv,
1077 			   struct batadv_tt_common_entry *common)
1078 {
1079 	void *hdr;
1080 	struct batadv_meshif_vlan *vlan;
1081 	struct batadv_tt_local_entry *local;
1082 	unsigned int last_seen_msecs;
1083 	u32 crc;
1084 
1085 	local = container_of(common, struct batadv_tt_local_entry, common);
1086 	last_seen_msecs = jiffies_to_msecs(jiffies - local->last_seen);
1087 
1088 	vlan = batadv_meshif_vlan_get(bat_priv, common->vid);
1089 	if (!vlan)
1090 		return 0;
1091 
1092 	crc = vlan->tt.crc;
1093 
1094 	batadv_meshif_vlan_put(vlan);
1095 
1096 	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
1097 			  &batadv_netlink_family,  NLM_F_MULTI,
1098 			  BATADV_CMD_GET_TRANSTABLE_LOCAL);
1099 	if (!hdr)
1100 		return -ENOBUFS;
1101 
1102 	genl_dump_check_consistent(cb, hdr);
1103 
1104 	if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) ||
1105 	    nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
1106 	    nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
1107 	    nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags))
1108 		goto nla_put_failure;
1109 
1110 	if (!(common->flags & BATADV_TT_CLIENT_NOPURGE) &&
1111 	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, last_seen_msecs))
1112 		goto nla_put_failure;
1113 
1114 	genlmsg_end(msg, hdr);
1115 	return 0;
1116 
1117  nla_put_failure:
1118 	genlmsg_cancel(msg, hdr);
1119 	return -EMSGSIZE;
1120 }
1121 
1122 /**
1123  * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
1124  * @msg: Netlink message to dump into
1125  * @portid: Port making netlink request
1126  * @cb: Control block containing additional options
1127  * @bat_priv: The bat priv with all the mesh interface information
1128  * @hash: hash to dump
1129  * @bucket: bucket index to dump
1130  * @idx_s: Number of entries to skip
1131  *
1132  * Return: Error code, or 0 on success
1133  */
1134 static int
batadv_tt_local_dump_bucket(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_hashtable * hash,unsigned int bucket,int * idx_s)1135 batadv_tt_local_dump_bucket(struct sk_buff *msg, u32 portid,
1136 			    struct netlink_callback *cb,
1137 			    struct batadv_priv *bat_priv,
1138 			    struct batadv_hashtable *hash, unsigned int bucket,
1139 			    int *idx_s)
1140 {
1141 	struct batadv_tt_common_entry *common;
1142 	int idx = 0;
1143 
1144 	spin_lock_bh(&hash->list_locks[bucket]);
1145 	cb->seq = atomic_read(&hash->generation) << 1 | 1;
1146 
1147 	hlist_for_each_entry(common, &hash->table[bucket], hash_entry) {
1148 		if (idx++ < *idx_s)
1149 			continue;
1150 
1151 		if (batadv_tt_local_dump_entry(msg, portid, cb, bat_priv,
1152 					       common)) {
1153 			spin_unlock_bh(&hash->list_locks[bucket]);
1154 			*idx_s = idx - 1;
1155 			return -EMSGSIZE;
1156 		}
1157 	}
1158 	spin_unlock_bh(&hash->list_locks[bucket]);
1159 
1160 	*idx_s = 0;
1161 	return 0;
1162 }
1163 
1164 /**
1165  * batadv_tt_local_dump() - Dump TT local entries into a message
1166  * @msg: Netlink message to dump into
1167  * @cb: Parameters from query
1168  *
1169  * Return: Error code, or 0 on success
1170  */
batadv_tt_local_dump(struct sk_buff * msg,struct netlink_callback * cb)1171 int batadv_tt_local_dump(struct sk_buff *msg, struct netlink_callback *cb)
1172 {
1173 	struct net_device *mesh_iface;
1174 	struct batadv_priv *bat_priv;
1175 	struct batadv_hard_iface *primary_if = NULL;
1176 	struct batadv_hashtable *hash;
1177 	int ret;
1178 	int bucket = cb->args[0];
1179 	int idx = cb->args[1];
1180 	int portid = NETLINK_CB(cb->skb).portid;
1181 
1182 	mesh_iface = batadv_netlink_get_meshif(cb);
1183 	if (IS_ERR(mesh_iface))
1184 		return PTR_ERR(mesh_iface);
1185 
1186 	bat_priv = netdev_priv(mesh_iface);
1187 
1188 	primary_if = batadv_primary_if_get_selected(bat_priv);
1189 	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
1190 		ret = -ENOENT;
1191 		goto out;
1192 	}
1193 
1194 	hash = bat_priv->tt.local_hash;
1195 
1196 	while (bucket < hash->size) {
1197 		if (batadv_tt_local_dump_bucket(msg, portid, cb, bat_priv,
1198 						hash, bucket, &idx))
1199 			break;
1200 
1201 		bucket++;
1202 	}
1203 
1204 	ret = msg->len;
1205 
1206  out:
1207 	batadv_hardif_put(primary_if);
1208 	dev_put(mesh_iface);
1209 
1210 	cb->args[0] = bucket;
1211 	cb->args[1] = idx;
1212 
1213 	return ret;
1214 }
1215 
1216 static void
batadv_tt_local_set_pending(struct batadv_priv * bat_priv,struct batadv_tt_local_entry * tt_local_entry,u16 flags,const char * message)1217 batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
1218 			    struct batadv_tt_local_entry *tt_local_entry,
1219 			    u16 flags, const char *message)
1220 {
1221 	batadv_tt_local_event(bat_priv, tt_local_entry, flags);
1222 
1223 	/* The local client has to be marked as "pending to be removed" but has
1224 	 * to be kept in the table in order to send it in a full table
1225 	 * response issued before the net ttvn increment (consistency check)
1226 	 */
1227 	tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
1228 
1229 	batadv_dbg(BATADV_DBG_TT, bat_priv,
1230 		   "Local tt entry (%pM, vid: %d) pending to be removed: %s\n",
1231 		   tt_local_entry->common.addr,
1232 		   batadv_print_vid(tt_local_entry->common.vid), message);
1233 }
1234 
1235 /**
1236  * batadv_tt_local_remove() - logically remove an entry from the local table
1237  * @bat_priv: the bat priv with all the mesh interface information
1238  * @addr: the MAC address of the client to remove
1239  * @vid: VLAN identifier
1240  * @message: message to append to the log on deletion
1241  * @roaming: true if the deletion is due to a roaming event
1242  *
1243  * Return: the flags assigned to the local entry before being deleted
1244  */
batadv_tt_local_remove(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid,const char * message,bool roaming)1245 u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr,
1246 			   unsigned short vid, const char *message,
1247 			   bool roaming)
1248 {
1249 	struct batadv_tt_local_entry *tt_removed_entry;
1250 	struct batadv_tt_local_entry *tt_local_entry;
1251 	u16 flags, curr_flags = BATADV_NO_FLAGS;
1252 	struct hlist_node *tt_removed_node;
1253 
1254 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
1255 	if (!tt_local_entry)
1256 		goto out;
1257 
1258 	curr_flags = tt_local_entry->common.flags;
1259 
1260 	flags = BATADV_TT_CLIENT_DEL;
1261 	/* if this global entry addition is due to a roaming, the node has to
1262 	 * mark the local entry as "roamed" in order to correctly reroute
1263 	 * packets later
1264 	 */
1265 	if (roaming) {
1266 		flags |= BATADV_TT_CLIENT_ROAM;
1267 		/* mark the local client as ROAMed */
1268 		tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
1269 	}
1270 
1271 	if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
1272 		batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
1273 					    message);
1274 		goto out;
1275 	}
1276 	/* if this client has been added right now, it is possible to
1277 	 * immediately purge it
1278 	 */
1279 	batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
1280 
1281 	tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash,
1282 					     batadv_compare_tt,
1283 					     batadv_choose_tt,
1284 					     &tt_local_entry->common);
1285 	if (!tt_removed_node)
1286 		goto out;
1287 
1288 	/* drop reference of remove hash entry */
1289 	tt_removed_entry = hlist_entry(tt_removed_node,
1290 				       struct batadv_tt_local_entry,
1291 				       common.hash_entry);
1292 	batadv_tt_local_entry_put(tt_removed_entry);
1293 
1294 out:
1295 	batadv_tt_local_entry_put(tt_local_entry);
1296 
1297 	return curr_flags;
1298 }
1299 
1300 /**
1301  * batadv_tt_local_purge_list() - purge inactive tt local entries
1302  * @bat_priv: the bat priv with all the mesh interface information
1303  * @head: pointer to the list containing the local tt entries
1304  * @timeout: parameter deciding whether a given tt local entry is considered
1305  *  inactive or not
1306  */
batadv_tt_local_purge_list(struct batadv_priv * bat_priv,struct hlist_head * head,int timeout)1307 static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
1308 				       struct hlist_head *head,
1309 				       int timeout)
1310 {
1311 	struct batadv_tt_local_entry *tt_local_entry;
1312 	struct batadv_tt_common_entry *tt_common_entry;
1313 	struct hlist_node *node_tmp;
1314 
1315 	hlist_for_each_entry_safe(tt_common_entry, node_tmp, head,
1316 				  hash_entry) {
1317 		tt_local_entry = container_of(tt_common_entry,
1318 					      struct batadv_tt_local_entry,
1319 					      common);
1320 		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE)
1321 			continue;
1322 
1323 		/* entry already marked for deletion */
1324 		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
1325 			continue;
1326 
1327 		if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
1328 			continue;
1329 
1330 		batadv_tt_local_set_pending(bat_priv, tt_local_entry,
1331 					    BATADV_TT_CLIENT_DEL, "timed out");
1332 	}
1333 }
1334 
1335 /**
1336  * batadv_tt_local_purge() - purge inactive tt local entries
1337  * @bat_priv: the bat priv with all the mesh interface information
1338  * @timeout: parameter deciding whether a given tt local entry is considered
1339  *  inactive or not
1340  */
batadv_tt_local_purge(struct batadv_priv * bat_priv,int timeout)1341 static void batadv_tt_local_purge(struct batadv_priv *bat_priv,
1342 				  int timeout)
1343 {
1344 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1345 	struct hlist_head *head;
1346 	spinlock_t *list_lock; /* protects write access to the hash lists */
1347 	u32 i;
1348 
1349 	for (i = 0; i < hash->size; i++) {
1350 		head = &hash->table[i];
1351 		list_lock = &hash->list_locks[i];
1352 
1353 		spin_lock_bh(list_lock);
1354 		batadv_tt_local_purge_list(bat_priv, head, timeout);
1355 		spin_unlock_bh(list_lock);
1356 	}
1357 }
1358 
batadv_tt_local_table_free(struct batadv_priv * bat_priv)1359 static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
1360 {
1361 	struct batadv_hashtable *hash;
1362 	spinlock_t *list_lock; /* protects write access to the hash lists */
1363 	struct batadv_tt_common_entry *tt_common_entry;
1364 	struct batadv_tt_local_entry *tt_local;
1365 	struct hlist_node *node_tmp;
1366 	struct hlist_head *head;
1367 	u32 i;
1368 
1369 	if (!bat_priv->tt.local_hash)
1370 		return;
1371 
1372 	hash = bat_priv->tt.local_hash;
1373 
1374 	for (i = 0; i < hash->size; i++) {
1375 		head = &hash->table[i];
1376 		list_lock = &hash->list_locks[i];
1377 
1378 		spin_lock_bh(list_lock);
1379 		hlist_for_each_entry_safe(tt_common_entry, node_tmp,
1380 					  head, hash_entry) {
1381 			hlist_del_rcu(&tt_common_entry->hash_entry);
1382 			tt_local = container_of(tt_common_entry,
1383 						struct batadv_tt_local_entry,
1384 						common);
1385 
1386 			batadv_tt_local_entry_put(tt_local);
1387 		}
1388 		spin_unlock_bh(list_lock);
1389 	}
1390 
1391 	batadv_hash_destroy(hash);
1392 
1393 	bat_priv->tt.local_hash = NULL;
1394 }
1395 
batadv_tt_global_init(struct batadv_priv * bat_priv)1396 static int batadv_tt_global_init(struct batadv_priv *bat_priv)
1397 {
1398 	if (bat_priv->tt.global_hash)
1399 		return 0;
1400 
1401 	bat_priv->tt.global_hash = batadv_hash_new(1024);
1402 
1403 	if (!bat_priv->tt.global_hash)
1404 		return -ENOMEM;
1405 
1406 	batadv_hash_set_lock_class(bat_priv->tt.global_hash,
1407 				   &batadv_tt_global_hash_lock_class_key);
1408 
1409 	return 0;
1410 }
1411 
batadv_tt_changes_list_free(struct batadv_priv * bat_priv)1412 static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
1413 {
1414 	struct batadv_tt_change_node *entry, *safe;
1415 
1416 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
1417 
1418 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
1419 				 list) {
1420 		list_del(&entry->list);
1421 		kmem_cache_free(batadv_tt_change_cache, entry);
1422 	}
1423 
1424 	WRITE_ONCE(bat_priv->tt.local_changes, 0);
1425 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
1426 }
1427 
1428 /**
1429  * batadv_tt_global_orig_entry_find() - find a TT orig_list_entry
1430  * @entry: the TT global entry where the orig_list_entry has to be
1431  *  extracted from
1432  * @orig_node: the originator for which the orig_list_entry has to be found
1433  *
1434  * retrieve the orig_tt_list_entry belonging to orig_node from the
1435  * batadv_tt_global_entry list
1436  *
1437  * Return: it with an increased refcounter, NULL if not found
1438  */
1439 static struct batadv_tt_orig_list_entry *
batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry * entry,const struct batadv_orig_node * orig_node)1440 batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
1441 				 const struct batadv_orig_node *orig_node)
1442 {
1443 	struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
1444 	const struct hlist_head *head;
1445 
1446 	rcu_read_lock();
1447 	head = &entry->orig_list;
1448 	hlist_for_each_entry_rcu(tmp_orig_entry, head, list) {
1449 		if (tmp_orig_entry->orig_node != orig_node)
1450 			continue;
1451 		if (!kref_get_unless_zero(&tmp_orig_entry->refcount))
1452 			continue;
1453 
1454 		orig_entry = tmp_orig_entry;
1455 		break;
1456 	}
1457 	rcu_read_unlock();
1458 
1459 	return orig_entry;
1460 }
1461 
1462 /**
1463  * batadv_tt_global_entry_has_orig() - check if a TT global entry is also
1464  *  handled by a given originator
1465  * @entry: the TT global entry to check
1466  * @orig_node: the originator to search in the list
1467  * @flags: a pointer to store TT flags for the given @entry received
1468  *  from @orig_node
1469  *
1470  * find out if an orig_node is already in the list of a tt_global_entry.
1471  *
1472  * Return: true if found, false otherwise
1473  */
1474 static bool
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry * entry,const struct batadv_orig_node * orig_node,u8 * flags)1475 batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
1476 				const struct batadv_orig_node *orig_node,
1477 				u8 *flags)
1478 {
1479 	struct batadv_tt_orig_list_entry *orig_entry;
1480 	bool found = false;
1481 
1482 	orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
1483 	if (orig_entry) {
1484 		found = true;
1485 
1486 		if (flags)
1487 			*flags = orig_entry->flags;
1488 
1489 		batadv_tt_orig_list_entry_put(orig_entry);
1490 	}
1491 
1492 	return found;
1493 }
1494 
1495 /**
1496  * batadv_tt_global_sync_flags() - update TT sync flags
1497  * @tt_global: the TT global entry to update sync flags in
1498  *
1499  * Updates the sync flag bits in the tt_global flag attribute with a logical
1500  * OR of all sync flags from any of its TT orig entries.
1501  */
1502 static void
batadv_tt_global_sync_flags(struct batadv_tt_global_entry * tt_global)1503 batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global)
1504 {
1505 	struct batadv_tt_orig_list_entry *orig_entry;
1506 	const struct hlist_head *head;
1507 	u16 flags = BATADV_NO_FLAGS;
1508 
1509 	rcu_read_lock();
1510 	head = &tt_global->orig_list;
1511 	hlist_for_each_entry_rcu(orig_entry, head, list)
1512 		flags |= orig_entry->flags;
1513 	rcu_read_unlock();
1514 
1515 	flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK);
1516 	tt_global->common.flags = flags;
1517 }
1518 
1519 /**
1520  * batadv_tt_global_orig_entry_add() - add or update a TT orig entry
1521  * @tt_global: the TT global entry to add an orig entry in
1522  * @orig_node: the originator to add an orig entry for
1523  * @ttvn: translation table version number of this changeset
1524  * @flags: TT sync flags
1525  */
1526 static void
batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry * tt_global,struct batadv_orig_node * orig_node,int ttvn,u8 flags)1527 batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
1528 				struct batadv_orig_node *orig_node, int ttvn,
1529 				u8 flags)
1530 {
1531 	struct batadv_tt_orig_list_entry *orig_entry;
1532 
1533 	spin_lock_bh(&tt_global->list_lock);
1534 
1535 	orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
1536 	if (orig_entry) {
1537 		/* refresh the ttvn: the current value could be a bogus one that
1538 		 * was added during a "temporary client detection"
1539 		 */
1540 		orig_entry->ttvn = ttvn;
1541 		orig_entry->flags = flags;
1542 		goto sync_flags;
1543 	}
1544 
1545 	orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC);
1546 	if (!orig_entry)
1547 		goto out;
1548 
1549 	INIT_HLIST_NODE(&orig_entry->list);
1550 	kref_get(&orig_node->refcount);
1551 	batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
1552 	orig_entry->orig_node = orig_node;
1553 	orig_entry->ttvn = ttvn;
1554 	orig_entry->flags = flags;
1555 	kref_init(&orig_entry->refcount);
1556 
1557 	kref_get(&orig_entry->refcount);
1558 	hlist_add_head_rcu(&orig_entry->list,
1559 			   &tt_global->orig_list);
1560 	atomic_inc(&tt_global->orig_list_count);
1561 
1562 sync_flags:
1563 	batadv_tt_global_sync_flags(tt_global);
1564 out:
1565 	batadv_tt_orig_list_entry_put(orig_entry);
1566 
1567 	spin_unlock_bh(&tt_global->list_lock);
1568 }
1569 
1570 /**
1571  * batadv_tt_global_add() - add a new TT global entry or update an existing one
1572  * @bat_priv: the bat priv with all the mesh interface information
1573  * @orig_node: the originator announcing the client
1574  * @tt_addr: the mac address of the non-mesh client
1575  * @vid: VLAN identifier
1576  * @flags: TT flags that have to be set for this non-mesh client
1577  * @ttvn: the tt version number ever announcing this non-mesh client
1578  *
1579  * Add a new TT global entry for the given originator. If the entry already
1580  * exists add a new reference to the given originator (a global entry can have
1581  * references to multiple originators) and adjust the flags attribute to reflect
1582  * the function argument.
1583  * If a TT local entry exists for this non-mesh client remove it.
1584  *
1585  * The caller must hold the orig_node refcount.
1586  *
1587  * Return: true if the new entry has been added, false otherwise
1588  */
batadv_tt_global_add(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * tt_addr,unsigned short vid,u16 flags,u8 ttvn)1589 static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
1590 				 struct batadv_orig_node *orig_node,
1591 				 const unsigned char *tt_addr,
1592 				 unsigned short vid, u16 flags, u8 ttvn)
1593 {
1594 	struct batadv_tt_global_entry *tt_global_entry;
1595 	struct batadv_tt_local_entry *tt_local_entry;
1596 	bool ret = false;
1597 	int hash_added;
1598 	struct batadv_tt_common_entry *common;
1599 	u16 local_flags;
1600 
1601 	/* ignore global entries from backbone nodes */
1602 	if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid))
1603 		return true;
1604 
1605 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
1606 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
1607 
1608 	/* if the node already has a local client for this entry, it has to wait
1609 	 * for a roaming advertisement instead of manually messing up the global
1610 	 * table
1611 	 */
1612 	if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
1613 	    !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
1614 		goto out;
1615 
1616 	if (!tt_global_entry) {
1617 		tt_global_entry = kmem_cache_zalloc(batadv_tg_cache,
1618 						    GFP_ATOMIC);
1619 		if (!tt_global_entry)
1620 			goto out;
1621 
1622 		common = &tt_global_entry->common;
1623 		ether_addr_copy(common->addr, tt_addr);
1624 		common->vid = vid;
1625 
1626 		if (!is_multicast_ether_addr(common->addr))
1627 			common->flags = flags & (~BATADV_TT_SYNC_MASK);
1628 
1629 		tt_global_entry->roam_at = 0;
1630 		/* node must store current time in case of roaming. This is
1631 		 * needed to purge this entry out on timeout (if nobody claims
1632 		 * it)
1633 		 */
1634 		if (flags & BATADV_TT_CLIENT_ROAM)
1635 			tt_global_entry->roam_at = jiffies;
1636 		kref_init(&common->refcount);
1637 		common->added_at = jiffies;
1638 
1639 		INIT_HLIST_HEAD(&tt_global_entry->orig_list);
1640 		atomic_set(&tt_global_entry->orig_list_count, 0);
1641 		spin_lock_init(&tt_global_entry->list_lock);
1642 
1643 		kref_get(&common->refcount);
1644 		hash_added = batadv_hash_add(bat_priv->tt.global_hash,
1645 					     batadv_compare_tt,
1646 					     batadv_choose_tt, common,
1647 					     &common->hash_entry);
1648 
1649 		if (unlikely(hash_added != 0)) {
1650 			/* remove the reference for the hash */
1651 			batadv_tt_global_entry_put(tt_global_entry);
1652 			goto out_remove;
1653 		}
1654 	} else {
1655 		common = &tt_global_entry->common;
1656 		/* If there is already a global entry, we can use this one for
1657 		 * our processing.
1658 		 * But if we are trying to add a temporary client then here are
1659 		 * two options at this point:
1660 		 * 1) the global client is not a temporary client: the global
1661 		 *    client has to be left as it is, temporary information
1662 		 *    should never override any already known client state
1663 		 * 2) the global client is a temporary client: purge the
1664 		 *    originator list and add the new one orig_entry
1665 		 */
1666 		if (flags & BATADV_TT_CLIENT_TEMP) {
1667 			if (!(common->flags & BATADV_TT_CLIENT_TEMP))
1668 				goto out;
1669 			if (batadv_tt_global_entry_has_orig(tt_global_entry,
1670 							    orig_node, NULL))
1671 				goto out_remove;
1672 			batadv_tt_global_del_orig_list(tt_global_entry);
1673 			goto add_orig_entry;
1674 		}
1675 
1676 		/* if the client was temporary added before receiving the first
1677 		 * OGM announcing it, we have to clear the TEMP flag. Also,
1678 		 * remove the previous temporary orig node and re-add it
1679 		 * if required. If the orig entry changed, the new one which
1680 		 * is a non-temporary entry is preferred.
1681 		 */
1682 		if (common->flags & BATADV_TT_CLIENT_TEMP) {
1683 			batadv_tt_global_del_orig_list(tt_global_entry);
1684 			common->flags &= ~BATADV_TT_CLIENT_TEMP;
1685 		}
1686 
1687 		/* the change can carry possible "attribute" flags like the
1688 		 * TT_CLIENT_TEMP, therefore they have to be copied in the
1689 		 * client entry
1690 		 */
1691 		if (!is_multicast_ether_addr(common->addr))
1692 			common->flags |= flags & (~BATADV_TT_SYNC_MASK);
1693 
1694 		/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
1695 		 * one originator left in the list and we previously received a
1696 		 * delete + roaming change for this originator.
1697 		 *
1698 		 * We should first delete the old originator before adding the
1699 		 * new one.
1700 		 */
1701 		if (common->flags & BATADV_TT_CLIENT_ROAM) {
1702 			batadv_tt_global_del_orig_list(tt_global_entry);
1703 			common->flags &= ~BATADV_TT_CLIENT_ROAM;
1704 			tt_global_entry->roam_at = 0;
1705 		}
1706 	}
1707 add_orig_entry:
1708 	/* add the new orig_entry (if needed) or update it */
1709 	batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn,
1710 					flags & BATADV_TT_SYNC_MASK);
1711 
1712 	batadv_dbg(BATADV_DBG_TT, bat_priv,
1713 		   "Creating new global tt entry: %pM (vid: %d, via %pM)\n",
1714 		   common->addr, batadv_print_vid(common->vid),
1715 		   orig_node->orig);
1716 	ret = true;
1717 
1718 out_remove:
1719 	/* Do not remove multicast addresses from the local hash on
1720 	 * global additions
1721 	 */
1722 	if (is_multicast_ether_addr(tt_addr))
1723 		goto out;
1724 
1725 	/* remove address from local hash if present */
1726 	local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
1727 					     "global tt received",
1728 					     flags & BATADV_TT_CLIENT_ROAM);
1729 	tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
1730 
1731 	if (!(flags & BATADV_TT_CLIENT_ROAM))
1732 		/* this is a normal global add. Therefore the client is not in a
1733 		 * roaming state anymore.
1734 		 */
1735 		tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
1736 
1737 out:
1738 	batadv_tt_global_entry_put(tt_global_entry);
1739 	batadv_tt_local_entry_put(tt_local_entry);
1740 	return ret;
1741 }
1742 
1743 /**
1744  * batadv_transtable_best_orig() - Get best originator list entry from tt entry
1745  * @bat_priv: the bat priv with all the mesh interface information
1746  * @tt_global_entry: global translation table entry to be analyzed
1747  *
1748  * This function assumes the caller holds rcu_read_lock().
1749  * Return: best originator list entry or NULL on errors.
1750  */
1751 static struct batadv_tt_orig_list_entry *
batadv_transtable_best_orig(struct batadv_priv * bat_priv,struct batadv_tt_global_entry * tt_global_entry)1752 batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1753 			    struct batadv_tt_global_entry *tt_global_entry)
1754 {
1755 	struct batadv_neigh_node *router, *best_router = NULL;
1756 	struct batadv_algo_ops *bao = bat_priv->algo_ops;
1757 	struct hlist_head *head;
1758 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
1759 
1760 	head = &tt_global_entry->orig_list;
1761 	hlist_for_each_entry_rcu(orig_entry, head, list) {
1762 		router = batadv_orig_router_get(orig_entry->orig_node,
1763 						BATADV_IF_DEFAULT);
1764 		if (!router)
1765 			continue;
1766 
1767 		if (best_router &&
1768 		    bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router,
1769 				   BATADV_IF_DEFAULT) <= 0) {
1770 			batadv_neigh_node_put(router);
1771 			continue;
1772 		}
1773 
1774 		/* release the refcount for the "old" best */
1775 		batadv_neigh_node_put(best_router);
1776 
1777 		best_entry = orig_entry;
1778 		best_router = router;
1779 	}
1780 
1781 	batadv_neigh_node_put(best_router);
1782 
1783 	return best_entry;
1784 }
1785 
1786 /**
1787  * batadv_tt_global_dump_subentry() - Dump all TT local entries into a message
1788  * @msg: Netlink message to dump into
1789  * @portid: Port making netlink request
1790  * @seq: Sequence number of netlink message
1791  * @common: tt local & tt global common data
1792  * @orig: Originator node announcing a non-mesh client
1793  * @best: Is the best originator for the TT entry
1794  *
1795  * Return: Error code, or 0 on success
1796  */
1797 static int
batadv_tt_global_dump_subentry(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_tt_common_entry * common,struct batadv_tt_orig_list_entry * orig,bool best)1798 batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
1799 			       struct batadv_tt_common_entry *common,
1800 			       struct batadv_tt_orig_list_entry *orig,
1801 			       bool best)
1802 {
1803 	u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags;
1804 	void *hdr;
1805 	struct batadv_orig_node_vlan *vlan;
1806 	u8 last_ttvn;
1807 	u32 crc;
1808 
1809 	vlan = batadv_orig_node_vlan_get(orig->orig_node,
1810 					 common->vid);
1811 	if (!vlan)
1812 		return 0;
1813 
1814 	crc = vlan->tt.crc;
1815 
1816 	batadv_orig_node_vlan_put(vlan);
1817 
1818 	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
1819 			  NLM_F_MULTI,
1820 			  BATADV_CMD_GET_TRANSTABLE_GLOBAL);
1821 	if (!hdr)
1822 		return -ENOBUFS;
1823 
1824 	last_ttvn = atomic_read(&orig->orig_node->last_ttvn);
1825 
1826 	if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) ||
1827 	    nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
1828 		    orig->orig_node->orig) ||
1829 	    nla_put_u8(msg, BATADV_ATTR_TT_TTVN, orig->ttvn) ||
1830 	    nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) ||
1831 	    nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
1832 	    nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
1833 	    nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags))
1834 		goto nla_put_failure;
1835 
1836 	if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
1837 		goto nla_put_failure;
1838 
1839 	genlmsg_end(msg, hdr);
1840 	return 0;
1841 
1842  nla_put_failure:
1843 	genlmsg_cancel(msg, hdr);
1844 	return -EMSGSIZE;
1845 }
1846 
1847 /**
1848  * batadv_tt_global_dump_entry() - Dump one TT global entry into a message
1849  * @msg: Netlink message to dump into
1850  * @portid: Port making netlink request
1851  * @seq: Sequence number of netlink message
1852  * @bat_priv: The bat priv with all the mesh interface information
1853  * @common: tt local & tt global common data
1854  * @sub_s: Number of entries to skip
1855  *
1856  * This function assumes the caller holds rcu_read_lock().
1857  *
1858  * Return: Error code, or 0 on success
1859  */
1860 static int
batadv_tt_global_dump_entry(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_tt_common_entry * common,int * sub_s)1861 batadv_tt_global_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
1862 			    struct batadv_priv *bat_priv,
1863 			    struct batadv_tt_common_entry *common, int *sub_s)
1864 {
1865 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
1866 	struct batadv_tt_global_entry *global;
1867 	struct hlist_head *head;
1868 	int sub = 0;
1869 	bool best;
1870 
1871 	global = container_of(common, struct batadv_tt_global_entry, common);
1872 	best_entry = batadv_transtable_best_orig(bat_priv, global);
1873 	head = &global->orig_list;
1874 
1875 	hlist_for_each_entry_rcu(orig_entry, head, list) {
1876 		if (sub++ < *sub_s)
1877 			continue;
1878 
1879 		best = (orig_entry == best_entry);
1880 
1881 		if (batadv_tt_global_dump_subentry(msg, portid, seq, common,
1882 						   orig_entry, best)) {
1883 			*sub_s = sub - 1;
1884 			return -EMSGSIZE;
1885 		}
1886 	}
1887 
1888 	*sub_s = 0;
1889 	return 0;
1890 }
1891 
1892 /**
1893  * batadv_tt_global_dump_bucket() - Dump one TT local bucket into a message
1894  * @msg: Netlink message to dump into
1895  * @portid: Port making netlink request
1896  * @seq: Sequence number of netlink message
1897  * @bat_priv: The bat priv with all the mesh interface information
1898  * @head: Pointer to the list containing the global tt entries
1899  * @idx_s: Number of entries to skip
1900  * @sub: Number of entries to skip
1901  *
1902  * Return: Error code, or 0 on success
1903  */
1904 static int
batadv_tt_global_dump_bucket(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct hlist_head * head,int * idx_s,int * sub)1905 batadv_tt_global_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1906 			     struct batadv_priv *bat_priv,
1907 			     struct hlist_head *head, int *idx_s, int *sub)
1908 {
1909 	struct batadv_tt_common_entry *common;
1910 	int idx = 0;
1911 
1912 	rcu_read_lock();
1913 	hlist_for_each_entry_rcu(common, head, hash_entry) {
1914 		if (idx++ < *idx_s)
1915 			continue;
1916 
1917 		if (batadv_tt_global_dump_entry(msg, portid, seq, bat_priv,
1918 						common, sub)) {
1919 			rcu_read_unlock();
1920 			*idx_s = idx - 1;
1921 			return -EMSGSIZE;
1922 		}
1923 	}
1924 	rcu_read_unlock();
1925 
1926 	*idx_s = 0;
1927 	*sub = 0;
1928 	return 0;
1929 }
1930 
1931 /**
1932  * batadv_tt_global_dump() -  Dump TT global entries into a message
1933  * @msg: Netlink message to dump into
1934  * @cb: Parameters from query
1935  *
1936  * Return: Error code, or length of message on success
1937  */
batadv_tt_global_dump(struct sk_buff * msg,struct netlink_callback * cb)1938 int batadv_tt_global_dump(struct sk_buff *msg, struct netlink_callback *cb)
1939 {
1940 	struct net_device *mesh_iface;
1941 	struct batadv_priv *bat_priv;
1942 	struct batadv_hard_iface *primary_if = NULL;
1943 	struct batadv_hashtable *hash;
1944 	struct hlist_head *head;
1945 	int ret;
1946 	int bucket = cb->args[0];
1947 	int idx = cb->args[1];
1948 	int sub = cb->args[2];
1949 	int portid = NETLINK_CB(cb->skb).portid;
1950 
1951 	mesh_iface = batadv_netlink_get_meshif(cb);
1952 	if (IS_ERR(mesh_iface))
1953 		return PTR_ERR(mesh_iface);
1954 
1955 	bat_priv = netdev_priv(mesh_iface);
1956 
1957 	primary_if = batadv_primary_if_get_selected(bat_priv);
1958 	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
1959 		ret = -ENOENT;
1960 		goto out;
1961 	}
1962 
1963 	hash = bat_priv->tt.global_hash;
1964 
1965 	while (bucket < hash->size) {
1966 		head = &hash->table[bucket];
1967 
1968 		if (batadv_tt_global_dump_bucket(msg, portid,
1969 						 cb->nlh->nlmsg_seq, bat_priv,
1970 						 head, &idx, &sub))
1971 			break;
1972 
1973 		bucket++;
1974 	}
1975 
1976 	ret = msg->len;
1977 
1978  out:
1979 	batadv_hardif_put(primary_if);
1980 	dev_put(mesh_iface);
1981 
1982 	cb->args[0] = bucket;
1983 	cb->args[1] = idx;
1984 	cb->args[2] = sub;
1985 
1986 	return ret;
1987 }
1988 
1989 /**
1990  * _batadv_tt_global_del_orig_entry() - remove and free an orig_entry
1991  * @tt_global_entry: the global entry to remove the orig_entry from
1992  * @orig_entry: the orig entry to remove and free
1993  *
1994  * Remove an orig_entry from its list in the given tt_global_entry and
1995  * free this orig_entry afterwards.
1996  *
1997  * Caller must hold tt_global_entry->list_lock and ensure orig_entry->list is
1998  * part of a list.
1999  */
2000 static void
_batadv_tt_global_del_orig_entry(struct batadv_tt_global_entry * tt_global_entry,struct batadv_tt_orig_list_entry * orig_entry)2001 _batadv_tt_global_del_orig_entry(struct batadv_tt_global_entry *tt_global_entry,
2002 				 struct batadv_tt_orig_list_entry *orig_entry)
2003 {
2004 	lockdep_assert_held(&tt_global_entry->list_lock);
2005 
2006 	batadv_tt_global_size_dec(orig_entry->orig_node,
2007 				  tt_global_entry->common.vid);
2008 	atomic_dec(&tt_global_entry->orig_list_count);
2009 	/* requires holding tt_global_entry->list_lock and orig_entry->list
2010 	 * being part of a list
2011 	 */
2012 	hlist_del_rcu(&orig_entry->list);
2013 	batadv_tt_orig_list_entry_put(orig_entry);
2014 }
2015 
2016 /* deletes the orig list of a tt_global_entry */
2017 static void
batadv_tt_global_del_orig_list(struct batadv_tt_global_entry * tt_global_entry)2018 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
2019 {
2020 	struct hlist_head *head;
2021 	struct hlist_node *safe;
2022 	struct batadv_tt_orig_list_entry *orig_entry;
2023 
2024 	spin_lock_bh(&tt_global_entry->list_lock);
2025 	head = &tt_global_entry->orig_list;
2026 	hlist_for_each_entry_safe(orig_entry, safe, head, list)
2027 		_batadv_tt_global_del_orig_entry(tt_global_entry, orig_entry);
2028 	spin_unlock_bh(&tt_global_entry->list_lock);
2029 }
2030 
2031 /**
2032  * batadv_tt_global_del_orig_node() - remove orig_node from a global tt entry
2033  * @bat_priv: the bat priv with all the mesh interface information
2034  * @tt_global_entry: the global entry to remove the orig_node from
2035  * @orig_node: the originator announcing the client
2036  * @message: message to append to the log on deletion
2037  *
2038  * Remove the given orig_node and its according orig_entry from the given
2039  * global tt entry.
2040  */
2041 static void
batadv_tt_global_del_orig_node(struct batadv_priv * bat_priv,struct batadv_tt_global_entry * tt_global_entry,struct batadv_orig_node * orig_node,const char * message)2042 batadv_tt_global_del_orig_node(struct batadv_priv *bat_priv,
2043 			       struct batadv_tt_global_entry *tt_global_entry,
2044 			       struct batadv_orig_node *orig_node,
2045 			       const char *message)
2046 {
2047 	struct hlist_head *head;
2048 	struct hlist_node *safe;
2049 	struct batadv_tt_orig_list_entry *orig_entry;
2050 	unsigned short vid;
2051 
2052 	spin_lock_bh(&tt_global_entry->list_lock);
2053 	head = &tt_global_entry->orig_list;
2054 	hlist_for_each_entry_safe(orig_entry, safe, head, list) {
2055 		if (orig_entry->orig_node == orig_node) {
2056 			vid = tt_global_entry->common.vid;
2057 			batadv_dbg(BATADV_DBG_TT, bat_priv,
2058 				   "Deleting %pM from global tt entry %pM (vid: %d): %s\n",
2059 				   orig_node->orig,
2060 				   tt_global_entry->common.addr,
2061 				   batadv_print_vid(vid), message);
2062 			_batadv_tt_global_del_orig_entry(tt_global_entry,
2063 							 orig_entry);
2064 		}
2065 	}
2066 	spin_unlock_bh(&tt_global_entry->list_lock);
2067 }
2068 
2069 /* If the client is to be deleted, we check if it is the last origantor entry
2070  * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
2071  * timer, otherwise we simply remove the originator scheduled for deletion.
2072  */
2073 static void
batadv_tt_global_del_roaming(struct batadv_priv * bat_priv,struct batadv_tt_global_entry * tt_global_entry,struct batadv_orig_node * orig_node,const char * message)2074 batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
2075 			     struct batadv_tt_global_entry *tt_global_entry,
2076 			     struct batadv_orig_node *orig_node,
2077 			     const char *message)
2078 {
2079 	bool last_entry = true;
2080 	struct hlist_head *head;
2081 	struct batadv_tt_orig_list_entry *orig_entry;
2082 
2083 	/* no local entry exists, case 1:
2084 	 * Check if this is the last one or if other entries exist.
2085 	 */
2086 
2087 	rcu_read_lock();
2088 	head = &tt_global_entry->orig_list;
2089 	hlist_for_each_entry_rcu(orig_entry, head, list) {
2090 		if (orig_entry->orig_node != orig_node) {
2091 			last_entry = false;
2092 			break;
2093 		}
2094 	}
2095 	rcu_read_unlock();
2096 
2097 	if (last_entry) {
2098 		/* its the last one, mark for roaming. */
2099 		tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
2100 		tt_global_entry->roam_at = jiffies;
2101 	} else {
2102 		/* there is another entry, we can simply delete this
2103 		 * one and can still use the other one.
2104 		 */
2105 		batadv_tt_global_del_orig_node(bat_priv, tt_global_entry,
2106 					       orig_node, message);
2107 	}
2108 }
2109 
2110 /**
2111  * batadv_tt_global_del() - remove a client from the global table
2112  * @bat_priv: the bat priv with all the mesh interface information
2113  * @orig_node: an originator serving this client
2114  * @addr: the mac address of the client
2115  * @vid: VLAN identifier
2116  * @message: a message explaining the reason for deleting the client to print
2117  *  for debugging purpose
2118  * @roaming: true if the deletion has been triggered by a roaming event
2119  */
batadv_tt_global_del(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * addr,unsigned short vid,const char * message,bool roaming)2120 static void batadv_tt_global_del(struct batadv_priv *bat_priv,
2121 				 struct batadv_orig_node *orig_node,
2122 				 const unsigned char *addr, unsigned short vid,
2123 				 const char *message, bool roaming)
2124 {
2125 	struct batadv_tt_global_entry *tt_global_entry;
2126 	struct batadv_tt_local_entry *local_entry = NULL;
2127 
2128 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
2129 	if (!tt_global_entry)
2130 		goto out;
2131 
2132 	if (!roaming) {
2133 		batadv_tt_global_del_orig_node(bat_priv, tt_global_entry,
2134 					       orig_node, message);
2135 
2136 		if (hlist_empty(&tt_global_entry->orig_list))
2137 			batadv_tt_global_free(bat_priv, tt_global_entry,
2138 					      message);
2139 
2140 		goto out;
2141 	}
2142 
2143 	/* if we are deleting a global entry due to a roam
2144 	 * event, there are two possibilities:
2145 	 * 1) the client roamed from node A to node B => if there
2146 	 *    is only one originator left for this client, we mark
2147 	 *    it with BATADV_TT_CLIENT_ROAM, we start a timer and we
2148 	 *    wait for node B to claim it. In case of timeout
2149 	 *    the entry is purged.
2150 	 *
2151 	 *    If there are other originators left, we directly delete
2152 	 *    the originator.
2153 	 * 2) the client roamed to us => we can directly delete
2154 	 *    the global entry, since it is useless now.
2155 	 */
2156 	local_entry = batadv_tt_local_hash_find(bat_priv,
2157 						tt_global_entry->common.addr,
2158 						vid);
2159 	if (local_entry) {
2160 		/* local entry exists, case 2: client roamed to us. */
2161 		batadv_tt_global_del_orig_list(tt_global_entry);
2162 		batadv_tt_global_free(bat_priv, tt_global_entry, message);
2163 	} else {
2164 		/* no local entry exists, case 1: check for roaming */
2165 		batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
2166 					     orig_node, message);
2167 	}
2168 
2169 out:
2170 	batadv_tt_global_entry_put(tt_global_entry);
2171 	batadv_tt_local_entry_put(local_entry);
2172 }
2173 
2174 /**
2175  * batadv_tt_global_del_orig() - remove all the TT global entries belonging to
2176  *  the given originator matching the provided vid
2177  * @bat_priv: the bat priv with all the mesh interface information
2178  * @orig_node: the originator owning the entries to remove
2179  * @match_vid: the VLAN identifier to match. If negative all the entries will be
2180  *  removed
2181  * @message: debug message to print as "reason"
2182  */
batadv_tt_global_del_orig(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,s32 match_vid,const char * message)2183 void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
2184 			       struct batadv_orig_node *orig_node,
2185 			       s32 match_vid,
2186 			       const char *message)
2187 {
2188 	struct batadv_tt_global_entry *tt_global;
2189 	struct batadv_tt_common_entry *tt_common_entry;
2190 	u32 i;
2191 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
2192 	struct hlist_node *safe;
2193 	struct hlist_head *head;
2194 	spinlock_t *list_lock; /* protects write access to the hash lists */
2195 	unsigned short vid;
2196 
2197 	if (!hash)
2198 		return;
2199 
2200 	for (i = 0; i < hash->size; i++) {
2201 		head = &hash->table[i];
2202 		list_lock = &hash->list_locks[i];
2203 
2204 		spin_lock_bh(list_lock);
2205 		hlist_for_each_entry_safe(tt_common_entry, safe,
2206 					  head, hash_entry) {
2207 			/* remove only matching entries */
2208 			if (match_vid >= 0 && tt_common_entry->vid != match_vid)
2209 				continue;
2210 
2211 			tt_global = container_of(tt_common_entry,
2212 						 struct batadv_tt_global_entry,
2213 						 common);
2214 
2215 			batadv_tt_global_del_orig_node(bat_priv, tt_global,
2216 						       orig_node, message);
2217 
2218 			if (hlist_empty(&tt_global->orig_list)) {
2219 				vid = tt_global->common.vid;
2220 				batadv_dbg(BATADV_DBG_TT, bat_priv,
2221 					   "Deleting global tt entry %pM (vid: %d): %s\n",
2222 					   tt_global->common.addr,
2223 					   batadv_print_vid(vid), message);
2224 				hlist_del_rcu(&tt_common_entry->hash_entry);
2225 				batadv_tt_global_entry_put(tt_global);
2226 			}
2227 		}
2228 		spin_unlock_bh(list_lock);
2229 	}
2230 	clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
2231 }
2232 
batadv_tt_global_to_purge(struct batadv_tt_global_entry * tt_global,char ** msg)2233 static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
2234 				      char **msg)
2235 {
2236 	bool purge = false;
2237 	unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
2238 	unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
2239 
2240 	if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
2241 	    batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
2242 		purge = true;
2243 		*msg = "Roaming timeout\n";
2244 	}
2245 
2246 	if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
2247 	    batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
2248 		purge = true;
2249 		*msg = "Temporary client timeout\n";
2250 	}
2251 
2252 	return purge;
2253 }
2254 
batadv_tt_global_purge(struct batadv_priv * bat_priv)2255 static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
2256 {
2257 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
2258 	struct hlist_head *head;
2259 	struct hlist_node *node_tmp;
2260 	spinlock_t *list_lock; /* protects write access to the hash lists */
2261 	u32 i;
2262 	char *msg = NULL;
2263 	struct batadv_tt_common_entry *tt_common;
2264 	struct batadv_tt_global_entry *tt_global;
2265 
2266 	for (i = 0; i < hash->size; i++) {
2267 		head = &hash->table[i];
2268 		list_lock = &hash->list_locks[i];
2269 
2270 		spin_lock_bh(list_lock);
2271 		hlist_for_each_entry_safe(tt_common, node_tmp, head,
2272 					  hash_entry) {
2273 			tt_global = container_of(tt_common,
2274 						 struct batadv_tt_global_entry,
2275 						 common);
2276 
2277 			if (!batadv_tt_global_to_purge(tt_global, &msg))
2278 				continue;
2279 
2280 			batadv_dbg(BATADV_DBG_TT, bat_priv,
2281 				   "Deleting global tt entry %pM (vid: %d): %s\n",
2282 				   tt_global->common.addr,
2283 				   batadv_print_vid(tt_global->common.vid),
2284 				   msg);
2285 
2286 			hlist_del_rcu(&tt_common->hash_entry);
2287 
2288 			batadv_tt_global_entry_put(tt_global);
2289 		}
2290 		spin_unlock_bh(list_lock);
2291 	}
2292 }
2293 
batadv_tt_global_table_free(struct batadv_priv * bat_priv)2294 static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
2295 {
2296 	struct batadv_hashtable *hash;
2297 	spinlock_t *list_lock; /* protects write access to the hash lists */
2298 	struct batadv_tt_common_entry *tt_common_entry;
2299 	struct batadv_tt_global_entry *tt_global;
2300 	struct hlist_node *node_tmp;
2301 	struct hlist_head *head;
2302 	u32 i;
2303 
2304 	if (!bat_priv->tt.global_hash)
2305 		return;
2306 
2307 	hash = bat_priv->tt.global_hash;
2308 
2309 	for (i = 0; i < hash->size; i++) {
2310 		head = &hash->table[i];
2311 		list_lock = &hash->list_locks[i];
2312 
2313 		spin_lock_bh(list_lock);
2314 		hlist_for_each_entry_safe(tt_common_entry, node_tmp,
2315 					  head, hash_entry) {
2316 			hlist_del_rcu(&tt_common_entry->hash_entry);
2317 			tt_global = container_of(tt_common_entry,
2318 						 struct batadv_tt_global_entry,
2319 						 common);
2320 			batadv_tt_global_entry_put(tt_global);
2321 		}
2322 		spin_unlock_bh(list_lock);
2323 	}
2324 
2325 	batadv_hash_destroy(hash);
2326 
2327 	bat_priv->tt.global_hash = NULL;
2328 }
2329 
2330 static bool
_batadv_is_ap_isolated(struct batadv_tt_local_entry * tt_local_entry,struct batadv_tt_global_entry * tt_global_entry)2331 _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
2332 		       struct batadv_tt_global_entry *tt_global_entry)
2333 {
2334 	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
2335 	    tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
2336 		return true;
2337 
2338 	/* check if the two clients are marked as isolated */
2339 	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA &&
2340 	    tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA)
2341 		return true;
2342 
2343 	return false;
2344 }
2345 
2346 /**
2347  * batadv_transtable_search() - get the mesh destination for a given client
2348  * @bat_priv: the bat priv with all the mesh interface information
2349  * @src: mac address of the source client
2350  * @addr: mac address of the destination client
2351  * @vid: VLAN identifier
2352  *
2353  * Return: a pointer to the originator that was selected as destination in the
2354  * mesh for contacting the client 'addr', NULL otherwise.
2355  * In case of multiple originators serving the same client, the function returns
2356  * the best one (best in terms of metric towards the destination node).
2357  *
2358  * If the two clients are AP isolated the function returns NULL.
2359  */
batadv_transtable_search(struct batadv_priv * bat_priv,const u8 * src,const u8 * addr,unsigned short vid)2360 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
2361 						  const u8 *src,
2362 						  const u8 *addr,
2363 						  unsigned short vid)
2364 {
2365 	struct batadv_tt_local_entry *tt_local_entry = NULL;
2366 	struct batadv_tt_global_entry *tt_global_entry = NULL;
2367 	struct batadv_orig_node *orig_node = NULL;
2368 	struct batadv_tt_orig_list_entry *best_entry;
2369 
2370 	if (src && batadv_vlan_ap_isola_get(bat_priv, vid)) {
2371 		tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
2372 		if (!tt_local_entry ||
2373 		    (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
2374 			goto out;
2375 	}
2376 
2377 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
2378 	if (!tt_global_entry)
2379 		goto out;
2380 
2381 	/* check whether the clients should not communicate due to AP
2382 	 * isolation
2383 	 */
2384 	if (tt_local_entry &&
2385 	    _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
2386 		goto out;
2387 
2388 	rcu_read_lock();
2389 	best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
2390 	/* found anything? */
2391 	if (best_entry)
2392 		orig_node = best_entry->orig_node;
2393 	if (orig_node && !kref_get_unless_zero(&orig_node->refcount))
2394 		orig_node = NULL;
2395 	rcu_read_unlock();
2396 
2397 out:
2398 	batadv_tt_global_entry_put(tt_global_entry);
2399 	batadv_tt_local_entry_put(tt_local_entry);
2400 
2401 	return orig_node;
2402 }
2403 
2404 /**
2405  * batadv_tt_global_crc() - calculates the checksum of the local table belonging
2406  *  to the given orig_node
2407  * @bat_priv: the bat priv with all the mesh interface information
2408  * @orig_node: originator for which the CRC should be computed
2409  * @vid: VLAN identifier for which the CRC32 has to be computed
2410  *
2411  * This function computes the checksum for the global table corresponding to a
2412  * specific originator. In particular, the checksum is computed as follows: For
2413  * each client connected to the originator the CRC32C of the MAC address and the
2414  * VID is computed and then all the CRC32Cs of the various clients are xor'ed
2415  * together.
2416  *
2417  * The idea behind is that CRC32C should be used as much as possible in order to
2418  * produce a unique hash of the table, but since the order which is used to feed
2419  * the CRC32C function affects the result and since every node in the network
2420  * probably sorts the clients differently, the hash function cannot be directly
2421  * computed over the entire table. Hence the CRC32C is used only on
2422  * the single client entry, while all the results are then xor'ed together
2423  * because the XOR operation can combine them all while trying to reduce the
2424  * noise as much as possible.
2425  *
2426  * Return: the checksum of the global table of a given originator.
2427  */
batadv_tt_global_crc(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,unsigned short vid)2428 static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
2429 				struct batadv_orig_node *orig_node,
2430 				unsigned short vid)
2431 {
2432 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
2433 	struct batadv_tt_orig_list_entry *tt_orig;
2434 	struct batadv_tt_common_entry *tt_common;
2435 	struct batadv_tt_global_entry *tt_global;
2436 	struct hlist_head *head;
2437 	u32 i, crc_tmp, crc = 0;
2438 	u8 flags;
2439 	__be16 tmp_vid;
2440 
2441 	for (i = 0; i < hash->size; i++) {
2442 		head = &hash->table[i];
2443 
2444 		rcu_read_lock();
2445 		hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
2446 			tt_global = container_of(tt_common,
2447 						 struct batadv_tt_global_entry,
2448 						 common);
2449 			/* compute the CRC only for entries belonging to the
2450 			 * VLAN identified by the vid passed as parameter
2451 			 */
2452 			if (tt_common->vid != vid)
2453 				continue;
2454 
2455 			/* Roaming clients are in the global table for
2456 			 * consistency only. They don't have to be
2457 			 * taken into account while computing the
2458 			 * global crc
2459 			 */
2460 			if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
2461 				continue;
2462 			/* Temporary clients have not been announced yet, so
2463 			 * they have to be skipped while computing the global
2464 			 * crc
2465 			 */
2466 			if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
2467 				continue;
2468 
2469 			/* find out if this global entry is announced by this
2470 			 * originator
2471 			 */
2472 			tt_orig = batadv_tt_global_orig_entry_find(tt_global,
2473 								   orig_node);
2474 			if (!tt_orig)
2475 				continue;
2476 
2477 			/* use network order to read the VID: this ensures that
2478 			 * every node reads the bytes in the same order.
2479 			 */
2480 			tmp_vid = htons(tt_common->vid);
2481 			crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid));
2482 
2483 			/* compute the CRC on flags that have to be kept in sync
2484 			 * among nodes
2485 			 */
2486 			flags = tt_orig->flags;
2487 			crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2488 
2489 			crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2490 
2491 			batadv_tt_orig_list_entry_put(tt_orig);
2492 		}
2493 		rcu_read_unlock();
2494 	}
2495 
2496 	return crc;
2497 }
2498 
2499 /**
2500  * batadv_tt_local_crc() - calculates the checksum of the local table
2501  * @bat_priv: the bat priv with all the mesh interface information
2502  * @vid: VLAN identifier for which the CRC32 has to be computed
2503  *
2504  * For details about the computation, please refer to the documentation for
2505  * batadv_tt_global_crc().
2506  *
2507  * Return: the checksum of the local table
2508  */
batadv_tt_local_crc(struct batadv_priv * bat_priv,unsigned short vid)2509 static u32 batadv_tt_local_crc(struct batadv_priv *bat_priv,
2510 			       unsigned short vid)
2511 {
2512 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2513 	struct batadv_tt_common_entry *tt_common;
2514 	struct hlist_head *head;
2515 	u32 i, crc_tmp, crc = 0;
2516 	u8 flags;
2517 	__be16 tmp_vid;
2518 
2519 	for (i = 0; i < hash->size; i++) {
2520 		head = &hash->table[i];
2521 
2522 		rcu_read_lock();
2523 		hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
2524 			/* compute the CRC only for entries belonging to the
2525 			 * VLAN identified by vid
2526 			 */
2527 			if (tt_common->vid != vid)
2528 				continue;
2529 
2530 			/* not yet committed clients have not to be taken into
2531 			 * account while computing the CRC
2532 			 */
2533 			if (tt_common->flags & BATADV_TT_CLIENT_NEW)
2534 				continue;
2535 
2536 			/* use network order to read the VID: this ensures that
2537 			 * every node reads the bytes in the same order.
2538 			 */
2539 			tmp_vid = htons(tt_common->vid);
2540 			crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid));
2541 
2542 			/* compute the CRC on flags that have to be kept in sync
2543 			 * among nodes
2544 			 */
2545 			flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2546 			crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2547 
2548 			crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2549 		}
2550 		rcu_read_unlock();
2551 	}
2552 
2553 	return crc;
2554 }
2555 
2556 /**
2557  * batadv_tt_req_node_release() - free tt_req node entry
2558  * @ref: kref pointer of the tt req_node entry
2559  */
batadv_tt_req_node_release(struct kref * ref)2560 static void batadv_tt_req_node_release(struct kref *ref)
2561 {
2562 	struct batadv_tt_req_node *tt_req_node;
2563 
2564 	tt_req_node = container_of(ref, struct batadv_tt_req_node, refcount);
2565 
2566 	kmem_cache_free(batadv_tt_req_cache, tt_req_node);
2567 }
2568 
2569 /**
2570  * batadv_tt_req_node_put() - decrement the tt_req_node refcounter and
2571  *  possibly release it
2572  * @tt_req_node: tt_req_node to be free'd
2573  */
batadv_tt_req_node_put(struct batadv_tt_req_node * tt_req_node)2574 static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
2575 {
2576 	if (!tt_req_node)
2577 		return;
2578 
2579 	kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
2580 }
2581 
batadv_tt_req_list_free(struct batadv_priv * bat_priv)2582 static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
2583 {
2584 	struct batadv_tt_req_node *node;
2585 	struct hlist_node *safe;
2586 
2587 	spin_lock_bh(&bat_priv->tt.req_list_lock);
2588 
2589 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2590 		hlist_del_init(&node->list);
2591 		batadv_tt_req_node_put(node);
2592 	}
2593 
2594 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
2595 }
2596 
batadv_tt_save_orig_buffer(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const void * tt_buff,u16 tt_buff_len)2597 static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
2598 				       struct batadv_orig_node *orig_node,
2599 				       const void *tt_buff,
2600 				       u16 tt_buff_len)
2601 {
2602 	/* Replace the old buffer only if I received something in the
2603 	 * last OGM (the OGM could carry no changes)
2604 	 */
2605 	spin_lock_bh(&orig_node->tt_buff_lock);
2606 	if (tt_buff_len > 0) {
2607 		kfree(orig_node->tt_buff);
2608 		orig_node->tt_buff_len = 0;
2609 		orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
2610 		if (orig_node->tt_buff) {
2611 			memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
2612 			orig_node->tt_buff_len = tt_buff_len;
2613 		}
2614 	}
2615 	spin_unlock_bh(&orig_node->tt_buff_lock);
2616 }
2617 
batadv_tt_req_purge(struct batadv_priv * bat_priv)2618 static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
2619 {
2620 	struct batadv_tt_req_node *node;
2621 	struct hlist_node *safe;
2622 
2623 	spin_lock_bh(&bat_priv->tt.req_list_lock);
2624 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2625 		if (batadv_has_timed_out(node->issued_at,
2626 					 BATADV_TT_REQUEST_TIMEOUT)) {
2627 			hlist_del_init(&node->list);
2628 			batadv_tt_req_node_put(node);
2629 		}
2630 	}
2631 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
2632 }
2633 
2634 /**
2635  * batadv_tt_req_node_new() - search and possibly create a tt_req_node object
2636  * @bat_priv: the bat priv with all the mesh interface information
2637  * @orig_node: orig node this request is being issued for
2638  *
2639  * Return: the pointer to the new tt_req_node struct if no request
2640  * has already been issued for this orig_node, NULL otherwise.
2641  */
2642 static struct batadv_tt_req_node *
batadv_tt_req_node_new(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)2643 batadv_tt_req_node_new(struct batadv_priv *bat_priv,
2644 		       struct batadv_orig_node *orig_node)
2645 {
2646 	struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
2647 
2648 	spin_lock_bh(&bat_priv->tt.req_list_lock);
2649 	hlist_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
2650 		if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
2651 		    !batadv_has_timed_out(tt_req_node_tmp->issued_at,
2652 					  BATADV_TT_REQUEST_TIMEOUT))
2653 			goto unlock;
2654 	}
2655 
2656 	tt_req_node = kmem_cache_alloc(batadv_tt_req_cache, GFP_ATOMIC);
2657 	if (!tt_req_node)
2658 		goto unlock;
2659 
2660 	kref_init(&tt_req_node->refcount);
2661 	ether_addr_copy(tt_req_node->addr, orig_node->orig);
2662 	tt_req_node->issued_at = jiffies;
2663 
2664 	kref_get(&tt_req_node->refcount);
2665 	hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list);
2666 unlock:
2667 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
2668 	return tt_req_node;
2669 }
2670 
2671 /**
2672  * batadv_tt_local_valid() - verify local tt entry and get flags
2673  * @entry_ptr: to be checked local tt entry
2674  * @data_ptr: not used but definition required to satisfy the callback prototype
2675  * @flags: a pointer to store TT flags for this client to
2676  *
2677  * Checks the validity of the given local TT entry. If it is, then the provided
2678  * flags pointer is updated.
2679  *
2680  * Return: true if the entry is a valid, false otherwise.
2681  */
batadv_tt_local_valid(const void * entry_ptr,const void * data_ptr,u8 * flags)2682 static bool batadv_tt_local_valid(const void *entry_ptr,
2683 				  const void *data_ptr,
2684 				  u8 *flags)
2685 {
2686 	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2687 
2688 	if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
2689 		return false;
2690 
2691 	if (flags)
2692 		*flags = tt_common_entry->flags;
2693 
2694 	return true;
2695 }
2696 
2697 /**
2698  * batadv_tt_global_valid() - verify global tt entry and get flags
2699  * @entry_ptr: to be checked global tt entry
2700  * @data_ptr: an orig_node object (may be NULL)
2701  * @flags: a pointer to store TT flags for this client to
2702  *
2703  * Checks the validity of the given global TT entry. If it is, then the provided
2704  * flags pointer is updated either with the common (summed) TT flags if data_ptr
2705  * is NULL or the specific, per originator TT flags otherwise.
2706  *
2707  * Return: true if the entry is a valid, false otherwise.
2708  */
batadv_tt_global_valid(const void * entry_ptr,const void * data_ptr,u8 * flags)2709 static bool batadv_tt_global_valid(const void *entry_ptr,
2710 				   const void *data_ptr,
2711 				   u8 *flags)
2712 {
2713 	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2714 	const struct batadv_tt_global_entry *tt_global_entry;
2715 	const struct batadv_orig_node *orig_node = data_ptr;
2716 
2717 	if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
2718 	    tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
2719 		return false;
2720 
2721 	tt_global_entry = container_of(tt_common_entry,
2722 				       struct batadv_tt_global_entry,
2723 				       common);
2724 
2725 	return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
2726 					       flags);
2727 }
2728 
2729 /**
2730  * batadv_tt_tvlv_generate() - fill the tvlv buff with the tt entries from the
2731  *  specified tt hash
2732  * @bat_priv: the bat priv with all the mesh interface information
2733  * @hash: hash table containing the tt entries
2734  * @tt_len: expected tvlv tt data buffer length in number of bytes
2735  * @tvlv_buff: pointer to the buffer to fill with the TT data
2736  * @valid_cb: function to filter tt change entries and to return TT flags
2737  * @cb_data: data passed to the filter function as argument
2738  *
2739  * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
2740  * is not provided then this becomes a no-op.
2741  *
2742  * Return: Remaining unused length in tvlv_buff.
2743  */
batadv_tt_tvlv_generate(struct batadv_priv * bat_priv,struct batadv_hashtable * hash,void * tvlv_buff,u16 tt_len,bool (* valid_cb)(const void *,const void *,u8 * flags),void * cb_data)2744 static u16 batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2745 				   struct batadv_hashtable *hash,
2746 				   void *tvlv_buff, u16 tt_len,
2747 				   bool (*valid_cb)(const void *,
2748 						    const void *,
2749 						    u8 *flags),
2750 				   void *cb_data)
2751 {
2752 	struct batadv_tt_common_entry *tt_common_entry;
2753 	struct batadv_tvlv_tt_change *tt_change;
2754 	struct hlist_head *head;
2755 	u16 tt_tot, tt_num_entries = 0;
2756 	u8 flags;
2757 	bool ret;
2758 	u32 i;
2759 
2760 	tt_tot = batadv_tt_entries(tt_len);
2761 	tt_change = tvlv_buff;
2762 
2763 	if (!valid_cb)
2764 		return tt_len;
2765 
2766 	rcu_read_lock();
2767 	for (i = 0; i < hash->size; i++) {
2768 		head = &hash->table[i];
2769 
2770 		hlist_for_each_entry_rcu(tt_common_entry,
2771 					 head, hash_entry) {
2772 			if (tt_tot == tt_num_entries)
2773 				break;
2774 
2775 			ret = valid_cb(tt_common_entry, cb_data, &flags);
2776 			if (!ret)
2777 				continue;
2778 
2779 			ether_addr_copy(tt_change->addr, tt_common_entry->addr);
2780 			tt_change->flags = flags;
2781 			tt_change->vid = htons(tt_common_entry->vid);
2782 			memset(tt_change->reserved, 0,
2783 			       sizeof(tt_change->reserved));
2784 
2785 			tt_num_entries++;
2786 			tt_change++;
2787 		}
2788 	}
2789 	rcu_read_unlock();
2790 
2791 	return batadv_tt_len(tt_tot - tt_num_entries);
2792 }
2793 
2794 /**
2795  * batadv_tt_global_check_crc() - check if all the CRCs are correct
2796  * @orig_node: originator for which the CRCs have to be checked
2797  * @tt_vlan: pointer to the first tvlv VLAN entry
2798  * @num_vlan: number of tvlv VLAN entries
2799  *
2800  * Return: true if all the received CRCs match the locally stored ones, false
2801  * otherwise
2802  */
batadv_tt_global_check_crc(struct batadv_orig_node * orig_node,struct batadv_tvlv_tt_vlan_data * tt_vlan,u16 num_vlan)2803 static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
2804 				       struct batadv_tvlv_tt_vlan_data *tt_vlan,
2805 				       u16 num_vlan)
2806 {
2807 	struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
2808 	struct batadv_orig_node_vlan *vlan;
2809 	int i, orig_num_vlan;
2810 	u32 crc;
2811 
2812 	/* check if each received CRC matches the locally stored one */
2813 	for (i = 0; i < num_vlan; i++) {
2814 		tt_vlan_tmp = tt_vlan + i;
2815 
2816 		/* if orig_node is a backbone node for this VLAN, don't check
2817 		 * the CRC as we ignore all the global entries over it
2818 		 */
2819 		if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv,
2820 						   orig_node->orig,
2821 						   ntohs(tt_vlan_tmp->vid)))
2822 			continue;
2823 
2824 		vlan = batadv_orig_node_vlan_get(orig_node,
2825 						 ntohs(tt_vlan_tmp->vid));
2826 		if (!vlan)
2827 			return false;
2828 
2829 		crc = vlan->tt.crc;
2830 		batadv_orig_node_vlan_put(vlan);
2831 
2832 		if (crc != ntohl(tt_vlan_tmp->crc))
2833 			return false;
2834 	}
2835 
2836 	/* check if any excess VLANs exist locally for the originator
2837 	 * which are not mentioned in the TVLV from the originator.
2838 	 */
2839 	rcu_read_lock();
2840 	orig_num_vlan = 0;
2841 	hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list)
2842 		orig_num_vlan++;
2843 	rcu_read_unlock();
2844 
2845 	if (orig_num_vlan > num_vlan)
2846 		return false;
2847 
2848 	return true;
2849 }
2850 
2851 /**
2852  * batadv_tt_local_update_crc() - update all the local CRCs
2853  * @bat_priv: the bat priv with all the mesh interface information
2854  */
batadv_tt_local_update_crc(struct batadv_priv * bat_priv)2855 static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv)
2856 {
2857 	struct batadv_meshif_vlan *vlan;
2858 
2859 	/* recompute the global CRC for each VLAN */
2860 	rcu_read_lock();
2861 	hlist_for_each_entry_rcu(vlan, &bat_priv->meshif_vlan_list, list) {
2862 		vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid);
2863 	}
2864 	rcu_read_unlock();
2865 }
2866 
2867 /**
2868  * batadv_tt_global_update_crc() - update all the global CRCs for this orig_node
2869  * @bat_priv: the bat priv with all the mesh interface information
2870  * @orig_node: the orig_node for which the CRCs have to be updated
2871  */
batadv_tt_global_update_crc(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)2872 static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv,
2873 					struct batadv_orig_node *orig_node)
2874 {
2875 	struct batadv_orig_node_vlan *vlan;
2876 	u32 crc;
2877 
2878 	/* recompute the global CRC for each VLAN */
2879 	rcu_read_lock();
2880 	hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
2881 		/* if orig_node is a backbone node for this VLAN, don't compute
2882 		 * the CRC as we ignore all the global entries over it
2883 		 */
2884 		if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig,
2885 						   vlan->vid))
2886 			continue;
2887 
2888 		crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid);
2889 		vlan->tt.crc = crc;
2890 	}
2891 	rcu_read_unlock();
2892 }
2893 
2894 /**
2895  * batadv_send_tt_request() - send a TT Request message to a given node
2896  * @bat_priv: the bat priv with all the mesh interface information
2897  * @dst_orig_node: the destination of the message
2898  * @ttvn: the version number that the source of the message is looking for
2899  * @tt_vlan: pointer to the first tvlv VLAN object to request
2900  * @num_vlan: number of tvlv VLAN entries
2901  * @full_table: ask for the entire translation table if true, while only for the
2902  *  last TT diff otherwise
2903  *
2904  * Return: true if the TT Request was sent, false otherwise
2905  */
batadv_send_tt_request(struct batadv_priv * bat_priv,struct batadv_orig_node * dst_orig_node,u8 ttvn,struct batadv_tvlv_tt_vlan_data * tt_vlan,u16 num_vlan,bool full_table)2906 static bool batadv_send_tt_request(struct batadv_priv *bat_priv,
2907 				   struct batadv_orig_node *dst_orig_node,
2908 				   u8 ttvn,
2909 				   struct batadv_tvlv_tt_vlan_data *tt_vlan,
2910 				   u16 num_vlan, bool full_table)
2911 {
2912 	struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2913 	struct batadv_tt_req_node *tt_req_node = NULL;
2914 	struct batadv_hard_iface *primary_if;
2915 	bool ret = false;
2916 	int i, size;
2917 
2918 	primary_if = batadv_primary_if_get_selected(bat_priv);
2919 	if (!primary_if)
2920 		goto out;
2921 
2922 	/* The new tt_req will be issued only if I'm not waiting for a
2923 	 * reply from the same orig_node yet
2924 	 */
2925 	tt_req_node = batadv_tt_req_node_new(bat_priv, dst_orig_node);
2926 	if (!tt_req_node)
2927 		goto out;
2928 
2929 	size = struct_size(tvlv_tt_data, vlan_data, num_vlan);
2930 	tvlv_tt_data = kzalloc(size, GFP_ATOMIC);
2931 	if (!tvlv_tt_data)
2932 		goto out;
2933 
2934 	tvlv_tt_data->flags = BATADV_TT_REQUEST;
2935 	tvlv_tt_data->ttvn = ttvn;
2936 	tvlv_tt_data->num_vlan = htons(num_vlan);
2937 
2938 	/* send all the CRCs within the request. This is needed by intermediate
2939 	 * nodes to ensure they have the correct table before replying
2940 	 */
2941 	for (i = 0; i < num_vlan; i++) {
2942 		tvlv_tt_data->vlan_data[i].vid = tt_vlan->vid;
2943 		tvlv_tt_data->vlan_data[i].crc = tt_vlan->crc;
2944 
2945 		tt_vlan++;
2946 	}
2947 
2948 	if (full_table)
2949 		tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2950 
2951 	batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
2952 		   dst_orig_node->orig, full_table ? 'F' : '.');
2953 
2954 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
2955 	batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2956 				 dst_orig_node->orig, BATADV_TVLV_TT, 1,
2957 				 tvlv_tt_data, size);
2958 	ret = true;
2959 
2960 out:
2961 	batadv_hardif_put(primary_if);
2962 
2963 	if (ret && tt_req_node) {
2964 		spin_lock_bh(&bat_priv->tt.req_list_lock);
2965 		if (!hlist_unhashed(&tt_req_node->list)) {
2966 			hlist_del_init(&tt_req_node->list);
2967 			batadv_tt_req_node_put(tt_req_node);
2968 		}
2969 		spin_unlock_bh(&bat_priv->tt.req_list_lock);
2970 	}
2971 
2972 	batadv_tt_req_node_put(tt_req_node);
2973 
2974 	kfree(tvlv_tt_data);
2975 	return ret;
2976 }
2977 
2978 /**
2979  * batadv_send_other_tt_response() - send reply to tt request concerning another
2980  *  node's translation table
2981  * @bat_priv: the bat priv with all the mesh interface information
2982  * @tt_data: tt data containing the tt request information
2983  * @req_src: mac address of tt request sender
2984  * @req_dst: mac address of tt request recipient
2985  *
2986  * Return: true if tt request reply was sent, false otherwise.
2987  */
batadv_send_other_tt_response(struct batadv_priv * bat_priv,struct batadv_tvlv_tt_data * tt_data,u8 * req_src,u8 * req_dst)2988 static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
2989 					  struct batadv_tvlv_tt_data *tt_data,
2990 					  u8 *req_src, u8 *req_dst)
2991 {
2992 	struct batadv_orig_node *req_dst_orig_node;
2993 	struct batadv_orig_node *res_dst_orig_node = NULL;
2994 	struct batadv_tvlv_tt_change *tt_change;
2995 	struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2996 	bool ret = false, full_table;
2997 	u8 orig_ttvn, req_ttvn;
2998 	u16 tvlv_len;
2999 	s32 tt_len;
3000 
3001 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3002 		   "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
3003 		   req_src, tt_data->ttvn, req_dst,
3004 		   ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.'));
3005 
3006 	/* Let's get the orig node of the REAL destination */
3007 	req_dst_orig_node = batadv_orig_hash_find(bat_priv, req_dst);
3008 	if (!req_dst_orig_node)
3009 		goto out;
3010 
3011 	res_dst_orig_node = batadv_orig_hash_find(bat_priv, req_src);
3012 	if (!res_dst_orig_node)
3013 		goto out;
3014 
3015 	orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn);
3016 	req_ttvn = tt_data->ttvn;
3017 
3018 	/* this node doesn't have the requested data */
3019 	if (orig_ttvn != req_ttvn ||
3020 	    !batadv_tt_global_check_crc(req_dst_orig_node, tt_data->vlan_data,
3021 					ntohs(tt_data->num_vlan)))
3022 		goto out;
3023 
3024 	/* If the full table has been explicitly requested */
3025 	if (tt_data->flags & BATADV_TT_FULL_TABLE ||
3026 	    !req_dst_orig_node->tt_buff)
3027 		full_table = true;
3028 	else
3029 		full_table = false;
3030 
3031 	/* TT fragmentation hasn't been implemented yet, so send as many
3032 	 * TT entries fit a single packet as possible only
3033 	 */
3034 	if (!full_table) {
3035 		spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
3036 		tt_len = req_dst_orig_node->tt_buff_len;
3037 
3038 		tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
3039 							      &tvlv_tt_data,
3040 							      &tt_change,
3041 							      &tt_len);
3042 		if (!tt_len)
3043 			goto unlock;
3044 
3045 		/* Copy the last orig_node's OGM buffer */
3046 		memcpy(tt_change, req_dst_orig_node->tt_buff,
3047 		       req_dst_orig_node->tt_buff_len);
3048 		spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
3049 	} else {
3050 		/* allocate the tvlv, put the tt_data and all the tt_vlan_data
3051 		 * in the initial part
3052 		 */
3053 		tt_len = -1;
3054 		tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
3055 							      &tvlv_tt_data,
3056 							      &tt_change,
3057 							      &tt_len);
3058 		if (!tt_len)
3059 			goto out;
3060 
3061 		/* fill the rest of the tvlv with the real TT entries */
3062 		tvlv_len -= batadv_tt_tvlv_generate(bat_priv,
3063 						    bat_priv->tt.global_hash,
3064 						    tt_change, tt_len,
3065 						    batadv_tt_global_valid,
3066 						    req_dst_orig_node);
3067 	}
3068 
3069 	/* Don't send the response, if larger than fragmented packet. */
3070 	tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
3071 	if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
3072 		net_ratelimited_function(batadv_info, bat_priv->mesh_iface,
3073 					 "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
3074 					 res_dst_orig_node->orig);
3075 		goto out;
3076 	}
3077 
3078 	tvlv_tt_data->flags = BATADV_TT_RESPONSE;
3079 	tvlv_tt_data->ttvn = req_ttvn;
3080 
3081 	if (full_table)
3082 		tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
3083 
3084 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3085 		   "Sending TT_RESPONSE %pM for %pM [%c] (ttvn: %u)\n",
3086 		   res_dst_orig_node->orig, req_dst_orig_node->orig,
3087 		   full_table ? 'F' : '.', req_ttvn);
3088 
3089 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
3090 
3091 	batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig,
3092 				 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
3093 				 tvlv_len);
3094 
3095 	ret = true;
3096 	goto out;
3097 
3098 unlock:
3099 	spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
3100 
3101 out:
3102 	batadv_orig_node_put(res_dst_orig_node);
3103 	batadv_orig_node_put(req_dst_orig_node);
3104 	kfree(tvlv_tt_data);
3105 	return ret;
3106 }
3107 
3108 /**
3109  * batadv_send_my_tt_response() - send reply to tt request concerning this
3110  *  node's translation table
3111  * @bat_priv: the bat priv with all the mesh interface information
3112  * @tt_data: tt data containing the tt request information
3113  * @req_src: mac address of tt request sender
3114  *
3115  * Return: true if tt request reply was sent, false otherwise.
3116  */
batadv_send_my_tt_response(struct batadv_priv * bat_priv,struct batadv_tvlv_tt_data * tt_data,u8 * req_src)3117 static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
3118 				       struct batadv_tvlv_tt_data *tt_data,
3119 				       u8 *req_src)
3120 {
3121 	struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
3122 	struct batadv_hard_iface *primary_if = NULL;
3123 	struct batadv_tvlv_tt_change *tt_change;
3124 	struct batadv_orig_node *orig_node;
3125 	u8 my_ttvn, req_ttvn;
3126 	u16 tvlv_len;
3127 	bool full_table;
3128 	s32 tt_len;
3129 
3130 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3131 		   "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
3132 		   req_src, tt_data->ttvn,
3133 		   ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.'));
3134 
3135 	spin_lock_bh(&bat_priv->tt.commit_lock);
3136 
3137 	my_ttvn = (u8)atomic_read(&bat_priv->tt.vn);
3138 	req_ttvn = tt_data->ttvn;
3139 
3140 	orig_node = batadv_orig_hash_find(bat_priv, req_src);
3141 	if (!orig_node)
3142 		goto out;
3143 
3144 	primary_if = batadv_primary_if_get_selected(bat_priv);
3145 	if (!primary_if)
3146 		goto out;
3147 
3148 	/* If the full table has been explicitly requested or the gap
3149 	 * is too big send the whole local translation table
3150 	 */
3151 	if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
3152 	    !bat_priv->tt.last_changeset)
3153 		full_table = true;
3154 	else
3155 		full_table = false;
3156 
3157 	/* TT fragmentation hasn't been implemented yet, so send as many
3158 	 * TT entries fit a single packet as possible only
3159 	 */
3160 	if (!full_table) {
3161 		spin_lock_bh(&bat_priv->tt.last_changeset_lock);
3162 
3163 		tt_len = bat_priv->tt.last_changeset_len;
3164 		tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
3165 							     &tvlv_tt_data,
3166 							     &tt_change,
3167 							     &tt_len);
3168 		if (!tt_len || !tvlv_len)
3169 			goto unlock;
3170 
3171 		/* Copy the last orig_node's OGM buffer */
3172 		memcpy(tt_change, bat_priv->tt.last_changeset,
3173 		       bat_priv->tt.last_changeset_len);
3174 		spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
3175 	} else {
3176 		req_ttvn = (u8)atomic_read(&bat_priv->tt.vn);
3177 
3178 		/* allocate the tvlv, put the tt_data and all the tt_vlan_data
3179 		 * in the initial part
3180 		 */
3181 		tt_len = -1;
3182 		tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
3183 							     &tvlv_tt_data,
3184 							     &tt_change,
3185 							     &tt_len);
3186 		if (!tt_len || !tvlv_len)
3187 			goto out;
3188 
3189 		/* fill the rest of the tvlv with the real TT entries */
3190 		tvlv_len -= batadv_tt_tvlv_generate(bat_priv,
3191 						    bat_priv->tt.local_hash,
3192 						    tt_change, tt_len,
3193 						    batadv_tt_local_valid,
3194 						    NULL);
3195 	}
3196 
3197 	tvlv_tt_data->flags = BATADV_TT_RESPONSE;
3198 	tvlv_tt_data->ttvn = req_ttvn;
3199 
3200 	if (full_table)
3201 		tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
3202 
3203 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3204 		   "Sending TT_RESPONSE to %pM [%c] (ttvn: %u)\n",
3205 		   orig_node->orig, full_table ? 'F' : '.', req_ttvn);
3206 
3207 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
3208 
3209 	batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
3210 				 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
3211 				 tvlv_len);
3212 
3213 	goto out;
3214 
3215 unlock:
3216 	spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
3217 out:
3218 	spin_unlock_bh(&bat_priv->tt.commit_lock);
3219 	batadv_orig_node_put(orig_node);
3220 	batadv_hardif_put(primary_if);
3221 	kfree(tvlv_tt_data);
3222 	/* The packet was for this host, so it doesn't need to be re-routed */
3223 	return true;
3224 }
3225 
3226 /**
3227  * batadv_send_tt_response() - send reply to tt request
3228  * @bat_priv: the bat priv with all the mesh interface information
3229  * @tt_data: tt data containing the tt request information
3230  * @req_src: mac address of tt request sender
3231  * @req_dst: mac address of tt request recipient
3232  *
3233  * Return: true if tt request reply was sent, false otherwise.
3234  */
batadv_send_tt_response(struct batadv_priv * bat_priv,struct batadv_tvlv_tt_data * tt_data,u8 * req_src,u8 * req_dst)3235 static bool batadv_send_tt_response(struct batadv_priv *bat_priv,
3236 				    struct batadv_tvlv_tt_data *tt_data,
3237 				    u8 *req_src, u8 *req_dst)
3238 {
3239 	if (batadv_is_my_mac(bat_priv, req_dst))
3240 		return batadv_send_my_tt_response(bat_priv, tt_data, req_src);
3241 	return batadv_send_other_tt_response(bat_priv, tt_data, req_src,
3242 					     req_dst);
3243 }
3244 
_batadv_tt_update_changes(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,struct batadv_tvlv_tt_change * tt_change,u16 tt_num_changes,u8 ttvn)3245 static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
3246 				      struct batadv_orig_node *orig_node,
3247 				      struct batadv_tvlv_tt_change *tt_change,
3248 				      u16 tt_num_changes, u8 ttvn)
3249 {
3250 	int i;
3251 	int roams;
3252 
3253 	for (i = 0; i < tt_num_changes; i++) {
3254 		if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
3255 			roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
3256 			batadv_tt_global_del(bat_priv, orig_node,
3257 					     (tt_change + i)->addr,
3258 					     ntohs((tt_change + i)->vid),
3259 					     "tt removed by changes",
3260 					     roams);
3261 		} else {
3262 			if (!batadv_tt_global_add(bat_priv, orig_node,
3263 						  (tt_change + i)->addr,
3264 						  ntohs((tt_change + i)->vid),
3265 						  (tt_change + i)->flags, ttvn))
3266 				/* In case of problem while storing a
3267 				 * global_entry, we stop the updating
3268 				 * procedure without committing the
3269 				 * ttvn change. This will avoid to send
3270 				 * corrupted data on tt_request
3271 				 */
3272 				return;
3273 		}
3274 	}
3275 	set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
3276 }
3277 
batadv_tt_fill_gtable(struct batadv_priv * bat_priv,struct batadv_tvlv_tt_change * tt_change,u8 ttvn,u8 * resp_src,u16 num_entries)3278 static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
3279 				  struct batadv_tvlv_tt_change *tt_change,
3280 				  u8 ttvn, u8 *resp_src,
3281 				  u16 num_entries)
3282 {
3283 	struct batadv_orig_node *orig_node;
3284 
3285 	orig_node = batadv_orig_hash_find(bat_priv, resp_src);
3286 	if (!orig_node)
3287 		goto out;
3288 
3289 	/* Purge the old table first.. */
3290 	batadv_tt_global_del_orig(bat_priv, orig_node, -1,
3291 				  "Received full table");
3292 
3293 	_batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
3294 				  ttvn);
3295 
3296 	spin_lock_bh(&orig_node->tt_buff_lock);
3297 	kfree(orig_node->tt_buff);
3298 	orig_node->tt_buff_len = 0;
3299 	orig_node->tt_buff = NULL;
3300 	spin_unlock_bh(&orig_node->tt_buff_lock);
3301 
3302 	atomic_set(&orig_node->last_ttvn, ttvn);
3303 
3304 out:
3305 	batadv_orig_node_put(orig_node);
3306 }
3307 
batadv_tt_update_changes(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,u16 tt_num_changes,u8 ttvn,struct batadv_tvlv_tt_change * tt_change)3308 static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
3309 				     struct batadv_orig_node *orig_node,
3310 				     u16 tt_num_changes, u8 ttvn,
3311 				     struct batadv_tvlv_tt_change *tt_change)
3312 {
3313 	_batadv_tt_update_changes(bat_priv, orig_node, tt_change,
3314 				  tt_num_changes, ttvn);
3315 
3316 	batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
3317 				   batadv_tt_len(tt_num_changes));
3318 	atomic_set(&orig_node->last_ttvn, ttvn);
3319 }
3320 
3321 /**
3322  * batadv_is_my_client() - check if a client is served by the local node
3323  * @bat_priv: the bat priv with all the mesh interface information
3324  * @addr: the mac address of the client to check
3325  * @vid: VLAN identifier
3326  *
3327  * Return: true if the client is served by this node, false otherwise.
3328  */
batadv_is_my_client(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid)3329 bool batadv_is_my_client(struct batadv_priv *bat_priv, const u8 *addr,
3330 			 unsigned short vid)
3331 {
3332 	struct batadv_tt_local_entry *tt_local_entry;
3333 	bool ret = false;
3334 
3335 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
3336 	if (!tt_local_entry)
3337 		goto out;
3338 	/* Check if the client has been logically deleted (but is kept for
3339 	 * consistency purpose)
3340 	 */
3341 	if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
3342 	    (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
3343 		goto out;
3344 	ret = true;
3345 out:
3346 	batadv_tt_local_entry_put(tt_local_entry);
3347 	return ret;
3348 }
3349 
3350 /**
3351  * batadv_handle_tt_response() - process incoming tt reply
3352  * @bat_priv: the bat priv with all the mesh interface information
3353  * @tt_data: tt data containing the tt request information
3354  * @resp_src: mac address of tt reply sender
3355  * @num_entries: number of tt change entries appended to the tt data
3356  */
batadv_handle_tt_response(struct batadv_priv * bat_priv,struct batadv_tvlv_tt_data * tt_data,u8 * resp_src,u16 num_entries)3357 static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
3358 				      struct batadv_tvlv_tt_data *tt_data,
3359 				      u8 *resp_src, u16 num_entries)
3360 {
3361 	struct batadv_tt_req_node *node;
3362 	struct hlist_node *safe;
3363 	struct batadv_orig_node *orig_node = NULL;
3364 	struct batadv_tvlv_tt_change *tt_change;
3365 	u8 *tvlv_ptr = (u8 *)tt_data;
3366 
3367 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3368 		   "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
3369 		   resp_src, tt_data->ttvn, num_entries,
3370 		   ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.'));
3371 
3372 	orig_node = batadv_orig_hash_find(bat_priv, resp_src);
3373 	if (!orig_node)
3374 		goto out;
3375 
3376 	spin_lock_bh(&orig_node->tt_lock);
3377 
3378 	tvlv_ptr += struct_size(tt_data, vlan_data, ntohs(tt_data->num_vlan));
3379 
3380 	tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr;
3381 	if (tt_data->flags & BATADV_TT_FULL_TABLE) {
3382 		batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn,
3383 				      resp_src, num_entries);
3384 	} else {
3385 		batadv_tt_update_changes(bat_priv, orig_node, num_entries,
3386 					 tt_data->ttvn, tt_change);
3387 	}
3388 
3389 	/* Recalculate the CRC for this orig_node and store it */
3390 	batadv_tt_global_update_crc(bat_priv, orig_node);
3391 
3392 	spin_unlock_bh(&orig_node->tt_lock);
3393 
3394 	/* Delete the tt_req_node from pending tt_requests list */
3395 	spin_lock_bh(&bat_priv->tt.req_list_lock);
3396 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
3397 		if (!batadv_compare_eth(node->addr, resp_src))
3398 			continue;
3399 		hlist_del_init(&node->list);
3400 		batadv_tt_req_node_put(node);
3401 	}
3402 
3403 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
3404 out:
3405 	batadv_orig_node_put(orig_node);
3406 }
3407 
batadv_tt_roam_list_free(struct batadv_priv * bat_priv)3408 static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
3409 {
3410 	struct batadv_tt_roam_node *node, *safe;
3411 
3412 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
3413 
3414 	list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
3415 		list_del(&node->list);
3416 		kmem_cache_free(batadv_tt_roam_cache, node);
3417 	}
3418 
3419 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
3420 }
3421 
batadv_tt_roam_purge(struct batadv_priv * bat_priv)3422 static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
3423 {
3424 	struct batadv_tt_roam_node *node, *safe;
3425 
3426 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
3427 	list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
3428 		if (!batadv_has_timed_out(node->first_time,
3429 					  BATADV_ROAMING_MAX_TIME))
3430 			continue;
3431 
3432 		list_del(&node->list);
3433 		kmem_cache_free(batadv_tt_roam_cache, node);
3434 	}
3435 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
3436 }
3437 
3438 /**
3439  * batadv_tt_check_roam_count() - check if a client has roamed too frequently
3440  * @bat_priv: the bat priv with all the mesh interface information
3441  * @client: mac address of the roaming client
3442  *
3443  * This function checks whether the client already reached the
3444  * maximum number of possible roaming phases. In this case the ROAMING_ADV
3445  * will not be sent.
3446  *
3447  * Return: true if the ROAMING_ADV can be sent, false otherwise
3448  */
batadv_tt_check_roam_count(struct batadv_priv * bat_priv,u8 * client)3449 static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, u8 *client)
3450 {
3451 	struct batadv_tt_roam_node *tt_roam_node;
3452 	bool ret = false;
3453 
3454 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
3455 	/* The new tt_req will be issued only if I'm not waiting for a
3456 	 * reply from the same orig_node yet
3457 	 */
3458 	list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
3459 		if (!batadv_compare_eth(tt_roam_node->addr, client))
3460 			continue;
3461 
3462 		if (batadv_has_timed_out(tt_roam_node->first_time,
3463 					 BATADV_ROAMING_MAX_TIME))
3464 			continue;
3465 
3466 		if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter))
3467 			/* Sorry, you roamed too many times! */
3468 			goto unlock;
3469 		ret = true;
3470 		break;
3471 	}
3472 
3473 	if (!ret) {
3474 		tt_roam_node = kmem_cache_alloc(batadv_tt_roam_cache,
3475 						GFP_ATOMIC);
3476 		if (!tt_roam_node)
3477 			goto unlock;
3478 
3479 		tt_roam_node->first_time = jiffies;
3480 		atomic_set(&tt_roam_node->counter,
3481 			   BATADV_ROAMING_MAX_COUNT - 1);
3482 		ether_addr_copy(tt_roam_node->addr, client);
3483 
3484 		list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
3485 		ret = true;
3486 	}
3487 
3488 unlock:
3489 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
3490 	return ret;
3491 }
3492 
3493 /**
3494  * batadv_send_roam_adv() - send a roaming advertisement message
3495  * @bat_priv: the bat priv with all the mesh interface information
3496  * @client: mac address of the roaming client
3497  * @vid: VLAN identifier
3498  * @orig_node: message destination
3499  *
3500  * Send a ROAMING_ADV message to the node which was previously serving this
3501  * client. This is done to inform the node that from now on all traffic destined
3502  * for this particular roamed client has to be forwarded to the sender of the
3503  * roaming message.
3504  */
batadv_send_roam_adv(struct batadv_priv * bat_priv,u8 * client,unsigned short vid,struct batadv_orig_node * orig_node)3505 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, u8 *client,
3506 				 unsigned short vid,
3507 				 struct batadv_orig_node *orig_node)
3508 {
3509 	struct batadv_hard_iface *primary_if;
3510 	struct batadv_tvlv_roam_adv tvlv_roam;
3511 
3512 	primary_if = batadv_primary_if_get_selected(bat_priv);
3513 	if (!primary_if)
3514 		goto out;
3515 
3516 	/* before going on we have to check whether the client has
3517 	 * already roamed to us too many times
3518 	 */
3519 	if (!batadv_tt_check_roam_count(bat_priv, client))
3520 		goto out;
3521 
3522 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3523 		   "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n",
3524 		   orig_node->orig, client, batadv_print_vid(vid));
3525 
3526 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
3527 
3528 	memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
3529 	tvlv_roam.vid = htons(vid);
3530 
3531 	batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
3532 				 orig_node->orig, BATADV_TVLV_ROAM, 1,
3533 				 &tvlv_roam, sizeof(tvlv_roam));
3534 
3535 out:
3536 	batadv_hardif_put(primary_if);
3537 }
3538 
batadv_tt_purge(struct work_struct * work)3539 static void batadv_tt_purge(struct work_struct *work)
3540 {
3541 	struct delayed_work *delayed_work;
3542 	struct batadv_priv_tt *priv_tt;
3543 	struct batadv_priv *bat_priv;
3544 
3545 	delayed_work = to_delayed_work(work);
3546 	priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
3547 	bat_priv = container_of(priv_tt, struct batadv_priv, tt);
3548 
3549 	batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT);
3550 	batadv_tt_global_purge(bat_priv);
3551 	batadv_tt_req_purge(bat_priv);
3552 	batadv_tt_roam_purge(bat_priv);
3553 
3554 	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
3555 			   msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
3556 }
3557 
3558 /**
3559  * batadv_tt_free() - Free translation table of mesh interface
3560  * @bat_priv: the bat priv with all the mesh interface information
3561  */
batadv_tt_free(struct batadv_priv * bat_priv)3562 void batadv_tt_free(struct batadv_priv *bat_priv)
3563 {
3564 	batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_ROAM, 1);
3565 
3566 	batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
3567 	batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
3568 
3569 	cancel_delayed_work_sync(&bat_priv->tt.work);
3570 
3571 	batadv_tt_local_table_free(bat_priv);
3572 	batadv_tt_global_table_free(bat_priv);
3573 	batadv_tt_req_list_free(bat_priv);
3574 	batadv_tt_changes_list_free(bat_priv);
3575 	batadv_tt_roam_list_free(bat_priv);
3576 
3577 	kfree(bat_priv->tt.last_changeset);
3578 }
3579 
3580 /**
3581  * batadv_tt_local_set_flags() - set or unset the specified flags on the local
3582  *  table and possibly count them in the TT size
3583  * @bat_priv: the bat priv with all the mesh interface information
3584  * @flags: the flag to switch
3585  * @enable: whether to set or unset the flag
3586  * @count: whether to increase the TT size by the number of changed entries
3587  */
batadv_tt_local_set_flags(struct batadv_priv * bat_priv,u16 flags,bool enable,bool count)3588 static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv, u16 flags,
3589 				      bool enable, bool count)
3590 {
3591 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
3592 	struct batadv_tt_common_entry *tt_common_entry;
3593 	struct hlist_head *head;
3594 	u32 i;
3595 
3596 	if (!hash)
3597 		return;
3598 
3599 	for (i = 0; i < hash->size; i++) {
3600 		head = &hash->table[i];
3601 
3602 		rcu_read_lock();
3603 		hlist_for_each_entry_rcu(tt_common_entry,
3604 					 head, hash_entry) {
3605 			if (enable) {
3606 				if ((tt_common_entry->flags & flags) == flags)
3607 					continue;
3608 				tt_common_entry->flags |= flags;
3609 			} else {
3610 				if (!(tt_common_entry->flags & flags))
3611 					continue;
3612 				tt_common_entry->flags &= ~flags;
3613 			}
3614 
3615 			if (!count)
3616 				continue;
3617 
3618 			batadv_tt_local_size_inc(bat_priv,
3619 						 tt_common_entry->vid);
3620 		}
3621 		rcu_read_unlock();
3622 	}
3623 }
3624 
3625 /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
batadv_tt_local_purge_pending_clients(struct batadv_priv * bat_priv)3626 static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
3627 {
3628 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
3629 	struct batadv_tt_common_entry *tt_common;
3630 	struct batadv_tt_local_entry *tt_local;
3631 	struct hlist_node *node_tmp;
3632 	struct hlist_head *head;
3633 	spinlock_t *list_lock; /* protects write access to the hash lists */
3634 	u32 i;
3635 
3636 	if (!hash)
3637 		return;
3638 
3639 	for (i = 0; i < hash->size; i++) {
3640 		head = &hash->table[i];
3641 		list_lock = &hash->list_locks[i];
3642 
3643 		spin_lock_bh(list_lock);
3644 		hlist_for_each_entry_safe(tt_common, node_tmp, head,
3645 					  hash_entry) {
3646 			if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
3647 				continue;
3648 
3649 			batadv_dbg(BATADV_DBG_TT, bat_priv,
3650 				   "Deleting local tt entry (%pM, vid: %d): pending\n",
3651 				   tt_common->addr,
3652 				   batadv_print_vid(tt_common->vid));
3653 
3654 			batadv_tt_local_size_dec(bat_priv, tt_common->vid);
3655 			hlist_del_rcu(&tt_common->hash_entry);
3656 			tt_local = container_of(tt_common,
3657 						struct batadv_tt_local_entry,
3658 						common);
3659 
3660 			batadv_tt_local_entry_put(tt_local);
3661 		}
3662 		spin_unlock_bh(list_lock);
3663 	}
3664 }
3665 
3666 /**
3667  * batadv_tt_local_commit_changes_nolock() - commit all pending local tt changes
3668  *  which have been queued in the time since the last commit
3669  * @bat_priv: the bat priv with all the mesh interface information
3670  *
3671  * Caller must hold tt->commit_lock.
3672  */
batadv_tt_local_commit_changes_nolock(struct batadv_priv * bat_priv)3673 static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
3674 {
3675 	lockdep_assert_held(&bat_priv->tt.commit_lock);
3676 
3677 	if (READ_ONCE(bat_priv->tt.local_changes) == 0) {
3678 		if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
3679 			batadv_tt_tvlv_container_update(bat_priv);
3680 		return;
3681 	}
3682 
3683 	batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
3684 
3685 	batadv_tt_local_purge_pending_clients(bat_priv);
3686 	batadv_tt_local_update_crc(bat_priv);
3687 
3688 	/* Increment the TTVN only once per OGM interval */
3689 	atomic_inc(&bat_priv->tt.vn);
3690 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3691 		   "Local changes committed, updating to ttvn %u\n",
3692 		   (u8)atomic_read(&bat_priv->tt.vn));
3693 
3694 	/* reset the sending counter */
3695 	atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
3696 	batadv_tt_tvlv_container_update(bat_priv);
3697 }
3698 
3699 /**
3700  * batadv_tt_local_commit_changes() - commit all pending local tt changes which
3701  *  have been queued in the time since the last commit
3702  * @bat_priv: the bat priv with all the mesh interface information
3703  */
batadv_tt_local_commit_changes(struct batadv_priv * bat_priv)3704 void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
3705 {
3706 	spin_lock_bh(&bat_priv->tt.commit_lock);
3707 	batadv_tt_local_commit_changes_nolock(bat_priv);
3708 	spin_unlock_bh(&bat_priv->tt.commit_lock);
3709 }
3710 
3711 /**
3712  * batadv_is_ap_isolated() - Check if packet from upper layer should be dropped
3713  * @bat_priv: the bat priv with all the mesh interface information
3714  * @src: source mac address of packet
3715  * @dst: destination mac address of packet
3716  * @vid: vlan id of packet
3717  *
3718  * Return: true when src+dst(+vid) pair should be isolated, false otherwise
3719  */
batadv_is_ap_isolated(struct batadv_priv * bat_priv,u8 * src,u8 * dst,unsigned short vid)3720 bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, u8 *src, u8 *dst,
3721 			   unsigned short vid)
3722 {
3723 	struct batadv_tt_local_entry *tt_local_entry;
3724 	struct batadv_tt_global_entry *tt_global_entry;
3725 	struct batadv_meshif_vlan *vlan;
3726 	bool ret = false;
3727 
3728 	vlan = batadv_meshif_vlan_get(bat_priv, vid);
3729 	if (!vlan)
3730 		return false;
3731 
3732 	if (!atomic_read(&vlan->ap_isolation))
3733 		goto vlan_put;
3734 
3735 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
3736 	if (!tt_local_entry)
3737 		goto vlan_put;
3738 
3739 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
3740 	if (!tt_global_entry)
3741 		goto local_entry_put;
3742 
3743 	if (_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
3744 		ret = true;
3745 
3746 	batadv_tt_global_entry_put(tt_global_entry);
3747 local_entry_put:
3748 	batadv_tt_local_entry_put(tt_local_entry);
3749 vlan_put:
3750 	batadv_meshif_vlan_put(vlan);
3751 	return ret;
3752 }
3753 
3754 /**
3755  * batadv_tt_update_orig() - update global translation table with new tt
3756  *  information received via ogms
3757  * @bat_priv: the bat priv with all the mesh interface information
3758  * @orig_node: the orig_node of the ogm
3759  * @tt_buff: pointer to the first tvlv VLAN entry
3760  * @tt_num_vlan: number of tvlv VLAN entries
3761  * @tt_change: pointer to the first entry in the TT buffer
3762  * @tt_num_changes: number of tt changes inside the tt buffer
3763  * @ttvn: translation table version number of this changeset
3764  */
batadv_tt_update_orig(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const void * tt_buff,u16 tt_num_vlan,struct batadv_tvlv_tt_change * tt_change,u16 tt_num_changes,u8 ttvn)3765 static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
3766 				  struct batadv_orig_node *orig_node,
3767 				  const void *tt_buff, u16 tt_num_vlan,
3768 				  struct batadv_tvlv_tt_change *tt_change,
3769 				  u16 tt_num_changes, u8 ttvn)
3770 {
3771 	u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn);
3772 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
3773 	bool full_table = true;
3774 	bool has_tt_init;
3775 
3776 	tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
3777 	has_tt_init = test_bit(BATADV_ORIG_CAPA_HAS_TT,
3778 			       &orig_node->capa_initialized);
3779 
3780 	/* orig table not initialised AND first diff is in the OGM OR the ttvn
3781 	 * increased by one -> we can apply the attached changes
3782 	 */
3783 	if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) {
3784 		/* the OGM could not contain the changes due to their size or
3785 		 * because they have already been sent BATADV_TT_OGM_APPEND_MAX
3786 		 * times.
3787 		 * In this case send a tt request
3788 		 */
3789 		if (!tt_num_changes) {
3790 			full_table = false;
3791 			goto request_table;
3792 		}
3793 
3794 		spin_lock_bh(&orig_node->tt_lock);
3795 
3796 		batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
3797 					 ttvn, tt_change);
3798 
3799 		/* Even if we received the precomputed crc with the OGM, we
3800 		 * prefer to recompute it to spot any possible inconsistency
3801 		 * in the global table
3802 		 */
3803 		batadv_tt_global_update_crc(bat_priv, orig_node);
3804 
3805 		spin_unlock_bh(&orig_node->tt_lock);
3806 
3807 		/* The ttvn alone is not enough to guarantee consistency
3808 		 * because a single value could represent different states
3809 		 * (due to the wrap around). Thus a node has to check whether
3810 		 * the resulting table (after applying the changes) is still
3811 		 * consistent or not. E.g. a node could disconnect while its
3812 		 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
3813 		 * checking the CRC value is mandatory to detect the
3814 		 * inconsistency
3815 		 */
3816 		if (!batadv_tt_global_check_crc(orig_node, tt_vlan,
3817 						tt_num_vlan))
3818 			goto request_table;
3819 	} else {
3820 		/* if we missed more than one change or our tables are not
3821 		 * in sync anymore -> request fresh tt data
3822 		 */
3823 		if (!has_tt_init || ttvn != orig_ttvn ||
3824 		    !batadv_tt_global_check_crc(orig_node, tt_vlan,
3825 						tt_num_vlan)) {
3826 request_table:
3827 			batadv_dbg(BATADV_DBG_TT, bat_priv,
3828 				   "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n",
3829 				   orig_node->orig, ttvn, orig_ttvn,
3830 				   tt_num_changes);
3831 			batadv_send_tt_request(bat_priv, orig_node, ttvn,
3832 					       tt_vlan, tt_num_vlan,
3833 					       full_table);
3834 			return;
3835 		}
3836 	}
3837 }
3838 
3839 /**
3840  * batadv_tt_global_client_is_roaming() - check if a client is marked as roaming
3841  * @bat_priv: the bat priv with all the mesh interface information
3842  * @addr: the mac address of the client to check
3843  * @vid: VLAN identifier
3844  *
3845  * Return: true if we know that the client has moved from its old originator
3846  * to another one. This entry is still kept for consistency purposes and will be
3847  * deleted later by a DEL or because of timeout
3848  */
batadv_tt_global_client_is_roaming(struct batadv_priv * bat_priv,u8 * addr,unsigned short vid)3849 bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
3850 					u8 *addr, unsigned short vid)
3851 {
3852 	struct batadv_tt_global_entry *tt_global_entry;
3853 	bool ret = false;
3854 
3855 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
3856 	if (!tt_global_entry)
3857 		goto out;
3858 
3859 	ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
3860 	batadv_tt_global_entry_put(tt_global_entry);
3861 out:
3862 	return ret;
3863 }
3864 
3865 /**
3866  * batadv_tt_local_client_is_roaming() - tells whether the client is roaming
3867  * @bat_priv: the bat priv with all the mesh interface information
3868  * @addr: the mac address of the local client to query
3869  * @vid: VLAN identifier
3870  *
3871  * Return: true if the local client is known to be roaming (it is not served by
3872  * this node anymore) or not. If yes, the client is still present in the table
3873  * to keep the latter consistent with the node TTVN
3874  */
batadv_tt_local_client_is_roaming(struct batadv_priv * bat_priv,u8 * addr,unsigned short vid)3875 bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
3876 				       u8 *addr, unsigned short vid)
3877 {
3878 	struct batadv_tt_local_entry *tt_local_entry;
3879 	bool ret = false;
3880 
3881 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
3882 	if (!tt_local_entry)
3883 		goto out;
3884 
3885 	ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
3886 	batadv_tt_local_entry_put(tt_local_entry);
3887 out:
3888 	return ret;
3889 }
3890 
3891 /**
3892  * batadv_tt_add_temporary_global_entry() - Add temporary entry to global TT
3893  * @bat_priv: the bat priv with all the mesh interface information
3894  * @orig_node: orig node which the temporary entry should be associated with
3895  * @addr: mac address of the client
3896  * @vid: VLAN id of the new temporary global translation table
3897  *
3898  * Return: true when temporary tt entry could be added, false otherwise
3899  */
batadv_tt_add_temporary_global_entry(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * addr,unsigned short vid)3900 bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
3901 					  struct batadv_orig_node *orig_node,
3902 					  const unsigned char *addr,
3903 					  unsigned short vid)
3904 {
3905 	/* ignore loop detect macs, they are not supposed to be in the tt local
3906 	 * data as well.
3907 	 */
3908 	if (batadv_bla_is_loopdetect_mac(addr))
3909 		return false;
3910 
3911 	if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
3912 				  BATADV_TT_CLIENT_TEMP,
3913 				  atomic_read(&orig_node->last_ttvn)))
3914 		return false;
3915 
3916 	batadv_dbg(BATADV_DBG_TT, bat_priv,
3917 		   "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n",
3918 		   addr, batadv_print_vid(vid), orig_node->orig);
3919 
3920 	return true;
3921 }
3922 
3923 /**
3924  * batadv_tt_local_resize_to_mtu() - resize the local translation table fit the
3925  *  maximum packet size that can be transported through the mesh
3926  * @mesh_iface: netdev struct of the mesh interface
3927  *
3928  * Remove entries older than 'timeout' and half timeout if more entries need
3929  * to be removed.
3930  */
batadv_tt_local_resize_to_mtu(struct net_device * mesh_iface)3931 void batadv_tt_local_resize_to_mtu(struct net_device *mesh_iface)
3932 {
3933 	struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
3934 	int packet_size_max = atomic_read(&bat_priv->packet_size_max);
3935 	int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
3936 	bool reduced = false;
3937 
3938 	spin_lock_bh(&bat_priv->tt.commit_lock);
3939 
3940 	while (timeout) {
3941 		table_size = batadv_tt_local_table_transmit_size(bat_priv);
3942 		if (packet_size_max >= table_size)
3943 			break;
3944 
3945 		batadv_tt_local_purge(bat_priv, timeout);
3946 		batadv_tt_local_purge_pending_clients(bat_priv);
3947 
3948 		timeout /= 2;
3949 		reduced = true;
3950 		net_ratelimited_function(batadv_info, mesh_iface,
3951 					 "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
3952 					 packet_size_max);
3953 	}
3954 
3955 	/* commit these changes immediately, to avoid synchronization problem
3956 	 * with the TTVN
3957 	 */
3958 	if (reduced)
3959 		batadv_tt_local_commit_changes_nolock(bat_priv);
3960 
3961 	spin_unlock_bh(&bat_priv->tt.commit_lock);
3962 }
3963 
3964 /**
3965  * batadv_tt_tvlv_ogm_handler_v1() - process incoming tt tvlv container
3966  * @bat_priv: the bat priv with all the mesh interface information
3967  * @orig: the orig_node of the ogm
3968  * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
3969  * @tvlv_value: tvlv buffer containing the gateway data
3970  * @tvlv_value_len: tvlv buffer length
3971  */
batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv * bat_priv,struct batadv_orig_node * orig,u8 flags,void * tvlv_value,u16 tvlv_value_len)3972 static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
3973 					  struct batadv_orig_node *orig,
3974 					  u8 flags, void *tvlv_value,
3975 					  u16 tvlv_value_len)
3976 {
3977 	struct batadv_tvlv_tt_change *tt_change;
3978 	struct batadv_tvlv_tt_data *tt_data;
3979 	u16 num_entries, num_vlan;
3980 	size_t tt_data_sz;
3981 
3982 	if (tvlv_value_len < sizeof(*tt_data))
3983 		return;
3984 
3985 	tt_data = tvlv_value;
3986 	num_vlan = ntohs(tt_data->num_vlan);
3987 
3988 	tt_data_sz = struct_size(tt_data, vlan_data, num_vlan);
3989 	if (tvlv_value_len < tt_data_sz)
3990 		return;
3991 
3992 	tt_change = (struct batadv_tvlv_tt_change *)((void *)tt_data
3993 						     + tt_data_sz);
3994 	tvlv_value_len -= tt_data_sz;
3995 
3996 	num_entries = batadv_tt_entries(tvlv_value_len);
3997 
3998 	batadv_tt_update_orig(bat_priv, orig, tt_data->vlan_data, num_vlan,
3999 			      tt_change, num_entries, tt_data->ttvn);
4000 }
4001 
4002 /**
4003  * batadv_tt_tvlv_unicast_handler_v1() - process incoming (unicast) tt tvlv
4004  *  container
4005  * @bat_priv: the bat priv with all the mesh interface information
4006  * @src: mac address of tt tvlv sender
4007  * @dst: mac address of tt tvlv recipient
4008  * @tvlv_value: tvlv buffer containing the tt data
4009  * @tvlv_value_len: tvlv buffer length
4010  *
4011  * Return: NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
4012  * otherwise.
4013  */
batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv * bat_priv,u8 * src,u8 * dst,void * tvlv_value,u16 tvlv_value_len)4014 static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
4015 					     u8 *src, u8 *dst,
4016 					     void *tvlv_value,
4017 					     u16 tvlv_value_len)
4018 {
4019 	struct batadv_tvlv_tt_data *tt_data;
4020 	u16 tt_vlan_len, tt_num_entries;
4021 	char tt_flag;
4022 	bool ret;
4023 
4024 	if (tvlv_value_len < sizeof(*tt_data))
4025 		return NET_RX_SUCCESS;
4026 
4027 	tt_data = tvlv_value;
4028 	tvlv_value_len -= sizeof(*tt_data);
4029 
4030 	tt_vlan_len = flex_array_size(tt_data, vlan_data,
4031 				      ntohs(tt_data->num_vlan));
4032 
4033 	if (tvlv_value_len < tt_vlan_len)
4034 		return NET_RX_SUCCESS;
4035 
4036 	tvlv_value_len -= tt_vlan_len;
4037 	tt_num_entries = batadv_tt_entries(tvlv_value_len);
4038 
4039 	switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) {
4040 	case BATADV_TT_REQUEST:
4041 		batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX);
4042 
4043 		/* If this node cannot provide a TT response the tt_request is
4044 		 * forwarded
4045 		 */
4046 		ret = batadv_send_tt_response(bat_priv, tt_data, src, dst);
4047 		if (!ret) {
4048 			if (tt_data->flags & BATADV_TT_FULL_TABLE)
4049 				tt_flag = 'F';
4050 			else
4051 				tt_flag = '.';
4052 
4053 			batadv_dbg(BATADV_DBG_TT, bat_priv,
4054 				   "Routing TT_REQUEST to %pM [%c]\n",
4055 				   dst, tt_flag);
4056 			/* tvlv API will re-route the packet */
4057 			return NET_RX_DROP;
4058 		}
4059 		break;
4060 	case BATADV_TT_RESPONSE:
4061 		batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
4062 
4063 		if (batadv_is_my_mac(bat_priv, dst)) {
4064 			batadv_handle_tt_response(bat_priv, tt_data,
4065 						  src, tt_num_entries);
4066 			return NET_RX_SUCCESS;
4067 		}
4068 
4069 		if (tt_data->flags & BATADV_TT_FULL_TABLE)
4070 			tt_flag =  'F';
4071 		else
4072 			tt_flag = '.';
4073 
4074 		batadv_dbg(BATADV_DBG_TT, bat_priv,
4075 			   "Routing TT_RESPONSE to %pM [%c]\n", dst, tt_flag);
4076 
4077 		/* tvlv API will re-route the packet */
4078 		return NET_RX_DROP;
4079 	}
4080 
4081 	return NET_RX_SUCCESS;
4082 }
4083 
4084 /**
4085  * batadv_roam_tvlv_unicast_handler_v1() - process incoming tt roam tvlv
4086  *  container
4087  * @bat_priv: the bat priv with all the mesh interface information
4088  * @src: mac address of tt tvlv sender
4089  * @dst: mac address of tt tvlv recipient
4090  * @tvlv_value: tvlv buffer containing the tt data
4091  * @tvlv_value_len: tvlv buffer length
4092  *
4093  * Return: NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
4094  * otherwise.
4095  */
batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv * bat_priv,u8 * src,u8 * dst,void * tvlv_value,u16 tvlv_value_len)4096 static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
4097 					       u8 *src, u8 *dst,
4098 					       void *tvlv_value,
4099 					       u16 tvlv_value_len)
4100 {
4101 	struct batadv_tvlv_roam_adv *roaming_adv;
4102 	struct batadv_orig_node *orig_node = NULL;
4103 
4104 	/* If this node is not the intended recipient of the
4105 	 * roaming advertisement the packet is forwarded
4106 	 * (the tvlv API will re-route the packet).
4107 	 */
4108 	if (!batadv_is_my_mac(bat_priv, dst))
4109 		return NET_RX_DROP;
4110 
4111 	if (tvlv_value_len < sizeof(*roaming_adv))
4112 		goto out;
4113 
4114 	orig_node = batadv_orig_hash_find(bat_priv, src);
4115 	if (!orig_node)
4116 		goto out;
4117 
4118 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
4119 	roaming_adv = tvlv_value;
4120 
4121 	batadv_dbg(BATADV_DBG_TT, bat_priv,
4122 		   "Received ROAMING_ADV from %pM (client %pM)\n",
4123 		   src, roaming_adv->client);
4124 
4125 	batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
4126 			     ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
4127 			     atomic_read(&orig_node->last_ttvn) + 1);
4128 
4129 out:
4130 	batadv_orig_node_put(orig_node);
4131 	return NET_RX_SUCCESS;
4132 }
4133 
4134 /**
4135  * batadv_tt_init() - initialise the translation table internals
4136  * @bat_priv: the bat priv with all the mesh interface information
4137  *
4138  * Return: 0 on success or negative error number in case of failure.
4139  */
batadv_tt_init(struct batadv_priv * bat_priv)4140 int batadv_tt_init(struct batadv_priv *bat_priv)
4141 {
4142 	int ret;
4143 
4144 	/* synchronized flags must be remote */
4145 	BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK));
4146 
4147 	ret = batadv_tt_local_init(bat_priv);
4148 	if (ret < 0)
4149 		return ret;
4150 
4151 	ret = batadv_tt_global_init(bat_priv);
4152 	if (ret < 0) {
4153 		batadv_tt_local_table_free(bat_priv);
4154 		return ret;
4155 	}
4156 
4157 	batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
4158 				     batadv_tt_tvlv_unicast_handler_v1, NULL,
4159 				     BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
4160 
4161 	batadv_tvlv_handler_register(bat_priv, NULL,
4162 				     batadv_roam_tvlv_unicast_handler_v1, NULL,
4163 				     BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
4164 
4165 	INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
4166 	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
4167 			   msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
4168 
4169 	return 1;
4170 }
4171 
4172 /**
4173  * batadv_tt_global_is_isolated() - check if a client is marked as isolated
4174  * @bat_priv: the bat priv with all the mesh interface information
4175  * @addr: the mac address of the client
4176  * @vid: the identifier of the VLAN where this client is connected
4177  *
4178  * Return: true if the client is marked with the TT_CLIENT_ISOLA flag, false
4179  * otherwise
4180  */
batadv_tt_global_is_isolated(struct batadv_priv * bat_priv,const u8 * addr,unsigned short vid)4181 bool batadv_tt_global_is_isolated(struct batadv_priv *bat_priv,
4182 				  const u8 *addr, unsigned short vid)
4183 {
4184 	struct batadv_tt_global_entry *tt;
4185 	bool ret;
4186 
4187 	tt = batadv_tt_global_hash_find(bat_priv, addr, vid);
4188 	if (!tt)
4189 		return false;
4190 
4191 	ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA;
4192 
4193 	batadv_tt_global_entry_put(tt);
4194 
4195 	return ret;
4196 }
4197 
4198 /**
4199  * batadv_tt_cache_init() - Initialize tt memory object cache
4200  *
4201  * Return: 0 on success or negative error number in case of failure.
4202  */
batadv_tt_cache_init(void)4203 int __init batadv_tt_cache_init(void)
4204 {
4205 	size_t tl_size = sizeof(struct batadv_tt_local_entry);
4206 	size_t tg_size = sizeof(struct batadv_tt_global_entry);
4207 	size_t tt_orig_size = sizeof(struct batadv_tt_orig_list_entry);
4208 	size_t tt_change_size = sizeof(struct batadv_tt_change_node);
4209 	size_t tt_req_size = sizeof(struct batadv_tt_req_node);
4210 	size_t tt_roam_size = sizeof(struct batadv_tt_roam_node);
4211 
4212 	batadv_tl_cache = kmem_cache_create("batadv_tl_cache", tl_size, 0,
4213 					    SLAB_HWCACHE_ALIGN, NULL);
4214 	if (!batadv_tl_cache)
4215 		return -ENOMEM;
4216 
4217 	batadv_tg_cache = kmem_cache_create("batadv_tg_cache", tg_size, 0,
4218 					    SLAB_HWCACHE_ALIGN, NULL);
4219 	if (!batadv_tg_cache)
4220 		goto err_tt_tl_destroy;
4221 
4222 	batadv_tt_orig_cache = kmem_cache_create("batadv_tt_orig_cache",
4223 						 tt_orig_size, 0,
4224 						 SLAB_HWCACHE_ALIGN, NULL);
4225 	if (!batadv_tt_orig_cache)
4226 		goto err_tt_tg_destroy;
4227 
4228 	batadv_tt_change_cache = kmem_cache_create("batadv_tt_change_cache",
4229 						   tt_change_size, 0,
4230 						   SLAB_HWCACHE_ALIGN, NULL);
4231 	if (!batadv_tt_change_cache)
4232 		goto err_tt_orig_destroy;
4233 
4234 	batadv_tt_req_cache = kmem_cache_create("batadv_tt_req_cache",
4235 						tt_req_size, 0,
4236 						SLAB_HWCACHE_ALIGN, NULL);
4237 	if (!batadv_tt_req_cache)
4238 		goto err_tt_change_destroy;
4239 
4240 	batadv_tt_roam_cache = kmem_cache_create("batadv_tt_roam_cache",
4241 						 tt_roam_size, 0,
4242 						 SLAB_HWCACHE_ALIGN, NULL);
4243 	if (!batadv_tt_roam_cache)
4244 		goto err_tt_req_destroy;
4245 
4246 	return 0;
4247 
4248 err_tt_req_destroy:
4249 	kmem_cache_destroy(batadv_tt_req_cache);
4250 	batadv_tt_req_cache = NULL;
4251 err_tt_change_destroy:
4252 	kmem_cache_destroy(batadv_tt_change_cache);
4253 	batadv_tt_change_cache = NULL;
4254 err_tt_orig_destroy:
4255 	kmem_cache_destroy(batadv_tt_orig_cache);
4256 	batadv_tt_orig_cache = NULL;
4257 err_tt_tg_destroy:
4258 	kmem_cache_destroy(batadv_tg_cache);
4259 	batadv_tg_cache = NULL;
4260 err_tt_tl_destroy:
4261 	kmem_cache_destroy(batadv_tl_cache);
4262 	batadv_tl_cache = NULL;
4263 
4264 	return -ENOMEM;
4265 }
4266 
4267 /**
4268  * batadv_tt_cache_destroy() - Destroy tt memory object cache
4269  */
batadv_tt_cache_destroy(void)4270 void batadv_tt_cache_destroy(void)
4271 {
4272 	kmem_cache_destroy(batadv_tl_cache);
4273 	kmem_cache_destroy(batadv_tg_cache);
4274 	kmem_cache_destroy(batadv_tt_orig_cache);
4275 	kmem_cache_destroy(batadv_tt_change_cache);
4276 	kmem_cache_destroy(batadv_tt_req_cache);
4277 	kmem_cache_destroy(batadv_tt_roam_cache);
4278 }
4279