translation-table.c 66.1 KB
Newer Older
1
/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
2
 *
3
 * Marek Lindner, Simon Wunderlich, Antonio Quartulli
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 */

#include "main.h"
#include "translation-table.h"
#include "soft-interface.h"
23
#include "hard-interface.h"
24
#include "send.h"
25 26
#include "hash.h"
#include "originator.h"
27
#include "routing.h"
28
#include "bridge_loop_avoidance.h"
29

30 31
#include <linux/crc16.h>

32 33
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
				 struct batadv_orig_node *orig_node);
34 35
static void batadv_tt_purge(struct work_struct *work);
static void
36
batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
37

38
/* returns 1 if they are the same mac addr */
39
static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
40
{
41
	const void *data1 = container_of(node, struct batadv_tt_common_entry,
42
					 hash_entry);
43 44 45 46

	return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}

47
static void batadv_tt_start_timer(struct batadv_priv *bat_priv)
48
{
49
	INIT_DELAYED_WORK(&bat_priv->tt_work, batadv_tt_purge);
50
	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work,
51
			   msecs_to_jiffies(5000));
52 53
}

54
static struct batadv_tt_common_entry *
55
batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data)
56 57 58
{
	struct hlist_head *head;
	struct hlist_node *node;
59 60
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
61
	uint32_t index;
62 63 64 65

	if (!hash)
		return NULL;

66
	index = batadv_choose_orig(data, hash->size);
67 68 69
	head = &hash->table[index];

	rcu_read_lock();
70
	hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) {
71
		if (!batadv_compare_eth(tt_common_entry, data))
72 73
			continue;

74
		if (!atomic_inc_not_zero(&tt_common_entry->refcount))
75 76
			continue;

77
		tt_common_entry_tmp = tt_common_entry;
78 79 80 81
		break;
	}
	rcu_read_unlock();

82
	return tt_common_entry_tmp;
83 84
}

85 86
static struct batadv_tt_local_entry *
batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
87
{
88 89
	struct batadv_tt_common_entry *tt_common_entry;
	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 93
	if (tt_common_entry)
		tt_local_entry = container_of(tt_common_entry,
94 95
					      struct batadv_tt_local_entry,
					      common);
96 97
	return tt_local_entry;
}
98

99 100
static struct batadv_tt_global_entry *
batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
101
{
102 103
	struct batadv_tt_common_entry *tt_common_entry;
	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 107
	if (tt_common_entry)
		tt_global_entry = container_of(tt_common_entry,
108 109
					       struct batadv_tt_global_entry,
					       common);
110
	return tt_global_entry;
111 112 113

}

114
static void
115
batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry)
116
{
117 118
	if (atomic_dec_and_test(&tt_local_entry->common.refcount))
		kfree_rcu(tt_local_entry, common.rcu);
119 120
}

121
static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu)
122
{
123 124
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_tt_global_entry *tt_global_entry;
125

126 127 128
	tt_common_entry = container_of(rcu, struct batadv_tt_common_entry, rcu);
	tt_global_entry = container_of(tt_common_entry,
				       struct batadv_tt_global_entry, common);
129 130 131 132

	kfree(tt_global_entry);
}

133
static void
134
batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry)
135
{
136
	if (atomic_dec_and_test(&tt_global_entry->common.refcount)) {
137
		batadv_tt_global_del_orig_list(tt_global_entry);
138
		call_rcu(&tt_global_entry->common.rcu,
139
			 batadv_tt_global_entry_free_rcu);
140 141 142
	}
}

143
static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
144
{
145
	struct batadv_tt_orig_list_entry *orig_entry;
146

147
	orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
148
	batadv_orig_node_free_ref(orig_entry->orig_node);
149 150 151
	kfree(orig_entry);
}

152
static void
153
batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
154
{
155 156
	/* to avoid race conditions, immediately decrease the tt counter */
	atomic_dec(&orig_entry->orig_node->tt_size);
157
	call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
158 159
}

160
static void batadv_tt_local_event(struct batadv_priv *bat_priv,
161
				  const uint8_t *addr, uint8_t flags)
162
{
163
	struct batadv_tt_change_node *tt_change_node, *entry, *safe;
164 165
	bool event_removed = false;
	bool del_op_requested, del_op_entry;
166 167 168 169 170 171

	tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);

	if (!tt_change_node)
		return;

172
	tt_change_node->change.flags = flags;
173 174
	memcpy(tt_change_node->change.addr, addr, ETH_ALEN);

175
	del_op_requested = flags & BATADV_TT_CLIENT_DEL;
176 177

	/* check for ADD+DEL or DEL+ADD events */
178
	spin_lock_bh(&bat_priv->tt_changes_list_lock);
179 180 181 182 183 184 185 186 187 188 189 190
	list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
				 list) {
		if (!batadv_compare_eth(entry->change.addr, addr))
			continue;

		/* DEL+ADD in the same orig interval have no effect and can be
		 * removed to avoid silly behaviour on the receiver side. The
		 * other way around (ADD+DEL) can happen in case of roaming of
		 * a client still in the NEW state. Roaming of NEW clients is
		 * now possible due to automatically recognition of "temporary"
		 * clients
		 */
191
		del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
192 193 194 195 196 197 198 199 200 201 202 203
		if (!del_op_requested && del_op_entry)
			goto del;
		if (del_op_requested && !del_op_entry)
			goto del;
		continue;
del:
		list_del(&entry->list);
		kfree(entry);
		event_removed = true;
		goto unlock;
	}

204 205
	/* track the change in the OGMinterval list */
	list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list);
206 207

unlock:
208 209
	spin_unlock_bh(&bat_priv->tt_changes_list_lock);

210 211 212 213
	if (event_removed)
		atomic_dec(&bat_priv->tt_local_changes);
	else
		atomic_inc(&bat_priv->tt_local_changes);
214 215
}

216
int batadv_tt_len(int changes_num)
217
{
218
	return changes_num * sizeof(struct batadv_tt_change);
219 220
}

221
static int batadv_tt_local_init(struct batadv_priv *bat_priv)
222
{
223
	if (bat_priv->tt_local_hash)
224
		return 0;
225

226
	bat_priv->tt_local_hash = batadv_hash_new(1024);
227

228
	if (!bat_priv->tt_local_hash)
229
		return -ENOMEM;
230

231
	return 0;
232 233
}

234 235
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
			 int ifindex)
236
{
237 238 239
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
	struct batadv_tt_local_entry *tt_local_entry = NULL;
	struct batadv_tt_global_entry *tt_global_entry = NULL;
240 241
	struct hlist_head *head;
	struct hlist_node *node;
242
	struct batadv_tt_orig_list_entry *orig_entry;
243
	int hash_added;
244

245
	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
246

247 248
	if (tt_local_entry) {
		tt_local_entry->last_seen = jiffies;
249 250
		/* possibly unset the BATADV_TT_CLIENT_PENDING flag */
		tt_local_entry->common.flags &= ~BATADV_TT_CLIENT_PENDING;
251
		goto out;
252 253
	}

254
	tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC);
255
	if (!tt_local_entry)
256
		goto out;
257

258
	batadv_dbg(BATADV_DBG_TT, bat_priv,
259 260
		   "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
		   (uint8_t)atomic_read(&bat_priv->ttvn));
261

262
	memcpy(tt_local_entry->common.addr, addr, ETH_ALEN);
263
	tt_local_entry->common.flags = BATADV_NO_FLAGS;
264
	if (batadv_is_wifi_iface(ifindex))
265
		tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI;
266 267
	atomic_set(&tt_local_entry->common.refcount, 2);
	tt_local_entry->last_seen = jiffies;
268 269

	/* the batman interface mac address should never be purged */
270
	if (batadv_compare_eth(addr, soft_iface->dev_addr))
271
		tt_local_entry->common.flags |= BATADV_TT_CLIENT_NOPURGE;
272

273 274
	/* The local entry has to be marked as NEW to avoid to send it in
	 * a full table response going out before the next ttvn increment
275 276
	 * (consistency check)
	 */
277
	tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW;
278

279
	hash_added = batadv_hash_add(bat_priv->tt_local_hash, batadv_compare_tt,
280 281
				     batadv_choose_orig,
				     &tt_local_entry->common,
282
				     &tt_local_entry->common.hash_entry);
283 284 285

	if (unlikely(hash_added != 0)) {
		/* remove the reference for the hash */
286
		batadv_tt_local_entry_free_ref(tt_local_entry);
287 288 289
		goto out;
	}

290
	batadv_tt_local_event(bat_priv, addr, tt_local_entry->common.flags);
291

292
	/* remove address from global hash if present */
293
	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
294

295 296
	/* Check whether it is a roaming! */
	if (tt_global_entry) {
297 298 299 300 301 302
		/* These node are probably going to update their tt table */
		head = &tt_global_entry->orig_list;
		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_entry, node, head, list) {
			orig_entry->orig_node->tt_poss_change = true;

303 304 305
			batadv_send_roam_adv(bat_priv,
					     tt_global_entry->common.addr,
					     orig_entry->orig_node);
306 307 308 309 310
		}
		rcu_read_unlock();
		/* The global entry has to be marked as ROAMING and
		 * has to be kept for consistency purpose
		 */
311
		tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
312
		tt_global_entry->roam_at = jiffies;
313 314 315
	}
out:
	if (tt_local_entry)
316
		batadv_tt_local_entry_free_ref(tt_local_entry);
317
	if (tt_global_entry)
318
		batadv_tt_global_entry_free_ref(tt_global_entry);
319 320
}

321 322 323 324
static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff,
					  int *packet_buff_len,
					  int min_packet_len,
					  int new_packet_len)
325 326 327 328 329 330 331 332 333 334 335 336 337 338
{
	unsigned char *new_buff;

	new_buff = kmalloc(new_packet_len, GFP_ATOMIC);

	/* keep old buffer if kmalloc should fail */
	if (new_buff) {
		memcpy(new_buff, *packet_buff, min_packet_len);
		kfree(*packet_buff);
		*packet_buff = new_buff;
		*packet_buff_len = new_packet_len;
	}
}

