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