Add delay-init quirk for Corsair K70 RGB keyboards
[pandora-kernel.git] / net / batman-adv / translation-table.c
1 /*
2  * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
3  *
4  * Marek Lindner, Simon Wunderlich
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  *
20  */
21
22 #include "main.h"
23 #include "translation-table.h"
24 #include "soft-interface.h"
25 #include "hard-interface.h"
26 #include "send.h"
27 #include "hash.h"
28 #include "originator.h"
29 #include "routing.h"
30
31 #include <linux/crc16.h>
32
33 static void _tt_global_del(struct bat_priv *bat_priv,
34                            struct tt_global_entry *tt_global_entry,
35                            const char *message);
36 static void tt_purge(struct work_struct *work);
37
38 /* returns 1 if they are the same mac addr */
39 static int compare_ltt(const struct hlist_node *node, const void *data2)
40 {
41         const void *data1 = container_of(node, struct tt_local_entry,
42                                          hash_entry);
43
44         return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
45 }
46
47 /* returns 1 if they are the same mac addr */
48 static int compare_gtt(const struct hlist_node *node, const void *data2)
49 {
50         const void *data1 = container_of(node, struct tt_global_entry,
51                                          hash_entry);
52
53         return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
54 }
55
56 static void tt_start_timer(struct bat_priv *bat_priv)
57 {
58         INIT_DELAYED_WORK(&bat_priv->tt_work, tt_purge);
59         queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work,
60                            msecs_to_jiffies(5000));
61 }
62
63 static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
64                                                  const void *data)
65 {
66         struct hashtable_t *hash = bat_priv->tt_local_hash;
67         struct hlist_head *head;
68         struct hlist_node *node;
69         struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL;
70         int index;
71
72         if (!hash)
73                 return NULL;
74
75         index = choose_orig(data, hash->size);
76         head = &hash->table[index];
77
78         rcu_read_lock();
79         hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) {
80                 if (!compare_eth(tt_local_entry, data))
81                         continue;
82
83                 if (!atomic_inc_not_zero(&tt_local_entry->refcount))
84                         continue;
85
86                 tt_local_entry_tmp = tt_local_entry;
87                 break;
88         }
89         rcu_read_unlock();
90
91         return tt_local_entry_tmp;
92 }
93
94 static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
95                                                    const void *data)
96 {
97         struct hashtable_t *hash = bat_priv->tt_global_hash;
98         struct hlist_head *head;
99         struct hlist_node *node;
100         struct tt_global_entry *tt_global_entry;
101         struct tt_global_entry *tt_global_entry_tmp = NULL;
102         int index;
103
104         if (!hash)
105                 return NULL;
106
107         index = choose_orig(data, hash->size);
108         head = &hash->table[index];
109
110         rcu_read_lock();
111         hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) {
112                 if (!compare_eth(tt_global_entry, data))
113                         continue;
114
115                 if (!atomic_inc_not_zero(&tt_global_entry->refcount))
116                         continue;
117
118                 tt_global_entry_tmp = tt_global_entry;
119                 break;
120         }
121         rcu_read_unlock();
122
123         return tt_global_entry_tmp;
124 }
125
126 static bool is_out_of_time(unsigned long starting_time, unsigned long timeout)
127 {
128         unsigned long deadline;
129         deadline = starting_time + msecs_to_jiffies(timeout);
130
131         return time_after(jiffies, deadline);
132 }
133
134 static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry)
135 {
136         if (atomic_dec_and_test(&tt_local_entry->refcount))
137                 kfree_rcu(tt_local_entry, rcu);
138 }
139
140 static void tt_global_entry_free_rcu(struct rcu_head *rcu)
141 {
142         struct tt_global_entry *tt_global_entry;
143
144         tt_global_entry = container_of(rcu, struct tt_global_entry, rcu);
145
146         if (tt_global_entry->orig_node)
147                 orig_node_free_ref(tt_global_entry->orig_node);
148
149         kfree(tt_global_entry);
150 }
151
152 static void tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry)
153 {
154         if (atomic_dec_and_test(&tt_global_entry->refcount))
155                 call_rcu(&tt_global_entry->rcu, tt_global_entry_free_rcu);
156 }
157
158 static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr,
159                            uint8_t flags)
160 {
161         struct tt_change_node *tt_change_node;
162
163         tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
164
165         if (!tt_change_node)
166                 return;
167
168         tt_change_node->change.flags = flags;
169         memcpy(tt_change_node->change.addr, addr, ETH_ALEN);
170
171         spin_lock_bh(&bat_priv->tt_changes_list_lock);
172         /* track the change in the OGMinterval list */
173         list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list);
174         atomic_inc(&bat_priv->tt_local_changes);
175         spin_unlock_bh(&bat_priv->tt_changes_list_lock);
176
177         atomic_set(&bat_priv->tt_ogm_append_cnt, 0);
178 }
179
180 int tt_len(int changes_num)
181 {
182         return changes_num * sizeof(struct tt_change);
183 }
184
185 static int tt_local_init(struct bat_priv *bat_priv)
186 {
187         if (bat_priv->tt_local_hash)
188                 return 1;
189
190         bat_priv->tt_local_hash = hash_new(1024);
191
192         if (!bat_priv->tt_local_hash)
193                 return 0;
194
195         return 1;
196 }
197
198 void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
199                   int ifindex)
200 {
201         struct bat_priv *bat_priv = netdev_priv(soft_iface);
202         struct tt_local_entry *tt_local_entry = NULL;
203         struct tt_global_entry *tt_global_entry = NULL;
204
205         tt_local_entry = tt_local_hash_find(bat_priv, addr);
206
207         if (tt_local_entry) {
208                 tt_local_entry->last_seen = jiffies;
209                 goto out;
210         }
211
212         tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC);
213         if (!tt_local_entry)
214                 goto out;
215
216         bat_dbg(DBG_TT, bat_priv,
217                 "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
218                 (uint8_t)atomic_read(&bat_priv->ttvn));
219
220         memcpy(tt_local_entry->addr, addr, ETH_ALEN);
221         tt_local_entry->last_seen = jiffies;
222         tt_local_entry->flags = NO_FLAGS;
223         if (is_wifi_iface(ifindex))
224                 tt_local_entry->flags |= TT_CLIENT_WIFI;
225         atomic_set(&tt_local_entry->refcount, 2);
226
227         /* the batman interface mac address should never be purged */
228         if (compare_eth(addr, soft_iface->dev_addr))
229                 tt_local_entry->flags |= TT_CLIENT_NOPURGE;
230
231         tt_local_event(bat_priv, addr, tt_local_entry->flags);
232
233         /* The local entry has to be marked as NEW to avoid to send it in
234          * a full table response going out before the next ttvn increment
235          * (consistency check) */
236         tt_local_entry->flags |= TT_CLIENT_NEW;
237
238         hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
239                  tt_local_entry, &tt_local_entry->hash_entry);
240
241         /* remove address from global hash if present */
242         tt_global_entry = tt_global_hash_find(bat_priv, addr);
243
244         /* Check whether it is a roaming! */
245         if (tt_global_entry) {
246                 /* This node is probably going to update its tt table */
247                 tt_global_entry->orig_node->tt_poss_change = true;
248                 /* The global entry has to be marked as ROAMING and has to be
249                  * kept for consistency purpose */
250                 tt_global_entry->flags |= TT_CLIENT_ROAM;
251                 tt_global_entry->roam_at = jiffies;
252
253                 send_roam_adv(bat_priv, tt_global_entry->addr,
254                               tt_global_entry->orig_node);
255         }
256 out:
257         if (tt_local_entry)
258                 tt_local_entry_free_ref(tt_local_entry);
259         if (tt_global_entry)
260                 tt_global_entry_free_ref(tt_global_entry);
261 }
262
263 int tt_changes_fill_buffer(struct bat_priv *bat_priv,
264                            unsigned char *buff, int buff_len)
265 {
266         int count = 0, tot_changes = 0;
267         struct tt_change_node *entry, *safe;
268
269         if (buff_len > 0)
270                 tot_changes = buff_len / tt_len(1);
271
272         spin_lock_bh(&bat_priv->tt_changes_list_lock);
273         atomic_set(&bat_priv->tt_local_changes, 0);
274
275         list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
276                         list) {
277                 if (count < tot_changes) {
278                         memcpy(buff + tt_len(count),
279                                &entry->change, sizeof(struct tt_change));
280                         count++;
281                 }
282                 list_del(&entry->list);
283                 kfree(entry);
284         }
285         spin_unlock_bh(&bat_priv->tt_changes_list_lock);
286
287         /* Keep the buffer for possible tt_request */
288         spin_lock_bh(&bat_priv->tt_buff_lock);
289         kfree(bat_priv->tt_buff);
290         bat_priv->tt_buff_len = 0;
291         bat_priv->tt_buff = NULL;
292         /* We check whether this new OGM has no changes due to size
293          * problems */
294         if (buff_len > 0) {
295                 /**
296                  * if kmalloc() fails we will reply with the full table
297                  * instead of providing the diff
298                  */
299                 bat_priv->tt_buff = kmalloc(buff_len, GFP_ATOMIC);
300                 if (bat_priv->tt_buff) {
301                         memcpy(bat_priv->tt_buff, buff, buff_len);
302                         bat_priv->tt_buff_len = buff_len;
303                 }
304         }
305         spin_unlock_bh(&bat_priv->tt_buff_lock);
306
307         return tot_changes;
308 }
309
310 int tt_local_seq_print_text(struct seq_file *seq, void *offset)
311 {
312         struct net_device *net_dev = (struct net_device *)seq->private;
313         struct bat_priv *bat_priv = netdev_priv(net_dev);
314         struct hashtable_t *hash = bat_priv->tt_local_hash;
315         struct tt_local_entry *tt_local_entry;
316         struct hard_iface *primary_if;
317         struct hlist_node *node;
318         struct hlist_head *head;
319         size_t buf_size, pos;
320         char *buff;
321         int i, ret = 0;
322
323         primary_if = primary_if_get_selected(bat_priv);
324         if (!primary_if) {
325                 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
326                                  "please specify interfaces to enable it\n",
327                                  net_dev->name);
328                 goto out;
329         }
330
331         if (primary_if->if_status != IF_ACTIVE) {
332                 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
333                                  "primary interface not active\n",
334                                  net_dev->name);
335                 goto out;
336         }
337
338         seq_printf(seq, "Locally retrieved addresses (from %s) "
339                    "announced via TT (TTVN: %u):\n",
340                    net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn));
341
342         buf_size = 1;
343         /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
344         for (i = 0; i < hash->size; i++) {
345                 head = &hash->table[i];
346
347                 rcu_read_lock();
348                 __hlist_for_each_rcu(node, head)
349                         buf_size += 29;
350                 rcu_read_unlock();
351         }
352
353         buff = kmalloc(buf_size, GFP_ATOMIC);
354         if (!buff) {
355                 ret = -ENOMEM;
356                 goto out;
357         }
358
359         buff[0] = '\0';
360         pos = 0;
361
362         for (i = 0; i < hash->size; i++) {
363                 head = &hash->table[i];
364
365                 rcu_read_lock();
366                 hlist_for_each_entry_rcu(tt_local_entry, node,
367                                          head, hash_entry) {
368                         pos += snprintf(buff + pos, 30, " * %pM "
369                                         "[%c%c%c%c%c]\n",
370                                         tt_local_entry->addr,
371                                         (tt_local_entry->flags &
372                                          TT_CLIENT_ROAM ? 'R' : '.'),
373                                         (tt_local_entry->flags &
374                                          TT_CLIENT_NOPURGE ? 'P' : '.'),
375                                         (tt_local_entry->flags &
376                                          TT_CLIENT_NEW ? 'N' : '.'),
377                                         (tt_local_entry->flags &
378                                          TT_CLIENT_PENDING ? 'X' : '.'),
379                                         (tt_local_entry->flags &
380                                          TT_CLIENT_WIFI ? 'W' : '.'));
381                 }
382                 rcu_read_unlock();
383         }
384
385         seq_printf(seq, "%s", buff);
386         kfree(buff);
387 out:
388         if (primary_if)
389                 hardif_free_ref(primary_if);
390         return ret;
391 }
392
393 static void tt_local_set_pending(struct bat_priv *bat_priv,
394                                  struct tt_local_entry *tt_local_entry,
395                                  uint16_t flags)
396 {
397         tt_local_event(bat_priv, tt_local_entry->addr,
398                        tt_local_entry->flags | flags);
399
400         /* The local client has to be marked as "pending to be removed" but has
401          * to be kept in the table in order to send it in a full table
402          * response issued before the net ttvn increment (consistency check) */
403         tt_local_entry->flags |= TT_CLIENT_PENDING;
404 }
405
406 void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
407                      const char *message, bool roaming)
408 {
409         struct tt_local_entry *tt_local_entry = NULL;
410
411         tt_local_entry = tt_local_hash_find(bat_priv, addr);
412         if (!tt_local_entry)
413                 goto out;
414
415         tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL |
416                              (roaming ? TT_CLIENT_ROAM : NO_FLAGS));
417
418         bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) pending to be removed: "
419                 "%s\n", tt_local_entry->addr, message);
420 out:
421         if (tt_local_entry)
422                 tt_local_entry_free_ref(tt_local_entry);
423 }
424
425 static void tt_local_purge(struct bat_priv *bat_priv)
426 {
427         struct hashtable_t *hash = bat_priv->tt_local_hash;
428         struct tt_local_entry *tt_local_entry;
429         struct hlist_node *node, *node_tmp;
430         struct hlist_head *head;
431         spinlock_t *list_lock; /* protects write access to the hash lists */
432         int i;
433
434         for (i = 0; i < hash->size; i++) {
435                 head = &hash->table[i];
436                 list_lock = &hash->list_locks[i];
437
438                 spin_lock_bh(list_lock);
439                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
440                                           head, hash_entry) {
441                         if (tt_local_entry->flags & TT_CLIENT_NOPURGE)
442                                 continue;
443
444                         /* entry already marked for deletion */
445                         if (tt_local_entry->flags & TT_CLIENT_PENDING)
446                                 continue;
447
448                         if (!is_out_of_time(tt_local_entry->last_seen,
449                                             TT_LOCAL_TIMEOUT * 1000))
450                                 continue;
451
452                         tt_local_set_pending(bat_priv, tt_local_entry,
453                                              TT_CLIENT_DEL);
454                         bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) "
455                                 "pending to be removed: timed out\n",
456                                 tt_local_entry->addr);
457                 }
458                 spin_unlock_bh(list_lock);
459         }
460
461 }
462
463 static void tt_local_table_free(struct bat_priv *bat_priv)
464 {
465         struct hashtable_t *hash;
466         spinlock_t *list_lock; /* protects write access to the hash lists */
467         struct tt_local_entry *tt_local_entry;
468         struct hlist_node *node, *node_tmp;
469         struct hlist_head *head;
470         int i;
471
472         if (!bat_priv->tt_local_hash)
473                 return;
474
475         hash = bat_priv->tt_local_hash;
476
477         for (i = 0; i < hash->size; i++) {
478                 head = &hash->table[i];
479                 list_lock = &hash->list_locks[i];
480
481                 spin_lock_bh(list_lock);
482                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
483                                           head, hash_entry) {
484                         hlist_del_rcu(node);
485                         tt_local_entry_free_ref(tt_local_entry);
486                 }
487                 spin_unlock_bh(list_lock);
488         }
489
490         hash_destroy(hash);
491
492         bat_priv->tt_local_hash = NULL;
493 }
494
495 static int tt_global_init(struct bat_priv *bat_priv)
496 {
497         if (bat_priv->tt_global_hash)
498                 return 1;
499
500         bat_priv->tt_global_hash = hash_new(1024);
501
502         if (!bat_priv->tt_global_hash)
503                 return 0;
504
505         return 1;
506 }
507
508 static void tt_changes_list_free(struct bat_priv *bat_priv)
509 {
510         struct tt_change_node *entry, *safe;
511
512         spin_lock_bh(&bat_priv->tt_changes_list_lock);
513
514         list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
515                                  list) {
516                 list_del(&entry->list);
517                 kfree(entry);
518         }
519
520         atomic_set(&bat_priv->tt_local_changes, 0);
521         spin_unlock_bh(&bat_priv->tt_changes_list_lock);
522 }
523
524 /* caller must hold orig_node refcount */
525 int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
526                   const unsigned char *tt_addr, uint8_t ttvn, bool roaming,
527                   bool wifi)
528 {
529         struct tt_global_entry *tt_global_entry;
530         struct orig_node *orig_node_tmp;
531         int ret = 0;
532
533         tt_global_entry = tt_global_hash_find(bat_priv, tt_addr);
534
535         if (!tt_global_entry) {
536                 tt_global_entry =
537                         kmalloc(sizeof(*tt_global_entry),
538                                 GFP_ATOMIC);
539                 if (!tt_global_entry)
540                         goto out;
541
542                 memcpy(tt_global_entry->addr, tt_addr, ETH_ALEN);
543                 /* Assign the new orig_node */
544                 atomic_inc(&orig_node->refcount);
545                 tt_global_entry->orig_node = orig_node;
546                 tt_global_entry->ttvn = ttvn;
547                 tt_global_entry->flags = NO_FLAGS;
548                 tt_global_entry->roam_at = 0;
549                 atomic_set(&tt_global_entry->refcount, 2);
550
551                 hash_add(bat_priv->tt_global_hash, compare_gtt,
552                          choose_orig, tt_global_entry,
553                          &tt_global_entry->hash_entry);
554                 atomic_inc(&orig_node->tt_size);
555         } else {
556                 if (tt_global_entry->orig_node != orig_node) {
557                         atomic_dec(&tt_global_entry->orig_node->tt_size);
558                         orig_node_tmp = tt_global_entry->orig_node;
559                         atomic_inc(&orig_node->refcount);
560                         tt_global_entry->orig_node = orig_node;
561                         orig_node_free_ref(orig_node_tmp);
562                         atomic_inc(&orig_node->tt_size);
563                 }
564                 tt_global_entry->ttvn = ttvn;
565                 tt_global_entry->flags = NO_FLAGS;
566                 tt_global_entry->roam_at = 0;
567         }
568
569         if (wifi)
570                 tt_global_entry->flags |= TT_CLIENT_WIFI;
571
572         bat_dbg(DBG_TT, bat_priv,
573                 "Creating new global tt entry: %pM (via %pM)\n",
574                 tt_global_entry->addr, orig_node->orig);
575
576         /* remove address from local hash if present */
577         tt_local_remove(bat_priv, tt_global_entry->addr,
578                         "global tt received", roaming);
579         ret = 1;
580 out:
581         if (tt_global_entry)
582                 tt_global_entry_free_ref(tt_global_entry);
583         return ret;
584 }
585
586 int tt_global_seq_print_text(struct seq_file *seq, void *offset)
587 {
588         struct net_device *net_dev = (struct net_device *)seq->private;
589         struct bat_priv *bat_priv = netdev_priv(net_dev);
590         struct hashtable_t *hash = bat_priv->tt_global_hash;
591         struct tt_global_entry *tt_global_entry;
592         struct hard_iface *primary_if;
593         struct hlist_node *node;
594         struct hlist_head *head;
595         size_t buf_size, pos;
596         char *buff;
597         int i, ret = 0;
598
599         primary_if = primary_if_get_selected(bat_priv);
600         if (!primary_if) {
601                 ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
602                                  "specify interfaces to enable it\n",
603                                  net_dev->name);
604                 goto out;
605         }
606
607         if (primary_if->if_status != IF_ACTIVE) {
608                 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
609                                  "primary interface not active\n",
610                                  net_dev->name);
611                 goto out;
612         }
613
614         seq_printf(seq,
615                    "Globally announced TT entries received via the mesh %s\n",
616                    net_dev->name);
617         seq_printf(seq, "       %-13s %s       %-15s %s %s\n",
618                    "Client", "(TTVN)", "Originator", "(Curr TTVN)", "Flags");
619
620         buf_size = 1;
621         /* Estimate length for: " * xx:xx:xx:xx:xx:xx (ttvn) via
622          * xx:xx:xx:xx:xx:xx (cur_ttvn)\n"*/
623         for (i = 0; i < hash->size; i++) {
624                 head = &hash->table[i];
625
626                 rcu_read_lock();
627                 __hlist_for_each_rcu(node, head)
628                         buf_size += 67;
629                 rcu_read_unlock();
630         }
631
632         buff = kmalloc(buf_size, GFP_ATOMIC);
633         if (!buff) {
634                 ret = -ENOMEM;
635                 goto out;
636         }
637
638         buff[0] = '\0';
639         pos = 0;
640
641         for (i = 0; i < hash->size; i++) {
642                 head = &hash->table[i];
643
644                 rcu_read_lock();
645                 hlist_for_each_entry_rcu(tt_global_entry, node,
646                                          head, hash_entry) {
647                         pos += snprintf(buff + pos, 69,
648                                         " * %pM  (%3u) via %pM     (%3u)   "
649                                         "[%c%c%c]\n", tt_global_entry->addr,
650                                         tt_global_entry->ttvn,
651                                         tt_global_entry->orig_node->orig,
652                                         (uint8_t) atomic_read(
653                                                 &tt_global_entry->orig_node->
654                                                 last_ttvn),
655                                         (tt_global_entry->flags &
656                                          TT_CLIENT_ROAM ? 'R' : '.'),
657                                         (tt_global_entry->flags &
658                                          TT_CLIENT_PENDING ? 'X' : '.'),
659                                         (tt_global_entry->flags &
660                                          TT_CLIENT_WIFI ? 'W' : '.'));
661                 }
662                 rcu_read_unlock();
663         }
664
665         seq_printf(seq, "%s", buff);
666         kfree(buff);
667 out:
668         if (primary_if)
669                 hardif_free_ref(primary_if);
670         return ret;
671 }
672
673 static void _tt_global_del(struct bat_priv *bat_priv,
674                            struct tt_global_entry *tt_global_entry,
675                            const char *message)
676 {
677         if (!tt_global_entry)
678                 goto out;
679
680         bat_dbg(DBG_TT, bat_priv,
681                 "Deleting global tt entry %pM (via %pM): %s\n",
682                 tt_global_entry->addr, tt_global_entry->orig_node->orig,
683                 message);
684
685         atomic_dec(&tt_global_entry->orig_node->tt_size);
686
687         hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
688                     tt_global_entry->addr);
689 out:
690         if (tt_global_entry)
691                 tt_global_entry_free_ref(tt_global_entry);
692 }
693
694 void tt_global_del(struct bat_priv *bat_priv,
695                    struct orig_node *orig_node, const unsigned char *addr,
696                    const char *message, bool roaming)
697 {
698         struct tt_global_entry *tt_global_entry = NULL;
699         struct tt_local_entry *tt_local_entry = NULL;
700
701         tt_global_entry = tt_global_hash_find(bat_priv, addr);
702         if (!tt_global_entry)
703                 goto out;
704
705         if (tt_global_entry->orig_node == orig_node) {
706                 if (roaming) {
707                         /* if we are deleting a global entry due to a roam
708                          * event, there are two possibilities:
709                          * 1) the client roamed from node A to node B => we mark
710                          *    it with TT_CLIENT_ROAM, we start a timer and we
711                          *    wait for node B to claim it. In case of timeout
712                          *    the entry is purged.
713                          * 2) the client roamed to us => we can directly delete
714                          *    the global entry, since it is useless now. */
715                         tt_local_entry = tt_local_hash_find(bat_priv,
716                                                         tt_global_entry->addr);
717                         if (!tt_local_entry) {
718                                 tt_global_entry->flags |= TT_CLIENT_ROAM;
719                                 tt_global_entry->roam_at = jiffies;
720                                 goto out;
721                         }
722                 }
723                 _tt_global_del(bat_priv, tt_global_entry, message);
724         }
725 out:
726         if (tt_global_entry)
727                 tt_global_entry_free_ref(tt_global_entry);
728         if (tt_local_entry)
729                 tt_local_entry_free_ref(tt_local_entry);
730 }
731
732 void tt_global_del_orig(struct bat_priv *bat_priv,
733                         struct orig_node *orig_node, const char *message)
734 {
735         struct tt_global_entry *tt_global_entry;
736         int i;
737         struct hashtable_t *hash = bat_priv->tt_global_hash;
738         struct hlist_node *node, *safe;
739         struct hlist_head *head;
740         spinlock_t *list_lock; /* protects write access to the hash lists */
741
742         if (!hash)
743                 return;
744
745         for (i = 0; i < hash->size; i++) {
746                 head = &hash->table[i];
747                 list_lock = &hash->list_locks[i];
748
749                 spin_lock_bh(list_lock);
750                 hlist_for_each_entry_safe(tt_global_entry, node, safe,
751                                          head, hash_entry) {
752                         if (tt_global_entry->orig_node == orig_node) {
753                                 bat_dbg(DBG_TT, bat_priv,
754                                         "Deleting global tt entry %pM "
755                                         "(via %pM): originator time out\n",
756                                         tt_global_entry->addr,
757                                         tt_global_entry->orig_node->orig);
758                                 hlist_del_rcu(node);
759                                 tt_global_entry_free_ref(tt_global_entry);
760                         }
761                 }
762                 spin_unlock_bh(list_lock);
763         }
764         atomic_set(&orig_node->tt_size, 0);
765 }
766
767 static void tt_global_roam_purge(struct bat_priv *bat_priv)
768 {
769         struct hashtable_t *hash = bat_priv->tt_global_hash;
770         struct tt_global_entry *tt_global_entry;
771         struct hlist_node *node, *node_tmp;
772         struct hlist_head *head;
773         spinlock_t *list_lock; /* protects write access to the hash lists */
774         int i;
775
776         for (i = 0; i < hash->size; i++) {
777                 head = &hash->table[i];
778                 list_lock = &hash->list_locks[i];
779
780                 spin_lock_bh(list_lock);
781                 hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
782                                           head, hash_entry) {
783                         if (!(tt_global_entry->flags & TT_CLIENT_ROAM))
784                                 continue;
785                         if (!is_out_of_time(tt_global_entry->roam_at,
786                                             TT_CLIENT_ROAM_TIMEOUT * 1000))
787                                 continue;
788
789                         bat_dbg(DBG_TT, bat_priv, "Deleting global "
790                                 "tt entry (%pM): Roaming timeout\n",
791                                 tt_global_entry->addr);
792                         atomic_dec(&tt_global_entry->orig_node->tt_size);
793                         hlist_del_rcu(node);
794                         tt_global_entry_free_ref(tt_global_entry);
795                 }
796                 spin_unlock_bh(list_lock);
797         }
798
799 }
800
801 static void tt_global_table_free(struct bat_priv *bat_priv)
802 {
803         struct hashtable_t *hash;
804         spinlock_t *list_lock; /* protects write access to the hash lists */
805         struct tt_global_entry *tt_global_entry;
806         struct hlist_node *node, *node_tmp;
807         struct hlist_head *head;
808         int i;
809
810         if (!bat_priv->tt_global_hash)
811                 return;
812
813         hash = bat_priv->tt_global_hash;
814
815         for (i = 0; i < hash->size; i++) {
816                 head = &hash->table[i];
817                 list_lock = &hash->list_locks[i];
818
819                 spin_lock_bh(list_lock);
820                 hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
821                                           head, hash_entry) {
822                         hlist_del_rcu(node);
823                         tt_global_entry_free_ref(tt_global_entry);
824                 }
825                 spin_unlock_bh(list_lock);
826         }
827
828         hash_destroy(hash);
829
830         bat_priv->tt_global_hash = NULL;
831 }
832
833 static bool _is_ap_isolated(struct tt_local_entry *tt_local_entry,
834                             struct tt_global_entry *tt_global_entry)
835 {
836         bool ret = false;
837
838         if (tt_local_entry->flags & TT_CLIENT_WIFI &&
839             tt_global_entry->flags & TT_CLIENT_WIFI)
840                 ret = true;
841
842         return ret;
843 }
844
845 struct orig_node *transtable_search(struct bat_priv *bat_priv,
846                                     const uint8_t *src, const uint8_t *addr)
847 {
848         struct tt_local_entry *tt_local_entry = NULL;
849         struct tt_global_entry *tt_global_entry = NULL;
850         struct orig_node *orig_node = NULL;
851
852         if (src && atomic_read(&bat_priv->ap_isolation)) {
853                 tt_local_entry = tt_local_hash_find(bat_priv, src);
854                 if (!tt_local_entry)
855                         goto out;
856         }
857
858         tt_global_entry = tt_global_hash_find(bat_priv, addr);
859         if (!tt_global_entry)
860                 goto out;
861
862         /* check whether the clients should not communicate due to AP
863          * isolation */
864         if (tt_local_entry && _is_ap_isolated(tt_local_entry, tt_global_entry))
865                 goto out;
866
867         if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
868                 goto out;
869
870         /* A global client marked as PENDING has already moved from that
871          * originator */
872         if (tt_global_entry->flags & TT_CLIENT_PENDING)
873                 goto out;
874
875         orig_node = tt_global_entry->orig_node;
876
877 out:
878         if (tt_global_entry)
879                 tt_global_entry_free_ref(tt_global_entry);
880         if (tt_local_entry)
881                 tt_local_entry_free_ref(tt_local_entry);
882
883         return orig_node;
884 }
885
886 /* Calculates the checksum of the local table of a given orig_node */
887 uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node)
888 {
889         uint16_t total = 0, total_one;
890         struct hashtable_t *hash = bat_priv->tt_global_hash;
891         struct tt_global_entry *tt_global_entry;
892         struct hlist_node *node;
893         struct hlist_head *head;
894         int i, j;
895
896         for (i = 0; i < hash->size; i++) {
897                 head = &hash->table[i];
898
899                 rcu_read_lock();
900                 hlist_for_each_entry_rcu(tt_global_entry, node,
901                                          head, hash_entry) {
902                         if (compare_eth(tt_global_entry->orig_node,
903                                         orig_node)) {
904                                 /* Roaming clients are in the global table for
905                                  * consistency only. They don't have to be
906                                  * taken into account while computing the
907                                  * global crc */
908                                 if (tt_global_entry->flags & TT_CLIENT_ROAM)
909                                         continue;
910                                 total_one = 0;
911                                 for (j = 0; j < ETH_ALEN; j++)
912                                         total_one = crc16_byte(total_one,
913                                                 tt_global_entry->addr[j]);
914                                 total ^= total_one;
915                         }
916                 }
917                 rcu_read_unlock();
918         }
919
920         return total;
921 }
922
923 /* Calculates the checksum of the local table */
924 uint16_t tt_local_crc(struct bat_priv *bat_priv)
925 {
926         uint16_t total = 0, total_one;
927         struct hashtable_t *hash = bat_priv->tt_local_hash;
928         struct tt_local_entry *tt_local_entry;
929         struct hlist_node *node;
930         struct hlist_head *head;
931         int i, j;
932
933         for (i = 0; i < hash->size; i++) {
934                 head = &hash->table[i];
935
936                 rcu_read_lock();
937                 hlist_for_each_entry_rcu(tt_local_entry, node,
938                                          head, hash_entry) {
939                         /* not yet committed clients have not to be taken into
940                          * account while computing the CRC */
941                         if (tt_local_entry->flags & TT_CLIENT_NEW)
942                                 continue;
943                         total_one = 0;
944                         for (j = 0; j < ETH_ALEN; j++)
945                                 total_one = crc16_byte(total_one,
946                                                    tt_local_entry->addr[j]);
947                         total ^= total_one;
948                 }
949                 rcu_read_unlock();
950         }
951
952         return total;
953 }
954
955 /**
956  * batadv_tt_req_node_release - free tt_req node entry
957  * @ref: kref pointer of the tt req_node entry
958  */
959 static void batadv_tt_req_node_release(struct kref *ref)
960 {
961         struct tt_req_node *tt_req_node;
962
963         tt_req_node = container_of(ref, struct tt_req_node, refcount);
964
965         kfree(tt_req_node);
966 }
967
968 /**
969  * batadv_tt_req_node_put - decrement the tt_req_node refcounter and
970  *  possibly release it
971  * @tt_req_node: tt_req_node to be free'd
972  */
973 static void batadv_tt_req_node_put(struct tt_req_node *tt_req_node)
974 {
975         kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
976 }
977
978 static void tt_req_list_free(struct bat_priv *bat_priv)
979 {
980         struct tt_req_node *node, *safe;
981
982         spin_lock_bh(&bat_priv->tt_req_list_lock);
983
984         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
985                 list_del(&node->list);
986                 batadv_tt_req_node_put(node);
987         }
988
989         spin_unlock_bh(&bat_priv->tt_req_list_lock);
990 }
991
992 void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
993                          const unsigned char *tt_buff, uint8_t tt_num_changes)
994 {
995         uint16_t tt_buff_len = tt_len(tt_num_changes);
996
997         /* Replace the old buffer only if I received something in the
998          * last OGM (the OGM could carry no changes) */
999         spin_lock_bh(&orig_node->tt_buff_lock);
1000         if (tt_buff_len > 0) {
1001                 kfree(orig_node->tt_buff);
1002                 orig_node->tt_buff_len = 0;
1003                 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
1004                 if (orig_node->tt_buff) {
1005                         memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
1006                         orig_node->tt_buff_len = tt_buff_len;
1007                 }
1008         }
1009         spin_unlock_bh(&orig_node->tt_buff_lock);
1010 }
1011
1012 static void tt_req_purge(struct bat_priv *bat_priv)
1013 {
1014         struct tt_req_node *node, *safe;
1015
1016         spin_lock_bh(&bat_priv->tt_req_list_lock);
1017         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1018                 if (is_out_of_time(node->issued_at,
1019                     TT_REQUEST_TIMEOUT * 1000)) {
1020                         list_del(&node->list);
1021                         batadv_tt_req_node_put(node);
1022                 }
1023         }
1024         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1025 }
1026
1027 /* returns the pointer to the new tt_req_node struct if no request
1028  * has already been issued for this orig_node, NULL otherwise */
1029 static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
1030                                           struct orig_node *orig_node)
1031 {
1032         struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1033
1034         spin_lock_bh(&bat_priv->tt_req_list_lock);
1035         list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
1036                 if (compare_eth(tt_req_node_tmp, orig_node) &&
1037                     !is_out_of_time(tt_req_node_tmp->issued_at,
1038                                     TT_REQUEST_TIMEOUT * 1000))
1039                         goto unlock;
1040         }
1041
1042         tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
1043         if (!tt_req_node)
1044                 goto unlock;
1045
1046         kref_init(&tt_req_node->refcount);
1047         memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1048         tt_req_node->issued_at = jiffies;
1049
1050         kref_get(&tt_req_node->refcount);
1051         list_add(&tt_req_node->list, &bat_priv->tt_req_list);
1052 unlock:
1053         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1054         return tt_req_node;
1055 }
1056
1057 /* data_ptr is useless here, but has to be kept to respect the prototype */
1058 static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr)
1059 {
1060         const struct tt_local_entry *tt_local_entry = entry_ptr;
1061
1062         if (tt_local_entry->flags & TT_CLIENT_NEW)
1063                 return 0;
1064         return 1;
1065 }
1066
1067 static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
1068 {
1069         const struct tt_global_entry *tt_global_entry = entry_ptr;
1070         const struct orig_node *orig_node = data_ptr;
1071
1072         if (tt_global_entry->flags & TT_CLIENT_ROAM)
1073                 return 0;
1074
1075         return (tt_global_entry->orig_node == orig_node);
1076 }
1077
1078 static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1079                                               struct hashtable_t *hash,
1080                                               struct hard_iface *primary_if,
1081                                               int (*valid_cb)(const void *,
1082                                                               const void *),
1083                                               void *cb_data)
1084 {
1085         struct tt_local_entry *tt_local_entry;
1086         struct tt_query_packet *tt_response;
1087         struct tt_change *tt_change;
1088         struct hlist_node *node;
1089         struct hlist_head *head;
1090         struct sk_buff *skb = NULL;
1091         uint16_t tt_tot, tt_count;
1092         ssize_t tt_query_size = sizeof(struct tt_query_packet);
1093         int i;
1094
1095         if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
1096                 tt_len = primary_if->soft_iface->mtu - tt_query_size;
1097                 tt_len -= tt_len % sizeof(struct tt_change);
1098         }
1099         tt_tot = tt_len / sizeof(struct tt_change);
1100
1101         skb = dev_alloc_skb(tt_query_size + tt_len + ETH_HLEN);
1102         if (!skb)
1103                 goto out;
1104
1105         skb_reserve(skb, ETH_HLEN);
1106         tt_response = (struct tt_query_packet *)skb_put(skb,
1107                                                      tt_query_size + tt_len);
1108         tt_response->ttvn = ttvn;
1109
1110         tt_change = (struct tt_change *)(skb->data + tt_query_size);
1111         tt_count = 0;
1112
1113         rcu_read_lock();
1114         for (i = 0; i < hash->size; i++) {
1115                 head = &hash->table[i];
1116
1117                 hlist_for_each_entry_rcu(tt_local_entry, node,
1118                                          head, hash_entry) {
1119                         if (tt_count == tt_tot)
1120                                 break;
1121
1122                         if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data)))
1123                                 continue;
1124
1125                         memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN);
1126                         tt_change->flags = NO_FLAGS;
1127
1128                         tt_count++;
1129                         tt_change++;
1130                 }
1131         }
1132         rcu_read_unlock();
1133
1134         /* store in the message the number of entries we have successfully
1135          * copied */
1136         tt_response->tt_data = htons(tt_count);
1137
1138 out:
1139         return skb;
1140 }
1141
1142 static int send_tt_request(struct bat_priv *bat_priv,
1143                            struct orig_node *dst_orig_node,
1144                            uint8_t ttvn, uint16_t tt_crc, bool full_table)
1145 {
1146         struct sk_buff *skb = NULL;
1147         struct tt_query_packet *tt_request;
1148         struct neigh_node *neigh_node = NULL;
1149         struct hard_iface *primary_if;
1150         struct tt_req_node *tt_req_node = NULL;
1151         int ret = 1;
1152
1153         primary_if = primary_if_get_selected(bat_priv);
1154         if (!primary_if)
1155                 goto out;
1156
1157         /* The new tt_req will be issued only if I'm not waiting for a
1158          * reply from the same orig_node yet */
1159         tt_req_node = new_tt_req_node(bat_priv, dst_orig_node);
1160         if (!tt_req_node)
1161                 goto out;
1162
1163         skb = dev_alloc_skb(sizeof(struct tt_query_packet) + ETH_HLEN);
1164         if (!skb)
1165                 goto out;
1166
1167         skb_reserve(skb, ETH_HLEN);
1168
1169         tt_request = (struct tt_query_packet *)skb_put(skb,
1170                                 sizeof(struct tt_query_packet));
1171
1172         tt_request->packet_type = BAT_TT_QUERY;
1173         tt_request->version = COMPAT_VERSION;
1174         memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1175         memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1176         tt_request->ttl = TTL;
1177         tt_request->ttvn = ttvn;
1178         tt_request->tt_data = tt_crc;
1179         tt_request->flags = TT_REQUEST;
1180
1181         if (full_table)
1182                 tt_request->flags |= TT_FULL_TABLE;
1183
1184         neigh_node = orig_node_get_router(dst_orig_node);
1185         if (!neigh_node)
1186                 goto out;
1187
1188         bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM "
1189                 "[%c]\n", dst_orig_node->orig, neigh_node->addr,
1190                 (full_table ? 'F' : '.'));
1191
1192         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1193         ret = 0;
1194
1195 out:
1196         if (neigh_node)
1197                 neigh_node_free_ref(neigh_node);
1198         if (primary_if)
1199                 hardif_free_ref(primary_if);
1200         if (ret)
1201                 kfree_skb(skb);
1202
1203         if (ret && tt_req_node) {
1204                 spin_lock_bh(&bat_priv->tt_req_list_lock);
1205                 if (!list_empty(&tt_req_node->list)) {
1206                         list_del(&tt_req_node->list);
1207                         batadv_tt_req_node_put(tt_req_node);
1208                 }
1209                 spin_unlock_bh(&bat_priv->tt_req_list_lock);
1210         }
1211
1212         if (tt_req_node)
1213                 batadv_tt_req_node_put(tt_req_node);
1214
1215         return ret;
1216 }
1217
1218 static bool send_other_tt_response(struct bat_priv *bat_priv,
1219                                    struct tt_query_packet *tt_request)
1220 {
1221         struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL;
1222         struct neigh_node *neigh_node = NULL;
1223         struct hard_iface *primary_if = NULL;
1224         uint8_t orig_ttvn, req_ttvn, ttvn;
1225         int ret = false;
1226         unsigned char *tt_buff;
1227         bool full_table;
1228         uint16_t tt_len, tt_tot;
1229         struct sk_buff *skb = NULL;
1230         struct tt_query_packet *tt_response;
1231
1232         bat_dbg(DBG_TT, bat_priv,
1233                 "Received TT_REQUEST from %pM for "
1234                 "ttvn: %u (%pM) [%c]\n", tt_request->src,
1235                 tt_request->ttvn, tt_request->dst,
1236                 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1237
1238         /* Let's get the orig node of the REAL destination */
1239         req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst);
1240         if (!req_dst_orig_node)
1241                 goto out;
1242
1243         res_dst_orig_node = get_orig_node(bat_priv, tt_request->src);
1244         if (!res_dst_orig_node)
1245                 goto out;
1246
1247         neigh_node = orig_node_get_router(res_dst_orig_node);
1248         if (!neigh_node)
1249                 goto out;
1250
1251         primary_if = primary_if_get_selected(bat_priv);
1252         if (!primary_if)
1253                 goto out;
1254
1255         orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1256         req_ttvn = tt_request->ttvn;
1257
1258         /* I don't have the requested data */
1259         if (orig_ttvn != req_ttvn ||
1260             tt_request->tt_data != req_dst_orig_node->tt_crc)
1261                 goto out;
1262
1263         /* If the full table has been explicitly requested */
1264         if (tt_request->flags & TT_FULL_TABLE ||
1265             !req_dst_orig_node->tt_buff)
1266                 full_table = true;
1267         else
1268                 full_table = false;
1269
1270         /* In this version, fragmentation is not implemented, then
1271          * I'll send only one packet with as much TT entries as I can */
1272         if (!full_table) {
1273                 spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1274                 tt_len = req_dst_orig_node->tt_buff_len;
1275                 tt_tot = tt_len / sizeof(struct tt_change);
1276
1277                 skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1278                                     tt_len + ETH_HLEN);
1279                 if (!skb)
1280                         goto unlock;
1281
1282                 skb_reserve(skb, ETH_HLEN);
1283                 tt_response = (struct tt_query_packet *)skb_put(skb,
1284                                 sizeof(struct tt_query_packet) + tt_len);
1285                 tt_response->ttvn = req_ttvn;
1286                 tt_response->tt_data = htons(tt_tot);
1287
1288                 tt_buff = skb->data + sizeof(struct tt_query_packet);
1289                 /* Copy the last orig_node's OGM buffer */
1290                 memcpy(tt_buff, req_dst_orig_node->tt_buff,
1291                        req_dst_orig_node->tt_buff_len);
1292
1293                 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1294         } else {
1295                 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size) *
1296                                                 sizeof(struct tt_change);
1297                 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1298
1299                 skb = tt_response_fill_table(tt_len, ttvn,
1300                                              bat_priv->tt_global_hash,
1301                                              primary_if, tt_global_valid_entry,
1302                                              req_dst_orig_node);
1303                 if (!skb)
1304                         goto out;
1305
1306                 tt_response = (struct tt_query_packet *)skb->data;
1307         }
1308
1309         tt_response->packet_type = BAT_TT_QUERY;
1310         tt_response->version = COMPAT_VERSION;
1311         tt_response->ttl = TTL;
1312         memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1313         memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1314         tt_response->flags = TT_RESPONSE;
1315
1316         if (full_table)
1317                 tt_response->flags |= TT_FULL_TABLE;
1318
1319         bat_dbg(DBG_TT, bat_priv,
1320                 "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
1321                 res_dst_orig_node->orig, neigh_node->addr,
1322                 req_dst_orig_node->orig, req_ttvn);
1323
1324         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1325         ret = true;
1326         goto out;
1327
1328 unlock:
1329         spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1330
1331 out:
1332         if (res_dst_orig_node)
1333                 orig_node_free_ref(res_dst_orig_node);
1334         if (req_dst_orig_node)
1335                 orig_node_free_ref(req_dst_orig_node);
1336         if (neigh_node)
1337                 neigh_node_free_ref(neigh_node);
1338         if (primary_if)
1339                 hardif_free_ref(primary_if);
1340         if (!ret)
1341                 kfree_skb(skb);
1342         return ret;
1343
1344 }
1345 static bool send_my_tt_response(struct bat_priv *bat_priv,
1346                                 struct tt_query_packet *tt_request)
1347 {
1348         struct orig_node *orig_node = NULL;
1349         struct neigh_node *neigh_node = NULL;
1350         struct hard_iface *primary_if = NULL;
1351         uint8_t my_ttvn, req_ttvn, ttvn;
1352         int ret = false;
1353         unsigned char *tt_buff;
1354         bool full_table;
1355         uint16_t tt_len, tt_tot;
1356         struct sk_buff *skb = NULL;
1357         struct tt_query_packet *tt_response;
1358
1359         bat_dbg(DBG_TT, bat_priv,
1360                 "Received TT_REQUEST from %pM for "
1361                 "ttvn: %u (me) [%c]\n", tt_request->src,
1362                 tt_request->ttvn,
1363                 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1364
1365
1366         my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1367         req_ttvn = tt_request->ttvn;
1368
1369         orig_node = get_orig_node(bat_priv, tt_request->src);
1370         if (!orig_node)
1371                 goto out;
1372
1373         neigh_node = orig_node_get_router(orig_node);
1374         if (!neigh_node)
1375                 goto out;
1376
1377         primary_if = primary_if_get_selected(bat_priv);
1378         if (!primary_if)
1379                 goto out;
1380
1381         /* If the full table has been explicitly requested or the gap
1382          * is too big send the whole local translation table */
1383         if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn ||
1384             !bat_priv->tt_buff)
1385                 full_table = true;
1386         else
1387                 full_table = false;
1388
1389         /* In this version, fragmentation is not implemented, then
1390          * I'll send only one packet with as much TT entries as I can */
1391         if (!full_table) {
1392                 spin_lock_bh(&bat_priv->tt_buff_lock);
1393                 tt_len = bat_priv->tt_buff_len;
1394                 tt_tot = tt_len / sizeof(struct tt_change);
1395
1396                 skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1397                                     tt_len + ETH_HLEN);
1398                 if (!skb)
1399                         goto unlock;
1400
1401                 skb_reserve(skb, ETH_HLEN);
1402                 tt_response = (struct tt_query_packet *)skb_put(skb,
1403                                 sizeof(struct tt_query_packet) + tt_len);
1404                 tt_response->ttvn = req_ttvn;
1405                 tt_response->tt_data = htons(tt_tot);
1406
1407                 tt_buff = skb->data + sizeof(struct tt_query_packet);
1408                 memcpy(tt_buff, bat_priv->tt_buff,
1409                        bat_priv->tt_buff_len);
1410                 spin_unlock_bh(&bat_priv->tt_buff_lock);
1411         } else {
1412                 tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt) *
1413                                                 sizeof(struct tt_change);
1414                 ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1415
1416                 skb = tt_response_fill_table(tt_len, ttvn,
1417                                              bat_priv->tt_local_hash,
1418                                              primary_if, tt_local_valid_entry,
1419                                              NULL);
1420                 if (!skb)
1421                         goto out;
1422
1423                 tt_response = (struct tt_query_packet *)skb->data;
1424         }
1425
1426         tt_response->packet_type = BAT_TT_QUERY;
1427         tt_response->version = COMPAT_VERSION;
1428         tt_response->ttl = TTL;
1429         memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1430         memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1431         tt_response->flags = TT_RESPONSE;
1432
1433         if (full_table)
1434                 tt_response->flags |= TT_FULL_TABLE;
1435
1436         bat_dbg(DBG_TT, bat_priv,
1437                 "Sending TT_RESPONSE to %pM via %pM [%c]\n",
1438                 orig_node->orig, neigh_node->addr,
1439                 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1440
1441         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1442         ret = true;
1443         goto out;
1444
1445 unlock:
1446         spin_unlock_bh(&bat_priv->tt_buff_lock);
1447 out:
1448         if (orig_node)
1449                 orig_node_free_ref(orig_node);
1450         if (neigh_node)
1451                 neigh_node_free_ref(neigh_node);
1452         if (primary_if)
1453                 hardif_free_ref(primary_if);
1454         if (!ret)
1455                 kfree_skb(skb);
1456         /* This packet was for me, so it doesn't need to be re-routed */
1457         return true;
1458 }
1459
1460 bool send_tt_response(struct bat_priv *bat_priv,
1461                       struct tt_query_packet *tt_request)
1462 {
1463         if (is_my_mac(tt_request->dst))
1464                 return send_my_tt_response(bat_priv, tt_request);
1465         else
1466                 return send_other_tt_response(bat_priv, tt_request);
1467 }
1468
1469 static void _tt_update_changes(struct bat_priv *bat_priv,
1470                                struct orig_node *orig_node,
1471                                struct tt_change *tt_change,
1472                                uint16_t tt_num_changes, uint8_t ttvn)
1473 {
1474         int i;
1475
1476         for (i = 0; i < tt_num_changes; i++) {
1477                 if ((tt_change + i)->flags & TT_CLIENT_DEL)
1478                         tt_global_del(bat_priv, orig_node,
1479                                       (tt_change + i)->addr,
1480                                       "tt removed by changes",
1481                                       (tt_change + i)->flags & TT_CLIENT_ROAM);
1482                 else
1483                         if (!tt_global_add(bat_priv, orig_node,
1484                                            (tt_change + i)->addr, ttvn, false,
1485                                            (tt_change + i)->flags &
1486                                                         TT_CLIENT_WIFI))
1487                                 /* In case of problem while storing a
1488                                  * global_entry, we stop the updating
1489                                  * procedure without committing the
1490                                  * ttvn change. This will avoid to send
1491                                  * corrupted data on tt_request
1492                                  */
1493                                 return;
1494         }
1495 }
1496
1497 static void tt_fill_gtable(struct bat_priv *bat_priv,
1498                            struct tt_query_packet *tt_response)
1499 {
1500         struct orig_node *orig_node = NULL;
1501
1502         orig_node = orig_hash_find(bat_priv, tt_response->src);
1503         if (!orig_node)
1504                 goto out;
1505
1506         /* Purge the old table first.. */
1507         tt_global_del_orig(bat_priv, orig_node, "Received full table");
1508
1509         _tt_update_changes(bat_priv, orig_node,
1510                            (struct tt_change *)(tt_response + 1),
1511                            tt_response->tt_data, tt_response->ttvn);
1512
1513         spin_lock_bh(&orig_node->tt_buff_lock);
1514         kfree(orig_node->tt_buff);
1515         orig_node->tt_buff_len = 0;
1516         orig_node->tt_buff = NULL;
1517         spin_unlock_bh(&orig_node->tt_buff_lock);
1518
1519         atomic_set(&orig_node->last_ttvn, tt_response->ttvn);
1520
1521 out:
1522         if (orig_node)
1523                 orig_node_free_ref(orig_node);
1524 }
1525
1526 static void tt_update_changes(struct bat_priv *bat_priv,
1527                               struct orig_node *orig_node,
1528                               uint16_t tt_num_changes, uint8_t ttvn,
1529                               struct tt_change *tt_change)
1530 {
1531         _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes,
1532                            ttvn);
1533
1534         tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change,
1535                             tt_num_changes);
1536         atomic_set(&orig_node->last_ttvn, ttvn);
1537 }
1538
1539 bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr)
1540 {
1541         struct tt_local_entry *tt_local_entry = NULL;
1542         bool ret = false;
1543
1544         tt_local_entry = tt_local_hash_find(bat_priv, addr);
1545         if (!tt_local_entry)
1546                 goto out;
1547         /* Check if the client has been logically deleted (but is kept for
1548          * consistency purpose) */
1549         if (tt_local_entry->flags & TT_CLIENT_PENDING)
1550                 goto out;
1551         ret = true;
1552 out:
1553         if (tt_local_entry)
1554                 tt_local_entry_free_ref(tt_local_entry);
1555         return ret;
1556 }
1557
1558 void handle_tt_response(struct bat_priv *bat_priv,
1559                         struct tt_query_packet *tt_response)
1560 {
1561         struct tt_req_node *node, *safe;
1562         struct orig_node *orig_node = NULL;
1563
1564         bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for "
1565                 "ttvn %d t_size: %d [%c]\n",
1566                 tt_response->src, tt_response->ttvn,
1567                 tt_response->tt_data,
1568                 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1569
1570         orig_node = orig_hash_find(bat_priv, tt_response->src);
1571         if (!orig_node)
1572                 goto out;
1573
1574         if (tt_response->flags & TT_FULL_TABLE)
1575                 tt_fill_gtable(bat_priv, tt_response);
1576         else
1577                 tt_update_changes(bat_priv, orig_node, tt_response->tt_data,
1578                                   tt_response->ttvn,
1579                                   (struct tt_change *)(tt_response + 1));
1580
1581         /* Delete the tt_req_node from pending tt_requests list */
1582         spin_lock_bh(&bat_priv->tt_req_list_lock);
1583         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1584                 if (!compare_eth(node->addr, tt_response->src))
1585                         continue;
1586                 list_del(&node->list);
1587                 batadv_tt_req_node_put(node);
1588         }
1589         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1590
1591         /* Recalculate the CRC for this orig_node and store it */
1592         orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1593         /* Roaming phase is over: tables are in sync again. I can
1594          * unset the flag */
1595         orig_node->tt_poss_change = false;
1596 out:
1597         if (orig_node)
1598                 orig_node_free_ref(orig_node);
1599 }
1600
1601 int tt_init(struct bat_priv *bat_priv)
1602 {
1603         if (!tt_local_init(bat_priv))
1604                 return 0;
1605
1606         if (!tt_global_init(bat_priv))
1607                 return 0;
1608
1609         tt_start_timer(bat_priv);
1610
1611         return 1;
1612 }
1613
1614 static void tt_roam_list_free(struct bat_priv *bat_priv)
1615 {
1616         struct tt_roam_node *node, *safe;
1617
1618         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1619
1620         list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1621                 list_del(&node->list);
1622                 kfree(node);
1623         }
1624
1625         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1626 }
1627
1628 static void tt_roam_purge(struct bat_priv *bat_priv)
1629 {
1630         struct tt_roam_node *node, *safe;
1631
1632         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1633         list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1634                 if (!is_out_of_time(node->first_time,
1635                                     ROAMING_MAX_TIME * 1000))
1636                         continue;
1637
1638                 list_del(&node->list);
1639                 kfree(node);
1640         }
1641         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1642 }
1643
1644 /* This function checks whether the client already reached the
1645  * maximum number of possible roaming phases. In this case the ROAMING_ADV
1646  * will not be sent.
1647  *
1648  * returns true if the ROAMING_ADV can be sent, false otherwise */
1649 static bool tt_check_roam_count(struct bat_priv *bat_priv,
1650                                 uint8_t *client)
1651 {
1652         struct tt_roam_node *tt_roam_node;
1653         bool ret = false;
1654
1655         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1656         /* The new tt_req will be issued only if I'm not waiting for a
1657          * reply from the same orig_node yet */
1658         list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
1659                 if (!compare_eth(tt_roam_node->addr, client))
1660                         continue;
1661
1662                 if (is_out_of_time(tt_roam_node->first_time,
1663                                    ROAMING_MAX_TIME * 1000))
1664                         continue;
1665
1666                 if (!atomic_dec_not_zero(&tt_roam_node->counter))
1667                         /* Sorry, you roamed too many times! */
1668                         goto unlock;
1669                 ret = true;
1670                 break;
1671         }
1672
1673         if (!ret) {
1674                 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
1675                 if (!tt_roam_node)
1676                         goto unlock;
1677
1678                 tt_roam_node->first_time = jiffies;
1679                 atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1);
1680                 memcpy(tt_roam_node->addr, client, ETH_ALEN);
1681
1682                 list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
1683                 ret = true;
1684         }
1685
1686 unlock:
1687         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1688         return ret;
1689 }
1690
1691 void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
1692                    struct orig_node *orig_node)
1693 {
1694         struct neigh_node *neigh_node = NULL;
1695         struct sk_buff *skb = NULL;
1696         struct roam_adv_packet *roam_adv_packet;
1697         int ret = 1;
1698         struct hard_iface *primary_if;
1699
1700         /* before going on we have to check whether the client has
1701          * already roamed to us too many times */
1702         if (!tt_check_roam_count(bat_priv, client))
1703                 goto out;
1704
1705         skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN);
1706         if (!skb)
1707                 goto out;
1708
1709         skb_reserve(skb, ETH_HLEN);
1710
1711         roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
1712                                         sizeof(struct roam_adv_packet));
1713
1714         roam_adv_packet->packet_type = BAT_ROAM_ADV;
1715         roam_adv_packet->version = COMPAT_VERSION;
1716         roam_adv_packet->ttl = TTL;
1717         primary_if = primary_if_get_selected(bat_priv);
1718         if (!primary_if)
1719                 goto out;
1720         memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1721         hardif_free_ref(primary_if);
1722         memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
1723         memcpy(roam_adv_packet->client, client, ETH_ALEN);
1724
1725         neigh_node = orig_node_get_router(orig_node);
1726         if (!neigh_node)
1727                 goto out;
1728
1729         bat_dbg(DBG_TT, bat_priv,
1730                 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
1731                 orig_node->orig, client, neigh_node->addr);
1732
1733         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1734         ret = 0;
1735
1736 out:
1737         if (neigh_node)
1738                 neigh_node_free_ref(neigh_node);
1739         if (ret)
1740                 kfree_skb(skb);
1741         return;
1742 }
1743
1744 static void tt_purge(struct work_struct *work)
1745 {
1746         struct delayed_work *delayed_work =
1747                 container_of(work, struct delayed_work, work);
1748         struct bat_priv *bat_priv =
1749                 container_of(delayed_work, struct bat_priv, tt_work);
1750
1751         tt_local_purge(bat_priv);
1752         tt_global_roam_purge(bat_priv);
1753         tt_req_purge(bat_priv);
1754         tt_roam_purge(bat_priv);
1755
1756         tt_start_timer(bat_priv);
1757 }
1758
1759 void tt_free(struct bat_priv *bat_priv)
1760 {
1761         cancel_delayed_work_sync(&bat_priv->tt_work);
1762
1763         tt_local_table_free(bat_priv);
1764         tt_global_table_free(bat_priv);
1765         tt_req_list_free(bat_priv);
1766         tt_changes_list_free(bat_priv);
1767         tt_roam_list_free(bat_priv);
1768
1769         kfree(bat_priv->tt_buff);
1770 }
1771
1772 /* This function will reset the specified flags from all the entries in
1773  * the given hash table and will increment num_local_tt for each involved
1774  * entry */
1775 static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags)
1776 {
1777         int i;
1778         struct hashtable_t *hash = bat_priv->tt_local_hash;
1779         struct hlist_head *head;
1780         struct hlist_node *node;
1781         struct tt_local_entry *tt_local_entry;
1782
1783         if (!hash)
1784                 return;
1785
1786         for (i = 0; i < hash->size; i++) {
1787                 head = &hash->table[i];
1788
1789                 rcu_read_lock();
1790                 hlist_for_each_entry_rcu(tt_local_entry, node,
1791                                          head, hash_entry) {
1792                         if (!(tt_local_entry->flags & flags))
1793                                 continue;
1794                         tt_local_entry->flags &= ~flags;
1795                         atomic_inc(&bat_priv->num_local_tt);
1796                 }
1797                 rcu_read_unlock();
1798         }
1799
1800 }
1801
1802 /* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
1803 static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
1804 {
1805         struct hashtable_t *hash = bat_priv->tt_local_hash;
1806         struct tt_local_entry *tt_local_entry;
1807         struct hlist_node *node, *node_tmp;
1808         struct hlist_head *head;
1809         spinlock_t *list_lock; /* protects write access to the hash lists */
1810         int i;
1811
1812         if (!hash)
1813                 return;
1814
1815         for (i = 0; i < hash->size; i++) {
1816                 head = &hash->table[i];
1817                 list_lock = &hash->list_locks[i];
1818
1819                 spin_lock_bh(list_lock);
1820                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
1821                                           head, hash_entry) {
1822                         if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
1823                                 continue;
1824
1825                         bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
1826                                 "(%pM): pending\n", tt_local_entry->addr);
1827
1828                         atomic_dec(&bat_priv->num_local_tt);
1829                         hlist_del_rcu(node);
1830                         tt_local_entry_free_ref(tt_local_entry);
1831                 }
1832                 spin_unlock_bh(list_lock);
1833         }
1834
1835 }
1836
1837 void tt_commit_changes(struct bat_priv *bat_priv)
1838 {
1839         tt_local_reset_flags(bat_priv, TT_CLIENT_NEW);
1840         tt_local_purge_pending_clients(bat_priv);
1841
1842         /* Increment the TTVN only once per OGM interval */
1843         atomic_inc(&bat_priv->ttvn);
1844         bat_priv->tt_poss_change = false;
1845 }
1846
1847 bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst)
1848 {
1849         struct tt_local_entry *tt_local_entry = NULL;
1850         struct tt_global_entry *tt_global_entry = NULL;
1851         bool ret = false;
1852
1853         if (!atomic_read(&bat_priv->ap_isolation))
1854                 goto out;
1855
1856         tt_local_entry = tt_local_hash_find(bat_priv, dst);
1857         if (!tt_local_entry)
1858                 goto out;
1859
1860         tt_global_entry = tt_global_hash_find(bat_priv, src);
1861         if (!tt_global_entry)
1862                 goto out;
1863
1864         if (!_is_ap_isolated(tt_local_entry, tt_global_entry))
1865                 goto out;
1866
1867         ret = true;
1868
1869 out:
1870         if (tt_global_entry)
1871                 tt_global_entry_free_ref(tt_global_entry);
1872         if (tt_local_entry)
1873                 tt_local_entry_free_ref(tt_local_entry);
1874         return ret;
1875 }
1876
1877 void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
1878                     const unsigned char *tt_buff, uint8_t tt_num_changes,
1879                     uint8_t ttvn, uint16_t tt_crc)
1880 {
1881         uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1882         bool full_table = true;
1883
1884         /* the ttvn increased by one -> we can apply the attached changes */
1885         if (ttvn - orig_ttvn == 1) {
1886                 /* the OGM could not contain the changes due to their size or
1887                  * because they have already been sent TT_OGM_APPEND_MAX times.
1888                  * In this case send a tt request */
1889                 if (!tt_num_changes) {
1890                         full_table = false;
1891                         goto request_table;
1892                 }
1893
1894                 tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
1895                                   (struct tt_change *)tt_buff);
1896
1897                 /* Even if we received the precomputed crc with the OGM, we
1898                  * prefer to recompute it to spot any possible inconsistency
1899                  * in the global table */
1900                 orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1901
1902                 /* The ttvn alone is not enough to guarantee consistency
1903                  * because a single value could represent different states
1904                  * (due to the wrap around). Thus a node has to check whether
1905                  * the resulting table (after applying the changes) is still
1906                  * consistent or not. E.g. a node could disconnect while its
1907                  * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
1908                  * checking the CRC value is mandatory to detect the
1909                  * inconsistency */
1910                 if (orig_node->tt_crc != tt_crc)
1911                         goto request_table;
1912
1913                 /* Roaming phase is over: tables are in sync again. I can
1914                  * unset the flag */
1915                 orig_node->tt_poss_change = false;
1916         } else {
1917                 /* if we missed more than one change or our tables are not
1918                  * in sync anymore -> request fresh tt data */
1919                 if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
1920 request_table:
1921                         bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
1922                                 "Need to retrieve the correct information "
1923                                 "(ttvn: %u last_ttvn: %u crc: %u last_crc: "
1924                                 "%u num_changes: %u)\n", orig_node->orig, ttvn,
1925                                 orig_ttvn, tt_crc, orig_node->tt_crc,
1926                                 tt_num_changes);
1927                         send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
1928                                         full_table);
1929                         return;
1930                 }
1931         }
1932 }