339
static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
340 341 342
					  unsigned char **packet_buff,
					  int *packet_buff_len,
					  int min_packet_len)
343
{
344
	struct batadv_hard_iface *primary_if;
345 346
	int req_len;

347
	primary_if = batadv_primary_if_get_selected(bat_priv);
348 349

	req_len = min_packet_len;
350
	req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes));
351 352 353 354 355 356 357

	/* if we have too many changes for one packet don't send any
	 * and wait for the tt table request which will be fragmented
	 */
	if ((!primary_if) || (req_len > primary_if->soft_iface->mtu))
		req_len = min_packet_len;

358 359
	batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
				      min_packet_len, req_len);
360 361

	if (primary_if)
362
		batadv_hardif_free_ref(primary_if);
363 364
}

365
static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
366 367 368
				       unsigned char **packet_buff,
				       int *packet_buff_len,
				       int min_packet_len)
369
{
370
	struct batadv_tt_change_node *entry, *safe;
371 372 373
	int count = 0, tot_changes = 0, new_len;
	unsigned char *tt_buff;

374 375
	batadv_tt_prepare_packet_buff(bat_priv, packet_buff,
				      packet_buff_len, min_packet_len);
376

377 378 379 380
	new_len = *packet_buff_len - min_packet_len;
	tt_buff = *packet_buff + min_packet_len;

	if (new_len > 0)
381
		tot_changes = new_len / batadv_tt_len(1);
382

383 384
	spin_lock_bh(&bat_priv->tt_changes_list_lock);
	atomic_set(&bat_priv->tt_local_changes, 0);
385

386
	list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
387
				 list) {
388
		if (count < tot_changes) {
389
			memcpy(tt_buff + batadv_tt_len(count),
390
			       &entry->change, sizeof(struct batadv_tt_change));
391 392
			count++;
		}
393 394
		list_del(&entry->list);
		kfree(entry);
395
	}
396 397 398 399 400 401 402
	spin_unlock_bh(&bat_priv->tt_changes_list_lock);

	/* Keep the buffer for possible tt_request */
	spin_lock_bh(&bat_priv->tt_buff_lock);
	kfree(bat_priv->tt_buff);
	bat_priv->tt_buff_len = 0;
	bat_priv->tt_buff = NULL;
403 404 405
	/* check whether this new OGM has no changes due to size problems */
	if (new_len > 0) {
		/* if kmalloc() fails we will reply with the full table
406 407
		 * instead of providing the diff
		 */
408
		bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC);
409
		if (bat_priv->tt_buff) {
410 411
			memcpy(bat_priv->tt_buff, tt_buff, new_len);
			bat_priv->tt_buff_len = new_len;
412 413 414
		}
	}
	spin_unlock_bh(&bat_priv->tt_buff_lock);
415

416
	return count;
417 418
}

419
int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
420 421
{
	struct net_device *net_dev = (struct net_device *)seq->private;
422
	struct batadv_priv *bat_priv = netdev_priv(net_dev);
423
	struct batadv_hashtable *hash = bat_priv->tt_local_hash;
424 425
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_hard_iface *primary_if;
426
	struct hlist_node *node;
427
	struct hlist_head *head;
428 429
	uint32_t i;
	int ret = 0;
430

431
	primary_if = batadv_primary_if_get_selected(bat_priv);
432
	if (!primary_if) {
433 434
		ret = seq_printf(seq,
				 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
435 436 437
				 net_dev->name);
		goto out;
	}
438

439
	if (primary_if->if_status != BATADV_IF_ACTIVE) {
440 441
		ret = seq_printf(seq,
				 "BATMAN mesh %s disabled - primary interface not active\n",
442 443
				 net_dev->name);
		goto out;
444 445
	}

446 447
	seq_printf(seq,
		   "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
448
		   net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn));
449 450 451 452

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

453
		rcu_read_lock();
454
		hlist_for_each_entry_rcu(tt_common_entry, node,
455
					 head, hash_entry) {
456
			seq_printf(seq, " * %pM [%c%c%c%c%c]\n",
457 458
				   tt_common_entry->addr,
				   (tt_common_entry->flags &
459
				    BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
460
				   (tt_common_entry->flags &
461
				    BATADV_TT_CLIENT_NOPURGE ? 'P' : '.'),
462
				   (tt_common_entry->flags &
463
				    BATADV_TT_CLIENT_NEW ? 'N' : '.'),
464
				   (tt_common_entry->flags &
465
				    BATADV_TT_CLIENT_PENDING ? 'X' : '.'),
466
				   (tt_common_entry->flags &
467
				    BATADV_TT_CLIENT_WIFI ? 'W' : '.'));
468
		}
469
		rcu_read_unlock();
470
	}
471 472
out:
	if (primary_if)
473
		batadv_hardif_free_ref(primary_if);
474
	return ret;
475 476
}

477 478 479 480
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)
481
{
482 483
	batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
			      tt_local_entry->common.flags | flags);
484

485 486
	/* The local client has to be marked as "pending to be removed" but has
	 * to be kept in the table in order to send it in a full table
487 488
	 * response issued before the net ttvn increment (consistency check)
	 */
489
	tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
490

491
	batadv_dbg(BATADV_DBG_TT, bat_priv,
492 493
		   "Local tt entry (%pM) pending to be removed: %s\n",
		   tt_local_entry->common.addr, message);
494 495
}

496
void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr,
497
			    const char *message, bool roaming)
498
{
499
	struct batadv_tt_local_entry *tt_local_entry = NULL;
500
	uint16_t flags;
501

502
	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
503 504 505
	if (!tt_local_entry)
		goto out;

506
	flags = BATADV_TT_CLIENT_DEL;
507
	if (roaming)
508
		flags |= BATADV_TT_CLIENT_ROAM;
509 510

	batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
511 512
out:
	if (tt_local_entry)
513
		batadv_tt_local_entry_free_ref(tt_local_entry);
514 515
}

516
static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
517
				       struct hlist_head *head)
518
{
519 520
	struct batadv_tt_local_entry *tt_local_entry;
	struct batadv_tt_common_entry *tt_common_entry;
521
	struct hlist_node *node, *node_tmp;
522 523 524 525

	hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head,
				  hash_entry) {
		tt_local_entry = container_of(tt_common_entry,
526 527
					      struct batadv_tt_local_entry,
					      common);
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE)
			continue;

		/* entry already marked for deletion */
		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
			continue;

		if (!batadv_has_timed_out(tt_local_entry->last_seen,
					  BATADV_TT_LOCAL_TIMEOUT))
			continue;

		batadv_tt_local_set_pending(bat_priv, tt_local_entry,
					    BATADV_TT_CLIENT_DEL, "timed out");
	}
}

544
static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
545
{
546
	struct batadv_hashtable *hash = bat_priv->tt_local_hash;
547
	struct hlist_head *head;
548
	spinlock_t *list_lock; /* protects write access to the hash lists */
549
	uint32_t i;
550 551 552

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
553
		list_lock = &hash->list_locks[i];
554

555
		spin_lock_bh(list_lock);
556
		batadv_tt_local_purge_list(bat_priv, head);
557
		spin_unlock_bh(list_lock);
558 559 560 561
	}

}

562
static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
563
{
564
	struct batadv_hashtable *hash;
565
	spinlock_t *list_lock; /* protects write access to the hash lists */
566 567
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_tt_local_entry *tt_local;
568 569
	struct hlist_node *node, *node_tmp;
	struct hlist_head *head;
570
	uint32_t i;
571

572
	if (!bat_priv->tt_local_hash)
573 574
		return;

575 576 577 578 579 580 581
	hash = bat_priv->tt_local_hash;

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
		list_lock = &hash->list_locks[i];

		spin_lock_bh(list_lock);
582
		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
583 584
					  head, hash_entry) {
			hlist_del_rcu(node);
585 586 587 588
			tt_local = container_of(tt_common_entry,
						struct batadv_tt_local_entry,
						common);
			batadv_tt_local_entry_free_ref(tt_local);
589 590 591 592
		}
		spin_unlock_bh(list_lock);
	}

593
	batadv_hash_destroy(hash);
594

595
	bat_priv->tt_local_hash = NULL;
596 597
}

598
static int batadv_tt_global_init(struct batadv_priv *bat_priv)
599
{
600
	if (bat_priv->tt_global_hash)
601
		return 0;
602

603
	bat_priv->tt_global_hash = batadv_hash_new(1024);
604

605
	if (!bat_priv->tt_global_hash)
606
		return -ENOMEM;
607

608
	return 0;
609 610
}

611
static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
612
{
613
	struct batadv_tt_change_node *entry, *safe;
614

615
	spin_lock_bh(&bat_priv->tt_changes_list_lock);
616

617 618 619 620 621
	list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
				 list) {
		list_del(&entry->list);
		kfree(entry);
	}
622

623 624 625
	atomic_set(&bat_priv->tt_local_changes, 0);
	spin_unlock_bh(&bat_priv->tt_changes_list_lock);
}
626

627 628 629
/* find out if an orig_node is already in the list of a tt_global_entry.
 * returns 1 if found, 0 otherwise
 */
630 631 632
static bool
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
				const struct batadv_orig_node *orig_node)
633
{
634
	struct batadv_tt_orig_list_entry *tmp_orig_entry;
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
	const struct hlist_head *head;
	struct hlist_node *node;
	bool found = false;

	rcu_read_lock();
	head = &entry->orig_list;
	hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) {
		if (tmp_orig_entry->orig_node == orig_node) {
			found = true;
			break;
		}
	}
	rcu_read_unlock();
	return found;
}

651
static void
652 653
batadv_tt_global_add_orig_entry(struct batadv_tt_global_entry *tt_global_entry,
				struct batadv_orig_node *orig_node, int ttvn)
