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