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