654
{
655
	struct batadv_tt_orig_list_entry *orig_entry;
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672

	orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
	if (!orig_entry)
		return;

	INIT_HLIST_NODE(&orig_entry->list);
	atomic_inc(&orig_node->refcount);
	atomic_inc(&orig_node->tt_size);
	orig_entry->orig_node = orig_node;
	orig_entry->ttvn = ttvn;

	spin_lock_bh(&tt_global_entry->list_lock);
	hlist_add_head_rcu(&orig_entry->list,
			   &tt_global_entry->orig_list);
	spin_unlock_bh(&tt_global_entry->list_lock);
}

673
/* caller must hold orig_node refcount */
674 675
int batadv_tt_global_add(struct batadv_priv *bat_priv,
			 struct batadv_orig_node *orig_node,
676 677
			 const unsigned char *tt_addr, uint8_t flags,
			 uint8_t ttvn)
678
{
679
	struct batadv_tt_global_entry *tt_global_entry = NULL;
680
	int ret = 0;
681
	int hash_added;
682
	struct batadv_tt_common_entry *common;
683

684
	tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
685 686

	if (!tt_global_entry) {
687
		tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
688
		if (!tt_global_entry)
689 690
			goto out;

691 692
		common = &tt_global_entry->common;
		memcpy(common->addr, tt_addr, ETH_ALEN);
693

694
		common->flags = flags;
695
		tt_global_entry->roam_at = 0;
696
		atomic_set(&common->refcount, 2);
697 698 699

		INIT_HLIST_HEAD(&tt_global_entry->orig_list);
		spin_lock_init(&tt_global_entry->list_lock);
700

701
		hash_added = batadv_hash_add(bat_priv->tt_global_hash,
702 703 704
					     batadv_compare_tt,
					     batadv_choose_orig, common,
					     &common->hash_entry);
705 706 707

		if (unlikely(hash_added != 0)) {
			/* remove the reference for the hash */
708
			batadv_tt_global_entry_free_ref(tt_global_entry);
709 710
			goto out_remove;
		}
711

712 713
		batadv_tt_global_add_orig_entry(tt_global_entry, orig_node,
						ttvn);
714
	} else {
715 716
		/* there is already a global entry, use this one. */

717 718
		/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
		 * one originator left in the list and we previously received a
719 720 721 722 723
		 * delete + roaming change for this originator.
		 *
		 * We should first delete the old originator before adding the
		 * new one.
		 */
724
		if (tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM) {
725
			batadv_tt_global_del_orig_list(tt_global_entry);
726
			tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
727
			tt_global_entry->roam_at = 0;
728
		}
729

730 731 732 733
		if (!batadv_tt_global_entry_has_orig(tt_global_entry,
						     orig_node))
			batadv_tt_global_add_orig_entry(tt_global_entry,
							orig_node, ttvn);
734
	}
735

736
	batadv_dbg(BATADV_DBG_TT, bat_priv,
737 738
		   "Creating new global tt entry: %pM (via %pM)\n",
		   tt_global_entry->common.addr, orig_node->orig);
739

740
out_remove:
741
	/* remove address from local hash if present */
742
	batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr,
743 744
			       "global tt received",
			       flags & BATADV_TT_CLIENT_ROAM);
745 746 747
	ret = 1;
out:
	if (tt_global_entry)
748
		batadv_tt_global_entry_free_ref(tt_global_entry);
749
	return ret;
750 751
}

752 753 754
/* print all orig nodes who announce the address for this global entry.
 * it is assumed that the caller holds rcu_read_lock();
 */
755
static void
756
batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
757
			     struct seq_file *seq)
758 759 760
{
	struct hlist_head *head;
	struct hlist_node *node;
761 762
	struct batadv_tt_orig_list_entry *orig_entry;
	struct batadv_tt_common_entry *tt_common_entry;
763 764 765 766 767 768 769 770 771 772 773 774 775
	uint16_t flags;
	uint8_t last_ttvn;

	tt_common_entry = &tt_global_entry->common;

	head = &tt_global_entry->orig_list;

	hlist_for_each_entry_rcu(orig_entry, node, head, list) {
		flags = tt_common_entry->flags;
		last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
		seq_printf(seq, " * %pM  (%3u) via %pM     (%3u)   [%c%c]\n",
			   tt_global_entry->common.addr, orig_entry->ttvn,
			   orig_entry->orig_node->orig, last_ttvn,
776 777
			   (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
			   (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'));
778 779 780
	}
}

781
int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
782 783
{
	struct net_device *net_dev = (struct net_device *)seq->private;
784
	struct batadv_priv *bat_priv = netdev_priv(net_dev);
785
	struct batadv_hashtable *hash = bat_priv->tt_global_hash;
786 787 788
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_tt_global_entry *tt_global;
	struct batadv_hard_iface *primary_if;
789
	struct hlist_node *node;
790
	struct hlist_head *head;
791 792
	uint32_t i;
	int ret = 0;
793

794
	primary_if = batadv_primary_if_get_selected(bat_priv);
795
	if (!primary_if) {
796 797
		ret = seq_printf(seq,
				 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
798 799 800
				 net_dev->name);
		goto out;
	}
801

802
	if (primary_if->if_status != BATADV_IF_ACTIVE) {
803 804
		ret = seq_printf(seq,
				 "BATMAN mesh %s disabled - primary interface not active\n",
805 806
				 net_dev->name);
		goto out;
807 808
	}

809 810
	seq_printf(seq,
		   "Globally announced TT entries received via the mesh %s\n",
811
		   net_dev->name);
812 813
	seq_printf(seq, "       %-13s %s       %-15s %s %s\n",
		   "Client", "(TTVN)", "Originator", "(Curr TTVN)", "Flags");
814 815 816 817

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

818
		rcu_read_lock();
819
		hlist_for_each_entry_rcu(tt_common_entry, node,
820
					 head, hash_entry) {
821 822 823 824
			tt_global = container_of(tt_common_entry,
						 struct batadv_tt_global_entry,
						 common);
			batadv_tt_global_print_entry(tt_global, seq);
825
		}
826
		rcu_read_unlock();
827
	}
828 829
out:
	if (primary_if)
830
		batadv_hardif_free_ref(primary_if);
831
	return ret;
832 833
}

834
/* deletes the orig list of a tt_global_entry */
835
static void
836
batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
837
{
838 839
	struct hlist_head *head;
	struct hlist_node *node, *safe;
840
	struct batadv_tt_orig_list_entry *orig_entry;
841

842 843 844 845
	spin_lock_bh(&tt_global_entry->list_lock);
	head = &tt_global_entry->orig_list;
	hlist_for_each_entry_safe(orig_entry, node, safe, head, list) {
		hlist_del_rcu(node);
846
		batadv_tt_orig_list_entry_free_ref(orig_entry);
847 848
	}
	spin_unlock_bh(&tt_global_entry->list_lock);
849

850 851
}

852
static void
853 854 855
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,
856
				const char *message)
857 858 859
{
	struct hlist_head *head;
	struct hlist_node *node, *safe;
860
	struct batadv_tt_orig_list_entry *orig_entry;
861 862 863 864 865

	spin_lock_bh(&tt_global_entry->list_lock);
	head = &tt_global_entry->orig_list;
	hlist_for_each_entry_safe(orig_entry, node, safe, head, list) {
		if (orig_entry->orig_node == orig_node) {
866
			batadv_dbg(BATADV_DBG_TT, bat_priv,
867 868 869
				   "Deleting %pM from global tt entry %pM: %s\n",
				   orig_node->orig,
				   tt_global_entry->common.addr, message);
870
			hlist_del_rcu(node);
871
			batadv_tt_orig_list_entry_free_ref(orig_entry);
872 873 874 875 876
		}
	}
	spin_unlock_bh(&tt_global_entry->list_lock);
}

877 878 879 880
static void
batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
			    struct batadv_tt_global_entry *tt_global_entry,
			    const char *message)
881
{
882 883
	batadv_dbg(BATADV_DBG_TT, bat_priv,
		   "Deleting global tt entry %pM: %s\n",
884
		   tt_global_entry->common.addr, message);
885

886
	batadv_hash_remove(bat_priv->tt_global_hash, batadv_compare_tt,
887
			   batadv_choose_orig, tt_global_entry->common.addr);
888
	batadv_tt_global_entry_free_ref(tt_global_entry);
889

890 891
}

892
/* If the client is to be deleted, we check if it is the last origantor entry
893 894
 * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
 * timer, otherwise we simply remove the originator scheduled for deletion.
895
 */
896
static void
897 898 899 900
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)
901 902 903 904
{
	bool last_entry = true;
	struct hlist_head *head;
	struct hlist_node *node;
905
	struct batadv_tt_orig_list_entry *orig_entry;
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922

	/* no local entry exists, case 1:
	 * Check if this is the last one or if other entries exist.
	 */

	rcu_read_lock();
	head = &tt_global_entry->orig_list;
	hlist_for_each_entry_rcu(orig_entry, node, head, list) {
		if (orig_entry->orig_node != orig_node) {
			last_entry = false;
			break;
		}
	}
	rcu_read_unlock();

	if (last_entry) {
		/* its the last one, mark for roaming. */
923
		tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
924 925 926 927 928
		tt_global_entry->roam_at = jiffies;
	} else
		/* there is another entry, we can simply delete this
		 * one and can still use the other one.
		 */
929 930
		batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
						orig_node, message);
931 932 933 934
}



935 936
static void batadv_tt_global_del(struct batadv_priv *bat_priv,
				 struct batadv_orig_node *orig_node,
937 938
				 const unsigned char *addr,
				 const char *message, bool roaming)
