Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[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_ref(struct tt_global_entry *tt_global_entry)
141 {
142         if (atomic_dec_and_test(&tt_global_entry->refcount))
143                 kfree_rcu(tt_global_entry, rcu);
144 }
145
146 static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr,
147                            uint8_t flags)
148 {
149         struct tt_change_node *tt_change_node;
150
151         tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
152
153         if (!tt_change_node)
154                 return;
155
156         tt_change_node->change.flags = flags;
157         memcpy(tt_change_node->change.addr, addr, ETH_ALEN);
158
159         spin_lock_bh(&bat_priv->tt_changes_list_lock);
160         /* track the change in the OGMinterval list */
161         list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list);
162         atomic_inc(&bat_priv->tt_local_changes);
163         spin_unlock_bh(&bat_priv->tt_changes_list_lock);
164
165         atomic_set(&bat_priv->tt_ogm_append_cnt, 0);
166 }
167
168 int tt_len(int changes_num)
169 {
170         return changes_num * sizeof(struct tt_change);
171 }
172
173 static int tt_local_init(struct bat_priv *bat_priv)
174 {
175         if (bat_priv->tt_local_hash)
176                 return 1;
177
178         bat_priv->tt_local_hash = hash_new(1024);
179
180         if (!bat_priv->tt_local_hash)
181                 return 0;
182
183         return 1;
184 }
185
186 void tt_local_add(struct net_device *soft_iface, const uint8_t *addr)
187 {
188         struct bat_priv *bat_priv = netdev_priv(soft_iface);
189         struct tt_local_entry *tt_local_entry = NULL;
190         struct tt_global_entry *tt_global_entry = NULL;
191
192         tt_local_entry = tt_local_hash_find(bat_priv, addr);
193
194         if (tt_local_entry) {
195                 tt_local_entry->last_seen = jiffies;
196                 goto out;
197         }
198
199         tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC);
200         if (!tt_local_entry)
201                 goto out;
202
203         bat_dbg(DBG_TT, bat_priv,
204                 "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
205                 (uint8_t)atomic_read(&bat_priv->ttvn));
206
207         memcpy(tt_local_entry->addr, addr, ETH_ALEN);
208         tt_local_entry->last_seen = jiffies;
209         tt_local_entry->flags = NO_FLAGS;
210         atomic_set(&tt_local_entry->refcount, 2);
211
212         /* the batman interface mac address should never be purged */
213         if (compare_eth(addr, soft_iface->dev_addr))
214                 tt_local_entry->flags |= TT_CLIENT_NOPURGE;
215
216         tt_local_event(bat_priv, addr, tt_local_entry->flags);
217
218         /* The local entry has to be marked as NEW to avoid to send it in
219          * a full table response going out before the next ttvn increment
220          * (consistency check) */
221         tt_local_entry->flags |= TT_CLIENT_NEW;
222
223         hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
224                  tt_local_entry, &tt_local_entry->hash_entry);
225
226         /* remove address from global hash if present */
227         tt_global_entry = tt_global_hash_find(bat_priv, addr);
228
229         /* Check whether it is a roaming! */
230         if (tt_global_entry) {
231                 /* This node is probably going to update its tt table */
232                 tt_global_entry->orig_node->tt_poss_change = true;
233                 /* The global entry has to be marked as PENDING and has to be
234                  * kept for consistency purpose */
235                 tt_global_entry->flags |= TT_CLIENT_PENDING;
236                 send_roam_adv(bat_priv, tt_global_entry->addr,
237                               tt_global_entry->orig_node);
238         }
239 out:
240         if (tt_local_entry)
241                 tt_local_entry_free_ref(tt_local_entry);
242         if (tt_global_entry)
243                 tt_global_entry_free_ref(tt_global_entry);
244 }
245
246 int tt_changes_fill_buffer(struct bat_priv *bat_priv,
247                            unsigned char *buff, int buff_len)
248 {
249         int count = 0, tot_changes = 0;
250         struct tt_change_node *entry, *safe;
251
252         if (buff_len > 0)
253                 tot_changes = buff_len / tt_len(1);
254
255         spin_lock_bh(&bat_priv->tt_changes_list_lock);
256         atomic_set(&bat_priv->tt_local_changes, 0);
257
258         list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
259                         list) {
260                 if (count < tot_changes) {
261                         memcpy(buff + tt_len(count),
262                                &entry->change, sizeof(struct tt_change));
263                         count++;
264                 }
265                 list_del(&entry->list);
266                 kfree(entry);
267         }
268         spin_unlock_bh(&bat_priv->tt_changes_list_lock);
269
270         /* Keep the buffer for possible tt_request */
271         spin_lock_bh(&bat_priv->tt_buff_lock);
272         kfree(bat_priv->tt_buff);
273         bat_priv->tt_buff_len = 0;
274         bat_priv->tt_buff = NULL;
275         /* We check whether this new OGM has no changes due to size
276          * problems */
277         if (buff_len > 0) {
278                 /**
279                  * if kmalloc() fails we will reply with the full table
280                  * instead of providing the diff
281                  */
282                 bat_priv->tt_buff = kmalloc(buff_len, GFP_ATOMIC);
283                 if (bat_priv->tt_buff) {
284                         memcpy(bat_priv->tt_buff, buff, buff_len);
285                         bat_priv->tt_buff_len = buff_len;
286                 }
287         }
288         spin_unlock_bh(&bat_priv->tt_buff_lock);
289
290         return tot_changes;
291 }
292
293 int tt_local_seq_print_text(struct seq_file *seq, void *offset)
294 {
295         struct net_device *net_dev = (struct net_device *)seq->private;
296         struct bat_priv *bat_priv = netdev_priv(net_dev);
297         struct hashtable_t *hash = bat_priv->tt_local_hash;
298         struct tt_local_entry *tt_local_entry;
299         struct hard_iface *primary_if;
300         struct hlist_node *node;
301         struct hlist_head *head;
302         size_t buf_size, pos;
303         char *buff;
304         int i, ret = 0;
305
306         primary_if = primary_if_get_selected(bat_priv);
307         if (!primary_if) {
308                 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
309                                  "please specify interfaces to enable it\n",
310                                  net_dev->name);
311                 goto out;
312         }
313
314         if (primary_if->if_status != IF_ACTIVE) {
315                 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
316                                  "primary interface not active\n",
317                                  net_dev->name);
318                 goto out;
319         }
320
321         seq_printf(seq, "Locally retrieved addresses (from %s) "
322                    "announced via TT (TTVN: %u):\n",
323                    net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn));
324
325         buf_size = 1;
326         /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
327         for (i = 0; i < hash->size; i++) {
328                 head = &hash->table[i];
329
330                 rcu_read_lock();
331                 __hlist_for_each_rcu(node, head)
332                         buf_size += 21;
333                 rcu_read_unlock();
334         }
335
336         buff = kmalloc(buf_size, GFP_ATOMIC);
337         if (!buff) {
338                 ret = -ENOMEM;
339                 goto out;
340         }
341
342         buff[0] = '\0';
343         pos = 0;
344
345         for (i = 0; i < hash->size; i++) {
346                 head = &hash->table[i];
347
348                 rcu_read_lock();
349                 hlist_for_each_entry_rcu(tt_local_entry, node,
350                                          head, hash_entry) {
351                         pos += snprintf(buff + pos, 22, " * %pM\n",
352                                         tt_local_entry->addr);
353                 }
354                 rcu_read_unlock();
355         }
356
357         seq_printf(seq, "%s", buff);
358         kfree(buff);
359 out:
360         if (primary_if)
361                 hardif_free_ref(primary_if);
362         return ret;
363 }
364
365 static void tt_local_set_pending(struct bat_priv *bat_priv,
366                                  struct tt_local_entry *tt_local_entry,
367                                  uint16_t flags)
368 {
369         tt_local_event(bat_priv, tt_local_entry->addr,
370                        tt_local_entry->flags | flags);
371
372         /* The local client has to be merked as "pending to be removed" but has
373          * to be kept in the table in order to send it in an full tables
374          * response issued before the net ttvn increment (consistency check) */
375         tt_local_entry->flags |= TT_CLIENT_PENDING;
376 }
377
378 void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
379                      const char *message, bool roaming)
380 {
381         struct tt_local_entry *tt_local_entry = NULL;
382
383         tt_local_entry = tt_local_hash_find(bat_priv, addr);
384         if (!tt_local_entry)
385                 goto out;
386
387         tt_local_set_pending(bat_priv, tt_local_entry, TT_CLIENT_DEL |
388                              (roaming ? TT_CLIENT_ROAM : NO_FLAGS));
389
390         bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) pending to be removed: "
391                 "%s\n", tt_local_entry->addr, message);
392 out:
393         if (tt_local_entry)
394                 tt_local_entry_free_ref(tt_local_entry);
395 }
396
397 static void tt_local_purge(struct bat_priv *bat_priv)
398 {
399         struct hashtable_t *hash = bat_priv->tt_local_hash;
400         struct tt_local_entry *tt_local_entry;
401         struct hlist_node *node, *node_tmp;
402         struct hlist_head *head;
403         spinlock_t *list_lock; /* protects write access to the hash lists */
404         int i;
405
406         for (i = 0; i < hash->size; i++) {
407                 head = &hash->table[i];
408                 list_lock = &hash->list_locks[i];
409
410                 spin_lock_bh(list_lock);
411                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
412                                           head, hash_entry) {
413                         if (tt_local_entry->flags & TT_CLIENT_NOPURGE)
414                                 continue;
415
416                         /* entry already marked for deletion */
417                         if (tt_local_entry->flags & TT_CLIENT_PENDING)
418                                 continue;
419
420                         if (!is_out_of_time(tt_local_entry->last_seen,
421                                             TT_LOCAL_TIMEOUT * 1000))
422                                 continue;
423
424                         tt_local_set_pending(bat_priv, tt_local_entry,
425                                              TT_CLIENT_DEL);
426                         bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) "
427                                 "pending to be removed: timed out\n",
428                                 tt_local_entry->addr);
429                 }
430                 spin_unlock_bh(list_lock);
431         }
432
433 }
434
435 static void tt_local_table_free(struct bat_priv *bat_priv)
436 {
437         struct hashtable_t *hash;
438         spinlock_t *list_lock; /* protects write access to the hash lists */
439         struct tt_local_entry *tt_local_entry;
440         struct hlist_node *node, *node_tmp;
441         struct hlist_head *head;
442         int i;
443
444         if (!bat_priv->tt_local_hash)
445                 return;
446
447         hash = bat_priv->tt_local_hash;
448
449         for (i = 0; i < hash->size; i++) {
450                 head = &hash->table[i];
451                 list_lock = &hash->list_locks[i];
452
453                 spin_lock_bh(list_lock);
454                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
455                                           head, hash_entry) {
456                         hlist_del_rcu(node);
457                         tt_local_entry_free_ref(tt_local_entry);
458                 }
459                 spin_unlock_bh(list_lock);
460         }
461
462         hash_destroy(hash);
463
464         bat_priv->tt_local_hash = NULL;
465 }
466
467 static int tt_global_init(struct bat_priv *bat_priv)
468 {
469         if (bat_priv->tt_global_hash)
470                 return 1;
471
472         bat_priv->tt_global_hash = hash_new(1024);
473
474         if (!bat_priv->tt_global_hash)
475                 return 0;
476
477         return 1;
478 }
479
480 static void tt_changes_list_free(struct bat_priv *bat_priv)
481 {
482         struct tt_change_node *entry, *safe;
483
484         spin_lock_bh(&bat_priv->tt_changes_list_lock);
485
486         list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list,
487                                  list) {
488                 list_del(&entry->list);
489                 kfree(entry);
490         }
491
492         atomic_set(&bat_priv->tt_local_changes, 0);
493         spin_unlock_bh(&bat_priv->tt_changes_list_lock);
494 }
495
496 /* caller must hold orig_node refcount */
497 int tt_global_add(struct bat_priv *bat_priv, struct orig_node *orig_node,
498                   const unsigned char *tt_addr, uint8_t ttvn, bool roaming)
499 {
500         struct tt_global_entry *tt_global_entry;
501         struct orig_node *orig_node_tmp;
502         int ret = 0;
503
504         tt_global_entry = tt_global_hash_find(bat_priv, tt_addr);
505
506         if (!tt_global_entry) {
507                 tt_global_entry =
508                         kmalloc(sizeof(*tt_global_entry),
509                                 GFP_ATOMIC);
510                 if (!tt_global_entry)
511                         goto out;
512
513                 memcpy(tt_global_entry->addr, tt_addr, ETH_ALEN);
514                 /* Assign the new orig_node */
515                 atomic_inc(&orig_node->refcount);
516                 tt_global_entry->orig_node = orig_node;
517                 tt_global_entry->ttvn = ttvn;
518                 tt_global_entry->flags = NO_FLAGS;
519                 tt_global_entry->roam_at = 0;
520                 atomic_set(&tt_global_entry->refcount, 2);
521
522                 hash_add(bat_priv->tt_global_hash, compare_gtt,
523                          choose_orig, tt_global_entry,
524                          &tt_global_entry->hash_entry);
525                 atomic_inc(&orig_node->tt_size);
526         } else {
527                 if (tt_global_entry->orig_node != orig_node) {
528                         atomic_dec(&tt_global_entry->orig_node->tt_size);
529                         orig_node_tmp = tt_global_entry->orig_node;
530                         atomic_inc(&orig_node->refcount);
531                         tt_global_entry->orig_node = orig_node;
532                         orig_node_free_ref(orig_node_tmp);
533                         atomic_inc(&orig_node->tt_size);
534                 }
535                 tt_global_entry->ttvn = ttvn;
536                 tt_global_entry->flags = NO_FLAGS;
537                 tt_global_entry->roam_at = 0;
538         }
539
540         bat_dbg(DBG_TT, bat_priv,
541                 "Creating new global tt entry: %pM (via %pM)\n",
542                 tt_global_entry->addr, orig_node->orig);
543
544         /* remove address from local hash if present */
545         tt_local_remove(bat_priv, tt_global_entry->addr,
546                         "global tt received", roaming);
547         ret = 1;
548 out:
549         if (tt_global_entry)
550                 tt_global_entry_free_ref(tt_global_entry);
551         return ret;
552 }
553
554 int tt_global_seq_print_text(struct seq_file *seq, void *offset)
555 {
556         struct net_device *net_dev = (struct net_device *)seq->private;
557         struct bat_priv *bat_priv = netdev_priv(net_dev);
558         struct hashtable_t *hash = bat_priv->tt_global_hash;
559         struct tt_global_entry *tt_global_entry;
560         struct hard_iface *primary_if;
561         struct hlist_node *node;
562         struct hlist_head *head;
563         size_t buf_size, pos;
564         char *buff;
565         int i, ret = 0;
566
567         primary_if = primary_if_get_selected(bat_priv);
568         if (!primary_if) {
569                 ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
570                                  "specify interfaces to enable it\n",
571                                  net_dev->name);
572                 goto out;
573         }
574
575         if (primary_if->if_status != IF_ACTIVE) {
576                 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
577                                  "primary interface not active\n",
578                                  net_dev->name);
579                 goto out;
580         }
581
582         seq_printf(seq,
583                    "Globally announced TT entries received via the mesh %s\n",
584                    net_dev->name);
585         seq_printf(seq, "       %-13s %s       %-15s %s\n",
586                    "Client", "(TTVN)", "Originator", "(Curr TTVN)");
587
588         buf_size = 1;
589         /* Estimate length for: " * xx:xx:xx:xx:xx:xx (ttvn) via
590          * xx:xx:xx:xx:xx:xx (cur_ttvn)\n"*/
591         for (i = 0; i < hash->size; i++) {
592                 head = &hash->table[i];
593
594                 rcu_read_lock();
595                 __hlist_for_each_rcu(node, head)
596                         buf_size += 59;
597                 rcu_read_unlock();
598         }
599
600         buff = kmalloc(buf_size, GFP_ATOMIC);
601         if (!buff) {
602                 ret = -ENOMEM;
603                 goto out;
604         }
605
606         buff[0] = '\0';
607         pos = 0;
608
609         for (i = 0; i < hash->size; i++) {
610                 head = &hash->table[i];
611
612                 rcu_read_lock();
613                 hlist_for_each_entry_rcu(tt_global_entry, node,
614                                          head, hash_entry) {
615                         pos += snprintf(buff + pos, 61,
616                                         " * %pM  (%3u) via %pM     (%3u)\n",
617                                         tt_global_entry->addr,
618                                         tt_global_entry->ttvn,
619                                         tt_global_entry->orig_node->orig,
620                                         (uint8_t) atomic_read(
621                                                 &tt_global_entry->orig_node->
622                                                 last_ttvn));
623                 }
624                 rcu_read_unlock();
625         }
626
627         seq_printf(seq, "%s", buff);
628         kfree(buff);
629 out:
630         if (primary_if)
631                 hardif_free_ref(primary_if);
632         return ret;
633 }
634
635 static void _tt_global_del(struct bat_priv *bat_priv,
636                            struct tt_global_entry *tt_global_entry,
637                            const char *message)
638 {
639         if (!tt_global_entry)
640                 goto out;
641
642         bat_dbg(DBG_TT, bat_priv,
643                 "Deleting global tt entry %pM (via %pM): %s\n",
644                 tt_global_entry->addr, tt_global_entry->orig_node->orig,
645                 message);
646
647         atomic_dec(&tt_global_entry->orig_node->tt_size);
648
649         hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
650                     tt_global_entry->addr);
651 out:
652         if (tt_global_entry)
653                 tt_global_entry_free_ref(tt_global_entry);
654 }
655
656 void tt_global_del(struct bat_priv *bat_priv,
657                    struct orig_node *orig_node, const unsigned char *addr,
658                    const char *message, bool roaming)
659 {
660         struct tt_global_entry *tt_global_entry = NULL;
661
662         tt_global_entry = tt_global_hash_find(bat_priv, addr);
663         if (!tt_global_entry)
664                 goto out;
665
666         if (tt_global_entry->orig_node == orig_node) {
667                 if (roaming) {
668                         tt_global_entry->flags |= TT_CLIENT_ROAM;
669                         tt_global_entry->roam_at = jiffies;
670                         goto out;
671                 }
672                 _tt_global_del(bat_priv, tt_global_entry, message);
673         }
674 out:
675         if (tt_global_entry)
676                 tt_global_entry_free_ref(tt_global_entry);
677 }
678
679 void tt_global_del_orig(struct bat_priv *bat_priv,
680                         struct orig_node *orig_node, const char *message)
681 {
682         struct tt_global_entry *tt_global_entry;
683         int i;
684         struct hashtable_t *hash = bat_priv->tt_global_hash;
685         struct hlist_node *node, *safe;
686         struct hlist_head *head;
687         spinlock_t *list_lock; /* protects write access to the hash lists */
688
689         for (i = 0; i < hash->size; i++) {
690                 head = &hash->table[i];
691                 list_lock = &hash->list_locks[i];
692
693                 spin_lock_bh(list_lock);
694                 hlist_for_each_entry_safe(tt_global_entry, node, safe,
695                                          head, hash_entry) {
696                         if (tt_global_entry->orig_node == orig_node) {
697                                 bat_dbg(DBG_TT, bat_priv,
698                                         "Deleting global tt entry %pM "
699                                         "(via %pM): originator time out\n",
700                                         tt_global_entry->addr,
701                                         tt_global_entry->orig_node->orig);
702                                 hlist_del_rcu(node);
703                                 tt_global_entry_free_ref(tt_global_entry);
704                         }
705                 }
706                 spin_unlock_bh(list_lock);
707         }
708         atomic_set(&orig_node->tt_size, 0);
709 }
710
711 static void tt_global_roam_purge(struct bat_priv *bat_priv)
712 {
713         struct hashtable_t *hash = bat_priv->tt_global_hash;
714         struct tt_global_entry *tt_global_entry;
715         struct hlist_node *node, *node_tmp;
716         struct hlist_head *head;
717         spinlock_t *list_lock; /* protects write access to the hash lists */
718         int i;
719
720         for (i = 0; i < hash->size; i++) {
721                 head = &hash->table[i];
722                 list_lock = &hash->list_locks[i];
723
724                 spin_lock_bh(list_lock);
725                 hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
726                                           head, hash_entry) {
727                         if (!(tt_global_entry->flags & TT_CLIENT_ROAM))
728                                 continue;
729                         if (!is_out_of_time(tt_global_entry->roam_at,
730                                             TT_CLIENT_ROAM_TIMEOUT * 1000))
731                                 continue;
732
733                         bat_dbg(DBG_TT, bat_priv, "Deleting global "
734                                 "tt entry (%pM): Roaming timeout\n",
735                                 tt_global_entry->addr);
736                         atomic_dec(&tt_global_entry->orig_node->tt_size);
737                         hlist_del_rcu(node);
738                         tt_global_entry_free_ref(tt_global_entry);
739                 }
740                 spin_unlock_bh(list_lock);
741         }
742
743 }
744
745 static void tt_global_table_free(struct bat_priv *bat_priv)
746 {
747         struct hashtable_t *hash;
748         spinlock_t *list_lock; /* protects write access to the hash lists */
749         struct tt_global_entry *tt_global_entry;
750         struct hlist_node *node, *node_tmp;
751         struct hlist_head *head;
752         int i;
753
754         if (!bat_priv->tt_global_hash)
755                 return;
756
757         hash = bat_priv->tt_global_hash;
758
759         for (i = 0; i < hash->size; i++) {
760                 head = &hash->table[i];
761                 list_lock = &hash->list_locks[i];
762
763                 spin_lock_bh(list_lock);
764                 hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
765                                           head, hash_entry) {
766                         hlist_del_rcu(node);
767                         tt_global_entry_free_ref(tt_global_entry);
768                 }
769                 spin_unlock_bh(list_lock);
770         }
771
772         hash_destroy(hash);
773
774         bat_priv->tt_global_hash = NULL;
775 }
776
777 struct orig_node *transtable_search(struct bat_priv *bat_priv,
778                                     const uint8_t *addr)
779 {
780         struct tt_global_entry *tt_global_entry;
781         struct orig_node *orig_node = NULL;
782
783         tt_global_entry = tt_global_hash_find(bat_priv, addr);
784
785         if (!tt_global_entry)
786                 goto out;
787
788         if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
789                 goto free_tt;
790
791         /* A global client marked as PENDING has already moved from that
792          * originator */
793         if (tt_global_entry->flags & TT_CLIENT_PENDING)
794                 goto free_tt;
795
796         orig_node = tt_global_entry->orig_node;
797
798 free_tt:
799         tt_global_entry_free_ref(tt_global_entry);
800 out:
801         return orig_node;
802 }
803
804 /* Calculates the checksum of the local table of a given orig_node */
805 uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node)
806 {
807         uint16_t total = 0, total_one;
808         struct hashtable_t *hash = bat_priv->tt_global_hash;
809         struct tt_global_entry *tt_global_entry;
810         struct hlist_node *node;
811         struct hlist_head *head;
812         int i, j;
813
814         for (i = 0; i < hash->size; i++) {
815                 head = &hash->table[i];
816
817                 rcu_read_lock();
818                 hlist_for_each_entry_rcu(tt_global_entry, node,
819                                          head, hash_entry) {
820                         if (compare_eth(tt_global_entry->orig_node,
821                                         orig_node)) {
822                                 /* Roaming clients are in the global table for
823                                  * consistency only. They don't have to be
824                                  * taken into account while computing the
825                                  * global crc */
826                                 if (tt_global_entry->flags & TT_CLIENT_ROAM)
827                                         continue;
828                                 total_one = 0;
829                                 for (j = 0; j < ETH_ALEN; j++)
830                                         total_one = crc16_byte(total_one,
831                                                 tt_global_entry->addr[j]);
832                                 total ^= total_one;
833                         }
834                 }
835                 rcu_read_unlock();
836         }
837
838         return total;
839 }
840
841 /* Calculates the checksum of the local table */
842 uint16_t tt_local_crc(struct bat_priv *bat_priv)
843 {
844         uint16_t total = 0, total_one;
845         struct hashtable_t *hash = bat_priv->tt_local_hash;
846         struct tt_local_entry *tt_local_entry;
847         struct hlist_node *node;
848         struct hlist_head *head;
849         int i, j;
850
851         for (i = 0; i < hash->size; i++) {
852                 head = &hash->table[i];
853
854                 rcu_read_lock();
855                 hlist_for_each_entry_rcu(tt_local_entry, node,
856                                          head, hash_entry) {
857                         /* not yet committed clients have not to be taken into
858                          * account while computing the CRC */
859                         if (tt_local_entry->flags & TT_CLIENT_NEW)
860                                 continue;
861                         total_one = 0;
862                         for (j = 0; j < ETH_ALEN; j++)
863                                 total_one = crc16_byte(total_one,
864                                                    tt_local_entry->addr[j]);
865                         total ^= total_one;
866                 }
867                 rcu_read_unlock();
868         }
869
870         return total;
871 }
872
873 static void tt_req_list_free(struct bat_priv *bat_priv)
874 {
875         struct tt_req_node *node, *safe;
876
877         spin_lock_bh(&bat_priv->tt_req_list_lock);
878
879         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
880                 list_del(&node->list);
881                 kfree(node);
882         }
883
884         spin_unlock_bh(&bat_priv->tt_req_list_lock);
885 }
886
887 void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
888                          const unsigned char *tt_buff, uint8_t tt_num_changes)
889 {
890         uint16_t tt_buff_len = tt_len(tt_num_changes);
891
892         /* Replace the old buffer only if I received something in the
893          * last OGM (the OGM could carry no changes) */
894         spin_lock_bh(&orig_node->tt_buff_lock);
895         if (tt_buff_len > 0) {
896                 kfree(orig_node->tt_buff);
897                 orig_node->tt_buff_len = 0;
898                 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
899                 if (orig_node->tt_buff) {
900                         memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
901                         orig_node->tt_buff_len = tt_buff_len;
902                 }
903         }
904         spin_unlock_bh(&orig_node->tt_buff_lock);
905 }
906
907 static void tt_req_purge(struct bat_priv *bat_priv)
908 {
909         struct tt_req_node *node, *safe;
910
911         spin_lock_bh(&bat_priv->tt_req_list_lock);
912         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
913                 if (is_out_of_time(node->issued_at,
914                     TT_REQUEST_TIMEOUT * 1000)) {
915                         list_del(&node->list);
916                         kfree(node);
917                 }
918         }
919         spin_unlock_bh(&bat_priv->tt_req_list_lock);
920 }
921
922 /* returns the pointer to the new tt_req_node struct if no request
923  * has already been issued for this orig_node, NULL otherwise */
924 static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
925                                           struct orig_node *orig_node)
926 {
927         struct tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
928
929         spin_lock_bh(&bat_priv->tt_req_list_lock);
930         list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
931                 if (compare_eth(tt_req_node_tmp, orig_node) &&
932                     !is_out_of_time(tt_req_node_tmp->issued_at,
933                                     TT_REQUEST_TIMEOUT * 1000))
934                         goto unlock;
935         }
936
937         tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
938         if (!tt_req_node)
939                 goto unlock;
940
941         memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
942         tt_req_node->issued_at = jiffies;
943
944         list_add(&tt_req_node->list, &bat_priv->tt_req_list);
945 unlock:
946         spin_unlock_bh(&bat_priv->tt_req_list_lock);
947         return tt_req_node;
948 }
949
950 /* data_ptr is useless here, but has to be kept to respect the prototype */
951 static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr)
952 {
953         const struct tt_local_entry *tt_local_entry = entry_ptr;
954
955         if (tt_local_entry->flags & TT_CLIENT_NEW)
956                 return 0;
957         return 1;
958 }
959
960 static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
961 {
962         const struct tt_global_entry *tt_global_entry = entry_ptr;
963         const struct orig_node *orig_node = data_ptr;
964
965         if (tt_global_entry->flags & TT_CLIENT_ROAM)
966                 return 0;
967
968         return (tt_global_entry->orig_node == orig_node);
969 }
970
971 static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
972                                               struct hashtable_t *hash,
973                                               struct hard_iface *primary_if,
974                                               int (*valid_cb)(const void *,
975                                                               const void *),
976                                               void *cb_data)
977 {
978         struct tt_local_entry *tt_local_entry;
979         struct tt_query_packet *tt_response;
980         struct tt_change *tt_change;
981         struct hlist_node *node;
982         struct hlist_head *head;
983         struct sk_buff *skb = NULL;
984         uint16_t tt_tot, tt_count;
985         ssize_t tt_query_size = sizeof(struct tt_query_packet);
986         int i;
987
988         if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
989                 tt_len = primary_if->soft_iface->mtu - tt_query_size;
990                 tt_len -= tt_len % sizeof(struct tt_change);
991         }
992         tt_tot = tt_len / sizeof(struct tt_change);
993
994         skb = dev_alloc_skb(tt_query_size + tt_len + ETH_HLEN);
995         if (!skb)
996                 goto out;
997
998         skb_reserve(skb, ETH_HLEN);
999         tt_response = (struct tt_query_packet *)skb_put(skb,
1000                                                      tt_query_size + tt_len);
1001         tt_response->ttvn = ttvn;
1002         tt_response->tt_data = htons(tt_tot);
1003
1004         tt_change = (struct tt_change *)(skb->data + tt_query_size);
1005         tt_count = 0;
1006
1007         rcu_read_lock();
1008         for (i = 0; i < hash->size; i++) {
1009                 head = &hash->table[i];
1010
1011                 hlist_for_each_entry_rcu(tt_local_entry, node,
1012                                          head, hash_entry) {
1013                         if (tt_count == tt_tot)
1014                                 break;
1015
1016                         if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data)))
1017                                 continue;
1018
1019                         memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN);
1020                         tt_change->flags = NO_FLAGS;
1021
1022                         tt_count++;
1023                         tt_change++;
1024                 }
1025         }
1026         rcu_read_unlock();
1027
1028 out:
1029         return skb;
1030 }
1031
1032 int send_tt_request(struct bat_priv *bat_priv, struct orig_node *dst_orig_node,
1033                     uint8_t ttvn, uint16_t tt_crc, bool full_table)
1034 {
1035         struct sk_buff *skb = NULL;
1036         struct tt_query_packet *tt_request;
1037         struct neigh_node *neigh_node = NULL;
1038         struct hard_iface *primary_if;
1039         struct tt_req_node *tt_req_node = NULL;
1040         int ret = 1;
1041
1042         primary_if = primary_if_get_selected(bat_priv);
1043         if (!primary_if)
1044                 goto out;
1045
1046         /* The new tt_req will be issued only if I'm not waiting for a
1047          * reply from the same orig_node yet */
1048         tt_req_node = new_tt_req_node(bat_priv, dst_orig_node);
1049         if (!tt_req_node)
1050                 goto out;
1051
1052         skb = dev_alloc_skb(sizeof(struct tt_query_packet) + ETH_HLEN);
1053         if (!skb)
1054                 goto out;
1055
1056         skb_reserve(skb, ETH_HLEN);
1057
1058         tt_request = (struct tt_query_packet *)skb_put(skb,
1059                                 sizeof(struct tt_query_packet));
1060
1061         tt_request->packet_type = BAT_TT_QUERY;
1062         tt_request->version = COMPAT_VERSION;
1063         memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1064         memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
1065         tt_request->ttl = TTL;
1066         tt_request->ttvn = ttvn;
1067         tt_request->tt_data = tt_crc;
1068         tt_request->flags = TT_REQUEST;
1069
1070         if (full_table)
1071                 tt_request->flags |= TT_FULL_TABLE;
1072
1073         neigh_node = orig_node_get_router(dst_orig_node);
1074         if (!neigh_node)
1075                 goto out;
1076
1077         bat_dbg(DBG_TT, bat_priv, "Sending TT_REQUEST to %pM via %pM "
1078                 "[%c]\n", dst_orig_node->orig, neigh_node->addr,
1079                 (full_table ? 'F' : '.'));
1080
1081         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1082         ret = 0;
1083
1084 out:
1085         if (neigh_node)
1086                 neigh_node_free_ref(neigh_node);
1087         if (primary_if)
1088                 hardif_free_ref(primary_if);
1089         if (ret)
1090                 kfree_skb(skb);
1091         if (ret && tt_req_node) {
1092                 spin_lock_bh(&bat_priv->tt_req_list_lock);
1093                 list_del(&tt_req_node->list);
1094                 spin_unlock_bh(&bat_priv->tt_req_list_lock);
1095                 kfree(tt_req_node);
1096         }
1097         return ret;
1098 }
1099
1100 static bool send_other_tt_response(struct bat_priv *bat_priv,
1101                                    struct tt_query_packet *tt_request)
1102 {
1103         struct orig_node *req_dst_orig_node = NULL, *res_dst_orig_node = NULL;
1104         struct neigh_node *neigh_node = NULL;
1105         struct hard_iface *primary_if = NULL;
1106         uint8_t orig_ttvn, req_ttvn, ttvn;
1107         int ret = false;
1108         unsigned char *tt_buff;
1109         bool full_table;
1110         uint16_t tt_len, tt_tot;
1111         struct sk_buff *skb = NULL;
1112         struct tt_query_packet *tt_response;
1113
1114         bat_dbg(DBG_TT, bat_priv,
1115                 "Received TT_REQUEST from %pM for "
1116                 "ttvn: %u (%pM) [%c]\n", tt_request->src,
1117                 tt_request->ttvn, tt_request->dst,
1118                 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1119
1120         /* Let's get the orig node of the REAL destination */
1121         req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst);
1122         if (!req_dst_orig_node)
1123                 goto out;
1124
1125         res_dst_orig_node = get_orig_node(bat_priv, tt_request->src);
1126         if (!res_dst_orig_node)
1127                 goto out;
1128
1129         neigh_node = orig_node_get_router(res_dst_orig_node);
1130         if (!neigh_node)
1131                 goto out;
1132
1133         primary_if = primary_if_get_selected(bat_priv);
1134         if (!primary_if)
1135                 goto out;
1136
1137         orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1138         req_ttvn = tt_request->ttvn;
1139
1140         /* I have not the requested data */
1141         if (orig_ttvn != req_ttvn ||
1142             tt_request->tt_data != req_dst_orig_node->tt_crc)
1143                 goto out;
1144
1145         /* If it has explicitly been requested the full table */
1146         if (tt_request->flags & TT_FULL_TABLE ||
1147             !req_dst_orig_node->tt_buff)
1148                 full_table = true;
1149         else
1150                 full_table = false;
1151
1152         /* In this version, fragmentation is not implemented, then
1153          * I'll send only one packet with as much TT entries as I can */
1154         if (!full_table) {
1155                 spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
1156                 tt_len = req_dst_orig_node->tt_buff_len;
1157                 tt_tot = tt_len / sizeof(struct tt_change);
1158
1159                 skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1160                                     tt_len + ETH_HLEN);
1161                 if (!skb)
1162                         goto unlock;
1163
1164                 skb_reserve(skb, ETH_HLEN);
1165                 tt_response = (struct tt_query_packet *)skb_put(skb,
1166                                 sizeof(struct tt_query_packet) + tt_len);
1167                 tt_response->ttvn = req_ttvn;
1168                 tt_response->tt_data = htons(tt_tot);
1169
1170                 tt_buff = skb->data + sizeof(struct tt_query_packet);
1171                 /* Copy the last orig_node's OGM buffer */
1172                 memcpy(tt_buff, req_dst_orig_node->tt_buff,
1173                        req_dst_orig_node->tt_buff_len);
1174
1175                 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1176         } else {
1177                 tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size) *
1178                                                 sizeof(struct tt_change);
1179                 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1180
1181                 skb = tt_response_fill_table(tt_len, ttvn,
1182                                              bat_priv->tt_global_hash,
1183                                              primary_if, tt_global_valid_entry,
1184                                              req_dst_orig_node);
1185                 if (!skb)
1186                         goto out;
1187
1188                 tt_response = (struct tt_query_packet *)skb->data;
1189         }
1190
1191         tt_response->packet_type = BAT_TT_QUERY;
1192         tt_response->version = COMPAT_VERSION;
1193         tt_response->ttl = TTL;
1194         memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
1195         memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1196         tt_response->flags = TT_RESPONSE;
1197
1198         if (full_table)
1199                 tt_response->flags |= TT_FULL_TABLE;
1200
1201         bat_dbg(DBG_TT, bat_priv,
1202                 "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
1203                 res_dst_orig_node->orig, neigh_node->addr,
1204                 req_dst_orig_node->orig, req_ttvn);
1205
1206         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1207         ret = true;
1208         goto out;
1209
1210 unlock:
1211         spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
1212
1213 out:
1214         if (res_dst_orig_node)
1215                 orig_node_free_ref(res_dst_orig_node);
1216         if (req_dst_orig_node)
1217                 orig_node_free_ref(req_dst_orig_node);
1218         if (neigh_node)
1219                 neigh_node_free_ref(neigh_node);
1220         if (primary_if)
1221                 hardif_free_ref(primary_if);
1222         if (!ret)
1223                 kfree_skb(skb);
1224         return ret;
1225
1226 }
1227 static bool send_my_tt_response(struct bat_priv *bat_priv,
1228                                 struct tt_query_packet *tt_request)
1229 {
1230         struct orig_node *orig_node = NULL;
1231         struct neigh_node *neigh_node = NULL;
1232         struct hard_iface *primary_if = NULL;
1233         uint8_t my_ttvn, req_ttvn, ttvn;
1234         int ret = false;
1235         unsigned char *tt_buff;
1236         bool full_table;
1237         uint16_t tt_len, tt_tot;
1238         struct sk_buff *skb = NULL;
1239         struct tt_query_packet *tt_response;
1240
1241         bat_dbg(DBG_TT, bat_priv,
1242                 "Received TT_REQUEST from %pM for "
1243                 "ttvn: %u (me) [%c]\n", tt_request->src,
1244                 tt_request->ttvn,
1245                 (tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
1246
1247
1248         my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1249         req_ttvn = tt_request->ttvn;
1250
1251         orig_node = get_orig_node(bat_priv, tt_request->src);
1252         if (!orig_node)
1253                 goto out;
1254
1255         neigh_node = orig_node_get_router(orig_node);
1256         if (!neigh_node)
1257                 goto out;
1258
1259         primary_if = primary_if_get_selected(bat_priv);
1260         if (!primary_if)
1261                 goto out;
1262
1263         /* If the full table has been explicitly requested or the gap
1264          * is too big send the whole local translation table */
1265         if (tt_request->flags & TT_FULL_TABLE || my_ttvn != req_ttvn ||
1266             !bat_priv->tt_buff)
1267                 full_table = true;
1268         else
1269                 full_table = false;
1270
1271         /* In this version, fragmentation is not implemented, then
1272          * I'll send only one packet with as much TT entries as I can */
1273         if (!full_table) {
1274                 spin_lock_bh(&bat_priv->tt_buff_lock);
1275                 tt_len = bat_priv->tt_buff_len;
1276                 tt_tot = tt_len / sizeof(struct tt_change);
1277
1278                 skb = dev_alloc_skb(sizeof(struct tt_query_packet) +
1279                                     tt_len + ETH_HLEN);
1280                 if (!skb)
1281                         goto unlock;
1282
1283                 skb_reserve(skb, ETH_HLEN);
1284                 tt_response = (struct tt_query_packet *)skb_put(skb,
1285                                 sizeof(struct tt_query_packet) + tt_len);
1286                 tt_response->ttvn = req_ttvn;
1287                 tt_response->tt_data = htons(tt_tot);
1288
1289                 tt_buff = skb->data + sizeof(struct tt_query_packet);
1290                 memcpy(tt_buff, bat_priv->tt_buff,
1291                        bat_priv->tt_buff_len);
1292                 spin_unlock_bh(&bat_priv->tt_buff_lock);
1293         } else {
1294                 tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt) *
1295                                                 sizeof(struct tt_change);
1296                 ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1297
1298                 skb = tt_response_fill_table(tt_len, ttvn,
1299                                              bat_priv->tt_local_hash,
1300                                              primary_if, tt_local_valid_entry,
1301                                              NULL);
1302                 if (!skb)
1303                         goto out;
1304
1305                 tt_response = (struct tt_query_packet *)skb->data;
1306         }
1307
1308         tt_response->packet_type = BAT_TT_QUERY;
1309         tt_response->version = COMPAT_VERSION;
1310         tt_response->ttl = TTL;
1311         memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1312         memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
1313         tt_response->flags = TT_RESPONSE;
1314
1315         if (full_table)
1316                 tt_response->flags |= TT_FULL_TABLE;
1317
1318         bat_dbg(DBG_TT, bat_priv,
1319                 "Sending TT_RESPONSE to %pM via %pM [%c]\n",
1320                 orig_node->orig, neigh_node->addr,
1321                 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1322
1323         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1324         ret = true;
1325         goto out;
1326
1327 unlock:
1328         spin_unlock_bh(&bat_priv->tt_buff_lock);
1329 out:
1330         if (orig_node)
1331                 orig_node_free_ref(orig_node);
1332         if (neigh_node)
1333                 neigh_node_free_ref(neigh_node);
1334         if (primary_if)
1335                 hardif_free_ref(primary_if);
1336         if (!ret)
1337                 kfree_skb(skb);
1338         /* This packet was for me, so it doesn't need to be re-routed */
1339         return true;
1340 }
1341
1342 bool send_tt_response(struct bat_priv *bat_priv,
1343                       struct tt_query_packet *tt_request)
1344 {
1345         if (is_my_mac(tt_request->dst))
1346                 return send_my_tt_response(bat_priv, tt_request);
1347         else
1348                 return send_other_tt_response(bat_priv, tt_request);
1349 }
1350
1351 static void _tt_update_changes(struct bat_priv *bat_priv,
1352                                struct orig_node *orig_node,
1353                                struct tt_change *tt_change,
1354                                uint16_t tt_num_changes, uint8_t ttvn)
1355 {
1356         int i;
1357
1358         for (i = 0; i < tt_num_changes; i++) {
1359                 if ((tt_change + i)->flags & TT_CLIENT_DEL)
1360                         tt_global_del(bat_priv, orig_node,
1361                                       (tt_change + i)->addr,
1362                                       "tt removed by changes",
1363                                       (tt_change + i)->flags & TT_CLIENT_ROAM);
1364                 else
1365                         if (!tt_global_add(bat_priv, orig_node,
1366                                            (tt_change + i)->addr, ttvn, false))
1367                                 /* In case of problem while storing a
1368                                  * global_entry, we stop the updating
1369                                  * procedure without committing the
1370                                  * ttvn change. This will avoid to send
1371                                  * corrupted data on tt_request
1372                                  */
1373                                 return;
1374         }
1375 }
1376
1377 static void tt_fill_gtable(struct bat_priv *bat_priv,
1378                            struct tt_query_packet *tt_response)
1379 {
1380         struct orig_node *orig_node = NULL;
1381
1382         orig_node = orig_hash_find(bat_priv, tt_response->src);
1383         if (!orig_node)
1384                 goto out;
1385
1386         /* Purge the old table first.. */
1387         tt_global_del_orig(bat_priv, orig_node, "Received full table");
1388
1389         _tt_update_changes(bat_priv, orig_node,
1390                            (struct tt_change *)(tt_response + 1),
1391                            tt_response->tt_data, tt_response->ttvn);
1392
1393         spin_lock_bh(&orig_node->tt_buff_lock);
1394         kfree(orig_node->tt_buff);
1395         orig_node->tt_buff_len = 0;
1396         orig_node->tt_buff = NULL;
1397         spin_unlock_bh(&orig_node->tt_buff_lock);
1398
1399         atomic_set(&orig_node->last_ttvn, tt_response->ttvn);
1400
1401 out:
1402         if (orig_node)
1403                 orig_node_free_ref(orig_node);
1404 }
1405
1406 void tt_update_changes(struct bat_priv *bat_priv, struct orig_node *orig_node,
1407                        uint16_t tt_num_changes, uint8_t ttvn,
1408                        struct tt_change *tt_change)
1409 {
1410         _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes,
1411                            ttvn);
1412
1413         tt_save_orig_buffer(bat_priv, orig_node, (unsigned char *)tt_change,
1414                             tt_num_changes);
1415         atomic_set(&orig_node->last_ttvn, ttvn);
1416 }
1417
1418 bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr)
1419 {
1420         struct tt_local_entry *tt_local_entry = NULL;
1421         bool ret = false;
1422
1423         tt_local_entry = tt_local_hash_find(bat_priv, addr);
1424         if (!tt_local_entry)
1425                 goto out;
1426         /* Check if the client has been logically deleted (but is kept for
1427          * consistency purpose) */
1428         if (tt_local_entry->flags & TT_CLIENT_PENDING)
1429                 goto out;
1430         ret = true;
1431 out:
1432         if (tt_local_entry)
1433                 tt_local_entry_free_ref(tt_local_entry);
1434         return ret;
1435 }
1436
1437 void handle_tt_response(struct bat_priv *bat_priv,
1438                         struct tt_query_packet *tt_response)
1439 {
1440         struct tt_req_node *node, *safe;
1441         struct orig_node *orig_node = NULL;
1442
1443         bat_dbg(DBG_TT, bat_priv, "Received TT_RESPONSE from %pM for "
1444                 "ttvn %d t_size: %d [%c]\n",
1445                 tt_response->src, tt_response->ttvn,
1446                 tt_response->tt_data,
1447                 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1448
1449         orig_node = orig_hash_find(bat_priv, tt_response->src);
1450         if (!orig_node)
1451                 goto out;
1452
1453         if (tt_response->flags & TT_FULL_TABLE)
1454                 tt_fill_gtable(bat_priv, tt_response);
1455         else
1456                 tt_update_changes(bat_priv, orig_node, tt_response->tt_data,
1457                                   tt_response->ttvn,
1458                                   (struct tt_change *)(tt_response + 1));
1459
1460         /* Delete the tt_req_node from pending tt_requests list */
1461         spin_lock_bh(&bat_priv->tt_req_list_lock);
1462         list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
1463                 if (!compare_eth(node->addr, tt_response->src))
1464                         continue;
1465                 list_del(&node->list);
1466                 kfree(node);
1467         }
1468         spin_unlock_bh(&bat_priv->tt_req_list_lock);
1469
1470         /* Recalculate the CRC for this orig_node and store it */
1471         orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1472         /* Roaming phase is over: tables are in sync again. I can
1473          * unset the flag */
1474         orig_node->tt_poss_change = false;
1475 out:
1476         if (orig_node)
1477                 orig_node_free_ref(orig_node);
1478 }
1479
1480 int tt_init(struct bat_priv *bat_priv)
1481 {
1482         if (!tt_local_init(bat_priv))
1483                 return 0;
1484
1485         if (!tt_global_init(bat_priv))
1486                 return 0;
1487
1488         tt_start_timer(bat_priv);
1489
1490         return 1;
1491 }
1492
1493 static void tt_roam_list_free(struct bat_priv *bat_priv)
1494 {
1495         struct tt_roam_node *node, *safe;
1496
1497         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1498
1499         list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1500                 list_del(&node->list);
1501                 kfree(node);
1502         }
1503
1504         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1505 }
1506
1507 static void tt_roam_purge(struct bat_priv *bat_priv)
1508 {
1509         struct tt_roam_node *node, *safe;
1510
1511         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1512         list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
1513                 if (!is_out_of_time(node->first_time,
1514                                     ROAMING_MAX_TIME * 1000))
1515                         continue;
1516
1517                 list_del(&node->list);
1518                 kfree(node);
1519         }
1520         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1521 }
1522
1523 /* This function checks whether the client already reached the
1524  * maximum number of possible roaming phases. In this case the ROAMING_ADV
1525  * will not be sent.
1526  *
1527  * returns true if the ROAMING_ADV can be sent, false otherwise */
1528 static bool tt_check_roam_count(struct bat_priv *bat_priv,
1529                                 uint8_t *client)
1530 {
1531         struct tt_roam_node *tt_roam_node;
1532         bool ret = false;
1533
1534         spin_lock_bh(&bat_priv->tt_roam_list_lock);
1535         /* The new tt_req will be issued only if I'm not waiting for a
1536          * reply from the same orig_node yet */
1537         list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) {
1538                 if (!compare_eth(tt_roam_node->addr, client))
1539                         continue;
1540
1541                 if (is_out_of_time(tt_roam_node->first_time,
1542                                    ROAMING_MAX_TIME * 1000))
1543                         continue;
1544
1545                 if (!atomic_dec_not_zero(&tt_roam_node->counter))
1546                         /* Sorry, you roamed too many times! */
1547                         goto unlock;
1548                 ret = true;
1549                 break;
1550         }
1551
1552         if (!ret) {
1553                 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
1554                 if (!tt_roam_node)
1555                         goto unlock;
1556
1557                 tt_roam_node->first_time = jiffies;
1558                 atomic_set(&tt_roam_node->counter, ROAMING_MAX_COUNT - 1);
1559                 memcpy(tt_roam_node->addr, client, ETH_ALEN);
1560
1561                 list_add(&tt_roam_node->list, &bat_priv->tt_roam_list);
1562                 ret = true;
1563         }
1564
1565 unlock:
1566         spin_unlock_bh(&bat_priv->tt_roam_list_lock);
1567         return ret;
1568 }
1569
1570 void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
1571                    struct orig_node *orig_node)
1572 {
1573         struct neigh_node *neigh_node = NULL;
1574         struct sk_buff *skb = NULL;
1575         struct roam_adv_packet *roam_adv_packet;
1576         int ret = 1;
1577         struct hard_iface *primary_if;
1578
1579         /* before going on we have to check whether the client has
1580          * already roamed to us too many times */
1581         if (!tt_check_roam_count(bat_priv, client))
1582                 goto out;
1583
1584         skb = dev_alloc_skb(sizeof(struct roam_adv_packet) + ETH_HLEN);
1585         if (!skb)
1586                 goto out;
1587
1588         skb_reserve(skb, ETH_HLEN);
1589
1590         roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
1591                                         sizeof(struct roam_adv_packet));
1592
1593         roam_adv_packet->packet_type = BAT_ROAM_ADV;
1594         roam_adv_packet->version = COMPAT_VERSION;
1595         roam_adv_packet->ttl = TTL;
1596         primary_if = primary_if_get_selected(bat_priv);
1597         if (!primary_if)
1598                 goto out;
1599         memcpy(roam_adv_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
1600         hardif_free_ref(primary_if);
1601         memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
1602         memcpy(roam_adv_packet->client, client, ETH_ALEN);
1603
1604         neigh_node = orig_node_get_router(orig_node);
1605         if (!neigh_node)
1606                 goto out;
1607
1608         bat_dbg(DBG_TT, bat_priv,
1609                 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
1610                 orig_node->orig, client, neigh_node->addr);
1611
1612         send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1613         ret = 0;
1614
1615 out:
1616         if (neigh_node)
1617                 neigh_node_free_ref(neigh_node);
1618         if (ret)
1619                 kfree_skb(skb);
1620         return;
1621 }
1622
1623 static void tt_purge(struct work_struct *work)
1624 {
1625         struct delayed_work *delayed_work =
1626                 container_of(work, struct delayed_work, work);
1627         struct bat_priv *bat_priv =
1628                 container_of(delayed_work, struct bat_priv, tt_work);
1629
1630         tt_local_purge(bat_priv);
1631         tt_global_roam_purge(bat_priv);
1632         tt_req_purge(bat_priv);
1633         tt_roam_purge(bat_priv);
1634
1635         tt_start_timer(bat_priv);
1636 }
1637
1638 void tt_free(struct bat_priv *bat_priv)
1639 {
1640         cancel_delayed_work_sync(&bat_priv->tt_work);
1641
1642         tt_local_table_free(bat_priv);
1643         tt_global_table_free(bat_priv);
1644         tt_req_list_free(bat_priv);
1645         tt_changes_list_free(bat_priv);
1646         tt_roam_list_free(bat_priv);
1647
1648         kfree(bat_priv->tt_buff);
1649 }
1650
1651 /* This function will reset the specified flags from all the entries in
1652  * the given hash table and will increment num_local_tt for each involved
1653  * entry */
1654 static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags)
1655 {
1656         int i;
1657         struct hashtable_t *hash = bat_priv->tt_local_hash;
1658         struct hlist_head *head;
1659         struct hlist_node *node;
1660         struct tt_local_entry *tt_local_entry;
1661
1662         if (!hash)
1663                 return;
1664
1665         for (i = 0; i < hash->size; i++) {
1666                 head = &hash->table[i];
1667
1668                 rcu_read_lock();
1669                 hlist_for_each_entry_rcu(tt_local_entry, node,
1670                                          head, hash_entry) {
1671                         tt_local_entry->flags &= ~flags;
1672                         atomic_inc(&bat_priv->num_local_tt);
1673                 }
1674                 rcu_read_unlock();
1675         }
1676
1677 }
1678
1679 /* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
1680 static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
1681 {
1682         struct hashtable_t *hash = bat_priv->tt_local_hash;
1683         struct tt_local_entry *tt_local_entry;
1684         struct hlist_node *node, *node_tmp;
1685         struct hlist_head *head;
1686         spinlock_t *list_lock; /* protects write access to the hash lists */
1687         int i;
1688
1689         if (!hash)
1690                 return;
1691
1692         for (i = 0; i < hash->size; i++) {
1693                 head = &hash->table[i];
1694                 list_lock = &hash->list_locks[i];
1695
1696                 spin_lock_bh(list_lock);
1697                 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
1698                                           head, hash_entry) {
1699                         if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
1700                                 continue;
1701
1702                         bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
1703                                 "(%pM): pending\n", tt_local_entry->addr);
1704
1705                         atomic_dec(&bat_priv->num_local_tt);
1706                         hlist_del_rcu(node);
1707                         tt_local_entry_free_ref(tt_local_entry);
1708                 }
1709                 spin_unlock_bh(list_lock);
1710         }
1711
1712 }
1713
1714 void tt_commit_changes(struct bat_priv *bat_priv)
1715 {
1716         tt_local_reset_flags(bat_priv, TT_CLIENT_NEW);
1717         tt_local_purge_pending_clients(bat_priv);
1718
1719         /* Increment the TTVN only once per OGM interval */
1720         atomic_inc(&bat_priv->ttvn);
1721         bat_priv->tt_poss_change = false;
1722 }