batman-adv: delete global entry in case of roaming
[linux-drm-fsl-dcu.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 static void tt_req_list_free(struct bat_priv *bat_priv)
956 {
957         struct tt_req_node *node, *safe;
958
959         spin_lock_bh(&bat_priv->tt_req_list_lock);
960
961         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
962                 list_del(&node->list);
963                 kfree(node);
964         }
965
966         spin_unlock_bh(&bat_priv->tt_req_list_lock);
967 }
968
969 void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
970                          const unsigned char *tt_buff, uint8_t tt_num_changes)
971 {
972         uint16_t tt_buff_len = tt_len(tt_num_changes);
973
974         /* Replace the old buffer only if I received something in the
975          * last OGM (the OGM could carry no changes) */
976         spin_lock_bh(&orig_node->tt_buff_lock);
977         if (tt_buff_len > 0) {
978                 kfree(orig_node->tt_buff);
979                 orig_node->tt_buff_len = 0;
980                 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
981                 if (orig_node->tt_buff) {
982                         memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
983                         orig_node->tt_buff_len = tt_buff_len;
984                 }
985         }
986         spin_unlock_bh(&orig_node->tt_buff_lock);
987 }
988
989 static void tt_req_purge(struct bat_priv *bat_priv)
990 {
991         struct tt_req_node *node, *safe;
992
993         spin_lock_bh(&bat_priv->tt_req_list_lock);
994         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
995                 if (is_out_of_time(node->issued_at,
996                     TT_REQUEST_TIMEOUT * 1000)) {
997                         list_del(&node->list);
998                         kfree(node);
999                 }
1000         }
1001         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1002 }
1003
1004 /* returns the pointer to the new tt_req_node struct if no request
1005  * has already been issued for this orig_node, NULL otherwise */
1006 static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
1007                                           struct orig_node *orig_node)
1008 {
1009         struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1010
1011         spin_lock_bh(&bat_priv->tt_req_list_lock);
1012         list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
1013                 if (compare_eth(tt_req_node_tmp, orig_node) &&
1014                     !is_out_of_time(tt_req_node_tmp->issued_at,
1015                                     TT_REQUEST_TIMEOUT * 1000))
1016                         goto unlock;
1017         }
1018
1019         tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
1020         if (!tt_req_node)
1021                 goto unlock;
1022
1023         memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1024         tt_req_node->issued_at = jiffies;
1025
1026         list_add(&tt_req_node->list, &bat_priv->tt_req_list);
1027 unlock:
1028         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1029         return tt_req_node;
1030 }
1031
1032 /* data_ptr is useless here, but has to be kept to respect the prototype */
1033 static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr)
1034 {
1035         const struct tt_local_entry *tt_local_entry = entry_ptr;
1036
1037         if (tt_local_entry->flags & TT_CLIENT_NEW)
1038                 return 0;
1039         return 1;
1040 }
1041
1042 static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
1043 {
1044         const struct tt_global_entry *tt_global_entry = entry_ptr;
1045         const struct orig_node *orig_node = data_ptr;
1046
1047         if (tt_global_entry->flags & TT_CLIENT_ROAM)
1048                 return 0;
1049
1050         return (tt_global_entry->orig_node == orig_node);
1051 }
1052
1053 static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
1054                                               struct hashtable_t *hash,
1055                                               struct hard_iface *primary_if,
1056                                               int (*valid_cb)(const void *,
1057                                                               const void *),
1058                                               void *cb_data)
1059 {
1060         struct tt_local_entry *tt_local_entry;
1061         struct tt_query_packet *tt_response;
1062         struct tt_change *tt_change;
1063         struct hlist_node *node;
1064         struct hlist_head *head;
1065         struct sk_buff *skb = NULL;
1066         uint16_t tt_tot, tt_count;
1067         ssize_t tt_query_size = sizeof(struct tt_query_packet);
1068         int i;
1069
1070         if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
1071                 tt_len = primary_if->soft_iface->mtu - tt_query_size;
1072                 tt_len -= tt_len % sizeof(struct tt_change);
1073         }
1074         tt_tot = tt_len / sizeof(struct tt_change);
1075
1076         skb = dev_alloc_skb(tt_query_size + tt_len + ETH_HLEN);
1077         if (!skb)
1078                 goto out;
1079
1080         skb_reserve(skb, ETH_HLEN);
1081         tt_response = (struct tt_query_packet *)skb_put(skb,
1082                                                      tt_query_size + tt_len);
1083         tt_response->ttvn = ttvn;
1084
1085         tt_change = (struct tt_change *)(skb->data + tt_query_size);
1086         tt_count = 0;
1087
1088         rcu_read_lock();
1089         for (i = 0; i < hash->size; i++) {
1090                 head = &hash->table[i];
1091
1092                 hlist_for_each_entry_rcu(tt_local_entry, node,
1093                                          head, hash_entry) {
1094                         if (tt_count == tt_tot)
1095                                 break;
1096
1097                         if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data)))
1098                                 continue;
1099
1100                         memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN);
1101                         tt_change->flags = NO_FLAGS;
1102
1103                         tt_count++;
1104                         tt_change++;
1105                 }
1106         }
1107         rcu_read_unlock();
1108
1109         /* store in the message the number of entries we have successfully
1110          * copied */
1111         tt_response->tt_data = htons(tt_count);
1112
1113 out:
1114         return skb;
1115 }
1116
1117 static int send_tt_request(struct bat_priv *bat_priv,
1118                            struct orig_node *dst_orig_node,
1119                            uint8_t ttvn, uint16_t tt_crc, bool full_table)
1120 {
1121         struct sk_buff *skb = NULL;
1122         struct tt_query_packet *tt_request;
1123         struct neigh_node *neigh_node = NULL;
1124         struct hard_iface *primary_if;
1125         struct tt_req_node *tt_req_node = NULL;
1126         int ret = 1;
1127
1128         primary_if = primary_if_get_selected(bat_priv);
1129         if (!primary_if)
1130                 goto out;
1131
1132         /* The new tt_req will be issued only if I'm not waiting for a
1133          * reply from the same orig_node yet */
1134         tt_req_node = new_tt_req_node(bat_priv, dst_orig_node);
1135         if (!tt_req_node)
1136                 goto out;
1137
1138         skb = dev_alloc_skb(sizeof(struct tt_query_packet) + ETH_HLEN);
1139         if (!skb)
1140                 goto out;
1141
1142         skb_reserve(skb, ETH_HLEN);
1143
1144         tt_request = (struct tt_query_packet *)skb_put(skb,
1145                                 sizeof(struct tt_query_packet));
1146
1147         tt_request->packet_type = BAT_TT_QUERY;
1148         tt_request->version = COMPAT_VERSION;
1149         memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1150         memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1151         tt_request->ttl = TTL;
1152         tt_request->ttvn = ttvn;
1153         tt_request->tt_data = tt_crc;
1154         tt_request->flags = TT_REQUEST;
1155
1156         if (full_table)
1157                 tt_request->flags |= TT_FULL_TABLE;
1158
1159         neigh_node = orig_node_get_router(dst_orig_node);
1160         if (!neigh_node)
1161                 goto out;
1162
1163         bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM "
1164                 "[%c]\n", dst_orig_node->orig, neigh_node->addr,
1165                 (full_table ? 'F' : '.'));
1166
1167         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1168         ret = 0;
1169
1170 out:
1171         if (neigh_node)
1172                 neigh_node_free_ref(neigh_node);
1173         if (primary_if)
1174                 hardif_free_ref(primary_if);
1175         if (ret)
1176                 kfree_skb(skb);
1177         if (ret && tt_req_node) {
1178                 spin_lock_bh(&bat_priv->tt_req_list_lock);
1179                 list_del(&tt_req_node->list);
1180                 spin_unlock_bh(&bat_priv->tt_req_list_lock);
1181                 kfree(tt_req_node);
1182         }
1183         return ret;
1184 }
1185
1186 static bool send_other_tt_response(struct bat_priv *bat_priv,
1187                                    struct tt_query_packet *tt_request)
1188 {
1189         struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL;
1190         struct neigh_node *neigh_node = NULL;
1191         struct hard_iface *primary_if = NULL;
1192         uint8_t orig_ttvn, req_ttvn, ttvn;
1193         int ret = false;
1194         unsigned char *tt_buff;
1195         bool full_table;
1196         uint16_t tt_len, tt_tot;
1197         struct sk_buff *skb = NULL;
1198         struct tt_query_packet *tt_response;
1199
1200         bat_dbg(DBG_TT, bat_priv,
1201                 "Received TT_REQUEST from %pM for "
1202                 "ttvn: %u (%pM) [%c]\n", tt_request->src,
1203                 tt_request->ttvn, tt_request->dst,
1204                 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1205
1206         /* Let's get the orig node of the REAL destination */
1207         req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst);
1208         if (!req_dst_orig_node)
1209                 goto out;
1210
1211         res_dst_orig_node = get_orig_node(bat_priv, tt_request->src);
1212         if (!res_dst_orig_node)
1213                 goto out;
1214
1215         neigh_node = orig_node_get_router(res_dst_orig_node);
1216         if (!neigh_node)
1217                 goto out;
1218
1219         primary_if = primary_if_get_selected(bat_priv);
1220         if (!primary_if)
1221                 goto out;
1222
1223         orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1224         req_ttvn = tt_request->ttvn;
1225
1226         /* I don't have the requested data */
1227         if (orig_ttvn != req_ttvn ||
1228             tt_request->tt_data != req_dst_orig_node->tt_crc)
1229                 goto out;
1230
1231         /* If the full table has been explicitly requested */
1232         if (tt_request->flags & TT_FULL_TABLE ||
1233             !req_dst_orig_node->tt_buff)
1234                 full_table = true;
1235         else
1236                 full_table = false;
1237
1238         /* In this version, fragmentation is not implemented, then
1239          * I'll send only one packet with as much TT entries as I can */
1240         if (!full_table) {
1241                 spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1242                 tt_len = req_dst_orig_node->tt_buff_len;
1243                 tt_tot = tt_len / sizeof(struct tt_change);
1244
1245                 skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1246                                     tt_len + ETH_HLEN);
1247                 if (!skb)
1248                         goto unlock;
1249
1250                 skb_reserve(skb, ETH_HLEN);
1251                 tt_response = (struct tt_query_packet *)skb_put(skb,
1252                                 sizeof(struct tt_query_packet) + tt_len);
1253                 tt_response->ttvn = req_ttvn;
1254                 tt_response->tt_data = htons(tt_tot);
1255
1256                 tt_buff = skb->data + sizeof(struct tt_query_packet);
1257                 /* Copy the last orig_node's OGM buffer */
1258                 memcpy(tt_buff, req_dst_orig_node->tt_buff,
1259                        req_dst_orig_node->tt_buff_len);
1260
1261                 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1262         } else {
1263                 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size) *
1264                                                 sizeof(struct tt_change);
1265                 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1266
1267                 skb = tt_response_fill_table(tt_len, ttvn,
1268                                              bat_priv->tt_global_hash,
1269                                              primary_if, tt_global_valid_entry,
1270                                              req_dst_orig_node);
1271                 if (!skb)
1272                         goto out;
1273
1274                 tt_response = (struct tt_query_packet *)skb->data;
1275         }
1276
1277         tt_response->packet_type = BAT_TT_QUERY;
1278         tt_response->version = COMPAT_VERSION;
1279         tt_response->ttl = TTL;
1280         memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1281         memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1282         tt_response->flags = TT_RESPONSE;
1283
1284         if (full_table)
1285                 tt_response->flags |= TT_FULL_TABLE;
1286
1287         bat_dbg(DBG_TT, bat_priv,
1288                 "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
1289                 res_dst_orig_node->orig, neigh_node->addr,
1290                 req_dst_orig_node->orig, req_ttvn);
1291
1292         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1293         ret = true;
1294         goto out;
1295
1296 unlock:
1297         spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1298
1299 out:
1300         if (res_dst_orig_node)
1301                 orig_node_free_ref(res_dst_orig_node);
1302         if (req_dst_orig_node)
1303                 orig_node_free_ref(req_dst_orig_node);
1304         if (neigh_node)
1305                 neigh_node_free_ref(neigh_node);
1306         if (primary_if)
1307                 hardif_free_ref(primary_if);
1308         if (!ret)
1309                 kfree_skb(skb);
1310         return ret;
1311
1312 }
1313 static bool send_my_tt_response(struct bat_priv *bat_priv,
1314                                 struct tt_query_packet *tt_request)
1315 {
1316         struct orig_node *orig_node = NULL;
1317         struct neigh_node *neigh_node = NULL;
1318         struct hard_iface *primary_if = NULL;
1319         uint8_t my_ttvn, req_ttvn, ttvn;
1320         int ret = false;
1321         unsigned char *tt_buff;
1322         bool full_table;
1323         uint16_t tt_len, tt_tot;
1324         struct sk_buff *skb = NULL;
1325         struct tt_query_packet *tt_response;
1326
1327         bat_dbg(DBG_TT, bat_priv,
1328                 "Received TT_REQUEST from %pM for "
1329                 "ttvn: %u (me) [%c]\n", tt_request->src,
1330                 tt_request->ttvn,
1331                 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1332
1333
1334         my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1335         req_ttvn = tt_request->ttvn;
1336
1337         orig_node = get_orig_node(bat_priv, tt_request->src);
1338         if (!orig_node)
1339                 goto out;
1340
1341         neigh_node = orig_node_get_router(orig_node);
1342         if (!neigh_node)
1343                 goto out;
1344
1345         primary_if = primary_if_get_selected(bat_priv);
1346         if (!primary_if)
1347                 goto out;
1348
1349         /* If the full table has been explicitly requested or the gap
1350          * is too big send the whole local translation table */
1351         if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn ||
1352             !bat_priv->tt_buff)
1353                 full_table = true;
1354         else
1355                 full_table = false;
1356
1357         /* In this version, fragmentation is not implemented, then
1358          * I'll send only one packet with as much TT entries as I can */
1359         if (!full_table) {
1360                 spin_lock_bh(&bat_priv->tt_buff_lock);
1361                 tt_len = bat_priv->tt_buff_len;
1362                 tt_tot = tt_len / sizeof(struct tt_change);
1363
1364                 skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1365                                     tt_len + ETH_HLEN);
1366                 if (!skb)
1367                         goto unlock;
1368
1369                 skb_reserve(skb, ETH_HLEN);
1370                 tt_response = (struct tt_query_packet *)skb_put(skb,
1371                                 sizeof(struct tt_query_packet) + tt_len);
1372                 tt_response->ttvn = req_ttvn;
1373                 tt_response->tt_data = htons(tt_tot);
1374
1375                 tt_buff = skb->data + sizeof(struct tt_query_packet);
1376                 memcpy(tt_buff, bat_priv->tt_buff,
1377                        bat_priv->tt_buff_len);
1378                 spin_unlock_bh(&bat_priv->tt_buff_lock);
1379         } else {
1380                 tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt) *
1381                                                 sizeof(struct tt_change);
1382                 ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1383
1384                 skb = tt_response_fill_table(tt_len, ttvn,
1385                                              bat_priv->tt_local_hash,
1386                                              primary_if, tt_local_valid_entry,
1387                                              NULL);
1388                 if (!skb)
1389                         goto out;
1390
1391                 tt_response = (struct tt_query_packet *)skb->data;
1392         }
1393
1394         tt_response->packet_type = BAT_TT_QUERY;
1395         tt_response->version = COMPAT_VERSION;
1396         tt_response->ttl = TTL;
1397         memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1398         memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1399         tt_response->flags = TT_RESPONSE;
1400
1401         if (full_table)
1402                 tt_response->flags |= TT_FULL_TABLE;
1403
1404         bat_dbg(DBG_TT, bat_priv,
1405                 "Sending TT_RESPONSE to %pM via %pM [%c]\n",
1406                 orig_node->orig, neigh_node->addr,
1407                 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1408
1409         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1410         ret = true;
1411         goto out;
1412
1413 unlock:
1414         spin_unlock_bh(&bat_priv->tt_buff_lock);
1415 out:
1416         if (orig_node)
1417                 orig_node_free_ref(orig_node);
1418         if (neigh_node)
1419                 neigh_node_free_ref(neigh_node);
1420         if (primary_if)
1421                 hardif_free_ref(primary_if);
1422         if (!ret)
1423                 kfree_skb(skb);
1424         /* This packet was for me, so it doesn't need to be re-routed */
1425         return true;
1426 }
1427
1428 bool send_tt_response(struct bat_priv *bat_priv,
1429                       struct tt_query_packet *tt_request)
1430 {
1431         if (is_my_mac(tt_request->dst))
1432                 return send_my_tt_response(bat_priv, tt_request);
1433         else
1434                 return send_other_tt_response(bat_priv, tt_request);
1435 }
1436
1437 static void _tt_update_changes(struct bat_priv *bat_priv,
1438                                struct orig_node *orig_node,
1439                                struct tt_change *tt_change,
1440                                uint16_t tt_num_changes, uint8_t ttvn)
1441 {
1442         int i;
1443
1444         for (i = 0; i < tt_num_changes; i++) {
1445                 if ((tt_change + i)->flags & TT_CLIENT_DEL)
1446                         tt_global_del(bat_priv, orig_node,
1447                                       (tt_change + i)->addr,
1448                                       "tt removed by changes",
1449                                       (tt_change + i)->flags & TT_CLIENT_ROAM);
1450                 else
1451                         if (!tt_global_add(bat_priv, orig_node,
1452                                            (tt_change + i)->addr, ttvn, false,
1453                                            (tt_change + i)->flags &
1454                                                         TT_CLIENT_WIFI))
1455                                 /* In case of problem while storing a
1456                                  * global_entry, we stop the updating
1457                                  * procedure without committing the
1458                                  * ttvn change. This will avoid to send
1459                                  * corrupted data on tt_request
1460                                  */
1461                                 return;
1462         }
1463 }
1464
1465 static void tt_fill_gtable(struct bat_priv *bat_priv,
1466                            struct tt_query_packet *tt_response)
1467 {
1468         struct orig_node *orig_node = NULL;
1469
1470         orig_node = orig_hash_find(bat_priv, tt_response->src);
1471         if (!orig_node)
1472                 goto out;
1473
1474         /* Purge the old table first.. */
1475         tt_global_del_orig(bat_priv, orig_node, "Received full table");
1476
1477         _tt_update_changes(bat_priv, orig_node,
1478                            (struct tt_change *)(tt_response + 1),
1479                            tt_response->tt_data, tt_response->ttvn);
1480
1481         spin_lock_bh(&orig_node->tt_buff_lock);
1482         kfree(orig_node->tt_buff);
1483         orig_node->tt_buff_len = 0;
1484         orig_node->tt_buff = NULL;
1485         spin_unlock_bh(&orig_node->tt_buff_lock);
1486
1487         atomic_set(&orig_node->last_ttvn, tt_response->ttvn);
1488
1489 out:
1490         if (orig_node)
1491                 orig_node_free_ref(orig_node);
1492 }
1493
1494 static void tt_update_changes(struct bat_priv *bat_priv,
1495                               struct orig_node *orig_node,
1496                               uint16_t tt_num_changes, uint8_t ttvn,
1497                               struct tt_change *tt_change)
1498 {
1499         _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes,
1500                            ttvn);
1501
1502         tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change,
1503                             tt_num_changes);
1504         atomic_set(&orig_node->last_ttvn, ttvn);
1505 }
1506
1507 bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr)
1508 {
1509         struct tt_local_entry *tt_local_entry = NULL;
1510         bool ret = false;
1511
1512         tt_local_entry = tt_local_hash_find(bat_priv, addr);
1513         if (!tt_local_entry)
1514                 goto out;
1515         /* Check if the client has been logically deleted (but is kept for
1516          * consistency purpose) */
1517         if (tt_local_entry->flags & TT_CLIENT_PENDING)
1518                 goto out;
1519         ret = true;
1520 out:
1521         if (tt_local_entry)
1522                 tt_local_entry_free_ref(tt_local_entry);
1523         return ret;
1524 }
1525
1526 void handle_tt_response(struct bat_priv *bat_priv,
1527                         struct tt_query_packet *tt_response)
1528 {
1529         struct tt_req_node *node, *safe;
1530         struct orig_node *orig_node = NULL;
1531
1532         bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for "
1533                 "ttvn %d t_size: %d [%c]\n",
1534                 tt_response->src, tt_response->ttvn,
1535                 tt_response->tt_data,
1536                 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1537
1538         orig_node = orig_hash_find(bat_priv, tt_response->src);
1539         if (!orig_node)
1540                 goto out;
1541
1542         if (tt_response->flags & TT_FULL_TABLE)
1543                 tt_fill_gtable(bat_priv, tt_response);
1544         else
1545                 tt_update_changes(bat_priv, orig_node, tt_response->tt_data,
1546                                   tt_response->ttvn,
1547                                   (struct tt_change *)(tt_response + 1));
1548
1549         /* Delete the tt_req_node from pending tt_requests list */
1550         spin_lock_bh(&bat_priv->tt_req_list_lock);
1551         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1552                 if (!compare_eth(node->addr, tt_response->src))
1553                         continue;
1554                 list_del(&node->list);
1555                 kfree(node);
1556         }
1557         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1558
1559         /* Recalculate the CRC for this orig_node and store it */
1560         orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1561         /* Roaming phase is over: tables are in sync again. I can
1562          * unset the flag */
1563         orig_node->tt_poss_change = false;
1564 out:
1565         if (orig_node)
1566                 orig_node_free_ref(orig_node);
1567 }
1568
1569 int tt_init(struct bat_priv *bat_priv)
1570 {
1571         if (!tt_local_init(bat_priv))
1572                 return 0;
1573
1574         if (!tt_global_init(bat_priv))
1575                 return 0;
1576
1577         tt_start_timer(bat_priv);
1578
1579         return 1;
1580 }
1581
1582 static void tt_roam_list_free(struct bat_priv *bat_priv)
1583 {
1584         struct tt_roam_node *node, *safe;
1585
1586         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1587
1588         list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1589                 list_del(&node->list);
1590                 kfree(node);
1591         }
1592
1593         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1594 }
1595
1596 static void tt_roam_purge(struct bat_priv *bat_priv)
1597 {
1598         struct tt_roam_node *node, *safe;
1599
1600         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1601         list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1602                 if (!is_out_of_time(node->first_time,
1603                                     ROAMING_MAX_TIME * 1000))
1604                         continue;
1605
1606                 list_del(&node->list);
1607                 kfree(node);
1608         }
1609         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1610 }
1611
1612 /* This function checks whether the client already reached the
1613  * maximum number of possible roaming phases. In this case the ROAMING_ADV
1614  * will not be sent.
1615  *
1616  * returns true if the ROAMING_ADV can be sent, false otherwise */
1617 static bool tt_check_roam_count(struct bat_priv *bat_priv,
1618                                 uint8_t *client)
1619 {
1620         struct tt_roam_node *tt_roam_node;
1621         bool ret = false;
1622
1623         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1624         /* The new tt_req will be issued only if I'm not waiting for a
1625          * reply from the same orig_node yet */
1626         list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
1627                 if (!compare_eth(tt_roam_node->addr, client))
1628                         continue;
1629
1630                 if (is_out_of_time(tt_roam_node->first_time,
1631                                    ROAMING_MAX_TIME * 1000))
1632                         continue;
1633
1634                 if (!atomic_dec_not_zero(&tt_roam_node->counter))
1635                         /* Sorry, you roamed too many times! */
1636                         goto unlock;
1637                 ret = true;
1638                 break;
1639         }
1640
1641         if (!ret) {
1642                 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
1643                 if (!tt_roam_node)
1644                         goto unlock;
1645
1646                 tt_roam_node->first_time = jiffies;
1647                 atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1);
1648                 memcpy(tt_roam_node->addr, client, ETH_ALEN);
1649
1650                 list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
1651                 ret = true;
1652         }
1653
1654 unlock:
1655         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1656         return ret;
1657 }
1658
1659 void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
1660                    struct orig_node *orig_node)
1661 {
1662         struct neigh_node *neigh_node = NULL;
1663         struct sk_buff *skb = NULL;
1664         struct roam_adv_packet *roam_adv_packet;
1665         int ret = 1;
1666         struct hard_iface *primary_if;
1667
1668         /* before going on we have to check whether the client has
1669          * already roamed to us too many times */
1670         if (!tt_check_roam_count(bat_priv, client))
1671                 goto out;
1672
1673         skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN);
1674         if (!skb)
1675                 goto out;
1676
1677         skb_reserve(skb, ETH_HLEN);
1678
1679         roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
1680                                         sizeof(struct roam_adv_packet));
1681
1682         roam_adv_packet->packet_type = BAT_ROAM_ADV;
1683         roam_adv_packet->version = COMPAT_VERSION;
1684         roam_adv_packet->ttl = TTL;
1685         primary_if = primary_if_get_selected(bat_priv);
1686         if (!primary_if)
1687                 goto out;
1688         memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1689         hardif_free_ref(primary_if);
1690         memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
1691         memcpy(roam_adv_packet->client, client, ETH_ALEN);
1692
1693         neigh_node = orig_node_get_router(orig_node);
1694         if (!neigh_node)
1695                 goto out;
1696
1697         bat_dbg(DBG_TT, bat_priv,
1698                 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
1699                 orig_node->orig, client, neigh_node->addr);
1700
1701         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1702         ret = 0;
1703
1704 out:
1705         if (neigh_node)
1706                 neigh_node_free_ref(neigh_node);
1707         if (ret)
1708                 kfree_skb(skb);
1709         return;
1710 }
1711
1712 static void tt_purge(struct work_struct *work)
1713 {
1714         struct delayed_work *delayed_work =
1715                 container_of(work, struct delayed_work, work);
1716         struct bat_priv *bat_priv =
1717                 container_of(delayed_work, struct bat_priv, tt_work);
1718
1719         tt_local_purge(bat_priv);
1720         tt_global_roam_purge(bat_priv);
1721         tt_req_purge(bat_priv);
1722         tt_roam_purge(bat_priv);
1723
1724         tt_start_timer(bat_priv);
1725 }
1726
1727 void tt_free(struct bat_priv *bat_priv)
1728 {
1729         cancel_delayed_work_sync(&bat_priv->tt_work);
1730
1731         tt_local_table_free(bat_priv);
1732         tt_global_table_free(bat_priv);
1733         tt_req_list_free(bat_priv);
1734         tt_changes_list_free(bat_priv);
1735         tt_roam_list_free(bat_priv);
1736
1737         kfree(bat_priv->tt_buff);
1738 }
1739
1740 /* This function will reset the specified flags from all the entries in
1741  * the given hash table and will increment num_local_tt for each involved
1742  * entry */
1743 static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags)
1744 {
1745         int i;
1746         struct hashtable_t *hash = bat_priv->tt_local_hash;
1747         struct hlist_head *head;
1748         struct hlist_node *node;
1749         struct tt_local_entry *tt_local_entry;
1750
1751         if (!hash)
1752                 return;
1753
1754         for (i = 0; i < hash->size; i++) {
1755                 head = &hash->table[i];
1756
1757                 rcu_read_lock();
1758                 hlist_for_each_entry_rcu(tt_local_entry, node,
1759                                          head, hash_entry) {
1760                         if (!(tt_local_entry->flags & flags))
1761                                 continue;
1762                         tt_local_entry->flags &= ~flags;
1763                         atomic_inc(&bat_priv->num_local_tt);
1764                 }
1765                 rcu_read_unlock();
1766         }
1767
1768 }
1769
1770 /* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
1771 static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
1772 {
1773         struct hashtable_t *hash = bat_priv->tt_local_hash;
1774         struct tt_local_entry *tt_local_entry;
1775         struct hlist_node *node, *node_tmp;
1776         struct hlist_head *head;
1777         spinlock_t *list_lock; /* protects write access to the hash lists */
1778         int i;
1779
1780         if (!hash)
1781                 return;
1782
1783         for (i = 0; i < hash->size; i++) {
1784                 head = &hash->table[i];
1785                 list_lock = &hash->list_locks[i];
1786
1787                 spin_lock_bh(list_lock);
1788                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
1789                                           head, hash_entry) {
1790                         if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
1791                                 continue;
1792
1793                         bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
1794                                 "(%pM): pending\n", tt_local_entry->addr);
1795
1796                         atomic_dec(&bat_priv->num_local_tt);
1797                         hlist_del_rcu(node);
1798                         tt_local_entry_free_ref(tt_local_entry);
1799                 }
1800                 spin_unlock_bh(list_lock);
1801         }
1802
1803 }
1804
1805 void tt_commit_changes(struct bat_priv *bat_priv)
1806 {
1807         tt_local_reset_flags(bat_priv, TT_CLIENT_NEW);
1808         tt_local_purge_pending_clients(bat_priv);
1809
1810         /* Increment the TTVN only once per OGM interval */
1811         atomic_inc(&bat_priv->ttvn);
1812         bat_priv->tt_poss_change = false;
1813 }
1814
1815 bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst)
1816 {
1817         struct tt_local_entry *tt_local_entry = NULL;
1818         struct tt_global_entry *tt_global_entry = NULL;
1819         bool ret = true;
1820
1821         if (!atomic_read(&bat_priv->ap_isolation))
1822                 return false;
1823
1824         tt_local_entry = tt_local_hash_find(bat_priv, dst);
1825         if (!tt_local_entry)
1826                 goto out;
1827
1828         tt_global_entry = tt_global_hash_find(bat_priv, src);
1829         if (!tt_global_entry)
1830                 goto out;
1831
1832         if (_is_ap_isolated(tt_local_entry, tt_global_entry))
1833                 goto out;
1834
1835         ret = false;
1836
1837 out:
1838         if (tt_global_entry)
1839                 tt_global_entry_free_ref(tt_global_entry);
1840         if (tt_local_entry)
1841                 tt_local_entry_free_ref(tt_local_entry);
1842         return ret;
1843 }
1844
1845 void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
1846                     const unsigned char *tt_buff, uint8_t tt_num_changes,
1847                     uint8_t ttvn, uint16_t tt_crc)
1848 {
1849         uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1850         bool full_table = true;
1851
1852         /* the ttvn increased by one -> we can apply the attached changes */
1853         if (ttvn - orig_ttvn == 1) {
1854                 /* the OGM could not contain the changes due to their size or
1855                  * because they have already been sent TT_OGM_APPEND_MAX times.
1856                  * In this case send a tt request */
1857                 if (!tt_num_changes) {
1858                         full_table = false;
1859                         goto request_table;
1860                 }
1861
1862                 tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
1863                                   (struct tt_change *)tt_buff);
1864
1865                 /* Even if we received the precomputed crc with the OGM, we
1866                  * prefer to recompute it to spot any possible inconsistency
1867                  * in the global table */
1868                 orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1869
1870                 /* The ttvn alone is not enough to guarantee consistency
1871                  * because a single value could represent different states
1872                  * (due to the wrap around). Thus a node has to check whether
1873                  * the resulting table (after applying the changes) is still
1874                  * consistent or not. E.g. a node could disconnect while its
1875                  * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
1876                  * checking the CRC value is mandatory to detect the
1877                  * inconsistency */
1878                 if (orig_node->tt_crc != tt_crc)
1879                         goto request_table;
1880
1881                 /* Roaming phase is over: tables are in sync again. I can
1882                  * unset the flag */
1883                 orig_node->tt_poss_change = false;
1884         } else {
1885                 /* if we missed more than one change or our tables are not
1886                  * in sync anymore -> request fresh tt data */
1887                 if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
1888 request_table:
1889                         bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
1890                                 "Need to retrieve the correct information "
1891                                 "(ttvn: %u last_ttvn: %u crc: %u last_crc: "
1892                                 "%u num_changes: %u)\n", orig_node->orig, ttvn,
1893                                 orig_ttvn, tt_crc, orig_node->tt_crc,
1894                                 tt_num_changes);
1895                         send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
1896                                         full_table);
1897                         return;
1898                 }
1899         }
1900 }