939
{
940 941
	struct batadv_tt_global_entry *tt_global_entry = NULL;
	struct batadv_tt_local_entry *local_entry = NULL;
942

943
	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
944
	if (!tt_global_entry)
945
		goto out;
946

947
	if (!roaming) {
948 949
		batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
						orig_node, message);
950 951

		if (hlist_empty(&tt_global_entry->orig_list))
952 953
			batadv_tt_global_del_struct(bat_priv, tt_global_entry,
						    message);
954 955 956

		goto out;
	}
957 958 959

	/* if we are deleting a global entry due to a roam
	 * event, there are two possibilities:
960 961
	 * 1) the client roamed from node A to node B => if there
	 *    is only one originator left for this client, we mark
962
	 *    it with BATADV_TT_CLIENT_ROAM, we start a timer and we
963 964
	 *    wait for node B to claim it. In case of timeout
	 *    the entry is purged.
965 966 967
	 *
	 *    If there are other originators left, we directly delete
	 *    the originator.
968
	 * 2) the client roamed to us => we can directly delete
969 970
	 *    the global entry, since it is useless now.
	 */
971 972 973
	local_entry = batadv_tt_local_hash_find(bat_priv,
						tt_global_entry->common.addr);
	if (local_entry) {
974
		/* local entry exists, case 2: client roamed to us. */
975 976
		batadv_tt_global_del_orig_list(tt_global_entry);
		batadv_tt_global_del_struct(bat_priv, tt_global_entry, message);
977 978
	} else
		/* no local entry exists, case 1: check for roaming */
979 980
		batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
					     orig_node, message);
981 982


983
out:
984
	if (tt_global_entry)
985 986 987
		batadv_tt_global_entry_free_ref(tt_global_entry);
	if (local_entry)
		batadv_tt_local_entry_free_ref(local_entry);
988 989
}

990 991 992
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
			       struct batadv_orig_node *orig_node,
			       const char *message)
993
{
994 995
	struct batadv_tt_global_entry *tt_global;
	struct batadv_tt_common_entry *tt_common_entry;
996
	uint32_t i;
997
	struct batadv_hashtable *hash = bat_priv->tt_global_hash;
998 999
	struct hlist_node *node, *safe;
	struct hlist_head *head;
1000
	spinlock_t *list_lock; /* protects write access to the hash lists */
1001

1002 1003 1004
	if (!hash)
		return;

1005 1006
	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
1007
		list_lock = &hash->list_locks[i];
1008

1009
		spin_lock_bh(list_lock);
1010
		hlist_for_each_entry_safe(tt_common_entry, node, safe,
1011
					  head, hash_entry) {
1012 1013 1014
			tt_global = container_of(tt_common_entry,
						 struct batadv_tt_global_entry,
						 common);
1015

1016
			batadv_tt_global_del_orig_entry(bat_priv, tt_global,
1017
							orig_node, message);
1018

1019
			if (hlist_empty(&tt_global->orig_list)) {
1020
				batadv_dbg(BATADV_DBG_TT, bat_priv,
1021
					   "Deleting global tt entry %pM: %s\n",
1022
					   tt_global->common.addr, message);
1023
				hlist_del_rcu(node);
1024
				batadv_tt_global_entry_free_ref(tt_global);
1025
			}
1026
		}
1027
		spin_unlock_bh(list_lock);
1028
	}
1029
	orig_node->tt_initialised = false;
1030 1031
}

1032
static void batadv_tt_global_roam_purge_list(struct batadv_priv *bat_priv,
1033
					     struct hlist_head *head)
1034
{
1035 1036
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_tt_global_entry *tt_global_entry;
1037
	struct hlist_node *node, *node_tmp;
1038 1039 1040 1041

	hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head,
				  hash_entry) {
		tt_global_entry = container_of(tt_common_entry,
1042 1043
					       struct batadv_tt_global_entry,
					       common);
1044
		if (!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM))
1045 1046 1047 1048 1049
			continue;
		if (!batadv_has_timed_out(tt_global_entry->roam_at,
					  BATADV_TT_CLIENT_ROAM_TIMEOUT))
			continue;

1050
		batadv_dbg(BATADV_DBG_TT, bat_priv,
1051 1052 1053 1054 1055 1056 1057 1058
			   "Deleting global tt entry (%pM): Roaming timeout\n",
			   tt_global_entry->common.addr);

		hlist_del_rcu(node);
		batadv_tt_global_entry_free_ref(tt_global_entry);
	}
}

1059
static void batadv_tt_global_roam_purge(struct batadv_priv *bat_priv)
1060
{
1061
	struct batadv_hashtable *hash = bat_priv->tt_global_hash;
1062
	struct hlist_head *head;
1063
	spinlock_t *list_lock; /* protects write access to the hash lists */
1064
	uint32_t i;
1065 1066 1067

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
1068
		list_lock = &hash->list_locks[i];
1069

1070
		spin_lock_bh(list_lock);
1071
		batadv_tt_global_roam_purge_list(bat_priv, head);
1072
		spin_unlock_bh(list_lock);
1073 1074 1075 1076
	}

}

1077
static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1078
{
1079
	struct batadv_hashtable *hash;
1080
	spinlock_t *list_lock; /* protects write access to the hash lists */
1081 1082
	struct batadv_tt_common_entry *tt_common_entry;
	struct batadv_tt_global_entry *tt_global;
1083 1084
	struct hlist_node *node, *node_tmp;
	struct hlist_head *head;
1085
	uint32_t i;
1086

1087
	if (!bat_priv->tt_global_hash)
1088 1089
		return;

1090 1091 1092 1093 1094 1095 1096
	hash = bat_priv->tt_global_hash;

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
		list_lock = &hash->list_locks[i];

		spin_lock_bh(list_lock);
1097
		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
1098 1099
					  head, hash_entry) {
			hlist_del_rcu(node);
1100 1101 1102 1103
			tt_global = container_of(tt_common_entry,
						 struct batadv_tt_global_entry,
						 common);
			batadv_tt_global_entry_free_ref(tt_global);
1104 1105 1106 1107
		}
		spin_unlock_bh(list_lock);
	}

1108
	batadv_hash_destroy(hash);
1109

1110
	bat_priv->tt_global_hash = NULL;
1111 1112
}

1113 1114 1115
static bool
_batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
		       struct batadv_tt_global_entry *tt_global_entry)
1116 1117 1118
{
	bool ret = false;

1119 1120
	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
	    tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
1121 1122 1123 1124 1125
		ret = true;

	return ret;
}

1126 1127 1128
struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
						  const uint8_t *src,
						  const uint8_t *addr)
1129
{
1130 1131 1132 1133
	struct batadv_tt_local_entry *tt_local_entry = NULL;
	struct batadv_tt_global_entry *tt_global_entry = NULL;
	struct batadv_orig_node *orig_node = NULL;
	struct batadv_neigh_node *router = NULL;
1134 1135
	struct hlist_head *head;
	struct hlist_node *node;
1136
	struct batadv_tt_orig_list_entry *orig_entry;
1137
	int best_tq;
1138

1139
	if (src && atomic_read(&bat_priv->ap_isolation)) {
1140
		tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
1141 1142 1143
		if (!tt_local_entry)
			goto out;
	}
1144

1145
	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
1146
	if (!tt_global_entry)
1147
		goto out;
1148

1149
	/* check whether the clients should not communicate due to AP
1150 1151
	 * isolation
	 */
1152 1153
	if (tt_local_entry &&
	    _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
1154 1155
		goto out;

1156
	best_tq = 0;
1157

1158 1159 1160
	rcu_read_lock();
	head = &tt_global_entry->orig_list;
	hlist_for_each_entry_rcu(orig_entry, node, head, list) {
1161
		router = batadv_orig_node_get_router(orig_entry->orig_node);
1162 1163
		if (!router)
			continue;
1164

1165 1166 1167 1168
		if (router->tq_avg > best_tq) {
			orig_node = orig_entry->orig_node;
			best_tq = router->tq_avg;
		}
1169
		batadv_neigh_node_free_ref(router);
1170 1171 1172 1173 1174
	}
	/* found anything? */
	if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
		orig_node = NULL;
	rcu_read_unlock();
1175
out:
1176
	if (tt_global_entry)
1177
		batadv_tt_global_entry_free_ref(tt_global_entry);
1178
	if (tt_local_entry)
1179
		batadv_tt_local_entry_free_ref(tt_local_entry);
1180

1181
	return orig_node;
1182
}
1183 1184

/* Calculates the checksum of the local table of a given orig_node */
1185 1186
static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
				     struct batadv_orig_node *orig_node)
1187 1188
{
	uint16_t total = 0, total_one;
1189
	struct batadv_hashtable *hash = bat_priv->tt_global_hash;
1190 1191
	struct batadv_tt_common_entry *tt_common;
	struct batadv_tt_global_entry *tt_global;
1192 1193
	struct hlist_node *node;
	struct hlist_head *head;
1194 1195
	uint32_t i;
	int j;
1196 1197 1198 1199 1200

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
1201
		hlist_for_each_entry_rcu(tt_common, node, head, hash_entry) {
1202 1203 1204
			tt_global = container_of(tt_common,
						 struct batadv_tt_global_entry,
						 common);
1205 1206 1207 1208 1209
			/* Roaming clients are in the global table for
			 * consistency only. They don't have to be
			 * taken into account while computing the
			 * global crc
			 */
1210
			if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
1211 1212 1213 1214 1215
				continue;

			/* find out if this global entry is announced by this
			 * originator
			 */
1216
			if (!batadv_tt_global_entry_has_orig(tt_global,
1217
							     orig_node))
1218 1219 1220 1221 1222
				continue;

			total_one = 0;
			for (j = 0; j < ETH_ALEN; j++)
				total_one = crc16_byte(total_one,
1223
						       tt_common->addr[j]);
1224
			total ^= total_one;
1225 1226 1227 1228 1229 1230 1231 1232
		}
		rcu_read_unlock();
	}

	return total;
}

