• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
2  *
3  * Marek Lindner, Simon Wunderlich, Antonio Quartulli
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA
18  */
19 
20 #include "main.h"
21 #include "translation-table.h"
22 #include "soft-interface.h"
23 #include "hard-interface.h"
24 #include "send.h"
25 #include "hash.h"
26 #include "originator.h"
27 #include "routing.h"
28 #include "bridge_loop_avoidance.h"
29 
30 #include <linux/crc16.h>
31 
32 /* hash class keys */
33 static struct lock_class_key batadv_tt_local_hash_lock_class_key;
34 static struct lock_class_key batadv_tt_global_hash_lock_class_key;
35 
36 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
37 				 struct batadv_orig_node *orig_node);
38 static void batadv_tt_purge(struct work_struct *work);
39 static void
40 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
41 static void batadv_tt_global_del(struct batadv_priv *bat_priv,
42 				 struct batadv_orig_node *orig_node,
43 				 const unsigned char *addr,
44 				 const char *message, bool roaming);
45 
46 /* returns 1 if they are the same mac addr */
batadv_compare_tt(const struct hlist_node * node,const void * data2)47 static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
48 {
49 	const void *data1 = container_of(node, struct batadv_tt_common_entry,
50 					 hash_entry);
51 
52 	return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
53 }
54 
55 static struct batadv_tt_common_entry *
batadv_tt_hash_find(struct batadv_hashtable * hash,const void * data)56 batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data)
57 {
58 	struct hlist_head *head;
59 	struct batadv_tt_common_entry *tt_common_entry;
60 	struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
61 	uint32_t index;
62 
63 	if (!hash)
64 		return NULL;
65 
66 	index = batadv_choose_orig(data, hash->size);
67 	head = &hash->table[index];
68 
69 	rcu_read_lock();
70 	hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) {
71 		if (!batadv_compare_eth(tt_common_entry, data))
72 			continue;
73 
74 		if (!atomic_inc_not_zero(&tt_common_entry->refcount))
75 			continue;
76 
77 		tt_common_entry_tmp = tt_common_entry;
78 		break;
79 	}
80 	rcu_read_unlock();
81 
82 	return tt_common_entry_tmp;
83 }
84 
85 static struct batadv_tt_local_entry *
batadv_tt_local_hash_find(struct batadv_priv * bat_priv,const void * data)86 batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
87 {
88 	struct batadv_tt_common_entry *tt_common_entry;
89 	struct batadv_tt_local_entry *tt_local_entry = NULL;
90 
91 	tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data);
92 	if (tt_common_entry)
93 		tt_local_entry = container_of(tt_common_entry,
94 					      struct batadv_tt_local_entry,
95 					      common);
96 	return tt_local_entry;
97 }
98 
99 static struct batadv_tt_global_entry *
batadv_tt_global_hash_find(struct batadv_priv * bat_priv,const void * data)100 batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
101 {
102 	struct batadv_tt_common_entry *tt_common_entry;
103 	struct batadv_tt_global_entry *tt_global_entry = NULL;
104 
105 	tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data);
106 	if (tt_common_entry)
107 		tt_global_entry = container_of(tt_common_entry,
108 					       struct batadv_tt_global_entry,
109 					       common);
110 	return tt_global_entry;
111 }
112 
113 static void
batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry * tt_local_entry)114 batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry)
115 {
116 	if (atomic_dec_and_test(&tt_local_entry->common.refcount))
117 		kfree_rcu(tt_local_entry, common.rcu);
118 }
119 
batadv_tt_global_entry_free_rcu(struct rcu_head * rcu)120 static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu)
121 {
122 	struct batadv_tt_common_entry *tt_common_entry;
123 	struct batadv_tt_global_entry *tt_global_entry;
124 
125 	tt_common_entry = container_of(rcu, struct batadv_tt_common_entry, rcu);
126 	tt_global_entry = container_of(tt_common_entry,
127 				       struct batadv_tt_global_entry, common);
128 
129 	kfree(tt_global_entry);
130 }
131 
132 static void
batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry * tt_global_entry)133 batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry)
134 {
135 	if (atomic_dec_and_test(&tt_global_entry->common.refcount)) {
136 		batadv_tt_global_del_orig_list(tt_global_entry);
137 		call_rcu(&tt_global_entry->common.rcu,
138 			 batadv_tt_global_entry_free_rcu);
139 	}
140 }
141 
batadv_tt_orig_list_entry_free_rcu(struct rcu_head * rcu)142 static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
143 {
144 	struct batadv_tt_orig_list_entry *orig_entry;
145 
146 	orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
147 
148 	/* We are in an rcu callback here, therefore we cannot use
149 	 * batadv_orig_node_free_ref() and its call_rcu():
150 	 * An rcu_barrier() wouldn't wait for that to finish
151 	 */
152 	batadv_orig_node_free_ref_now(orig_entry->orig_node);
153 	kfree(orig_entry);
154 }
155 
156 static void
batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry * orig_entry)157 batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
158 {
159 	if (!atomic_dec_and_test(&orig_entry->refcount))
160 		return;
161 	/* to avoid race conditions, immediately decrease the tt counter */
162 	atomic_dec(&orig_entry->orig_node->tt_size);
163 	call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
164 }
165 
batadv_tt_local_event(struct batadv_priv * bat_priv,const uint8_t * addr,uint8_t flags)166 static void batadv_tt_local_event(struct batadv_priv *bat_priv,
167 				  const uint8_t *addr, uint8_t flags)
168 {
169 	struct batadv_tt_change_node *tt_change_node, *entry, *safe;
170 	bool event_removed = false;
171 	bool del_op_requested, del_op_entry;
172 
173 	tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
174 
175 	if (!tt_change_node)
176 		return;
177 
178 	tt_change_node->change.flags = flags;
179 	memcpy(tt_change_node->change.addr, addr, ETH_ALEN);
180 
181 	del_op_requested = flags & BATADV_TT_CLIENT_DEL;
182 
183 	/* check for ADD+DEL or DEL+ADD events */
184 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
185 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
186 				 list) {
187 		if (!batadv_compare_eth(entry->change.addr, addr))
188 			continue;
189 
190 		/* DEL+ADD in the same orig interval have no effect and can be
191 		 * removed to avoid silly behaviour on the receiver side. The
192 		 * other way around (ADD+DEL) can happen in case of roaming of
193 		 * a client still in the NEW state. Roaming of NEW clients is
194 		 * now possible due to automatically recognition of "temporary"
195 		 * clients
196 		 */
197 		del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
198 		if (!del_op_requested && del_op_entry)
199 			goto del;
200 		if (del_op_requested && !del_op_entry)
201 			goto del;
202 		continue;
203 del:
204 		list_del(&entry->list);
205 		kfree(entry);
206 		kfree(tt_change_node);
207 		event_removed = true;
208 		goto unlock;
209 	}
210 
211 	/* track the change in the OGMinterval list */
212 	list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
213 
214 unlock:
215 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
216 
217 	if (event_removed)
218 		atomic_dec(&bat_priv->tt.local_changes);
219 	else
220 		atomic_inc(&bat_priv->tt.local_changes);
221 }
222 
batadv_tt_len(int changes_num)223 int batadv_tt_len(int changes_num)
224 {
225 	return changes_num * sizeof(struct batadv_tt_change);
226 }
227 
batadv_tt_local_init(struct batadv_priv * bat_priv)228 static int batadv_tt_local_init(struct batadv_priv *bat_priv)
229 {
230 	if (bat_priv->tt.local_hash)
231 		return 0;
232 
233 	bat_priv->tt.local_hash = batadv_hash_new(1024);
234 
235 	if (!bat_priv->tt.local_hash)
236 		return -ENOMEM;
237 
238 	batadv_hash_set_lock_class(bat_priv->tt.local_hash,
239 				   &batadv_tt_local_hash_lock_class_key);
240 
241 	return 0;
242 }
243 
batadv_tt_global_free(struct batadv_priv * bat_priv,struct batadv_tt_global_entry * tt_global,const char * message)244 static void batadv_tt_global_free(struct batadv_priv *bat_priv,
245 				  struct batadv_tt_global_entry *tt_global,
246 				  const char *message)
247 {
248 	batadv_dbg(BATADV_DBG_TT, bat_priv,
249 		   "Deleting global tt entry %pM: %s\n",
250 		   tt_global->common.addr, message);
251 
252 	batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
253 			   batadv_choose_orig, tt_global->common.addr);
254 	batadv_tt_global_entry_free_ref(tt_global);
255 }
256 
batadv_tt_local_add(struct net_device * soft_iface,const uint8_t * addr,int ifindex)257 void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
258 			 int ifindex)
259 {
260 	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
261 	struct batadv_tt_local_entry *tt_local;
262 	struct batadv_tt_global_entry *tt_global;
263 	struct hlist_head *head;
264 	struct batadv_tt_orig_list_entry *orig_entry;
265 	int hash_added;
266 	bool roamed_back = false;
267 
268 	tt_local = batadv_tt_local_hash_find(bat_priv, addr);
269 	tt_global = batadv_tt_global_hash_find(bat_priv, addr);
270 
271 	if (tt_local) {
272 		tt_local->last_seen = jiffies;
273 		if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
274 			batadv_dbg(BATADV_DBG_TT, bat_priv,
275 				   "Re-adding pending client %pM\n", addr);
276 			/* whatever the reason why the PENDING flag was set,
277 			 * this is a client which was enqueued to be removed in
278 			 * this orig_interval. Since it popped up again, the
279 			 * flag can be reset like it was never enqueued
280 			 */
281 			tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
282 			goto add_event;
283 		}
284 
285 		if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
286 			batadv_dbg(BATADV_DBG_TT, bat_priv,
287 				   "Roaming client %pM came back to its original location\n",
288 				   addr);
289 			/* the ROAM flag is set because this client roamed away
290 			 * and the node got a roaming_advertisement message. Now
291 			 * that the client popped up again at its original
292 			 * location such flag can be unset
293 			 */
294 			tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
295 			roamed_back = true;
296 		}
297 		goto check_roaming;
298 	}
299 
300 	tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
301 	if (!tt_local)
302 		goto out;
303 
304 	batadv_dbg(BATADV_DBG_TT, bat_priv,
305 		   "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
306 		   (uint8_t)atomic_read(&bat_priv->tt.vn));
307 
308 	memcpy(tt_local->common.addr, addr, ETH_ALEN);
309 	/* The local entry has to be marked as NEW to avoid to send it in
310 	 * a full table response going out before the next ttvn increment
311 	 * (consistency check)
312 	 */
313 	tt_local->common.flags = BATADV_TT_CLIENT_NEW;
314 	if (batadv_is_wifi_iface(ifindex))
315 		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
316 	atomic_set(&tt_local->common.refcount, 2);
317 	tt_local->last_seen = jiffies;
318 	tt_local->common.added_at = tt_local->last_seen;
319 
320 	/* the batman interface mac address should never be purged */
321 	if (batadv_compare_eth(addr, soft_iface->dev_addr))
322 		tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
323 
324 	hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
325 				     batadv_choose_orig, &tt_local->common,
326 				     &tt_local->common.hash_entry);
327 
328 	if (unlikely(hash_added != 0)) {
329 		/* remove the reference for the hash */
330 		batadv_tt_local_entry_free_ref(tt_local);
331 		goto out;
332 	}
333 
334 add_event:
335 	batadv_tt_local_event(bat_priv, addr, tt_local->common.flags);
336 
337 check_roaming:
338 	/* Check whether it is a roaming, but don't do anything if the roaming
339 	 * process has already been handled
340 	 */
341 	if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
342 		/* These node are probably going to update their tt table */
343 		head = &tt_global->orig_list;
344 		rcu_read_lock();
345 		hlist_for_each_entry_rcu(orig_entry, head, list) {
346 			batadv_send_roam_adv(bat_priv, tt_global->common.addr,
347 					     orig_entry->orig_node);
348 		}
349 		rcu_read_unlock();
350 		if (roamed_back) {
351 			batadv_tt_global_free(bat_priv, tt_global,
352 					      "Roaming canceled");
353 			tt_global = NULL;
354 		} else {
355 			/* The global entry has to be marked as ROAMING and
356 			 * has to be kept for consistency purpose
357 			 */
358 			tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
359 			tt_global->roam_at = jiffies;
360 		}
361 	}
362 
363 out:
364 	if (tt_local)
365 		batadv_tt_local_entry_free_ref(tt_local);
366 	if (tt_global)
367 		batadv_tt_global_entry_free_ref(tt_global);
368 }
369 
batadv_tt_realloc_packet_buff(unsigned char ** packet_buff,int * packet_buff_len,int min_packet_len,int new_packet_len)370 static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff,
371 					  int *packet_buff_len,
372 					  int min_packet_len,
373 					  int new_packet_len)
374 {
375 	unsigned char *new_buff;
376 
377 	new_buff = kmalloc(new_packet_len, GFP_ATOMIC);
378 
379 	/* keep old buffer if kmalloc should fail */
380 	if (new_buff) {
381 		memcpy(new_buff, *packet_buff, min_packet_len);
382 		kfree(*packet_buff);
383 		*packet_buff = new_buff;
384 		*packet_buff_len = new_packet_len;
385 	}
386 }
387 
batadv_tt_prepare_packet_buff(struct batadv_priv * bat_priv,unsigned char ** packet_buff,int * packet_buff_len,int min_packet_len)388 static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
389 					  unsigned char **packet_buff,
390 					  int *packet_buff_len,
391 					  int min_packet_len)
392 {
393 	int req_len;
394 
395 	req_len = min_packet_len;
396 	req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
397 
398 	/* if we have too many changes for one packet don't send any
399 	 * and wait for the tt table request which will be fragmented
400 	 */
401 	if (req_len > bat_priv->soft_iface->mtu)
402 		req_len = min_packet_len;
403 
404 	batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
405 				      min_packet_len, req_len);
406 }
407 
batadv_tt_changes_fill_buff(struct batadv_priv * bat_priv,unsigned char ** packet_buff,int * packet_buff_len,int min_packet_len)408 static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
409 				       unsigned char **packet_buff,
410 				       int *packet_buff_len,
411 				       int min_packet_len)
412 {
413 	struct batadv_tt_change_node *entry, *safe;
414 	int count = 0, tot_changes = 0, new_len;
415 	unsigned char *tt_buff;
416 
417 	batadv_tt_prepare_packet_buff(bat_priv, packet_buff,
418 				      packet_buff_len, min_packet_len);
419 
420 	new_len = *packet_buff_len - min_packet_len;
421 	tt_buff = *packet_buff + min_packet_len;
422 
423 	if (new_len > 0)
424 		tot_changes = new_len / batadv_tt_len(1);
425 
426 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
427 	atomic_set(&bat_priv->tt.local_changes, 0);
428 
429 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
430 				 list) {
431 		if (count < tot_changes) {
432 			memcpy(tt_buff + batadv_tt_len(count),
433 			       &entry->change, sizeof(struct batadv_tt_change));
434 			count++;
435 		}
436 		list_del(&entry->list);
437 		kfree(entry);
438 	}
439 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
440 
441 	/* Keep the buffer for possible tt_request */
442 	spin_lock_bh(&bat_priv->tt.last_changeset_lock);
443 	kfree(bat_priv->tt.last_changeset);
444 	bat_priv->tt.last_changeset_len = 0;
445 	bat_priv->tt.last_changeset = NULL;
446 	/* check whether this new OGM has no changes due to size problems */
447 	if (new_len > 0) {
448 		/* if kmalloc() fails we will reply with the full table
449 		 * instead of providing the diff
450 		 */
451 		bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC);
452 		if (bat_priv->tt.last_changeset) {
453 			memcpy(bat_priv->tt.last_changeset, tt_buff, new_len);
454 			bat_priv->tt.last_changeset_len = new_len;
455 		}
456 	}
457 	spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
458 
459 	return count;
460 }
461 
batadv_tt_local_seq_print_text(struct seq_file * seq,void * offset)462 int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
463 {
464 	struct net_device *net_dev = (struct net_device *)seq->private;
465 	struct batadv_priv *bat_priv = netdev_priv(net_dev);
466 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
467 	struct batadv_tt_common_entry *tt_common_entry;
468 	struct batadv_tt_local_entry *tt_local;
469 	struct batadv_hard_iface *primary_if;
470 	struct hlist_head *head;
471 	uint32_t i;
472 	int last_seen_secs;
473 	int last_seen_msecs;
474 	unsigned long last_seen_jiffies;
475 	bool no_purge;
476 	uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE;
477 
478 	primary_if = batadv_seq_print_text_primary_if_get(seq);
479 	if (!primary_if)
480 		goto out;
481 
482 	seq_printf(seq,
483 		   "Locally retrieved addresses (from %s) announced via TT (TTVN: %u CRC: %#.4x):\n",
484 		   net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn),
485 		   bat_priv->tt.local_crc);
486 	seq_printf(seq, "       %-13s %-7s %-10s\n", "Client", "Flags",
487 		   "Last seen");
488 
489 	for (i = 0; i < hash->size; i++) {
490 		head = &hash->table[i];
491 
492 		rcu_read_lock();
493 		hlist_for_each_entry_rcu(tt_common_entry,
494 					 head, hash_entry) {
495 			tt_local = container_of(tt_common_entry,
496 						struct batadv_tt_local_entry,
497 						common);
498 			last_seen_jiffies = jiffies - tt_local->last_seen;
499 			last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
500 			last_seen_secs = last_seen_msecs / 1000;
501 			last_seen_msecs = last_seen_msecs % 1000;
502 
503 			no_purge = tt_common_entry->flags & np_flag;
504 
505 			seq_printf(seq, " * %pM [%c%c%c%c%c] %3u.%03u\n",
506 				   tt_common_entry->addr,
507 				   (tt_common_entry->flags &
508 				    BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
509 				   no_purge ? 'P' : '.',
510 				   (tt_common_entry->flags &
511 				    BATADV_TT_CLIENT_NEW ? 'N' : '.'),
512 				   (tt_common_entry->flags &
513 				    BATADV_TT_CLIENT_PENDING ? 'X' : '.'),
514 				   (tt_common_entry->flags &
515 				    BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
516 				   no_purge ? 0 : last_seen_secs,
517 				   no_purge ? 0 : last_seen_msecs);
518 		}
519 		rcu_read_unlock();
520 	}
521 out:
522 	if (primary_if)
523 		batadv_hardif_free_ref(primary_if);
524 	return 0;
525 }
526 
527 static void
batadv_tt_local_set_pending(struct batadv_priv * bat_priv,struct batadv_tt_local_entry * tt_local_entry,uint16_t flags,const char * message)528 batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
529 			    struct batadv_tt_local_entry *tt_local_entry,
530 			    uint16_t flags, const char *message)
531 {
532 	batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
533 			      tt_local_entry->common.flags | flags);
534 
535 	/* The local client has to be marked as "pending to be removed" but has
536 	 * to be kept in the table in order to send it in a full table
537 	 * response issued before the net ttvn increment (consistency check)
538 	 */
539 	tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
540 
541 	batadv_dbg(BATADV_DBG_TT, bat_priv,
542 		   "Local tt entry (%pM) pending to be removed: %s\n",
543 		   tt_local_entry->common.addr, message);
544 }
545 
546 /**
547  * batadv_tt_local_remove - logically remove an entry from the local table
548  * @bat_priv: the bat priv with all the soft interface information
549  * @addr: the MAC address of the client to remove
550  * @message: message to append to the log on deletion
551  * @roaming: true if the deletion is due to a roaming event
552  *
553  * Returns the flags assigned to the local entry before being deleted
554  */
batadv_tt_local_remove(struct batadv_priv * bat_priv,const uint8_t * addr,const char * message,bool roaming)555 uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
556 				const uint8_t *addr, const char *message,
557 				bool roaming)
558 {
559 	struct batadv_tt_local_entry *tt_local_entry;
560 	uint16_t flags, curr_flags = BATADV_NO_FLAGS;
561 
562 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
563 	if (!tt_local_entry)
564 		goto out;
565 
566 	curr_flags = tt_local_entry->common.flags;
567 
568 	flags = BATADV_TT_CLIENT_DEL;
569 	/* if this global entry addition is due to a roaming, the node has to
570 	 * mark the local entry as "roamed" in order to correctly reroute
571 	 * packets later
572 	 */
573 	if (roaming) {
574 		flags |= BATADV_TT_CLIENT_ROAM;
575 		/* mark the local client as ROAMed */
576 		tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
577 	}
578 
579 	if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
580 		batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
581 					    message);
582 		goto out;
583 	}
584 	/* if this client has been added right now, it is possible to
585 	 * immediately purge it
586 	 */
587 	batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
588 			      curr_flags | BATADV_TT_CLIENT_DEL);
589 	hlist_del_rcu(&tt_local_entry->common.hash_entry);
590 	batadv_tt_local_entry_free_ref(tt_local_entry);
591 
592 out:
593 	if (tt_local_entry)
594 		batadv_tt_local_entry_free_ref(tt_local_entry);
595 
596 	return curr_flags;
597 }
598 
batadv_tt_local_purge_list(struct batadv_priv * bat_priv,struct hlist_head * head)599 static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
600 				       struct hlist_head *head)
601 {
602 	struct batadv_tt_local_entry *tt_local_entry;
603 	struct batadv_tt_common_entry *tt_common_entry;
604 	struct hlist_node *node_tmp;
605 
606 	hlist_for_each_entry_safe(tt_common_entry, node_tmp, head,
607 				  hash_entry) {
608 		tt_local_entry = container_of(tt_common_entry,
609 					      struct batadv_tt_local_entry,
610 					      common);
611 		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE)
612 			continue;
613 
614 		/* entry already marked for deletion */
615 		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
616 			continue;
617 
618 		if (!batadv_has_timed_out(tt_local_entry->last_seen,
619 					  BATADV_TT_LOCAL_TIMEOUT))
620 			continue;
621 
622 		batadv_tt_local_set_pending(bat_priv, tt_local_entry,
623 					    BATADV_TT_CLIENT_DEL, "timed out");
624 	}
625 }
626 
batadv_tt_local_purge(struct batadv_priv * bat_priv)627 static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
628 {
629 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
630 	struct hlist_head *head;
631 	spinlock_t *list_lock; /* protects write access to the hash lists */
632 	uint32_t i;
633 
634 	for (i = 0; i < hash->size; i++) {
635 		head = &hash->table[i];
636 		list_lock = &hash->list_locks[i];
637 
638 		spin_lock_bh(list_lock);
639 		batadv_tt_local_purge_list(bat_priv, head);
640 		spin_unlock_bh(list_lock);
641 	}
642 }
643 
batadv_tt_local_table_free(struct batadv_priv * bat_priv)644 static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
645 {
646 	struct batadv_hashtable *hash;
647 	spinlock_t *list_lock; /* protects write access to the hash lists */
648 	struct batadv_tt_common_entry *tt_common_entry;
649 	struct batadv_tt_local_entry *tt_local;
650 	struct hlist_node *node_tmp;
651 	struct hlist_head *head;
652 	uint32_t i;
653 
654 	if (!bat_priv->tt.local_hash)
655 		return;
656 
657 	hash = bat_priv->tt.local_hash;
658 
659 	for (i = 0; i < hash->size; i++) {
660 		head = &hash->table[i];
661 		list_lock = &hash->list_locks[i];
662 
663 		spin_lock_bh(list_lock);
664 		hlist_for_each_entry_safe(tt_common_entry, node_tmp,
665 					  head, hash_entry) {
666 			hlist_del_rcu(&tt_common_entry->hash_entry);
667 			tt_local = container_of(tt_common_entry,
668 						struct batadv_tt_local_entry,
669 						common);
670 			batadv_tt_local_entry_free_ref(tt_local);
671 		}
672 		spin_unlock_bh(list_lock);
673 	}
674 
675 	batadv_hash_destroy(hash);
676 
677 	bat_priv->tt.local_hash = NULL;
678 }
679 
batadv_tt_global_init(struct batadv_priv * bat_priv)680 static int batadv_tt_global_init(struct batadv_priv *bat_priv)
681 {
682 	if (bat_priv->tt.global_hash)
683 		return 0;
684 
685 	bat_priv->tt.global_hash = batadv_hash_new(1024);
686 
687 	if (!bat_priv->tt.global_hash)
688 		return -ENOMEM;
689 
690 	batadv_hash_set_lock_class(bat_priv->tt.global_hash,
691 				   &batadv_tt_global_hash_lock_class_key);
692 
693 	return 0;
694 }
695 
batadv_tt_changes_list_free(struct batadv_priv * bat_priv)696 static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
697 {
698 	struct batadv_tt_change_node *entry, *safe;
699 
700 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
701 
702 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
703 				 list) {
704 		list_del(&entry->list);
705 		kfree(entry);
706 	}
707 
708 	atomic_set(&bat_priv->tt.local_changes, 0);
709 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
710 }
711 
712 /* retrieves the orig_tt_list_entry belonging to orig_node from the
713  * batadv_tt_global_entry list
714  *
715  * returns it with an increased refcounter, NULL if not found
716  */
717 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)718 batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
719 				 const struct batadv_orig_node *orig_node)
720 {
721 	struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
722 	const struct hlist_head *head;
723 
724 	rcu_read_lock();
725 	head = &entry->orig_list;
726 	hlist_for_each_entry_rcu(tmp_orig_entry, head, list) {
727 		if (tmp_orig_entry->orig_node != orig_node)
728 			continue;
729 		if (!atomic_inc_not_zero(&tmp_orig_entry->refcount))
730 			continue;
731 
732 		orig_entry = tmp_orig_entry;
733 		break;
734 	}
735 	rcu_read_unlock();
736 
737 	return orig_entry;
738 }
739 
740 /* find out if an orig_node is already in the list of a tt_global_entry.
741  * returns true if found, false otherwise
742  */
743 static bool
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry * entry,const struct batadv_orig_node * orig_node)744 batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
745 				const struct batadv_orig_node *orig_node)
746 {
747 	struct batadv_tt_orig_list_entry *orig_entry;
748 	bool found = false;
749 
750 	orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
751 	if (orig_entry) {
752 		found = true;
753 		batadv_tt_orig_list_entry_free_ref(orig_entry);
754 	}
755 
756 	return found;
757 }
758 
759 static void
batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry * tt_global,struct batadv_orig_node * orig_node,int ttvn)760 batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
761 				struct batadv_orig_node *orig_node, int ttvn)
762 {
763 	struct batadv_tt_orig_list_entry *orig_entry;
764 
765 	orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
766 	if (orig_entry) {
767 		/* refresh the ttvn: the current value could be a bogus one that
768 		 * was added during a "temporary client detection"
769 		 */
770 		orig_entry->ttvn = ttvn;
771 		goto out;
772 	}
773 
774 	orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
775 	if (!orig_entry)
776 		goto out;
777 
778 	INIT_HLIST_NODE(&orig_entry->list);
779 	atomic_inc(&orig_node->refcount);
780 	atomic_inc(&orig_node->tt_size);
781 	orig_entry->orig_node = orig_node;
782 	orig_entry->ttvn = ttvn;
783 	atomic_set(&orig_entry->refcount, 2);
784 
785 	spin_lock_bh(&tt_global->list_lock);
786 	hlist_add_head_rcu(&orig_entry->list,
787 			   &tt_global->orig_list);
788 	spin_unlock_bh(&tt_global->list_lock);
789 out:
790 	if (orig_entry)
791 		batadv_tt_orig_list_entry_free_ref(orig_entry);
792 }
793 
794 /* caller must hold orig_node refcount */
batadv_tt_global_add(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * tt_addr,uint8_t flags,uint8_t ttvn)795 int batadv_tt_global_add(struct batadv_priv *bat_priv,
796 			 struct batadv_orig_node *orig_node,
797 			 const unsigned char *tt_addr, uint8_t flags,
798 			 uint8_t ttvn)
799 {
800 	struct batadv_tt_global_entry *tt_global_entry;
801 	struct batadv_tt_local_entry *tt_local_entry;
802 	int ret = 0;
803 	int hash_added;
804 	struct batadv_tt_common_entry *common;
805 	uint16_t local_flags;
806 
807 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
808 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr);
809 
810 	/* if the node already has a local client for this entry, it has to wait
811 	 * for a roaming advertisement instead of manually messing up the global
812 	 * table
813 	 */
814 	if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
815 	    !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
816 		goto out;
817 
818 	if (!tt_global_entry) {
819 		tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
820 		if (!tt_global_entry)
821 			goto out;
822 
823 		common = &tt_global_entry->common;
824 		memcpy(common->addr, tt_addr, ETH_ALEN);
825 
826 		common->flags = flags;
827 		tt_global_entry->roam_at = 0;
828 		/* node must store current time in case of roaming. This is
829 		 * needed to purge this entry out on timeout (if nobody claims
830 		 * it)
831 		 */
832 		if (flags & BATADV_TT_CLIENT_ROAM)
833 			tt_global_entry->roam_at = jiffies;
834 		atomic_set(&common->refcount, 2);
835 		common->added_at = jiffies;
836 
837 		INIT_HLIST_HEAD(&tt_global_entry->orig_list);
838 		spin_lock_init(&tt_global_entry->list_lock);
839 
840 		hash_added = batadv_hash_add(bat_priv->tt.global_hash,
841 					     batadv_compare_tt,
842 					     batadv_choose_orig, common,
843 					     &common->hash_entry);
844 
845 		if (unlikely(hash_added != 0)) {
846 			/* remove the reference for the hash */
847 			batadv_tt_global_entry_free_ref(tt_global_entry);
848 			goto out_remove;
849 		}
850 	} else {
851 		common = &tt_global_entry->common;
852 		/* If there is already a global entry, we can use this one for
853 		 * our processing.
854 		 * But if we are trying to add a temporary client then here are
855 		 * two options at this point:
856 		 * 1) the global client is not a temporary client: the global
857 		 *    client has to be left as it is, temporary information
858 		 *    should never override any already known client state
859 		 * 2) the global client is a temporary client: purge the
860 		 *    originator list and add the new one orig_entry
861 		 */
862 		if (flags & BATADV_TT_CLIENT_TEMP) {
863 			if (!(common->flags & BATADV_TT_CLIENT_TEMP))
864 				goto out;
865 			if (batadv_tt_global_entry_has_orig(tt_global_entry,
866 							    orig_node))
867 				goto out_remove;
868 			batadv_tt_global_del_orig_list(tt_global_entry);
869 			goto add_orig_entry;
870 		}
871 
872 		/* if the client was temporary added before receiving the first
873 		 * OGM announcing it, we have to clear the TEMP flag
874 		 */
875 		common->flags &= ~BATADV_TT_CLIENT_TEMP;
876 
877 		/* the change can carry possible "attribute" flags like the
878 		 * TT_CLIENT_WIFI, therefore they have to be copied in the
879 		 * client entry
880 		 */
881 		tt_global_entry->common.flags |= flags;
882 
883 		/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
884 		 * one originator left in the list and we previously received a
885 		 * delete + roaming change for this originator.
886 		 *
887 		 * We should first delete the old originator before adding the
888 		 * new one.
889 		 */
890 		if (common->flags & BATADV_TT_CLIENT_ROAM) {
891 			batadv_tt_global_del_orig_list(tt_global_entry);
892 			common->flags &= ~BATADV_TT_CLIENT_ROAM;
893 			tt_global_entry->roam_at = 0;
894 		}
895 	}
896 add_orig_entry:
897 	/* add the new orig_entry (if needed) or update it */
898 	batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
899 
900 	batadv_dbg(BATADV_DBG_TT, bat_priv,
901 		   "Creating new global tt entry: %pM (via %pM)\n",
902 		   common->addr, orig_node->orig);
903 	ret = 1;
904 
905 out_remove:
906 
907 	/* remove address from local hash if present */
908 	local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
909 					     "global tt received",
910 					     flags & BATADV_TT_CLIENT_ROAM);
911 	tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
912 
913 	if (!(flags & BATADV_TT_CLIENT_ROAM))
914 		/* this is a normal global add. Therefore the client is not in a
915 		 * roaming state anymore.
916 		 */
917 		tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
918 
919 out:
920 	if (tt_global_entry)
921 		batadv_tt_global_entry_free_ref(tt_global_entry);
922 	if (tt_local_entry)
923 		batadv_tt_local_entry_free_ref(tt_local_entry);
924 	return ret;
925 }
926 
927 /* batadv_transtable_best_orig - Get best originator list entry from tt entry
928  * @tt_global_entry: global translation table entry to be analyzed
929  *
930  * This functon assumes the caller holds rcu_read_lock().
931  * Returns best originator list entry or NULL on errors.
932  */
933 static struct batadv_tt_orig_list_entry *
batadv_transtable_best_orig(struct batadv_tt_global_entry * tt_global_entry)934 batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
935 {
936 	struct batadv_neigh_node *router = NULL;
937 	struct hlist_head *head;
938 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
939 	int best_tq = 0;
940 
941 	head = &tt_global_entry->orig_list;
942 	hlist_for_each_entry_rcu(orig_entry, head, list) {
943 		router = batadv_orig_node_get_router(orig_entry->orig_node);
944 		if (!router)
945 			continue;
946 
947 		if (router->tq_avg > best_tq) {
948 			best_entry = orig_entry;
949 			best_tq = router->tq_avg;
950 		}
951 
952 		batadv_neigh_node_free_ref(router);
953 	}
954 
955 	return best_entry;
956 }
957 
958 /* batadv_tt_global_print_entry - print all orig nodes who announce the address
959  * for this global entry
960  * @tt_global_entry: global translation table entry to be printed
961  * @seq: debugfs table seq_file struct
962  *
963  * This functon assumes the caller holds rcu_read_lock().
964  */
965 static void
batadv_tt_global_print_entry(struct batadv_tt_global_entry * tt_global_entry,struct seq_file * seq)966 batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
967 			     struct seq_file *seq)
968 {
969 	struct hlist_head *head;
970 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
971 	struct batadv_tt_common_entry *tt_common_entry;
972 	uint16_t flags;
973 	uint8_t last_ttvn;
974 
975 	tt_common_entry = &tt_global_entry->common;
976 	flags = tt_common_entry->flags;
977 
978 	best_entry = batadv_transtable_best_orig(tt_global_entry);
979 	if (best_entry) {
980 		last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
981 		seq_printf(seq,
982 			   " %c %pM  (%3u) via %pM     (%3u)   (%#.4x) [%c%c%c]\n",
983 			   '*', tt_global_entry->common.addr,
984 			   best_entry->ttvn, best_entry->orig_node->orig,
985 			   last_ttvn, best_entry->orig_node->tt_crc,
986 			   (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
987 			   (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
988 			   (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
989 	}
990 
991 	head = &tt_global_entry->orig_list;
992 
993 	hlist_for_each_entry_rcu(orig_entry, head, list) {
994 		if (best_entry == orig_entry)
995 			continue;
996 
997 		last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
998 		seq_printf(seq,	" %c %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
999 			   '+', tt_global_entry->common.addr,
1000 			   orig_entry->ttvn, orig_entry->orig_node->orig,
1001 			   last_ttvn,
1002 			   (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1003 			   (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1004 			   (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1005 	}
1006 }
1007 
batadv_tt_global_seq_print_text(struct seq_file * seq,void * offset)1008 int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
1009 {
1010 	struct net_device *net_dev = (struct net_device *)seq->private;
1011 	struct batadv_priv *bat_priv = netdev_priv(net_dev);
1012 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1013 	struct batadv_tt_common_entry *tt_common_entry;
1014 	struct batadv_tt_global_entry *tt_global;
1015 	struct batadv_hard_iface *primary_if;
1016 	struct hlist_head *head;
1017 	uint32_t i;
1018 
1019 	primary_if = batadv_seq_print_text_primary_if_get(seq);
1020 	if (!primary_if)
1021 		goto out;
1022 
1023 	seq_printf(seq,
1024 		   "Globally announced TT entries received via the mesh %s\n",
1025 		   net_dev->name);
1026 	seq_printf(seq, "       %-13s %s       %-15s %s (%-6s) %s\n",
1027 		   "Client", "(TTVN)", "Originator", "(Curr TTVN)", "CRC",
1028 		   "Flags");
1029 
1030 	for (i = 0; i < hash->size; i++) {
1031 		head = &hash->table[i];
1032 
1033 		rcu_read_lock();
1034 		hlist_for_each_entry_rcu(tt_common_entry,
1035 					 head, hash_entry) {
1036 			tt_global = container_of(tt_common_entry,
1037 						 struct batadv_tt_global_entry,
1038 						 common);
1039 			batadv_tt_global_print_entry(tt_global, seq);
1040 		}
1041 		rcu_read_unlock();
1042 	}
1043 out:
1044 	if (primary_if)
1045 		batadv_hardif_free_ref(primary_if);
1046 	return 0;
1047 }
1048 
1049 /* deletes the orig list of a tt_global_entry */
1050 static void
batadv_tt_global_del_orig_list(struct batadv_tt_global_entry * tt_global_entry)1051 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
1052 {
1053 	struct hlist_head *head;
1054 	struct hlist_node *safe;
1055 	struct batadv_tt_orig_list_entry *orig_entry;
1056 
1057 	spin_lock_bh(&tt_global_entry->list_lock);
1058 	head = &tt_global_entry->orig_list;
1059 	hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1060 		hlist_del_rcu(&orig_entry->list);
1061 		batadv_tt_orig_list_entry_free_ref(orig_entry);
1062 	}
1063 	spin_unlock_bh(&tt_global_entry->list_lock);
1064 }
1065 
1066 static void
batadv_tt_global_del_orig_entry(struct batadv_priv * bat_priv,struct batadv_tt_global_entry * tt_global_entry,struct batadv_orig_node * orig_node,const char * message)1067 batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
1068 				struct batadv_tt_global_entry *tt_global_entry,
1069 				struct batadv_orig_node *orig_node,
1070 				const char *message)
1071 {
1072 	struct hlist_head *head;
1073 	struct hlist_node *safe;
1074 	struct batadv_tt_orig_list_entry *orig_entry;
1075 
1076 	spin_lock_bh(&tt_global_entry->list_lock);
1077 	head = &tt_global_entry->orig_list;
1078 	hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1079 		if (orig_entry->orig_node == orig_node) {
1080 			batadv_dbg(BATADV_DBG_TT, bat_priv,
1081 				   "Deleting %pM from global tt entry %pM: %s\n",
1082 				   orig_node->orig,
1083 				   tt_global_entry->common.addr, message);
1084 			hlist_del_rcu(&orig_entry->list);
1085 			batadv_tt_orig_list_entry_free_ref(orig_entry);
1086 		}
1087 	}
1088 	spin_unlock_bh(&tt_global_entry->list_lock);
1089 }
1090 
1091 /* If the client is to be deleted, we check if it is the last origantor entry
1092  * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
1093  * timer, otherwise we simply remove the originator scheduled for deletion.
1094  */
1095 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)1096 batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
1097 			     struct batadv_tt_global_entry *tt_global_entry,
1098 			     struct batadv_orig_node *orig_node,
1099 			     const char *message)
1100 {
1101 	bool last_entry = true;
1102 	struct hlist_head *head;
1103 	struct batadv_tt_orig_list_entry *orig_entry;
1104 
1105 	/* no local entry exists, case 1:
1106 	 * Check if this is the last one or if other entries exist.
1107 	 */
1108 
1109 	rcu_read_lock();
1110 	head = &tt_global_entry->orig_list;
1111 	hlist_for_each_entry_rcu(orig_entry, head, list) {
1112 		if (orig_entry->orig_node != orig_node) {
1113 			last_entry = false;
1114 			break;
1115 		}
1116 	}
1117 	rcu_read_unlock();
1118 
1119 	if (last_entry) {
1120 		/* its the last one, mark for roaming. */
1121 		tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
1122 		tt_global_entry->roam_at = jiffies;
1123 	} else
1124 		/* there is another entry, we can simply delete this
1125 		 * one and can still use the other one.
1126 		 */
1127 		batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1128 						orig_node, message);
1129 }
1130 
1131 
1132 
batadv_tt_global_del(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * addr,const char * message,bool roaming)1133 static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1134 				 struct batadv_orig_node *orig_node,
1135 				 const unsigned char *addr,
1136 				 const char *message, bool roaming)
1137 {
1138 	struct batadv_tt_global_entry *tt_global_entry;
1139 	struct batadv_tt_local_entry *local_entry = NULL;
1140 
1141 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
1142 	if (!tt_global_entry)
1143 		goto out;
1144 
1145 	if (!roaming) {
1146 		batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1147 						orig_node, message);
1148 
1149 		if (hlist_empty(&tt_global_entry->orig_list))
1150 			batadv_tt_global_free(bat_priv, tt_global_entry,
1151 					      message);
1152 
1153 		goto out;
1154 	}
1155 
1156 	/* if we are deleting a global entry due to a roam
1157 	 * event, there are two possibilities:
1158 	 * 1) the client roamed from node A to node B => if there
1159 	 *    is only one originator left for this client, we mark
1160 	 *    it with BATADV_TT_CLIENT_ROAM, we start a timer and we
1161 	 *    wait for node B to claim it. In case of timeout
1162 	 *    the entry is purged.
1163 	 *
1164 	 *    If there are other originators left, we directly delete
1165 	 *    the originator.
1166 	 * 2) the client roamed to us => we can directly delete
1167 	 *    the global entry, since it is useless now.
1168 	 */
1169 	local_entry = batadv_tt_local_hash_find(bat_priv,
1170 						tt_global_entry->common.addr);
1171 	if (local_entry) {
1172 		/* local entry exists, case 2: client roamed to us. */
1173 		batadv_tt_global_del_orig_list(tt_global_entry);
1174 		batadv_tt_global_free(bat_priv, tt_global_entry, message);
1175 	} else
1176 		/* no local entry exists, case 1: check for roaming */
1177 		batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
1178 					     orig_node, message);
1179 
1180 
1181 out:
1182 	if (tt_global_entry)
1183 		batadv_tt_global_entry_free_ref(tt_global_entry);
1184 	if (local_entry)
1185 		batadv_tt_local_entry_free_ref(local_entry);
1186 }
1187 
batadv_tt_global_del_orig(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const char * message)1188 void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1189 			       struct batadv_orig_node *orig_node,
1190 			       const char *message)
1191 {
1192 	struct batadv_tt_global_entry *tt_global;
1193 	struct batadv_tt_common_entry *tt_common_entry;
1194 	uint32_t i;
1195 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1196 	struct hlist_node *safe;
1197 	struct hlist_head *head;
1198 	spinlock_t *list_lock; /* protects write access to the hash lists */
1199 
1200 	if (!hash)
1201 		return;
1202 
1203 	for (i = 0; i < hash->size; i++) {
1204 		head = &hash->table[i];
1205 		list_lock = &hash->list_locks[i];
1206 
1207 		spin_lock_bh(list_lock);
1208 		hlist_for_each_entry_safe(tt_common_entry, safe,
1209 					  head, hash_entry) {
1210 			tt_global = container_of(tt_common_entry,
1211 						 struct batadv_tt_global_entry,
1212 						 common);
1213 
1214 			batadv_tt_global_del_orig_entry(bat_priv, tt_global,
1215 							orig_node, message);
1216 
1217 			if (hlist_empty(&tt_global->orig_list)) {
1218 				batadv_dbg(BATADV_DBG_TT, bat_priv,
1219 					   "Deleting global tt entry %pM: %s\n",
1220 					   tt_global->common.addr, message);
1221 				hlist_del_rcu(&tt_common_entry->hash_entry);
1222 				batadv_tt_global_entry_free_ref(tt_global);
1223 			}
1224 		}
1225 		spin_unlock_bh(list_lock);
1226 	}
1227 	orig_node->tt_initialised = false;
1228 }
1229 
batadv_tt_global_to_purge(struct batadv_tt_global_entry * tt_global,char ** msg)1230 static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
1231 				      char **msg)
1232 {
1233 	bool purge = false;
1234 	unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
1235 	unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
1236 
1237 	if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
1238 	    batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
1239 		purge = true;
1240 		*msg = "Roaming timeout\n";
1241 	}
1242 
1243 	if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
1244 	    batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
1245 		purge = true;
1246 		*msg = "Temporary client timeout\n";
1247 	}
1248 
1249 	return purge;
1250 }
1251 
batadv_tt_global_purge(struct batadv_priv * bat_priv)1252 static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
1253 {
1254 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1255 	struct hlist_head *head;
1256 	struct hlist_node *node_tmp;
1257 	spinlock_t *list_lock; /* protects write access to the hash lists */
1258 	uint32_t i;
1259 	char *msg = NULL;
1260 	struct batadv_tt_common_entry *tt_common;
1261 	struct batadv_tt_global_entry *tt_global;
1262 
1263 	for (i = 0; i < hash->size; i++) {
1264 		head = &hash->table[i];
1265 		list_lock = &hash->list_locks[i];
1266 
1267 		spin_lock_bh(list_lock);
1268 		hlist_for_each_entry_safe(tt_common, node_tmp, head,
1269 					  hash_entry) {
1270 			tt_global = container_of(tt_common,
1271 						 struct batadv_tt_global_entry,
1272 						 common);
1273 
1274 			if (!batadv_tt_global_to_purge(tt_global, &msg))
1275 				continue;
1276 
1277 			batadv_dbg(BATADV_DBG_TT, bat_priv,
1278 				   "Deleting global tt entry (%pM): %s\n",
1279 				   tt_global->common.addr, msg);
1280 
1281 			hlist_del_rcu(&tt_common->hash_entry);
1282 
1283 			batadv_tt_global_entry_free_ref(tt_global);
1284 		}
1285 		spin_unlock_bh(list_lock);
1286 	}
1287 }
1288 
batadv_tt_global_table_free(struct batadv_priv * bat_priv)1289 static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1290 {
1291 	struct batadv_hashtable *hash;
1292 	spinlock_t *list_lock; /* protects write access to the hash lists */
1293 	struct batadv_tt_common_entry *tt_common_entry;
1294 	struct batadv_tt_global_entry *tt_global;
1295 	struct hlist_node *node_tmp;
1296 	struct hlist_head *head;
1297 	uint32_t i;
1298 
1299 	if (!bat_priv->tt.global_hash)
1300 		return;
1301 
1302 	hash = bat_priv->tt.global_hash;
1303 
1304 	for (i = 0; i < hash->size; i++) {
1305 		head = &hash->table[i];
1306 		list_lock = &hash->list_locks[i];
1307 
1308 		spin_lock_bh(list_lock);
1309 		hlist_for_each_entry_safe(tt_common_entry, node_tmp,
1310 					  head, hash_entry) {
1311 			hlist_del_rcu(&tt_common_entry->hash_entry);
1312 			tt_global = container_of(tt_common_entry,
1313 						 struct batadv_tt_global_entry,
1314 						 common);
1315 			batadv_tt_global_entry_free_ref(tt_global);
1316 		}
1317 		spin_unlock_bh(list_lock);
1318 	}
1319 
1320 	batadv_hash_destroy(hash);
1321 
1322 	bat_priv->tt.global_hash = NULL;
1323 }
1324 
1325 static bool
_batadv_is_ap_isolated(struct batadv_tt_local_entry * tt_local_entry,struct batadv_tt_global_entry * tt_global_entry)1326 _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
1327 		       struct batadv_tt_global_entry *tt_global_entry)
1328 {
1329 	bool ret = false;
1330 
1331 	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
1332 	    tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
1333 		ret = true;
1334 
1335 	return ret;
1336 }
1337 
batadv_transtable_search(struct batadv_priv * bat_priv,const uint8_t * src,const uint8_t * addr)1338 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1339 						  const uint8_t *src,
1340 						  const uint8_t *addr)
1341 {
1342 	struct batadv_tt_local_entry *tt_local_entry = NULL;
1343 	struct batadv_tt_global_entry *tt_global_entry = NULL;
1344 	struct batadv_orig_node *orig_node = NULL;
1345 	struct batadv_tt_orig_list_entry *best_entry;
1346 
1347 	if (src && atomic_read(&bat_priv->ap_isolation)) {
1348 		tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
1349 		if (!tt_local_entry ||
1350 		    (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
1351 			goto out;
1352 	}
1353 
1354 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
1355 	if (!tt_global_entry)
1356 		goto out;
1357 
1358 	/* check whether the clients should not communicate due to AP
1359 	 * isolation
1360 	 */
1361 	if (tt_local_entry &&
1362 	    _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
1363 		goto out;
1364 
1365 	rcu_read_lock();
1366 	best_entry = batadv_transtable_best_orig(tt_global_entry);
1367 	/* found anything? */
1368 	if (best_entry)
1369 		orig_node = best_entry->orig_node;
1370 	if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
1371 		orig_node = NULL;
1372 	rcu_read_unlock();
1373 
1374 out:
1375 	if (tt_global_entry)
1376 		batadv_tt_global_entry_free_ref(tt_global_entry);
1377 	if (tt_local_entry)
1378 		batadv_tt_local_entry_free_ref(tt_local_entry);
1379 
1380 	return orig_node;
1381 }
1382 
1383 /* Calculates the checksum of the local table of a given orig_node */
batadv_tt_global_crc(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)1384 static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1385 				     struct batadv_orig_node *orig_node)
1386 {
1387 	uint16_t total = 0, total_one;
1388 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1389 	struct batadv_tt_common_entry *tt_common;
1390 	struct batadv_tt_global_entry *tt_global;
1391 	struct hlist_head *head;
1392 	uint32_t i;
1393 	int j;
1394 
1395 	for (i = 0; i < hash->size; i++) {
1396 		head = &hash->table[i];
1397 
1398 		rcu_read_lock();
1399 		hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
1400 			tt_global = container_of(tt_common,
1401 						 struct batadv_tt_global_entry,
1402 						 common);
1403 			/* Roaming clients are in the global table for
1404 			 * consistency only. They don't have to be
1405 			 * taken into account while computing the
1406 			 * global crc
1407 			 */
1408 			if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
1409 				continue;
1410 			/* Temporary clients have not been announced yet, so
1411 			 * they have to be skipped while computing the global
1412 			 * crc
1413 			 */
1414 			if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
1415 				continue;
1416 
1417 			/* find out if this global entry is announced by this
1418 			 * originator
1419 			 */
1420 			if (!batadv_tt_global_entry_has_orig(tt_global,
1421 							     orig_node))
1422 				continue;
1423 
1424 			total_one = 0;
1425 			for (j = 0; j < ETH_ALEN; j++)
1426 				total_one = crc16_byte(total_one,
1427 						       tt_common->addr[j]);
1428 			total ^= total_one;
1429 		}
1430 		rcu_read_unlock();
1431 	}
1432 
1433 	return total;
1434 }
1435 
1436 /* Calculates the checksum of the local table */
batadv_tt_local_crc(struct batadv_priv * bat_priv)1437 static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
1438 {
1439 	uint16_t total = 0, total_one;
1440 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1441 	struct batadv_tt_common_entry *tt_common;
1442 	struct hlist_head *head;
1443 	uint32_t i;
1444 	int j;
1445 
1446 	for (i = 0; i < hash->size; i++) {
1447 		head = &hash->table[i];
1448 
1449 		rcu_read_lock();
1450 		hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
1451 			/* not yet committed clients have not to be taken into
1452 			 * account while computing the CRC
1453 			 */
1454 			if (tt_common->flags & BATADV_TT_CLIENT_NEW)
1455 				continue;
1456 			total_one = 0;
1457 			for (j = 0; j < ETH_ALEN; j++)
1458 				total_one = crc16_byte(total_one,
1459 						       tt_common->addr[j]);
1460 			total ^= total_one;
1461 		}
1462 		rcu_read_unlock();
1463 	}
1464 
1465 	return total;
1466 }
1467 
batadv_tt_req_list_free(struct batadv_priv * bat_priv)1468 static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
1469 {
1470 	struct batadv_tt_req_node *node, *safe;
1471 
1472 	spin_lock_bh(&bat_priv->tt.req_list_lock);
1473 
1474 	list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1475 		list_del(&node->list);
1476 		kfree(node);
1477 	}
1478 
1479 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
1480 }
1481 
batadv_tt_save_orig_buffer(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * tt_buff,uint8_t tt_num_changes)1482 static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
1483 				       struct batadv_orig_node *orig_node,
1484 				       const unsigned char *tt_buff,
1485 				       uint8_t tt_num_changes)
1486 {
1487 	uint16_t tt_buff_len = batadv_tt_len(tt_num_changes);
1488 
1489 	/* Replace the old buffer only if I received something in the
1490 	 * last OGM (the OGM could carry no changes)
1491 	 */
1492 	spin_lock_bh(&orig_node->tt_buff_lock);
1493 	if (tt_buff_len > 0) {
1494 		kfree(orig_node->tt_buff);
1495 		orig_node->tt_buff_len = 0;
1496 		orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
1497 		if (orig_node->tt_buff) {
1498 			memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
1499 			orig_node->tt_buff_len = tt_buff_len;
1500 		}
1501 	}
1502 	spin_unlock_bh(&orig_node->tt_buff_lock);
1503 }
1504 
batadv_tt_req_purge(struct batadv_priv * bat_priv)1505 static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
1506 {
1507 	struct batadv_tt_req_node *node, *safe;
1508 
1509 	spin_lock_bh(&bat_priv->tt.req_list_lock);
1510 	list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1511 		if (batadv_has_timed_out(node->issued_at,
1512 					 BATADV_TT_REQUEST_TIMEOUT)) {
1513 			list_del(&node->list);
1514 			kfree(node);
1515 		}
1516 	}
1517 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
1518 }
1519 
1520 /* returns the pointer to the new tt_req_node struct if no request
1521  * has already been issued for this orig_node, NULL otherwise
1522  */
1523 static struct batadv_tt_req_node *
batadv_new_tt_req_node(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node)1524 batadv_new_tt_req_node(struct batadv_priv *bat_priv,
1525 		       struct batadv_orig_node *orig_node)
1526 {
1527 	struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1528 
1529 	spin_lock_bh(&bat_priv->tt.req_list_lock);
1530 	list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
1531 		if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
1532 		    !batadv_has_timed_out(tt_req_node_tmp->issued_at,
1533 					  BATADV_TT_REQUEST_TIMEOUT))
1534 			goto unlock;
1535 	}
1536 
1537 	tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
1538 	if (!tt_req_node)
1539 		goto unlock;
1540 
1541 	memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1542 	tt_req_node->issued_at = jiffies;
1543 
1544 	list_add(&tt_req_node->list, &bat_priv->tt.req_list);
1545 unlock:
1546 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
1547 	return tt_req_node;
1548 }
1549 
1550 /* data_ptr is useless here, but has to be kept to respect the prototype */
batadv_tt_local_valid_entry(const void * entry_ptr,const void * data_ptr)1551 static int batadv_tt_local_valid_entry(const void *entry_ptr,
1552 				       const void *data_ptr)
1553 {
1554 	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
1555 
1556 	if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
1557 		return 0;
1558 	return 1;
1559 }
1560 
batadv_tt_global_valid(const void * entry_ptr,const void * data_ptr)1561 static int batadv_tt_global_valid(const void *entry_ptr,
1562 				  const void *data_ptr)
1563 {
1564 	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
1565 	const struct batadv_tt_global_entry *tt_global_entry;
1566 	const struct batadv_orig_node *orig_node = data_ptr;
1567 
1568 	if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
1569 	    tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
1570 		return 0;
1571 
1572 	tt_global_entry = container_of(tt_common_entry,
1573 				       struct batadv_tt_global_entry,
1574 				       common);
1575 
1576 	return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
1577 }
1578 
1579 static struct sk_buff *
batadv_tt_response_fill_table(uint16_t tt_len,uint8_t ttvn,struct batadv_hashtable * hash,struct batadv_priv * bat_priv,int (* valid_cb)(const void *,const void *),void * cb_data)1580 batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1581 			      struct batadv_hashtable *hash,
1582 			      struct batadv_priv *bat_priv,
1583 			      int (*valid_cb)(const void *, const void *),
1584 			      void *cb_data)
1585 {
1586 	struct batadv_tt_common_entry *tt_common_entry;
1587 	struct batadv_tt_query_packet *tt_response;
1588 	struct batadv_tt_change *tt_change;
1589 	struct hlist_head *head;
1590 	struct sk_buff *skb = NULL;
1591 	uint16_t tt_tot, tt_count;
1592 	ssize_t tt_query_size = sizeof(struct batadv_tt_query_packet);
1593 	uint32_t i;
1594 	size_t len;
1595 
1596 	if (tt_query_size + tt_len > bat_priv->soft_iface->mtu) {
1597 		tt_len = bat_priv->soft_iface->mtu - tt_query_size;
1598 		tt_len -= tt_len % sizeof(struct batadv_tt_change);
1599 	}
1600 	tt_tot = tt_len / sizeof(struct batadv_tt_change);
1601 
1602 	len = tt_query_size + tt_len;
1603 	skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
1604 	if (!skb)
1605 		goto out;
1606 
1607 	skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1608 	tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
1609 	tt_response->ttvn = ttvn;
1610 
1611 	tt_change = (struct batadv_tt_change *)(skb->data + tt_query_size);
1612 	tt_count = 0;
1613 
1614 	rcu_read_lock();
1615 	for (i = 0; i < hash->size; i++) {
1616 		head = &hash->table[i];
1617 
1618 		hlist_for_each_entry_rcu(tt_common_entry,
1619 					 head, hash_entry) {
1620 			if (tt_count == tt_tot)
1621 				break;
1622 
1623 			if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
1624 				continue;
1625 
1626 			memcpy(tt_change->addr, tt_common_entry->addr,
1627 			       ETH_ALEN);
1628 			tt_change->flags = tt_common_entry->flags;
1629 
1630 			tt_count++;
1631 			tt_change++;
1632 		}
1633 	}
1634 	rcu_read_unlock();
1635 
1636 	/* store in the message the number of entries we have successfully
1637 	 * copied
1638 	 */
1639 	tt_response->tt_data = htons(tt_count);
1640 
1641 out:
1642 	return skb;
1643 }
1644 
batadv_send_tt_request(struct batadv_priv * bat_priv,struct batadv_orig_node * dst_orig_node,uint8_t ttvn,uint16_t tt_crc,bool full_table)1645 static int batadv_send_tt_request(struct batadv_priv *bat_priv,
1646 				  struct batadv_orig_node *dst_orig_node,
1647 				  uint8_t ttvn, uint16_t tt_crc,
1648 				  bool full_table)
1649 {
1650 	struct sk_buff *skb = NULL;
1651 	struct batadv_tt_query_packet *tt_request;
1652 	struct batadv_hard_iface *primary_if;
1653 	struct batadv_tt_req_node *tt_req_node = NULL;
1654 	int ret = 1;
1655 	size_t tt_req_len;
1656 
1657 	primary_if = batadv_primary_if_get_selected(bat_priv);
1658 	if (!primary_if)
1659 		goto out;
1660 
1661 	/* The new tt_req will be issued only if I'm not waiting for a
1662 	 * reply from the same orig_node yet
1663 	 */
1664 	tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node);
1665 	if (!tt_req_node)
1666 		goto out;
1667 
1668 	skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN);
1669 	if (!skb)
1670 		goto out;
1671 
1672 	skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1673 
1674 	tt_req_len = sizeof(*tt_request);
1675 	tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
1676 
1677 	tt_request->header.packet_type = BATADV_TT_QUERY;
1678 	tt_request->header.version = BATADV_COMPAT_VERSION;
1679 	memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1680 	memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1681 	tt_request->header.ttl = BATADV_TTL;
1682 	tt_request->ttvn = ttvn;
1683 	tt_request->tt_data = htons(tt_crc);
1684 	tt_request->flags = BATADV_TT_REQUEST;
1685 
1686 	if (full_table)
1687 		tt_request->flags |= BATADV_TT_FULL_TABLE;
1688 
1689 	batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
1690 		   dst_orig_node->orig, (full_table ? 'F' : '.'));
1691 
1692 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
1693 
1694 	if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL))
1695 		ret = 0;
1696 
1697 out:
1698 	if (primary_if)
1699 		batadv_hardif_free_ref(primary_if);
1700 	if (ret)
1701 		kfree_skb(skb);
1702 	if (ret && tt_req_node) {
1703 		spin_lock_bh(&bat_priv->tt.req_list_lock);
1704 		list_del(&tt_req_node->list);
1705 		spin_unlock_bh(&bat_priv->tt.req_list_lock);
1706 		kfree(tt_req_node);
1707 	}
1708 	return ret;
1709 }
1710 
1711 static bool
batadv_send_other_tt_response(struct batadv_priv * bat_priv,struct batadv_tt_query_packet * tt_request)1712 batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1713 			      struct batadv_tt_query_packet *tt_request)
1714 {
1715 	struct batadv_orig_node *req_dst_orig_node;
1716 	struct batadv_orig_node *res_dst_orig_node = NULL;
1717 	uint8_t orig_ttvn, req_ttvn, ttvn;
1718 	int ret = false;
1719 	unsigned char *tt_buff;
1720 	bool full_table;
1721 	uint16_t tt_len, tt_tot;
1722 	struct sk_buff *skb = NULL;
1723 	struct batadv_tt_query_packet *tt_response;
1724 	uint8_t *packet_pos;
1725 	size_t len;
1726 
1727 	batadv_dbg(BATADV_DBG_TT, bat_priv,
1728 		   "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
1729 		   tt_request->src, tt_request->ttvn, tt_request->dst,
1730 		   (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1731 
1732 	/* Let's get the orig node of the REAL destination */
1733 	req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst);
1734 	if (!req_dst_orig_node)
1735 		goto out;
1736 
1737 	res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src);
1738 	if (!res_dst_orig_node)
1739 		goto out;
1740 
1741 	orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1742 	req_ttvn = tt_request->ttvn;
1743 
1744 	/* I don't have the requested data */
1745 	if (orig_ttvn != req_ttvn ||
1746 	    tt_request->tt_data != htons(req_dst_orig_node->tt_crc))
1747 		goto out;
1748 
1749 	/* If the full table has been explicitly requested */
1750 	if (tt_request->flags & BATADV_TT_FULL_TABLE ||
1751 	    !req_dst_orig_node->tt_buff)
1752 		full_table = true;
1753 	else
1754 		full_table = false;
1755 
1756 	/* In this version, fragmentation is not implemented, then
1757 	 * I'll send only one packet with as much TT entries as I can
1758 	 */
1759 	if (!full_table) {
1760 		spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1761 		tt_len = req_dst_orig_node->tt_buff_len;
1762 		tt_tot = tt_len / sizeof(struct batadv_tt_change);
1763 
1764 		len = sizeof(*tt_response) + tt_len;
1765 		skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
1766 		if (!skb)
1767 			goto unlock;
1768 
1769 		skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1770 		packet_pos = skb_put(skb, len);
1771 		tt_response = (struct batadv_tt_query_packet *)packet_pos;
1772 		tt_response->ttvn = req_ttvn;
1773 		tt_response->tt_data = htons(tt_tot);
1774 
1775 		tt_buff = skb->data + sizeof(*tt_response);
1776 		/* Copy the last orig_node's OGM buffer */
1777 		memcpy(tt_buff, req_dst_orig_node->tt_buff,
1778 		       req_dst_orig_node->tt_buff_len);
1779 
1780 		spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1781 	} else {
1782 		tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size);
1783 		tt_len *= sizeof(struct batadv_tt_change);
1784 		ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1785 
1786 		skb = batadv_tt_response_fill_table(tt_len, ttvn,
1787 						    bat_priv->tt.global_hash,
1788 						    bat_priv,
1789 						    batadv_tt_global_valid,
1790 						    req_dst_orig_node);
1791 		if (!skb)
1792 			goto out;
1793 
1794 		tt_response = (struct batadv_tt_query_packet *)skb->data;
1795 	}
1796 
1797 	tt_response->header.packet_type = BATADV_TT_QUERY;
1798 	tt_response->header.version = BATADV_COMPAT_VERSION;
1799 	tt_response->header.ttl = BATADV_TTL;
1800 	memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1801 	memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1802 	tt_response->flags = BATADV_TT_RESPONSE;
1803 
1804 	if (full_table)
1805 		tt_response->flags |= BATADV_TT_FULL_TABLE;
1806 
1807 	batadv_dbg(BATADV_DBG_TT, bat_priv,
1808 		   "Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n",
1809 		   res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn);
1810 
1811 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
1812 
1813 	if (batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL))
1814 		ret = true;
1815 	goto out;
1816 
1817 unlock:
1818 	spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1819 
1820 out:
1821 	if (res_dst_orig_node)
1822 		batadv_orig_node_free_ref(res_dst_orig_node);
1823 	if (req_dst_orig_node)
1824 		batadv_orig_node_free_ref(req_dst_orig_node);
1825 	if (!ret)
1826 		kfree_skb(skb);
1827 	return ret;
1828 }
1829 
1830 static bool
batadv_send_my_tt_response(struct batadv_priv * bat_priv,struct batadv_tt_query_packet * tt_request)1831 batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1832 			   struct batadv_tt_query_packet *tt_request)
1833 {
1834 	struct batadv_orig_node *orig_node;
1835 	struct batadv_hard_iface *primary_if = NULL;
1836 	uint8_t my_ttvn, req_ttvn, ttvn;
1837 	int ret = false;
1838 	unsigned char *tt_buff;
1839 	bool full_table;
1840 	uint16_t tt_len, tt_tot;
1841 	struct sk_buff *skb = NULL;
1842 	struct batadv_tt_query_packet *tt_response;
1843 	uint8_t *packet_pos;
1844 	size_t len;
1845 
1846 	batadv_dbg(BATADV_DBG_TT, bat_priv,
1847 		   "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
1848 		   tt_request->src, tt_request->ttvn,
1849 		   (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1850 
1851 
1852 	my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1853 	req_ttvn = tt_request->ttvn;
1854 
1855 	orig_node = batadv_orig_hash_find(bat_priv, tt_request->src);
1856 	if (!orig_node)
1857 		goto out;
1858 
1859 	primary_if = batadv_primary_if_get_selected(bat_priv);
1860 	if (!primary_if)
1861 		goto out;
1862 
1863 	/* If the full table has been explicitly requested or the gap
1864 	 * is too big send the whole local translation table
1865 	 */
1866 	if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
1867 	    !bat_priv->tt.last_changeset)
1868 		full_table = true;
1869 	else
1870 		full_table = false;
1871 
1872 	/* In this version, fragmentation is not implemented, then
1873 	 * I'll send only one packet with as much TT entries as I can
1874 	 */
1875 	if (!full_table) {
1876 		spin_lock_bh(&bat_priv->tt.last_changeset_lock);
1877 		tt_len = bat_priv->tt.last_changeset_len;
1878 		tt_tot = tt_len / sizeof(struct batadv_tt_change);
1879 
1880 		len = sizeof(*tt_response) + tt_len;
1881 		skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
1882 		if (!skb)
1883 			goto unlock;
1884 
1885 		skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
1886 		packet_pos = skb_put(skb, len);
1887 		tt_response = (struct batadv_tt_query_packet *)packet_pos;
1888 		tt_response->ttvn = req_ttvn;
1889 		tt_response->tt_data = htons(tt_tot);
1890 
1891 		tt_buff = skb->data + sizeof(*tt_response);
1892 		memcpy(tt_buff, bat_priv->tt.last_changeset,
1893 		       bat_priv->tt.last_changeset_len);
1894 		spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1895 	} else {
1896 		tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num);
1897 		tt_len *= sizeof(struct batadv_tt_change);
1898 		ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1899 
1900 		skb = batadv_tt_response_fill_table(tt_len, ttvn,
1901 						    bat_priv->tt.local_hash,
1902 						    bat_priv,
1903 						    batadv_tt_local_valid_entry,
1904 						    NULL);
1905 		if (!skb)
1906 			goto out;
1907 
1908 		tt_response = (struct batadv_tt_query_packet *)skb->data;
1909 	}
1910 
1911 	tt_response->header.packet_type = BATADV_TT_QUERY;
1912 	tt_response->header.version = BATADV_COMPAT_VERSION;
1913 	tt_response->header.ttl = BATADV_TTL;
1914 	memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1915 	memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1916 	tt_response->flags = BATADV_TT_RESPONSE;
1917 
1918 	if (full_table)
1919 		tt_response->flags |= BATADV_TT_FULL_TABLE;
1920 
1921 	batadv_dbg(BATADV_DBG_TT, bat_priv,
1922 		   "Sending TT_RESPONSE to %pM [%c]\n",
1923 		   orig_node->orig,
1924 		   (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1925 
1926 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
1927 
1928 	if (batadv_send_skb_to_orig(skb, orig_node, NULL))
1929 		ret = true;
1930 	goto out;
1931 
1932 unlock:
1933 	spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1934 out:
1935 	if (orig_node)
1936 		batadv_orig_node_free_ref(orig_node);
1937 	if (primary_if)
1938 		batadv_hardif_free_ref(primary_if);
1939 	if (!ret)
1940 		kfree_skb(skb);
1941 	/* This packet was for me, so it doesn't need to be re-routed */
1942 	return true;
1943 }
1944 
batadv_send_tt_response(struct batadv_priv * bat_priv,struct batadv_tt_query_packet * tt_request)1945 bool batadv_send_tt_response(struct batadv_priv *bat_priv,
1946 			     struct batadv_tt_query_packet *tt_request)
1947 {
1948 	if (batadv_is_my_mac(bat_priv, tt_request->dst)) {
1949 		/* don't answer backbone gws! */
1950 		if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src))
1951 			return true;
1952 
1953 		return batadv_send_my_tt_response(bat_priv, tt_request);
1954 	} else {
1955 		return batadv_send_other_tt_response(bat_priv, tt_request);
1956 	}
1957 }
1958 
_batadv_tt_update_changes(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,struct batadv_tt_change * tt_change,uint16_t tt_num_changes,uint8_t ttvn)1959 static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
1960 				      struct batadv_orig_node *orig_node,
1961 				      struct batadv_tt_change *tt_change,
1962 				      uint16_t tt_num_changes, uint8_t ttvn)
1963 {
1964 	int i;
1965 	int roams;
1966 
1967 	for (i = 0; i < tt_num_changes; i++) {
1968 		if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
1969 			roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
1970 			batadv_tt_global_del(bat_priv, orig_node,
1971 					     (tt_change + i)->addr,
1972 					     "tt removed by changes",
1973 					     roams);
1974 		} else {
1975 			if (!batadv_tt_global_add(bat_priv, orig_node,
1976 						  (tt_change + i)->addr,
1977 						  (tt_change + i)->flags, ttvn))
1978 				/* In case of problem while storing a
1979 				 * global_entry, we stop the updating
1980 				 * procedure without committing the
1981 				 * ttvn change. This will avoid to send
1982 				 * corrupted data on tt_request
1983 				 */
1984 				return;
1985 		}
1986 	}
1987 	orig_node->tt_initialised = true;
1988 }
1989 
batadv_tt_fill_gtable(struct batadv_priv * bat_priv,struct batadv_tt_query_packet * tt_response)1990 static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
1991 				  struct batadv_tt_query_packet *tt_response)
1992 {
1993 	struct batadv_orig_node *orig_node;
1994 
1995 	orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
1996 	if (!orig_node)
1997 		goto out;
1998 
1999 	/* Purge the old table first.. */
2000 	batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table");
2001 
2002 	_batadv_tt_update_changes(bat_priv, orig_node,
2003 				  (struct batadv_tt_change *)(tt_response + 1),
2004 				  ntohs(tt_response->tt_data),
2005 				  tt_response->ttvn);
2006 
2007 	spin_lock_bh(&orig_node->tt_buff_lock);
2008 	kfree(orig_node->tt_buff);
2009 	orig_node->tt_buff_len = 0;
2010 	orig_node->tt_buff = NULL;
2011 	spin_unlock_bh(&orig_node->tt_buff_lock);
2012 
2013 	atomic_set(&orig_node->last_ttvn, tt_response->ttvn);
2014 
2015 out:
2016 	if (orig_node)
2017 		batadv_orig_node_free_ref(orig_node);
2018 }
2019 
batadv_tt_update_changes(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,uint16_t tt_num_changes,uint8_t ttvn,struct batadv_tt_change * tt_change)2020 static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
2021 				     struct batadv_orig_node *orig_node,
2022 				     uint16_t tt_num_changes, uint8_t ttvn,
2023 				     struct batadv_tt_change *tt_change)
2024 {
2025 	_batadv_tt_update_changes(bat_priv, orig_node, tt_change,
2026 				  tt_num_changes, ttvn);
2027 
2028 	batadv_tt_save_orig_buffer(bat_priv, orig_node,
2029 				   (unsigned char *)tt_change, tt_num_changes);
2030 	atomic_set(&orig_node->last_ttvn, ttvn);
2031 }
2032 
batadv_is_my_client(struct batadv_priv * bat_priv,const uint8_t * addr)2033 bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
2034 {
2035 	struct batadv_tt_local_entry *tt_local_entry;
2036 	bool ret = false;
2037 
2038 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
2039 	if (!tt_local_entry)
2040 		goto out;
2041 	/* Check if the client has been logically deleted (but is kept for
2042 	 * consistency purpose)
2043 	 */
2044 	if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
2045 	    (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
2046 		goto out;
2047 	ret = true;
2048 out:
2049 	if (tt_local_entry)
2050 		batadv_tt_local_entry_free_ref(tt_local_entry);
2051 	return ret;
2052 }
2053 
batadv_handle_tt_response(struct batadv_priv * bat_priv,struct batadv_tt_query_packet * tt_response)2054 void batadv_handle_tt_response(struct batadv_priv *bat_priv,
2055 			       struct batadv_tt_query_packet *tt_response)
2056 {
2057 	struct batadv_tt_req_node *node, *safe;
2058 	struct batadv_orig_node *orig_node = NULL;
2059 	struct batadv_tt_change *tt_change;
2060 
2061 	batadv_dbg(BATADV_DBG_TT, bat_priv,
2062 		   "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
2063 		   tt_response->src, tt_response->ttvn,
2064 		   ntohs(tt_response->tt_data),
2065 		   (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2066 
2067 	/* we should have never asked a backbone gw */
2068 	if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src))
2069 		goto out;
2070 
2071 	orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
2072 	if (!orig_node)
2073 		goto out;
2074 
2075 	if (tt_response->flags & BATADV_TT_FULL_TABLE) {
2076 		batadv_tt_fill_gtable(bat_priv, tt_response);
2077 	} else {
2078 		tt_change = (struct batadv_tt_change *)(tt_response + 1);
2079 		batadv_tt_update_changes(bat_priv, orig_node,
2080 					 ntohs(tt_response->tt_data),
2081 					 tt_response->ttvn, tt_change);
2082 	}
2083 
2084 	/* Delete the tt_req_node from pending tt_requests list */
2085 	spin_lock_bh(&bat_priv->tt.req_list_lock);
2086 	list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2087 		if (!batadv_compare_eth(node->addr, tt_response->src))
2088 			continue;
2089 		list_del(&node->list);
2090 		kfree(node);
2091 	}
2092 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
2093 
2094 	/* Recalculate the CRC for this orig_node and store it */
2095 	orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2096 out:
2097 	if (orig_node)
2098 		batadv_orig_node_free_ref(orig_node);
2099 }
2100 
batadv_tt_init(struct batadv_priv * bat_priv)2101 int batadv_tt_init(struct batadv_priv *bat_priv)
2102 {
2103 	int ret;
2104 
2105 	ret = batadv_tt_local_init(bat_priv);
2106 	if (ret < 0)
2107 		return ret;
2108 
2109 	ret = batadv_tt_global_init(bat_priv);
2110 	if (ret < 0)
2111 		return ret;
2112 
2113 	INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
2114 	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2115 			   msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2116 
2117 	return 1;
2118 }
2119 
batadv_tt_roam_list_free(struct batadv_priv * bat_priv)2120 static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
2121 {
2122 	struct batadv_tt_roam_node *node, *safe;
2123 
2124 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
2125 
2126 	list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
2127 		list_del(&node->list);
2128 		kfree(node);
2129 	}
2130 
2131 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2132 }
2133 
batadv_tt_roam_purge(struct batadv_priv * bat_priv)2134 static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
2135 {
2136 	struct batadv_tt_roam_node *node, *safe;
2137 
2138 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
2139 	list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
2140 		if (!batadv_has_timed_out(node->first_time,
2141 					  BATADV_ROAMING_MAX_TIME))
2142 			continue;
2143 
2144 		list_del(&node->list);
2145 		kfree(node);
2146 	}
2147 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2148 }
2149 
2150 /* This function checks whether the client already reached the
2151  * maximum number of possible roaming phases. In this case the ROAMING_ADV
2152  * will not be sent.
2153  *
2154  * returns true if the ROAMING_ADV can be sent, false otherwise
2155  */
batadv_tt_check_roam_count(struct batadv_priv * bat_priv,uint8_t * client)2156 static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
2157 				       uint8_t *client)
2158 {
2159 	struct batadv_tt_roam_node *tt_roam_node;
2160 	bool ret = false;
2161 
2162 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
2163 	/* The new tt_req will be issued only if I'm not waiting for a
2164 	 * reply from the same orig_node yet
2165 	 */
2166 	list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
2167 		if (!batadv_compare_eth(tt_roam_node->addr, client))
2168 			continue;
2169 
2170 		if (batadv_has_timed_out(tt_roam_node->first_time,
2171 					 BATADV_ROAMING_MAX_TIME))
2172 			continue;
2173 
2174 		if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter))
2175 			/* Sorry, you roamed too many times! */
2176 			goto unlock;
2177 		ret = true;
2178 		break;
2179 	}
2180 
2181 	if (!ret) {
2182 		tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
2183 		if (!tt_roam_node)
2184 			goto unlock;
2185 
2186 		tt_roam_node->first_time = jiffies;
2187 		atomic_set(&tt_roam_node->counter,
2188 			   BATADV_ROAMING_MAX_COUNT - 1);
2189 		memcpy(tt_roam_node->addr, client, ETH_ALEN);
2190 
2191 		list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
2192 		ret = true;
2193 	}
2194 
2195 unlock:
2196 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2197 	return ret;
2198 }
2199 
batadv_send_roam_adv(struct batadv_priv * bat_priv,uint8_t * client,struct batadv_orig_node * orig_node)2200 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2201 				 struct batadv_orig_node *orig_node)
2202 {
2203 	struct sk_buff *skb = NULL;
2204 	struct batadv_roam_adv_packet *roam_adv_packet;
2205 	int ret = 1;
2206 	struct batadv_hard_iface *primary_if;
2207 	size_t len = sizeof(*roam_adv_packet);
2208 
2209 	/* before going on we have to check whether the client has
2210 	 * already roamed to us too many times
2211 	 */
2212 	if (!batadv_tt_check_roam_count(bat_priv, client))
2213 		goto out;
2214 
2215 	skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN);
2216 	if (!skb)
2217 		goto out;
2218 
2219 	skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
2220 
2221 	roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
2222 
2223 	roam_adv_packet->header.packet_type = BATADV_ROAM_ADV;
2224 	roam_adv_packet->header.version = BATADV_COMPAT_VERSION;
2225 	roam_adv_packet->header.ttl = BATADV_TTL;
2226 	roam_adv_packet->reserved = 0;
2227 	primary_if = batadv_primary_if_get_selected(bat_priv);
2228 	if (!primary_if)
2229 		goto out;
2230 	memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
2231 	batadv_hardif_free_ref(primary_if);
2232 	memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
2233 	memcpy(roam_adv_packet->client, client, ETH_ALEN);
2234 
2235 	batadv_dbg(BATADV_DBG_TT, bat_priv,
2236 		   "Sending ROAMING_ADV to %pM (client %pM)\n",
2237 		   orig_node->orig, client);
2238 
2239 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
2240 
2241 	if (batadv_send_skb_to_orig(skb, orig_node, NULL))
2242 		ret = 0;
2243 
2244 out:
2245 	if (ret && skb)
2246 		kfree_skb(skb);
2247 	return;
2248 }
2249 
batadv_tt_purge(struct work_struct * work)2250 static void batadv_tt_purge(struct work_struct *work)
2251 {
2252 	struct delayed_work *delayed_work;
2253 	struct batadv_priv_tt *priv_tt;
2254 	struct batadv_priv *bat_priv;
2255 
2256 	delayed_work = container_of(work, struct delayed_work, work);
2257 	priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
2258 	bat_priv = container_of(priv_tt, struct batadv_priv, tt);
2259 
2260 	batadv_tt_local_purge(bat_priv);
2261 	batadv_tt_global_purge(bat_priv);
2262 	batadv_tt_req_purge(bat_priv);
2263 	batadv_tt_roam_purge(bat_priv);
2264 
2265 	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2266 			   msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2267 }
2268 
batadv_tt_free(struct batadv_priv * bat_priv)2269 void batadv_tt_free(struct batadv_priv *bat_priv)
2270 {
2271 	cancel_delayed_work_sync(&bat_priv->tt.work);
2272 
2273 	batadv_tt_local_table_free(bat_priv);
2274 	batadv_tt_global_table_free(bat_priv);
2275 	batadv_tt_req_list_free(bat_priv);
2276 	batadv_tt_changes_list_free(bat_priv);
2277 	batadv_tt_roam_list_free(bat_priv);
2278 
2279 	kfree(bat_priv->tt.last_changeset);
2280 }
2281 
2282 /* This function will enable or disable the specified flags for all the entries
2283  * in the given hash table and returns the number of modified entries
2284  */
batadv_tt_set_flags(struct batadv_hashtable * hash,uint16_t flags,bool enable)2285 static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
2286 				    uint16_t flags, bool enable)
2287 {
2288 	uint32_t i;
2289 	uint16_t changed_num = 0;
2290 	struct hlist_head *head;
2291 	struct batadv_tt_common_entry *tt_common_entry;
2292 
2293 	if (!hash)
2294 		goto out;
2295 
2296 	for (i = 0; i < hash->size; i++) {
2297 		head = &hash->table[i];
2298 
2299 		rcu_read_lock();
2300 		hlist_for_each_entry_rcu(tt_common_entry,
2301 					 head, hash_entry) {
2302 			if (enable) {
2303 				if ((tt_common_entry->flags & flags) == flags)
2304 					continue;
2305 				tt_common_entry->flags |= flags;
2306 			} else {
2307 				if (!(tt_common_entry->flags & flags))
2308 					continue;
2309 				tt_common_entry->flags &= ~flags;
2310 			}
2311 			changed_num++;
2312 		}
2313 		rcu_read_unlock();
2314 	}
2315 out:
2316 	return changed_num;
2317 }
2318 
2319 /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
batadv_tt_local_purge_pending_clients(struct batadv_priv * bat_priv)2320 static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2321 {
2322 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2323 	struct batadv_tt_common_entry *tt_common;
2324 	struct batadv_tt_local_entry *tt_local;
2325 	struct hlist_node *node_tmp;
2326 	struct hlist_head *head;
2327 	spinlock_t *list_lock; /* protects write access to the hash lists */
2328 	uint32_t i;
2329 
2330 	if (!hash)
2331 		return;
2332 
2333 	for (i = 0; i < hash->size; i++) {
2334 		head = &hash->table[i];
2335 		list_lock = &hash->list_locks[i];
2336 
2337 		spin_lock_bh(list_lock);
2338 		hlist_for_each_entry_safe(tt_common, node_tmp, head,
2339 					  hash_entry) {
2340 			if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
2341 				continue;
2342 
2343 			batadv_dbg(BATADV_DBG_TT, bat_priv,
2344 				   "Deleting local tt entry (%pM): pending\n",
2345 				   tt_common->addr);
2346 
2347 			atomic_dec(&bat_priv->tt.local_entry_num);
2348 			hlist_del_rcu(&tt_common->hash_entry);
2349 			tt_local = container_of(tt_common,
2350 						struct batadv_tt_local_entry,
2351 						common);
2352 			batadv_tt_local_entry_free_ref(tt_local);
2353 		}
2354 		spin_unlock_bh(list_lock);
2355 	}
2356 }
2357 
batadv_tt_commit_changes(struct batadv_priv * bat_priv,unsigned char ** packet_buff,int * packet_buff_len,int packet_min_len)2358 static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2359 				    unsigned char **packet_buff,
2360 				    int *packet_buff_len, int packet_min_len)
2361 {
2362 	uint16_t changed_num = 0;
2363 
2364 	if (atomic_read(&bat_priv->tt.local_changes) < 1)
2365 		return -ENOENT;
2366 
2367 	changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
2368 					  BATADV_TT_CLIENT_NEW, false);
2369 
2370 	/* all reset entries have to be counted as local entries */
2371 	atomic_add(changed_num, &bat_priv->tt.local_entry_num);
2372 	batadv_tt_local_purge_pending_clients(bat_priv);
2373 	bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv);
2374 
2375 	/* Increment the TTVN only once per OGM interval */
2376 	atomic_inc(&bat_priv->tt.vn);
2377 	batadv_dbg(BATADV_DBG_TT, bat_priv,
2378 		   "Local changes committed, updating to ttvn %u\n",
2379 		   (uint8_t)atomic_read(&bat_priv->tt.vn));
2380 
2381 	/* reset the sending counter */
2382 	atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2383 
2384 	return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
2385 					   packet_buff_len, packet_min_len);
2386 }
2387 
2388 /* when calling this function (hard_iface == primary_if) has to be true */
batadv_tt_append_diff(struct batadv_priv * bat_priv,unsigned char ** packet_buff,int * packet_buff_len,int packet_min_len)2389 int batadv_tt_append_diff(struct batadv_priv *bat_priv,
2390 			  unsigned char **packet_buff, int *packet_buff_len,
2391 			  int packet_min_len)
2392 {
2393 	int tt_num_changes;
2394 
2395 	/* if at least one change happened */
2396 	tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff,
2397 						  packet_buff_len,
2398 						  packet_min_len);
2399 
2400 	/* if the changes have been sent often enough */
2401 	if ((tt_num_changes < 0) &&
2402 	    (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) {
2403 		batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
2404 					      packet_min_len, packet_min_len);
2405 		tt_num_changes = 0;
2406 	}
2407 
2408 	return tt_num_changes;
2409 }
2410 
batadv_is_ap_isolated(struct batadv_priv * bat_priv,uint8_t * src,uint8_t * dst)2411 bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
2412 			   uint8_t *dst)
2413 {
2414 	struct batadv_tt_local_entry *tt_local_entry = NULL;
2415 	struct batadv_tt_global_entry *tt_global_entry = NULL;
2416 	bool ret = false;
2417 
2418 	if (!atomic_read(&bat_priv->ap_isolation))
2419 		goto out;
2420 
2421 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst);
2422 	if (!tt_local_entry)
2423 		goto out;
2424 
2425 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, src);
2426 	if (!tt_global_entry)
2427 		goto out;
2428 
2429 	if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
2430 		goto out;
2431 
2432 	ret = true;
2433 
2434 out:
2435 	if (tt_global_entry)
2436 		batadv_tt_global_entry_free_ref(tt_global_entry);
2437 	if (tt_local_entry)
2438 		batadv_tt_local_entry_free_ref(tt_local_entry);
2439 	return ret;
2440 }
2441 
batadv_tt_update_orig(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * tt_buff,uint8_t tt_num_changes,uint8_t ttvn,uint16_t tt_crc)2442 void batadv_tt_update_orig(struct batadv_priv *bat_priv,
2443 			   struct batadv_orig_node *orig_node,
2444 			   const unsigned char *tt_buff, uint8_t tt_num_changes,
2445 			   uint8_t ttvn, uint16_t tt_crc)
2446 {
2447 	uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
2448 	bool full_table = true;
2449 	struct batadv_tt_change *tt_change;
2450 
2451 	/* don't care about a backbone gateways updates. */
2452 	if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
2453 		return;
2454 
2455 	/* orig table not initialised AND first diff is in the OGM OR the ttvn
2456 	 * increased by one -> we can apply the attached changes
2457 	 */
2458 	if ((!orig_node->tt_initialised && ttvn == 1) ||
2459 	    ttvn - orig_ttvn == 1) {
2460 		/* the OGM could not contain the changes due to their size or
2461 		 * because they have already been sent BATADV_TT_OGM_APPEND_MAX
2462 		 * times.
2463 		 * In this case send a tt request
2464 		 */
2465 		if (!tt_num_changes) {
2466 			full_table = false;
2467 			goto request_table;
2468 		}
2469 
2470 		tt_change = (struct batadv_tt_change *)tt_buff;
2471 		batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
2472 					 ttvn, tt_change);
2473 
2474 		/* Even if we received the precomputed crc with the OGM, we
2475 		 * prefer to recompute it to spot any possible inconsistency
2476 		 * in the global table
2477 		 */
2478 		orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2479 
2480 		/* The ttvn alone is not enough to guarantee consistency
2481 		 * because a single value could represent different states
2482 		 * (due to the wrap around). Thus a node has to check whether
2483 		 * the resulting table (after applying the changes) is still
2484 		 * consistent or not. E.g. a node could disconnect while its
2485 		 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
2486 		 * checking the CRC value is mandatory to detect the
2487 		 * inconsistency
2488 		 */
2489 		if (orig_node->tt_crc != tt_crc)
2490 			goto request_table;
2491 	} else {
2492 		/* if we missed more than one change or our tables are not
2493 		 * in sync anymore -> request fresh tt data
2494 		 */
2495 		if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
2496 		    orig_node->tt_crc != tt_crc) {
2497 request_table:
2498 			batadv_dbg(BATADV_DBG_TT, bat_priv,
2499 				   "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %#.4x last_crc: %#.4x num_changes: %u)\n",
2500 				   orig_node->orig, ttvn, orig_ttvn, tt_crc,
2501 				   orig_node->tt_crc, tt_num_changes);
2502 			batadv_send_tt_request(bat_priv, orig_node, ttvn,
2503 					       tt_crc, full_table);
2504 			return;
2505 		}
2506 	}
2507 }
2508 
2509 /* returns true whether we know that the client has moved from its old
2510  * originator to another one. This entry is kept is still kept for consistency
2511  * purposes
2512  */
batadv_tt_global_client_is_roaming(struct batadv_priv * bat_priv,uint8_t * addr)2513 bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2514 					uint8_t *addr)
2515 {
2516 	struct batadv_tt_global_entry *tt_global_entry;
2517 	bool ret = false;
2518 
2519 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
2520 	if (!tt_global_entry)
2521 		goto out;
2522 
2523 	ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
2524 	batadv_tt_global_entry_free_ref(tt_global_entry);
2525 out:
2526 	return ret;
2527 }
2528 
2529 /**
2530  * batadv_tt_local_client_is_roaming - tells whether the client is roaming
2531  * @bat_priv: the bat priv with all the soft interface information
2532  * @addr: the MAC address of the local client to query
2533  *
2534  * Returns true if the local client is known to be roaming (it is not served by
2535  * this node anymore) or not. If yes, the client is still present in the table
2536  * to keep the latter consistent with the node TTVN
2537  */
batadv_tt_local_client_is_roaming(struct batadv_priv * bat_priv,uint8_t * addr)2538 bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
2539 				       uint8_t *addr)
2540 {
2541 	struct batadv_tt_local_entry *tt_local_entry;
2542 	bool ret = false;
2543 
2544 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
2545 	if (!tt_local_entry)
2546 		goto out;
2547 
2548 	ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
2549 	batadv_tt_local_entry_free_ref(tt_local_entry);
2550 out:
2551 	return ret;
2552 }
2553 
batadv_tt_add_temporary_global_entry(struct batadv_priv * bat_priv,struct batadv_orig_node * orig_node,const unsigned char * addr)2554 bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2555 					  struct batadv_orig_node *orig_node,
2556 					  const unsigned char *addr)
2557 {
2558 	bool ret = false;
2559 
2560 	/* if the originator is a backbone node (meaning it belongs to the same
2561 	 * LAN of this node) the temporary client must not be added because to
2562 	 * reach such destination the node must use the LAN instead of the mesh
2563 	 */
2564 	if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
2565 		goto out;
2566 
2567 	if (!batadv_tt_global_add(bat_priv, orig_node, addr,
2568 				  BATADV_TT_CLIENT_TEMP,
2569 				  atomic_read(&orig_node->last_ttvn)))
2570 		goto out;
2571 
2572 	batadv_dbg(BATADV_DBG_TT, bat_priv,
2573 		   "Added temporary global client (addr: %pM orig: %pM)\n",
2574 		   addr, orig_node->orig);
2575 	ret = true;
2576 out:
2577 	return ret;
2578 }
2579