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