/* Calculates the checksum of the local table */
1233
static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
1234 1235
{
	uint16_t total = 0, total_one;
1236
	struct batadv_hashtable *hash = bat_priv->tt_local_hash;
1237
	struct batadv_tt_common_entry *tt_common;
1238 1239
	struct hlist_node *node;
	struct hlist_head *head;
1240 1241
	uint32_t i;
	int j;
1242 1243 1244 1245 1246

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
1247
		hlist_for_each_entry_rcu(tt_common, node, head, hash_entry) {
1248
			/* not yet committed clients have not to be taken into
1249 1250
			 * account while computing the CRC
			 */
1251
			if (tt_common->flags & BATADV_TT_CLIENT_NEW)
1252
				continue;
1253 1254 1255
			total_one = 0;
			for (j = 0; j < ETH_ALEN; j++)
				total_one = crc16_byte(total_one,
1256
						       tt_common->addr[j]);
1257 1258 1259 1260 1261 1262 1263 1264
			total ^= total_one;
		}
		rcu_read_unlock();
	}

	return total;
}

1265
static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
1266
{
1267
	struct batadv_tt_req_node *node, *safe;
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278

	spin_lock_bh(&bat_priv->tt_req_list_lock);

	list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
		list_del(&node->list);
		kfree(node);
	}

	spin_unlock_bh(&bat_priv->tt_req_list_lock);
}

1279 1280
static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
				       struct batadv_orig_node *orig_node,
1281 1282
				       const unsigned char *tt_buff,
				       uint8_t tt_num_changes)
1283
{
1284
	uint16_t tt_buff_len = batadv_tt_len(tt_num_changes);
1285 1286

	/* Replace the old buffer only if I received something in the
1287 1288
	 * last OGM (the OGM could carry no changes)
	 */
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
	spin_lock_bh(&orig_node->tt_buff_lock);
	if (tt_buff_len > 0) {
		kfree(orig_node->tt_buff);
		orig_node->tt_buff_len = 0;
		orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
		if (orig_node->tt_buff) {
			memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
			orig_node->tt_buff_len = tt_buff_len;
		}
	}
	spin_unlock_bh(&orig_node->tt_buff_lock);
}

1302
static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
1303
{
1304
	struct batadv_tt_req_node *node, *safe;
1305 1306 1307

	spin_lock_bh(&bat_priv->tt_req_list_lock);
	list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1308 1309
		if (batadv_has_timed_out(node->issued_at,
					 BATADV_TT_REQUEST_TIMEOUT)) {
1310 1311 1312 1313 1314 1315 1316 1317
			list_del(&node->list);
			kfree(node);
		}
	}
	spin_unlock_bh(&bat_priv->tt_req_list_lock);
}

/* returns the pointer to the new tt_req_node struct if no request
1318 1319
 * has already been issued for this orig_node, NULL otherwise
 */
1320 1321 1322
static struct batadv_tt_req_node *
batadv_new_tt_req_node(struct batadv_priv *bat_priv,
		       struct batadv_orig_node *orig_node)
1323
{
1324
	struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1325 1326 1327

	spin_lock_bh(&bat_priv->tt_req_list_lock);
	list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
1328 1329
		if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
		    !batadv_has_timed_out(tt_req_node_tmp->issued_at,
1330
					  BATADV_TT_REQUEST_TIMEOUT))
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
			goto unlock;
	}

	tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
	if (!tt_req_node)
		goto unlock;

	memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
	tt_req_node->issued_at = jiffies;

	list_add(&tt_req_node->list, &bat_priv->tt_req_list);
unlock:
	spin_unlock_bh(&bat_priv->tt_req_list_lock);
	return tt_req_node;
}

1347
/* data_ptr is useless here, but has to be kept to respect the prototype */
1348 1349
static int batadv_tt_local_valid_entry(const void *entry_ptr,
				       const void *data_ptr)
1350
{
1351
	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
1352

1353
	if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
1354 1355 1356 1357
		return 0;
	return 1;
}

1358 1359
static int batadv_tt_global_valid(const void *entry_ptr,
				  const void *data_ptr)
1360
{
1361 1362 1363
	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
	const struct batadv_tt_global_entry *tt_global_entry;
	const struct batadv_orig_node *orig_node = data_ptr;
1364

1365
	if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM)
1366 1367
		return 0;

1368 1369
	tt_global_entry = container_of(tt_common_entry,
				       struct batadv_tt_global_entry,
1370 1371
				       common);

1372
	return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
1373 1374
}

1375 1376
static struct sk_buff *
batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1377
			      struct batadv_hashtable *hash,
1378
			      struct batadv_hard_iface *primary_if,
1379 1380
			      int (*valid_cb)(const void *, const void *),
			      void *cb_data)
1381
{
1382
	struct batadv_tt_common_entry *tt_common_entry;
1383 1384
	struct batadv_tt_query_packet *tt_response;
	struct batadv_tt_change *tt_change;
1385 1386 1387 1388
	struct hlist_node *node;
	struct hlist_head *head;
	struct sk_buff *skb = NULL;
	uint16_t tt_tot, tt_count;
1389
	ssize_t tt_query_size = sizeof(struct batadv_tt_query_packet);
1390
	uint32_t i;
1391
	size_t len;
1392 1393 1394

	if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
		tt_len = primary_if->soft_iface->mtu - tt_query_size;
1395
		tt_len -= tt_len % sizeof(struct batadv_tt_change);
1396
	}
1397
	tt_tot = tt_len / sizeof(struct batadv_tt_change);
1398

1399 1400
	len = tt_query_size + tt_len;
	skb = dev_alloc_skb(len + ETH_HLEN);
1401 1402 1403 1404
	if (!skb)
		goto out;

	skb_reserve(skb, ETH_HLEN);
1405
	tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
1406 1407
	tt_response->ttvn = ttvn;

1408
	tt_change = (struct batadv_tt_change *)(skb->data + tt_query_size);
1409 1410 1411 1412 1413 1414
	tt_count = 0;

	rcu_read_lock();
	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

1415
		hlist_for_each_entry_rcu(tt_common_entry, node,
1416 1417 1418 1419
					 head, hash_entry) {
			if (tt_count == tt_tot)
				break;

1420
			if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
1421 1422
				continue;

1423 1424
			memcpy(tt_change->addr, tt_common_entry->addr,
			       ETH_ALEN);
1425
			tt_change->flags = BATADV_NO_FLAGS;
1426 1427 1428 1429 1430 1431 1432

			tt_count++;
			tt_change++;
		}
	}
	rcu_read_unlock();

1433
	/* store in the message the number of entries we have successfully
1434 1435
	 * copied
	 */
1436 1437
	tt_response->tt_data = htons(tt_count);

1438 1439 1440 1441
out:
	return skb;
}

1442 1443
static int batadv_send_tt_request(struct batadv_priv *bat_priv,
				  struct batadv_orig_node *dst_orig_node,
1444 1445
				  uint8_t ttvn, uint16_t tt_crc,
				  bool full_table)
1446 1447
{
	struct sk_buff *skb = NULL;
1448
	struct batadv_tt_query_packet *tt_request;
1449 1450 1451
	struct batadv_neigh_node *neigh_node = NULL;
	struct batadv_hard_iface *primary_if;
	struct batadv_tt_req_node *tt_req_node = NULL;
1452
	int ret = 1;
1453
	size_t tt_req_len;
1454

1455
	primary_if = batadv_primary_if_get_selected(bat_priv);
1456 1457 1458 1459
	if (!primary_if)
		goto out;

	/* The new tt_req will be issued only if I'm not waiting for a
1460 1461
	 * reply from the same orig_node yet
	 */
1462
	tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node);
1463 1464 1465
	if (!tt_req_node)
		goto out;

1466
	skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN);
1467 1468 1469 1470 1471
	if (!skb)
		goto out;

	skb_reserve(skb, ETH_HLEN);

1472 1473
	tt_req_len = sizeof(*tt_request);
	tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
1474

1475
	tt_request->header.packet_type = BATADV_TT_QUERY;
1476
	tt_request->header.version = BATADV_COMPAT_VERSION;
1477 1478
	memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
	memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1479
	tt_request->header.ttl = BATADV_TTL;
1480
	tt_request->ttvn = ttvn;
1481
	tt_request->tt_data = htons(tt_crc);
1482
	tt_request->flags = BATADV_TT_REQUEST;
1483 1484

	if (full_table)
1485
		tt_request->flags |= BATADV_TT_FULL_TABLE;
1486

1487
	neigh_node = batadv_orig_node_get_router(dst_orig_node);
1488 1489 1490
	if (!neigh_node)
		goto out;

1491
	batadv_dbg(BATADV_DBG_TT, bat_priv,
1492 1493 1494
		   "Sending TT_REQUEST to %pM via %pM [%c]\n",
		   dst_orig_node->orig, neigh_node->addr,
		   (full_table ? 'F' : '.'));
1495

1496
	batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
1497

1498
	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1499 1500 1501 1502
	ret = 0;

out:
	if (neigh_node)
1503
		batadv_neigh_node_free_ref(neigh_node);
1504
	if (primary_if)
1505
		batadv_hardif_free_ref(primary_if);
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
	if (ret)
		kfree_skb(skb);
	if (ret && tt_req_node) {
		spin_lock_bh(&bat_priv->tt_req_list_lock);
		list_del(&tt_req_node->list);
		spin_unlock_bh(&bat_priv->tt_req_list_lock);
		kfree(tt_req_node);
	}
	return ret;
}

1517
static bool
1518
batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1519
			      struct batadv_tt_query_packet *tt_request)
