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