1520
{
1521 1522 1523 1524
	struct batadv_orig_node *req_dst_orig_node = NULL;
	struct batadv_orig_node *res_dst_orig_node = NULL;
	struct batadv_neigh_node *neigh_node = NULL;
	struct batadv_hard_iface *primary_if = NULL;
1525 1526 1527 1528 1529 1530
	uint8_t orig_ttvn, req_ttvn, ttvn;
	int ret = false;
	unsigned char *tt_buff;
	bool full_table;
	uint16_t tt_len, tt_tot;
	struct sk_buff *skb = NULL;
1531 1532
	struct batadv_tt_query_packet *tt_response;
	size_t len;
1533

1534
	batadv_dbg(BATADV_DBG_TT, bat_priv,
1535 1536
		   "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
		   tt_request->src, tt_request->ttvn, tt_request->dst,
1537
		   (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1538 1539

	/* Let's get the orig node of the REAL destination */
1540
	req_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->dst);
1541 1542 1543
	if (!req_dst_orig_node)
		goto out;

1544
	res_dst_orig_node = batadv_orig_hash_find(bat_priv, tt_request->src);
1545 1546 1547
	if (!res_dst_orig_node)
		goto out;

1548
	neigh_node = batadv_orig_node_get_router(res_dst_orig_node);
1549 1550 1551
	if (!neigh_node)
		goto out;

1552
	primary_if = batadv_primary_if_get_selected(bat_priv);
1553 1554 1555 1556 1557 1558
	if (!primary_if)
		goto out;

	orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
	req_ttvn = tt_request->ttvn;

1559
	/* I don't have the requested data */
1560
	if (orig_ttvn != req_ttvn ||
1561
	    tt_request->tt_data != htons(req_dst_orig_node->tt_crc))
1562 1563
		goto out;

1564
	/* If the full table has been explicitly requested */
1565
	if (tt_request->flags & BATADV_TT_FULL_TABLE ||
1566 1567 1568 1569 1570 1571
	    !req_dst_orig_node->tt_buff)
		full_table = true;
	else
		full_table = false;

	/* In this version, fragmentation is not implemented, then
1572 1573
	 * I'll send only one packet with as much TT entries as I can
	 */
1574 1575 1576
	if (!full_table) {
		spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
		tt_len = req_dst_orig_node->tt_buff_len;
1577
		tt_tot = tt_len / sizeof(struct batadv_tt_change);
1578

1579 1580
		len = sizeof(*tt_response) + tt_len;
		skb = dev_alloc_skb(len + ETH_HLEN);
1581 1582 1583 1584
		if (!skb)
			goto unlock;

		skb_reserve(skb, ETH_HLEN);
1585 1586
		tt_response = (struct batadv_tt_query_packet *)skb_put(skb,
								       len);
1587 1588 1589
		tt_response->ttvn = req_ttvn;
		tt_response->tt_data = htons(tt_tot);

1590
		tt_buff = skb->data + sizeof(*tt_response);
1591 1592 1593 1594 1595 1596
		/* Copy the last orig_node's OGM buffer */
		memcpy(tt_buff, req_dst_orig_node->tt_buff,
		       req_dst_orig_node->tt_buff_len);

		spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
	} else {
1597 1598
		tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size);
		tt_len *= sizeof(struct batadv_tt_change);
1599 1600
		ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);

1601 1602 1603 1604 1605
		skb = batadv_tt_response_fill_table(tt_len, ttvn,
						    bat_priv->tt_global_hash,
						    primary_if,
						    batadv_tt_global_valid,
						    req_dst_orig_node);
1606 1607 1608
		if (!skb)
			goto out;

1609
		tt_response = (struct batadv_tt_query_packet *)skb->data;
1610 1611
	}

1612
	tt_response->header.packet_type = BATADV_TT_QUERY;
1613
	tt_response->header.version = BATADV_COMPAT_VERSION;
1614
	tt_response->header.ttl = BATADV_TTL;
1615 1616
	memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
	memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1617
	tt_response->flags = BATADV_TT_RESPONSE;
1618 1619

	if (full_table)
1620
		tt_response->flags |= BATADV_TT_FULL_TABLE;
1621

1622
	batadv_dbg(BATADV_DBG_TT, bat_priv,
1623 1624 1625
		   "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
		   res_dst_orig_node->orig, neigh_node->addr,
		   req_dst_orig_node->orig, req_ttvn);
1626

1627
	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
1628

1629
	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1630 1631 1632 1633 1634 1635 1636 1637
	ret = true;
	goto out;

unlock:
	spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);

out:
	if (res_dst_orig_node)
1638
		batadv_orig_node_free_ref(res_dst_orig_node);
1639
	if (req_dst_orig_node)
1640
		batadv_orig_node_free_ref(req_dst_orig_node);
1641
	if (neigh_node)
1642
		batadv_neigh_node_free_ref(neigh_node);
1643
	if (primary_if)
1644
		batadv_hardif_free_ref(primary_if);
1645 1646 1647 1648 1649
	if (!ret)
		kfree_skb(skb);
	return ret;

}
1650 1651

static bool
1652
batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1653
			   struct batadv_tt_query_packet *tt_request)
1654
{
1655 1656 1657
	struct batadv_orig_node *orig_node = NULL;
	struct batadv_neigh_node *neigh_node = NULL;
	struct batadv_hard_iface *primary_if = NULL;
1658 1659 1660 1661 1662 1663
	uint8_t my_ttvn, req_ttvn, ttvn;
	int ret = false;
	unsigned char *tt_buff;
	bool full_table;
	uint16_t tt_len, tt_tot;
	struct sk_buff *skb = NULL;
1664 1665
	struct batadv_tt_query_packet *tt_response;
	size_t len;
1666

1667
	batadv_dbg(BATADV_DBG_TT, bat_priv,
1668 1669
		   "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
		   tt_request->src, tt_request->ttvn,
1670
		   (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1671 1672 1673 1674 1675


	my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
	req_ttvn = tt_request->ttvn;

1676
	orig_node = batadv_orig_hash_find(bat_priv, tt_request->src);
1677 1678 1679
	if (!orig_node)
		goto out;

1680
	neigh_node = batadv_orig_node_get_router(orig_node);
1681 1682 1683
	if (!neigh_node)
		goto out;

1684
	primary_if = batadv_primary_if_get_selected(bat_priv);
1685 1686 1687 1688
	if (!primary_if)
		goto out;

	/* If the full table has been explicitly requested or the gap
1689 1690
	 * is too big send the whole local translation table
	 */
1691
	if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
1692 1693 1694 1695 1696 1697
	    !bat_priv->tt_buff)
		full_table = true;
	else
		full_table = false;

	/* In this version, fragmentation is not implemented, then
1698 1699
	 * I'll send only one packet with as much TT entries as I can
	 */
1700 1701 1702
	if (!full_table) {
		spin_lock_bh(&bat_priv->tt_buff_lock);
		tt_len = bat_priv->tt_buff_len;
1703
		tt_tot = tt_len / sizeof(struct batadv_tt_change);
1704

1705 1706
		len = sizeof(*tt_response) + tt_len;
		skb = dev_alloc_skb(len + ETH_HLEN);
1707 1708 1709 1710
		if (!skb)
			goto unlock;

		skb_reserve(skb, ETH_HLEN);
1711 1712
		tt_response = (struct batadv_tt_query_packet *)skb_put(skb,
								       len);
1713 1714 1715
		tt_response->ttvn = req_ttvn;
		tt_response->tt_data = htons(tt_tot);

1716
		tt_buff = skb->data + sizeof(*tt_response);
1717 1718 1719 1720
		memcpy(tt_buff, bat_priv->tt_buff,
		       bat_priv->tt_buff_len);
		spin_unlock_bh(&bat_priv->tt_buff_lock);
	} else {
1721 1722
		tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt);
		tt_len *= sizeof(struct batadv_tt_change);
1723 1724
		ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);

1725 1726 1727 1728 1729
		skb = batadv_tt_response_fill_table(tt_len, ttvn,
						    bat_priv->tt_local_hash,
						    primary_if,
						    batadv_tt_local_valid_entry,
						    NULL);
1730 1731 1732
		if (!skb)
			goto out;

1733
		tt_response = (struct batadv_tt_query_packet *)skb->data;
1734 1735
	}

1736
	tt_response->header.packet_type = BATADV_TT_QUERY;
1737
	tt_response->header.version = BATADV_COMPAT_VERSION;
1738
	tt_response->header.ttl = BATADV_TTL;
1739 1740
	memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
	memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1741
	tt_response->flags = BATADV_TT_RESPONSE;
1742 1743

	if (full_table)
1744
		tt_response->flags |= BATADV_TT_FULL_TABLE;
1745

1746
	batadv_dbg(BATADV_DBG_TT, bat_priv,
1747 1748
		   "Sending TT_RESPONSE to %pM via %pM [%c]\n",
		   orig_node->orig, neigh_node->addr,
1749
		   (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1750

1751
	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
1752

1753
	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1754 1755 1756 1757 1758 1759 1760
	ret = true;
	goto out;

unlock:
	spin_unlock_bh(&bat_priv->tt_buff_lock);
out:
	if (orig_node)
1761
		batadv_orig_node_free_ref(orig_node);
1762
	if (neigh_node)
1763
		batadv_neigh_node_free_ref(neigh_node);
1764
	if (primary_if)
1765
		batadv_hardif_free_ref(primary_if);
1766 1767 1768 1769 1770 1771
	if (!ret)
		kfree_skb(skb);
	/* This packet was for me, so it doesn't need to be re-routed */
	return true;
}

1772
bool batadv_send_tt_response(struct batadv_priv *bat_priv,
1773
			     struct batadv_tt_query_packet *tt_request)
1774
{
1775
	if (batadv_is_my_mac(tt_request->dst)) {
1776
		/* don't answer backbone gws! */
1777
		if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src))
1778 1779
			return true;

1780
		return batadv_send_my_tt_response(bat_priv, tt_request);
1781
	} else {
1782
		return batadv_send_other_tt_response(bat_priv, tt_request);
1783
	}
1784 1785
}

1786 1787
static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
				      struct batadv_orig_node *orig_node,
1788
				      struct batadv_tt_change *tt_change,
1789
				      uint16_t tt_num_changes, uint8_t ttvn)
1790 1791
{
	int i;
1792
	int roams;
1793 1794

	for (i = 0; i < tt_num_changes; i++) {
1795 1796
		if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
			roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
1797 1798
			batadv_tt_global_del(bat_priv, orig_node,
					     (tt_change + i)->addr,
1799 1800
					     "tt removed by changes",
					     roams);
1801 1802
		} else {
			if (!batadv_tt_global_add(bat_priv, orig_node,
1803 1804
						  (tt_change + i)->addr,
						  (tt_change + i)->flags, ttvn))
1805 1806 1807 1808 1809 1810 1811
				/* In case of problem while storing a
				 * global_entry, we stop the updating
				 * procedure without committing the
				 * ttvn change. This will avoid to send
				 * corrupted data on tt_request
				 */
				return;
1812
		}
1813
	}
1814
	orig_node->tt_initialised = true;
1815 1816
}

1817
static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
1818
				  struct batadv_tt_query_packet *tt_response)
1819
{
1820
	struct batadv_orig_node *orig_node = NULL;
1821

1822
	orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
1823 1824 1825 1826
	if (!orig_node)
		goto out;

	/* Purge the old table first.. */
1827
	batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table");
1828

1829
	_batadv_tt_update_changes(bat_priv, orig_node,
1830
				  (struct batadv_tt_change *)(tt_response + 1),
1831 1832
				  ntohs(tt_response->tt_data),
				  tt_response->ttvn);
1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843

	spin_lock_bh(&orig_node->tt_buff_lock);
	kfree(orig_node->tt_buff);
	orig_node->tt_buff_len = 0;
	orig_node->tt_buff = NULL;
	spin_unlock_bh(&orig_node->tt_buff_lock);

	atomic_set(&orig_node->last_ttvn, tt_response->ttvn);

out:
	if (orig_node)
1844
		batadv_orig_node_free_ref(orig_node);
1845 1846
}

1847 1848
static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
				     struct batadv_orig_node *orig_node,
1849
				     uint16_t tt_num_changes, uint8_t ttvn,
1850
				     struct batadv_tt_change *tt_change)
1851
{
1852 1853
	_batadv_tt_update_changes(bat_priv, orig_node, tt_change,
				  tt_num_changes, ttvn);
1854

1855 1856
	batadv_tt_save_orig_buffer(bat_priv, orig_node,
				   (unsigned char *)tt_change, tt_num_changes);
1857 1858 1859
	atomic_set(&orig_node->last_ttvn, ttvn);
}

1860
bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
1861
{
1862
	struct batadv_tt_local_entry *tt_local_entry = NULL;
1863
	bool ret = false;
1864

1865
	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
1866 1867
	if (!tt_local_entry)
		goto out;
1868
	/* Check if the client has been logically deleted (but is kept for
1869 1870
	 * consistency purpose)
	 */
1871
	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
1872
		goto out;
1873 1874
	ret = true;
out:
1875
	if (tt_local_entry)
1876
		batadv_tt_local_entry_free_ref(tt_local_entry);
1877
	return ret;
1878 1879
}

1880
void batadv_handle_tt_response(struct batadv_priv *bat_priv,
1881
			       struct batadv_tt_query_packet *tt_response)
1882
{
1883 1884
	struct batadv_tt_req_node *node, *safe;
	struct batadv_orig_node *orig_node = NULL;
1885
	struct batadv_tt_change *tt_change;
1886

1887
	batadv_dbg(BATADV_DBG_TT, bat_priv,
1888 1889 1890
		   "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
		   tt_response->src, tt_response->ttvn,
		   ntohs(tt_response->tt_data),
1891
		   (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1892

1893
	/* we should have never asked a backbone gw */
1894
	if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_response->src))
1895 1896
		goto out;

1897
	orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
1898 1899 1900
	if (!orig_node)
		goto out;

1901
	if (tt_response->flags & BATADV_TT_FULL_TABLE) {
1902
		batadv_tt_fill_gtable(bat_priv, tt_response);
1903 1904
	} else {
		tt_change = (struct batadv_tt_change *)(tt_response + 1);
1905 1906
		batadv_tt_update_changes(bat_priv, orig_node,
					 ntohs(tt_response->tt_data),
1907 1908
					 tt_response->ttvn, tt_change);
	}
1909 1910 1911 1912

	/* Delete the tt_req_node from pending tt_requests list */
	spin_lock_bh(&bat_priv->tt_req_list_lock);
	list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1913
		if (!batadv_compare_eth(node->addr, tt_response->src))
1914 1915 1916 1917 1918 1919 1920
			continue;
		list_del(&node->list);
		kfree(node);
	}
	spin_unlock_bh(&bat_priv->tt_req_list_lock);

	/* Recalculate the CRC for this orig_node and store it */
1921
	orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
1922
	/* Roaming phase is over: tables are in sync again. I can
1923 1924
	 * unset the flag
	 */
1925
	orig_node->tt_poss_change = false;
1926 1927
out:
	if (orig_node)
1928
		batadv_orig_node_free_ref(orig_node);
1929 1930
}

1931
int batadv_tt_init(struct batadv_priv *bat_priv)
1932
{
1933
	int ret;
1934

1935
	ret = batadv_tt_local_init(bat_priv);
1936 1937 1938
	if (ret < 0)
		return ret;

1939
	ret = batadv_tt_global_init(bat_priv);
1940 1941
	if (ret < 0)
		return ret;
1942

1943
	batadv_tt_start_timer(bat_priv);
1944 1945 1946 1947

	return 1;
}

1948
static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
1949
{
1950
	struct batadv_tt_roam_node *node, *safe;
1951

1952
	spin_lock_bh(&bat_priv->tt_roam_list_lock);
1953

1954 1955 1956 1957 1958 1959 1960 1961
	list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
		list_del(&node->list);
		kfree(node);
	}

	spin_unlock_bh(&bat_priv->tt_roam_list_lock);
}

1962
static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
1963
{
1964
	struct batadv_tt_roam_node *node, *safe;
1965 1966 1967

	spin_lock_bh(&bat_priv->tt_roam_list_lock);
	list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1968 1969
		if (!batadv_has_timed_out(node->first_time,
					  BATADV_ROAMING_MAX_TIME))
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981
			continue;

		list_del(&node->list);
		kfree(node);
	}
	spin_unlock_bh(&bat_priv->tt_roam_list_lock);
}

/* This function checks whether the client already reached the
 * maximum number of possible roaming phases. In this case the ROAMING_ADV
 * will not be sent.
 *
1982 1983
 * returns true if the ROAMING_ADV can be sent, false otherwise
 */
1984
static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
1985
				       uint8_t *client)
1986
{
1987
	struct batadv_tt_roam_node *tt_roam_node;
1988 1989 1990 1991
	bool ret = false;

	spin_lock_bh(&bat_priv->tt_roam_list_lock);
	/* The new tt_req will be issued only if I'm not waiting for a
1992 1993
	 * reply from the same orig_node yet
	 */
1994
	list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
1995
		if (!batadv_compare_eth(tt_roam_node->addr, client))
1996 1997
			continue;

1998
		if (batadv_has_timed_out(tt_roam_node->first_time,
1999
					 BATADV_ROAMING_MAX_TIME))
2000 2001
			continue;

2002
		if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter))
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
			/* Sorry, you roamed too many times! */
			goto unlock;
		ret = true;
		break;
	}

	if (!ret) {
		tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
		if (!tt_roam_node)
			goto unlock;

		tt_roam_node->first_time = jiffies;
2015 2016
		atomic_set(&tt_roam_node->counter,
			   BATADV_ROAMING_MAX_COUNT - 1);
2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027
		memcpy(tt_roam_node->addr, client, ETH_ALEN);

		list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
		ret = true;
	}

unlock:
	spin_unlock_bh(&bat_priv->tt_roam_list_lock);
	return ret;
}

2028 2029
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
				 struct batadv_orig_node *orig_node)
2030
{
2031
	struct batadv_neigh_node *neigh_node = NULL;
2032
	struct sk_buff *skb = NULL;
2033
	struct batadv_roam_adv_packet *roam_adv_packet;
2034
	int ret = 1;
2035
	struct batadv_hard_iface *primary_if;
2036
	size_t len = sizeof(*roam_adv_packet);
2037 2038

	/* before going on we have to check whether the client has
2039 2040
	 * already roamed to us too many times
	 */
2041
	if (!batadv_tt_check_roam_count(bat_priv, client))
2042 2043
		goto out;

2044
	skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN);
2045 2046 2047 2048 2049
	if (!skb)
		goto out;

	skb_reserve(skb, ETH_HLEN);

2050
	roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
2051

2052
	roam_adv_packet->header.packet_type = BATADV_ROAM_ADV;
2053
	roam_adv_packet->header.version = BATADV_COMPAT_VERSION;
2054
	roam_adv_packet->header.ttl = BATADV_TTL;
2055
	primary_if = batadv_primary_if_get_selected(bat_priv);
2056 2057 2058
	if (!primary_if)
		goto out;
	memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
2059
	batadv_hardif_free_ref(primary_if);
2060 2061 2062
	memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
	memcpy(roam_adv_packet->client, client, ETH_ALEN);

2063
	neigh_node = batadv_orig_node_get_router(orig_node);
2064 2065 2066
	if (!neigh_node)
		goto out;

2067
	batadv_dbg(BATADV_DBG_TT, bat_priv,
2068 2069
		   "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
		   orig_node->orig, client, neigh_node->addr);
2070

2071
	batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
2072

2073
	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
2074 2075 2076 2077
	ret = 0;

out:
	if (neigh_node)
2078
		batadv_neigh_node_free_ref(neigh_node);
2079 2080 2081
	if (ret)
		kfree_skb(skb);
	return;
2082 2083
}

2084
static void batadv_tt_purge(struct work_struct *work)
2085
{
2086 2087 2088 2089 2090
	struct delayed_work *delayed_work;
	struct batadv_priv *bat_priv;

	delayed_work = container_of(work, struct delayed_work, work);
	bat_priv = container_of(delayed_work, struct batadv_priv, tt_work);
2091

2092 2093 2094 2095
	batadv_tt_local_purge(bat_priv);
	batadv_tt_global_roam_purge(bat_priv);
	batadv_tt_req_purge(bat_priv);
	batadv_tt_roam_purge(bat_priv);
2096

2097
	batadv_tt_start_timer(bat_priv);
2098
}
2099

2100
void batadv_tt_free(struct batadv_priv *bat_priv)
2101 2102 2103
{
	cancel_delayed_work_sync(&bat_priv->tt_work);

2104 2105 2106 2107 2108
	batadv_tt_local_table_free(bat_priv);
	batadv_tt_global_table_free(bat_priv);
	batadv_tt_req_list_free(bat_priv);
	batadv_tt_changes_list_free(bat_priv);
	batadv_tt_roam_list_free(bat_priv);
2109 2110 2111

	kfree(bat_priv->tt_buff);
}
2112

2113
/* This function will enable or disable the specified flags for all the entries
2114 2115
 * in the given hash table and returns the number of modified entries
 */
2116 2117
static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
				    uint16_t flags, bool enable)
2118
{
2119
	uint32_t i;
2120
	uint16_t changed_num = 0;
2121 2122
	struct hlist_head *head;
	struct hlist_node *node;
2123
	struct batadv_tt_common_entry *tt_common_entry;
2124 2125

	if (!hash)
2126
		goto out;
2127 2128 2129 2130 2131

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
2132
		hlist_for_each_entry_rcu(tt_common_entry, node,
2133
					 head, hash_entry) {
2134 2135 2136 2137 2138 2139 2140 2141 2142 2143
			if (enable) {
				if ((tt_common_entry->flags & flags) == flags)
					continue;
				tt_common_entry->flags |= flags;
			} else {
				if (!(tt_common_entry->flags & flags))
					continue;
				tt_common_entry->flags &= ~flags;
			}
			changed_num++;
2144 2145 2146
		}
		rcu_read_unlock();
	}
2147 2148
out:
	return changed_num;
2149 2150
}

2151
/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
2152
static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2153
{
2154
	struct batadv_hashtable *hash = bat_priv->tt_local_hash;
2155 2156
	struct batadv_tt_common_entry *tt_common;
	struct batadv_tt_local_entry *tt_local;
2157 2158 2159
	struct hlist_node *node, *node_tmp;
	struct hlist_head *head;
	spinlock_t *list_lock; /* protects write access to the hash lists */
2160
	uint32_t i;
2161 2162 2163 2164 2165 2166 2167 2168 2169

	if (!hash)
		return;

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
		list_lock = &hash->list_locks[i];

		spin_lock_bh(list_lock);
2170 2171 2172
		hlist_for_each_entry_safe(tt_common, node, node_tmp, head,
					  hash_entry) {
			if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
2173 2174
				continue;

2175
			batadv_dbg(BATADV_DBG_TT, bat_priv,
2176
				   "Deleting local tt entry (%pM): pending\n",
2177
				   tt_common->addr);
2178 2179 2180

			atomic_dec(&bat_priv->num_local_tt);
			hlist_del_rcu(node);
2181 2182 2183 2184
			tt_local = container_of(tt_common,
						struct batadv_tt_local_entry,
						common);
			batadv_tt_local_entry_free_ref(tt_local);
2185 2186 2187 2188 2189 2190
		}
		spin_unlock_bh(list_lock);
	}

}

2191
static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2192 2193
				    unsigned char **packet_buff,
				    int *packet_buff_len, int packet_min_len)
2194
{
2195 2196 2197 2198 2199
	uint16_t changed_num = 0;

	if (atomic_read(&bat_priv->tt_local_changes) < 1)
		return -ENOENT;

2200
	changed_num = batadv_tt_set_flags(bat_priv->tt_local_hash,
2201
					  BATADV_TT_CLIENT_NEW, false);
2202 2203

	/* all reset entries have to be counted as local entries */
2204
	atomic_add(changed_num, &bat_priv->num_local_tt);
2205
	batadv_tt_local_purge_pending_clients(bat_priv);
2206
	bat_priv->tt_crc = batadv_tt_local_crc(bat_priv);
2207 2208 2209

	/* Increment the TTVN only once per OGM interval */
	atomic_inc(&bat_priv->ttvn);
2210
	batadv_dbg(BATADV_DBG_TT, bat_priv,
2211 2212
		   "Local changes committed, updating to ttvn %u\n",
		   (uint8_t)atomic_read(&bat_priv->ttvn));
2213
	bat_priv->tt_poss_change = false;
2214 2215

	/* reset the sending counter */
2216
	atomic_set(&bat_priv->tt_ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2217

2218 2219
	return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
					   packet_buff_len, packet_min_len);
2220 2221 2222
}

/* when calling this function (hard_iface == primary_if) has to be true */
2223
int batadv_tt_append_diff(struct batadv_priv *bat_priv,
2224 2225 2226 2227 2228 2229
			  unsigned char **packet_buff, int *packet_buff_len,
			  int packet_min_len)
{
	int tt_num_changes;

	/* if at least one change happened */
2230 2231 2232
	tt_num_changes = batadv_tt_commit_changes(bat_priv, packet_buff,
						  packet_buff_len,
						  packet_min_len);
2233 2234 2235

	/* if the changes have been sent often enough */
	if ((tt_num_changes < 0) &&
2236
	    (!batadv_atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) {
2237 2238
		batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
					      packet_min_len, packet_min_len);
2239 2240 2241 2242
		tt_num_changes = 0;
	}

	return tt_num_changes;
2243
}
2244

2245
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
2246
			   uint8_t *dst)
2247
{
2248 2249
	struct batadv_tt_local_entry *tt_local_entry = NULL;
	struct batadv_tt_global_entry *tt_global_entry = NULL;
2250
	bool ret = false;
2251 2252

	if (!atomic_read(&bat_priv->ap_isolation))
2253
		goto out;
2254

2255
	tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst);
2256 2257 2258
	if (!tt_local_entry)
		goto out;

2259
	tt_global_entry = batadv_tt_global_hash_find(bat_priv, src);
2260 2261 2262
	if (!tt_global_entry)
		goto out;

2263
	if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
2264 2265
		goto out;

2266
	ret = true;
2267 2268 2269

out:
	if (tt_global_entry)
2270
		batadv_tt_global_entry_free_ref(tt_global_entry);
2271
	if (tt_local_entry)
2272
		batadv_tt_local_entry_free_ref(tt_local_entry);
2273 2274
	return ret;
}
2275

2276 2277
void batadv_tt_update_orig(struct batadv_priv *bat_priv,
			   struct batadv_orig_node *orig_node,
2278 2279
			   const unsigned char *tt_buff, uint8_t tt_num_changes,
			   uint8_t ttvn, uint16_t tt_crc)
2280 2281 2282
{
	uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
	bool full_table = true;
2283
	struct batadv_tt_change *tt_change;
2284

2285
	/* don't care about a backbone gateways updates. */
2286
	if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
2287 2288
		return;

2289
	/* orig table not initialised AND first diff is in the OGM OR the ttvn
2290 2291
	 * increased by one -> we can apply the attached changes
	 */
2292 2293
	if ((!orig_node->tt_initialised && ttvn == 1) ||
	    ttvn - orig_ttvn == 1) {
2294
		/* the OGM could not contain the changes due to their size or
2295 2296
		 * because they have already been sent BATADV_TT_OGM_APPEND_MAX
		 * times.
2297 2298
		 * In this case send a tt request
		 */
2299 2300 2301 2302 2303
		if (!tt_num_changes) {
			full_table = false;
			goto request_table;
		}

2304
		tt_change = (struct batadv_tt_change *)tt_buff;
2305
		batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
2306
					 ttvn, tt_change);
2307 2308 2309

		/* Even if we received the precomputed crc with the OGM, we
		 * prefer to recompute it to spot any possible inconsistency
2310 2311
		 * in the global table
		 */
2312
		orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
2313 2314 2315 2316 2317 2318 2319 2320

		/* The ttvn alone is not enough to guarantee consistency
		 * because a single value could represent different states
		 * (due to the wrap around). Thus a node has to check whether
		 * the resulting table (after applying the changes) is still
		 * consistent or not. E.g. a node could disconnect while its
		 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
		 * checking the CRC value is mandatory to detect the
2321 2322
		 * inconsistency
		 */
2323 2324 2325 2326
		if (orig_node->tt_crc != tt_crc)
			goto request_table;

		/* Roaming phase is over: tables are in sync again. I can
2327 2328
		 * unset the flag
		 */
2329 2330 2331
		orig_node->tt_poss_change = false;
	} else {
		/* if we missed more than one change or our tables are not
2332 2333
		 * in sync anymore -> request fresh tt data
		 */
2334 2335
		if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
		    orig_node->tt_crc != tt_crc) {
2336
request_table:
2337
			batadv_dbg(BATADV_DBG_TT, bat_priv,
2338 2339 2340
				   "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %u last_crc: %u num_changes: %u)\n",
				   orig_node->orig, ttvn, orig_ttvn, tt_crc,
				   orig_node->tt_crc, tt_num_changes);
2341 2342
			batadv_send_tt_request(bat_priv, orig_node, ttvn,
					       tt_crc, full_table);
2343 2344 2345 2346
			return;
		}
	}
}
2347 2348 2349 2350 2351

/* returns true whether we know that the client has moved from its old
 * originator to another one. This entry is kept is still kept for consistency
 * purposes
 */
2352
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2353
					uint8_t *addr)
2354
{
2355
	struct batadv_tt_global_entry *tt_global_entry;
2356 2357
	bool ret = false;

2358
	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
2359 2360 2361
	if (!tt_global_entry)
		goto out;

2362
	ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
2363
	batadv_tt_global_entry_free_ref(tt_global_entry);
2364 2365 2366
out:
	return ret;
}