linux/net/batman-adv/translation-table.c
<<
>>
Prefs
   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/crc32c.h>
  31
  32/* hash class keys */
  33static struct lock_class_key batadv_tt_local_hash_lock_class_key;
  34static struct lock_class_key batadv_tt_global_hash_lock_class_key;
  35
  36static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
  37                                 unsigned short vid,
  38                                 struct batadv_orig_node *orig_node);
  39static void batadv_tt_purge(struct work_struct *work);
  40static void
  41batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
  42static void batadv_tt_global_del(struct batadv_priv *bat_priv,
  43                                 struct batadv_orig_node *orig_node,
  44                                 const unsigned char *addr,
  45                                 unsigned short vid, const char *message,
  46                                 bool roaming);
  47
  48/* returns 1 if they are the same mac addr */
  49static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
  50{
  51        const void *data1 = container_of(node, struct batadv_tt_common_entry,
  52                                         hash_entry);
  53
  54        return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
  55}
  56
  57/**
  58 * batadv_choose_tt - return the index of the tt entry in the hash table
  59 * @data: pointer to the tt_common_entry object to map
  60 * @size: the size of the hash table
  61 *
  62 * Returns the hash index where the object represented by 'data' should be
  63 * stored at.
  64 */
  65static inline uint32_t batadv_choose_tt(const void *data, uint32_t size)
  66{
  67        struct batadv_tt_common_entry *tt;
  68        uint32_t hash = 0;
  69
  70        tt = (struct batadv_tt_common_entry *)data;
  71        hash = batadv_hash_bytes(hash, &tt->addr, ETH_ALEN);
  72        hash = batadv_hash_bytes(hash, &tt->vid, sizeof(tt->vid));
  73
  74        hash += (hash << 3);
  75        hash ^= (hash >> 11);
  76        hash += (hash << 15);
  77
  78        return hash % size;
  79}
  80
  81/**
  82 * batadv_tt_hash_find - look for a client in the given hash table
  83 * @hash: the hash table to search
  84 * @addr: the mac address of the client to look for
  85 * @vid: VLAN identifier
  86 *
  87 * Returns a pointer to the tt_common struct belonging to the searched client if
  88 * found, NULL otherwise.
  89 */
  90static struct batadv_tt_common_entry *
  91batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr,
  92                    unsigned short vid)
  93{
  94        struct hlist_head *head;
  95        struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
  96        uint32_t index;
  97
  98        if (!hash)
  99                return NULL;
 100
 101        memcpy(to_search.addr, addr, ETH_ALEN);
 102        to_search.vid = vid;
 103
 104        index = batadv_choose_tt(&to_search, hash->size);
 105        head = &hash->table[index];
 106
 107        rcu_read_lock();
 108        hlist_for_each_entry_rcu(tt, head, hash_entry) {
 109                if (!batadv_compare_eth(tt, addr))
 110                        continue;
 111
 112                if (tt->vid != vid)
 113                        continue;
 114
 115                if (!atomic_inc_not_zero(&tt->refcount))
 116                        continue;
 117
 118                tt_tmp = tt;
 119                break;
 120        }
 121        rcu_read_unlock();
 122
 123        return tt_tmp;
 124}
 125
 126/**
 127 * batadv_tt_local_hash_find - search the local table for a given client
 128 * @bat_priv: the bat priv with all the soft interface information
 129 * @addr: the mac address of the client to look for
 130 * @vid: VLAN identifier
 131 *
 132 * Returns a pointer to the corresponding tt_local_entry struct if the client is
 133 * found, NULL otherwise.
 134 */
 135static struct batadv_tt_local_entry *
 136batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
 137                          unsigned short vid)
 138{
 139        struct batadv_tt_common_entry *tt_common_entry;
 140        struct batadv_tt_local_entry *tt_local_entry = NULL;
 141
 142        tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
 143                                              vid);
 144        if (tt_common_entry)
 145                tt_local_entry = container_of(tt_common_entry,
 146                                              struct batadv_tt_local_entry,
 147                                              common);
 148        return tt_local_entry;
 149}
 150
 151/**
 152 * batadv_tt_global_hash_find - search the global table for a given client
 153 * @bat_priv: the bat priv with all the soft interface information
 154 * @addr: the mac address of the client to look for
 155 * @vid: VLAN identifier
 156 *
 157 * Returns a pointer to the corresponding tt_global_entry struct if the client
 158 * is found, NULL otherwise.
 159 */
 160static struct batadv_tt_global_entry *
 161batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
 162                           unsigned short vid)
 163{
 164        struct batadv_tt_common_entry *tt_common_entry;
 165        struct batadv_tt_global_entry *tt_global_entry = NULL;
 166
 167        tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
 168                                              vid);
 169        if (tt_common_entry)
 170                tt_global_entry = container_of(tt_common_entry,
 171                                               struct batadv_tt_global_entry,
 172                                               common);
 173        return tt_global_entry;
 174}
 175
 176static void
 177batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry)
 178{
 179        if (atomic_dec_and_test(&tt_local_entry->common.refcount))
 180                kfree_rcu(tt_local_entry, common.rcu);
 181}
 182
 183/**
 184 * batadv_tt_global_entry_free_ref - decrement the refcounter for a
 185 *  tt_global_entry and possibly free it
 186 * @tt_global_entry: the object to free
 187 */
 188static void
 189batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry)
 190{
 191        if (atomic_dec_and_test(&tt_global_entry->common.refcount)) {
 192                batadv_tt_global_del_orig_list(tt_global_entry);
 193                kfree_rcu(tt_global_entry, common.rcu);
 194        }
 195}
 196
 197static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
 198{
 199        struct batadv_tt_orig_list_entry *orig_entry;
 200
 201        orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
 202
 203        /* We are in an rcu callback here, therefore we cannot use
 204         * batadv_orig_node_free_ref() and its call_rcu():
 205         * An rcu_barrier() wouldn't wait for that to finish
 206         */
 207        batadv_orig_node_free_ref_now(orig_entry->orig_node);
 208        kfree(orig_entry);
 209}
 210
 211/**
 212 * batadv_tt_local_size_mod - change the size by v of the local table identified
 213 *  by vid
 214 * @bat_priv: the bat priv with all the soft interface information
 215 * @vid: the VLAN identifier of the sub-table to change
 216 * @v: the amount to sum to the local table size
 217 */
 218static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv,
 219                                     unsigned short vid, int v)
 220{
 221        struct batadv_softif_vlan *vlan;
 222
 223        vlan = batadv_softif_vlan_get(bat_priv, vid);
 224        if (!vlan)
 225                return;
 226
 227        atomic_add(v, &vlan->tt.num_entries);
 228
 229        batadv_softif_vlan_free_ref(vlan);
 230}
 231
 232/**
 233 * batadv_tt_local_size_inc - increase by one the local table size for the given
 234 *  vid
 235 * @bat_priv: the bat priv with all the soft interface information
 236 * @vid: the VLAN identifier
 237 */
 238static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv,
 239                                     unsigned short vid)
 240{
 241        batadv_tt_local_size_mod(bat_priv, vid, 1);
 242}
 243
 244/**
 245 * batadv_tt_local_size_dec - decrease by one the local table size for the given
 246 *  vid
 247 * @bat_priv: the bat priv with all the soft interface information
 248 * @vid: the VLAN identifier
 249 */
 250static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv,
 251                                     unsigned short vid)
 252{
 253        batadv_tt_local_size_mod(bat_priv, vid, -1);
 254}
 255
 256/**
 257 * batadv_tt_global_size_mod - change the size by v of the local table
 258 *  identified by vid
 259 * @bat_priv: the bat priv with all the soft interface information
 260 * @vid: the VLAN identifier
 261 * @v: the amount to sum to the global table size
 262 */
 263static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
 264                                      unsigned short vid, int v)
 265{
 266        struct batadv_orig_node_vlan *vlan;
 267
 268        vlan = batadv_orig_node_vlan_new(orig_node, vid);
 269        if (!vlan)
 270                return;
 271
 272        if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
 273                spin_lock_bh(&orig_node->vlan_list_lock);
 274                list_del_rcu(&vlan->list);
 275                spin_unlock_bh(&orig_node->vlan_list_lock);
 276                batadv_orig_node_vlan_free_ref(vlan);
 277        }
 278
 279        batadv_orig_node_vlan_free_ref(vlan);
 280}
 281
 282/**
 283 * batadv_tt_global_size_inc - increase by one the global table size for the
 284 *  given vid
 285 * @orig_node: the originator which global table size has to be decreased
 286 * @vid: the vlan identifier
 287 */
 288static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node,
 289                                      unsigned short vid)
 290{
 291        batadv_tt_global_size_mod(orig_node, vid, 1);
 292}
 293
 294/**
 295 * batadv_tt_global_size_dec - decrease by one the global table size for the
 296 *  given vid
 297 * @orig_node: the originator which global table size has to be decreased
 298 * @vid: the vlan identifier
 299 */
 300static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
 301                                      unsigned short vid)
 302{
 303        batadv_tt_global_size_mod(orig_node, vid, -1);
 304}
 305
 306static void
 307batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
 308{
 309        if (!atomic_dec_and_test(&orig_entry->refcount))
 310                return;
 311
 312        call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
 313}
 314
 315/**
 316 * batadv_tt_local_event - store a local TT event (ADD/DEL)
 317 * @bat_priv: the bat priv with all the soft interface information
 318 * @tt_local_entry: the TT entry involved in the event
 319 * @event_flags: flags to store in the event structure
 320 */
 321static void batadv_tt_local_event(struct batadv_priv *bat_priv,
 322                                  struct batadv_tt_local_entry *tt_local_entry,
 323                                  uint8_t event_flags)
 324{
 325        struct batadv_tt_change_node *tt_change_node, *entry, *safe;
 326        struct batadv_tt_common_entry *common = &tt_local_entry->common;
 327        uint8_t flags = common->flags | event_flags;
 328        bool event_removed = false;
 329        bool del_op_requested, del_op_entry;
 330
 331        tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
 332        if (!tt_change_node)
 333                return;
 334
 335        tt_change_node->change.flags = flags;
 336        memset(tt_change_node->change.reserved, 0,
 337               sizeof(tt_change_node->change.reserved));
 338        memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
 339        tt_change_node->change.vid = htons(common->vid);
 340
 341        del_op_requested = flags & BATADV_TT_CLIENT_DEL;
 342
 343        /* check for ADD+DEL or DEL+ADD events */
 344        spin_lock_bh(&bat_priv->tt.changes_list_lock);
 345        list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
 346                                 list) {
 347                if (!batadv_compare_eth(entry->change.addr, common->addr))
 348                        continue;
 349
 350                /* DEL+ADD in the same orig interval have no effect and can be
 351                 * removed to avoid silly behaviour on the receiver side. The
 352                 * other way around (ADD+DEL) can happen in case of roaming of
 353                 * a client still in the NEW state. Roaming of NEW clients is
 354                 * now possible due to automatically recognition of "temporary"
 355                 * clients
 356                 */
 357                del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
 358                if (!del_op_requested && del_op_entry)
 359                        goto del;
 360                if (del_op_requested && !del_op_entry)
 361                        goto del;
 362
 363                /* this is a second add in the same originator interval. It
 364                 * means that flags have been changed: update them!
 365                 */
 366                if (!del_op_requested && !del_op_entry)
 367                        entry->change.flags = flags;
 368
 369                continue;
 370del:
 371                list_del(&entry->list);
 372                kfree(entry);
 373                kfree(tt_change_node);
 374                event_removed = true;
 375                goto unlock;
 376        }
 377
 378        /* track the change in the OGMinterval list */
 379        list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
 380
 381unlock:
 382        spin_unlock_bh(&bat_priv->tt.changes_list_lock);
 383
 384        if (event_removed)
 385                atomic_dec(&bat_priv->tt.local_changes);
 386        else
 387                atomic_inc(&bat_priv->tt.local_changes);
 388}
 389
 390/**
 391 * batadv_tt_len - compute length in bytes of given number of tt changes
 392 * @changes_num: number of tt changes
 393 *
 394 * Returns computed length in bytes.
 395 */
 396static int batadv_tt_len(int changes_num)
 397{
 398        return changes_num * sizeof(struct batadv_tvlv_tt_change);
 399}
 400
 401/**
 402 * batadv_tt_entries - compute the number of entries fitting in tt_len bytes
 403 * @tt_len: available space
 404 *
 405 * Returns the number of entries.
 406 */
 407static uint16_t batadv_tt_entries(uint16_t tt_len)
 408{
 409        return tt_len / batadv_tt_len(1);
 410}
 411
 412/**
 413 * batadv_tt_local_table_transmit_size - calculates the local translation table
 414 *  size when transmitted over the air
 415 * @bat_priv: the bat priv with all the soft interface information
 416 *
 417 * Returns local translation table size in bytes.
 418 */
 419static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
 420{
 421        uint16_t num_vlan = 0, tt_local_entries = 0;
 422        struct batadv_softif_vlan *vlan;
 423        int hdr_size;
 424
 425        rcu_read_lock();
 426        hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
 427                num_vlan++;
 428                tt_local_entries += atomic_read(&vlan->tt.num_entries);
 429        }
 430        rcu_read_unlock();
 431
 432        /* header size of tvlv encapsulated tt response payload */
 433        hdr_size = sizeof(struct batadv_unicast_tvlv_packet);
 434        hdr_size += sizeof(struct batadv_tvlv_hdr);
 435        hdr_size += sizeof(struct batadv_tvlv_tt_data);
 436        hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data);
 437
 438        return hdr_size + batadv_tt_len(tt_local_entries);
 439}
 440
 441static int batadv_tt_local_init(struct batadv_priv *bat_priv)
 442{
 443        if (bat_priv->tt.local_hash)
 444                return 0;
 445
 446        bat_priv->tt.local_hash = batadv_hash_new(1024);
 447
 448        if (!bat_priv->tt.local_hash)
 449                return -ENOMEM;
 450
 451        batadv_hash_set_lock_class(bat_priv->tt.local_hash,
 452                                   &batadv_tt_local_hash_lock_class_key);
 453
 454        return 0;
 455}
 456
 457static void batadv_tt_global_free(struct batadv_priv *bat_priv,
 458                                  struct batadv_tt_global_entry *tt_global,
 459                                  const char *message)
 460{
 461        batadv_dbg(BATADV_DBG_TT, bat_priv,
 462                   "Deleting global tt entry %pM (vid: %d): %s\n",
 463                   tt_global->common.addr,
 464                   BATADV_PRINT_VID(tt_global->common.vid), message);
 465
 466        batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
 467                           batadv_choose_tt, &tt_global->common);
 468        batadv_tt_global_entry_free_ref(tt_global);
 469}
 470
 471/**
 472 * batadv_tt_local_add - add a new client to the local table or update an
 473 *  existing client
 474 * @soft_iface: netdev struct of the mesh interface
 475 * @addr: the mac address of the client to add
 476 * @vid: VLAN identifier
 477 * @ifindex: index of the interface where the client is connected to (useful to
 478 *  identify wireless clients)
 479 *
 480 * Returns true if the client was successfully added, false otherwise.
 481 */
 482bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 483                         unsigned short vid, int ifindex)
 484{
 485        struct batadv_priv *bat_priv = netdev_priv(soft_iface);
 486        struct batadv_tt_local_entry *tt_local;
 487        struct batadv_tt_global_entry *tt_global;
 488        struct net_device *in_dev = NULL;
 489        struct hlist_head *head;
 490        struct batadv_tt_orig_list_entry *orig_entry;
 491        int hash_added, table_size, packet_size_max;
 492        bool ret = false, roamed_back = false;
 493        uint8_t remote_flags;
 494
 495        if (ifindex != BATADV_NULL_IFINDEX)
 496                in_dev = dev_get_by_index(&init_net, ifindex);
 497
 498        tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
 499        tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
 500
 501        if (tt_local) {
 502                tt_local->last_seen = jiffies;
 503                if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
 504                        batadv_dbg(BATADV_DBG_TT, bat_priv,
 505                                   "Re-adding pending client %pM (vid: %d)\n",
 506                                   addr, BATADV_PRINT_VID(vid));
 507                        /* whatever the reason why the PENDING flag was set,
 508                         * this is a client which was enqueued to be removed in
 509                         * this orig_interval. Since it popped up again, the
 510                         * flag can be reset like it was never enqueued
 511                         */
 512                        tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
 513                        goto add_event;
 514                }
 515
 516                if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
 517                        batadv_dbg(BATADV_DBG_TT, bat_priv,
 518                                   "Roaming client %pM (vid: %d) came back to its original location\n",
 519                                   addr, BATADV_PRINT_VID(vid));
 520                        /* the ROAM flag is set because this client roamed away
 521                         * and the node got a roaming_advertisement message. Now
 522                         * that the client popped up again at its original
 523                         * location such flag can be unset
 524                         */
 525                        tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
 526                        roamed_back = true;
 527                }
 528                goto check_roaming;
 529        }
 530
 531        /* Ignore the client if we cannot send it in a full table response. */
 532        table_size = batadv_tt_local_table_transmit_size(bat_priv);
 533        table_size += batadv_tt_len(1);
 534        packet_size_max = atomic_read(&bat_priv->packet_size_max);
 535        if (table_size > packet_size_max) {
 536                net_ratelimited_function(batadv_info, soft_iface,
 537                                         "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
 538                                         table_size, packet_size_max, addr);
 539                goto out;
 540        }
 541
 542        tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
 543        if (!tt_local)
 544                goto out;
 545
 546        batadv_dbg(BATADV_DBG_TT, bat_priv,
 547                   "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
 548                   addr, BATADV_PRINT_VID(vid),
 549                   (uint8_t)atomic_read(&bat_priv->tt.vn));
 550
 551        memcpy(tt_local->common.addr, addr, ETH_ALEN);
 552        /* The local entry has to be marked as NEW to avoid to send it in
 553         * a full table response going out before the next ttvn increment
 554         * (consistency check)
 555         */
 556        tt_local->common.flags = BATADV_TT_CLIENT_NEW;
 557        tt_local->common.vid = vid;
 558        if (batadv_is_wifi_netdev(in_dev))
 559                tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
 560        atomic_set(&tt_local->common.refcount, 2);
 561        tt_local->last_seen = jiffies;
 562        tt_local->common.added_at = tt_local->last_seen;
 563
 564        /* the batman interface mac address should never be purged */
 565        if (batadv_compare_eth(addr, soft_iface->dev_addr))
 566                tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
 567
 568        hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
 569                                     batadv_choose_tt, &tt_local->common,
 570                                     &tt_local->common.hash_entry);
 571
 572        if (unlikely(hash_added != 0)) {
 573                /* remove the reference for the hash */
 574                batadv_tt_local_entry_free_ref(tt_local);
 575                goto out;
 576        }
 577
 578add_event:
 579        batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
 580
 581check_roaming:
 582        /* Check whether it is a roaming, but don't do anything if the roaming
 583         * process has already been handled
 584         */
 585        if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
 586                /* These node are probably going to update their tt table */
 587                head = &tt_global->orig_list;
 588                rcu_read_lock();
 589                hlist_for_each_entry_rcu(orig_entry, head, list) {
 590                        batadv_send_roam_adv(bat_priv, tt_global->common.addr,
 591                                             tt_global->common.vid,
 592                                             orig_entry->orig_node);
 593                }
 594                rcu_read_unlock();
 595                if (roamed_back) {
 596                        batadv_tt_global_free(bat_priv, tt_global,
 597                                              "Roaming canceled");
 598                        tt_global = NULL;
 599                } else {
 600                        /* The global entry has to be marked as ROAMING and
 601                         * has to be kept for consistency purpose
 602                         */
 603                        tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
 604                        tt_global->roam_at = jiffies;
 605                }
 606        }
 607
 608        /* store the current remote flags before altering them. This helps
 609         * understanding is flags are changing or not
 610         */
 611        remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
 612
 613        if (batadv_is_wifi_netdev(in_dev))
 614                tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
 615        else
 616                tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
 617
 618        /* if any "dynamic" flag has been modified, resend an ADD event for this
 619         * entry so that all the nodes can get the new flags
 620         */
 621        if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK))
 622                batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
 623
 624        ret = true;
 625out:
 626        if (in_dev)
 627                dev_put(in_dev);
 628        if (tt_local)
 629                batadv_tt_local_entry_free_ref(tt_local);
 630        if (tt_global)
 631                batadv_tt_global_entry_free_ref(tt_global);
 632        return ret;
 633}
 634
 635/**
 636 * batadv_tt_prepare_tvlv_global_data - prepare the TVLV TT header to send
 637 *  within a TT Response directed to another node
 638 * @orig_node: originator for which the TT data has to be prepared
 639 * @tt_data: uninitialised pointer to the address of the TVLV buffer
 640 * @tt_change: uninitialised pointer to the address of the area where the TT
 641 *  changed can be stored
 642 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
 643 *  function reserves the amount of space needed to send the entire global TT
 644 *  table. In case of success the value is updated with the real amount of
 645 *  reserved bytes
 646
 647 * Allocate the needed amount of memory for the entire TT TVLV and write its
 648 * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
 649 * objects, one per active VLAN served by the originator node.
 650 *
 651 * Return the size of the allocated buffer or 0 in case of failure.
 652 */
 653static uint16_t
 654batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
 655                                   struct batadv_tvlv_tt_data **tt_data,
 656                                   struct batadv_tvlv_tt_change **tt_change,
 657                                   int32_t *tt_len)
 658{
 659        uint16_t num_vlan = 0, num_entries = 0, change_offset, tvlv_len;
 660        struct batadv_tvlv_tt_vlan_data *tt_vlan;
 661        struct batadv_orig_node_vlan *vlan;
 662        uint8_t *tt_change_ptr;
 663
 664        rcu_read_lock();
 665        list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
 666                num_vlan++;
 667                num_entries += atomic_read(&vlan->tt.num_entries);
 668        }
 669
 670        change_offset = sizeof(**tt_data);
 671        change_offset += num_vlan * sizeof(*tt_vlan);
 672
 673        /* if tt_len is negative, allocate the space needed by the full table */
 674        if (*tt_len < 0)
 675                *tt_len = batadv_tt_len(num_entries);
 676
 677        tvlv_len = *tt_len;
 678        tvlv_len += change_offset;
 679
 680        *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
 681        if (!*tt_data) {
 682                *tt_len = 0;
 683                goto out;
 684        }
 685
 686        (*tt_data)->flags = BATADV_NO_FLAGS;
 687        (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
 688        (*tt_data)->num_vlan = htons(num_vlan);
 689
 690        tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
 691        list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
 692                tt_vlan->vid = htons(vlan->vid);
 693                tt_vlan->crc = htonl(vlan->tt.crc);
 694
 695                tt_vlan++;
 696        }
 697
 698        tt_change_ptr = (uint8_t *)*tt_data + change_offset;
 699        *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
 700
 701out:
 702        rcu_read_unlock();
 703        return tvlv_len;
 704}
 705
 706/**
 707 * batadv_tt_prepare_tvlv_local_data - allocate and prepare the TT TVLV for this
 708 *  node
 709 * @bat_priv: the bat priv with all the soft interface information
 710 * @tt_data: uninitialised pointer to the address of the TVLV buffer
 711 * @tt_change: uninitialised pointer to the address of the area where the TT
 712 *  changes can be stored
 713 * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
 714 *  function reserves the amount of space needed to send the entire local TT
 715 *  table. In case of success the value is updated with the real amount of
 716 *  reserved bytes
 717 *
 718 * Allocate the needed amount of memory for the entire TT TVLV and write its
 719 * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
 720 * objects, one per active VLAN.
 721 *
 722 * Return the size of the allocated buffer or 0 in case of failure.
 723 */
 724static uint16_t
 725batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
 726                                  struct batadv_tvlv_tt_data **tt_data,
 727                                  struct batadv_tvlv_tt_change **tt_change,
 728                                  int32_t *tt_len)
 729{
 730        struct batadv_tvlv_tt_vlan_data *tt_vlan;
 731        struct batadv_softif_vlan *vlan;
 732        uint16_t num_vlan = 0, num_entries = 0, tvlv_len;
 733        uint8_t *tt_change_ptr;
 734        int change_offset;
 735
 736        rcu_read_lock();
 737        hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
 738                num_vlan++;
 739                num_entries += atomic_read(&vlan->tt.num_entries);
 740        }
 741
 742        change_offset = sizeof(**tt_data);
 743        change_offset += num_vlan * sizeof(*tt_vlan);
 744
 745        /* if tt_len is negative, allocate the space needed by the full table */
 746        if (*tt_len < 0)
 747                *tt_len = batadv_tt_len(num_entries);
 748
 749        tvlv_len = *tt_len;
 750        tvlv_len += change_offset;
 751
 752        *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
 753        if (!*tt_data) {
 754                tvlv_len = 0;
 755                goto out;
 756        }
 757
 758        (*tt_data)->flags = BATADV_NO_FLAGS;
 759        (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn);
 760        (*tt_data)->num_vlan = htons(num_vlan);
 761
 762        tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
 763        hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
 764                tt_vlan->vid = htons(vlan->vid);
 765                tt_vlan->crc = htonl(vlan->tt.crc);
 766
 767                tt_vlan++;
 768        }
 769
 770        tt_change_ptr = (uint8_t *)*tt_data + change_offset;
 771        *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
 772
 773out:
 774        rcu_read_unlock();
 775        return tvlv_len;
 776}
 777
 778/**
 779 * batadv_tt_tvlv_container_update - update the translation table tvlv container
 780 *  after local tt changes have been committed
 781 * @bat_priv: the bat priv with all the soft interface information
 782 */
 783static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
 784{
 785        struct batadv_tt_change_node *entry, *safe;
 786        struct batadv_tvlv_tt_data *tt_data;
 787        struct batadv_tvlv_tt_change *tt_change;
 788        int tt_diff_len, tt_change_len = 0;
 789        int tt_diff_entries_num = 0, tt_diff_entries_count = 0;
 790        uint16_t tvlv_len;
 791
 792        tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes);
 793        tt_diff_len = batadv_tt_len(tt_diff_entries_num);
 794
 795        /* if we have too many changes for one packet don't send any
 796         * and wait for the tt table request which will be fragmented
 797         */
 798        if (tt_diff_len > bat_priv->soft_iface->mtu)
 799                tt_diff_len = 0;
 800
 801        tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
 802                                                     &tt_change, &tt_diff_len);
 803        if (!tvlv_len)
 804                return;
 805
 806        tt_data->flags = BATADV_TT_OGM_DIFF;
 807
 808        if (tt_diff_len == 0)
 809                goto container_register;
 810
 811        spin_lock_bh(&bat_priv->tt.changes_list_lock);
 812        atomic_set(&bat_priv->tt.local_changes, 0);
 813
 814        list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
 815                                 list) {
 816                if (tt_diff_entries_count < tt_diff_entries_num) {
 817                        memcpy(tt_change + tt_diff_entries_count,
 818                               &entry->change,
 819                               sizeof(struct batadv_tvlv_tt_change));
 820                        tt_diff_entries_count++;
 821                }
 822                list_del(&entry->list);
 823                kfree(entry);
 824        }
 825        spin_unlock_bh(&bat_priv->tt.changes_list_lock);
 826
 827        /* Keep the buffer for possible tt_request */
 828        spin_lock_bh(&bat_priv->tt.last_changeset_lock);
 829        kfree(bat_priv->tt.last_changeset);
 830        bat_priv->tt.last_changeset_len = 0;
 831        bat_priv->tt.last_changeset = NULL;
 832        tt_change_len = batadv_tt_len(tt_diff_entries_count);
 833        /* check whether this new OGM has no changes due to size problems */
 834        if (tt_diff_entries_count > 0) {
 835                /* if kmalloc() fails we will reply with the full table
 836                 * instead of providing the diff
 837                 */
 838                bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
 839                if (bat_priv->tt.last_changeset) {
 840                        memcpy(bat_priv->tt.last_changeset,
 841                               tt_change, tt_change_len);
 842                        bat_priv->tt.last_changeset_len = tt_diff_len;
 843                }
 844        }
 845        spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
 846
 847container_register:
 848        batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
 849                                       tvlv_len);
 850        kfree(tt_data);
 851}
 852
 853int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
 854{
 855        struct net_device *net_dev = (struct net_device *)seq->private;
 856        struct batadv_priv *bat_priv = netdev_priv(net_dev);
 857        struct batadv_hashtable *hash = bat_priv->tt.local_hash;
 858        struct batadv_tt_common_entry *tt_common_entry;
 859        struct batadv_tt_local_entry *tt_local;
 860        struct batadv_hard_iface *primary_if;
 861        struct batadv_softif_vlan *vlan;
 862        struct hlist_head *head;
 863        unsigned short vid;
 864        uint32_t i;
 865        int last_seen_secs;
 866        int last_seen_msecs;
 867        unsigned long last_seen_jiffies;
 868        bool no_purge;
 869        uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE;
 870
 871        primary_if = batadv_seq_print_text_primary_if_get(seq);
 872        if (!primary_if)
 873                goto out;
 874
 875        seq_printf(seq,
 876                   "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
 877                   net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
 878        seq_printf(seq, "       %-13s  %s %-7s %-9s (%-10s)\n", "Client", "VID",
 879                   "Flags", "Last seen", "CRC");
 880
 881        for (i = 0; i < hash->size; i++) {
 882                head = &hash->table[i];
 883
 884                rcu_read_lock();
 885                hlist_for_each_entry_rcu(tt_common_entry,
 886                                         head, hash_entry) {
 887                        tt_local = container_of(tt_common_entry,
 888                                                struct batadv_tt_local_entry,
 889                                                common);
 890                        vid = tt_common_entry->vid;
 891                        last_seen_jiffies = jiffies - tt_local->last_seen;
 892                        last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
 893                        last_seen_secs = last_seen_msecs / 1000;
 894                        last_seen_msecs = last_seen_msecs % 1000;
 895
 896                        no_purge = tt_common_entry->flags & np_flag;
 897
 898                        vlan = batadv_softif_vlan_get(bat_priv, vid);
 899                        if (!vlan) {
 900                                seq_printf(seq, "Cannot retrieve VLAN %d\n",
 901                                           BATADV_PRINT_VID(vid));
 902                                continue;
 903                        }
 904
 905                        seq_printf(seq,
 906                                   " * %pM %4i [%c%c%c%c%c] %3u.%03u   (%#.8x)\n",
 907                                   tt_common_entry->addr,
 908                                   BATADV_PRINT_VID(tt_common_entry->vid),
 909                                   (tt_common_entry->flags &
 910                                    BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
 911                                   no_purge ? 'P' : '.',
 912                                   (tt_common_entry->flags &
 913                                    BATADV_TT_CLIENT_NEW ? 'N' : '.'),
 914                                   (tt_common_entry->flags &
 915                                    BATADV_TT_CLIENT_PENDING ? 'X' : '.'),
 916                                   (tt_common_entry->flags &
 917                                    BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
 918                                   no_purge ? 0 : last_seen_secs,
 919                                   no_purge ? 0 : last_seen_msecs,
 920                                   vlan->tt.crc);
 921
 922                        batadv_softif_vlan_free_ref(vlan);
 923                }
 924                rcu_read_unlock();
 925        }
 926out:
 927        if (primary_if)
 928                batadv_hardif_free_ref(primary_if);
 929        return 0;
 930}
 931
 932static void
 933batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
 934                            struct batadv_tt_local_entry *tt_local_entry,
 935                            uint16_t flags, const char *message)
 936{
 937        batadv_tt_local_event(bat_priv, tt_local_entry, flags);
 938
 939        /* The local client has to be marked as "pending to be removed" but has
 940         * to be kept in the table in order to send it in a full table
 941         * response issued before the net ttvn increment (consistency check)
 942         */
 943        tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
 944
 945        batadv_dbg(BATADV_DBG_TT, bat_priv,
 946                   "Local tt entry (%pM, vid: %d) pending to be removed: %s\n",
 947                   tt_local_entry->common.addr,
 948                   BATADV_PRINT_VID(tt_local_entry->common.vid), message);
 949}
 950
 951/**
 952 * batadv_tt_local_remove - logically remove an entry from the local table
 953 * @bat_priv: the bat priv with all the soft interface information
 954 * @addr: the MAC address of the client to remove
 955 * @vid: VLAN identifier
 956 * @message: message to append to the log on deletion
 957 * @roaming: true if the deletion is due to a roaming event
 958 *
 959 * Returns the flags assigned to the local entry before being deleted
 960 */
 961uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
 962                                const uint8_t *addr, unsigned short vid,
 963                                const char *message, bool roaming)
 964{
 965        struct batadv_tt_local_entry *tt_local_entry;
 966        uint16_t flags, curr_flags = BATADV_NO_FLAGS;
 967
 968        tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
 969        if (!tt_local_entry)
 970                goto out;
 971
 972        curr_flags = tt_local_entry->common.flags;
 973
 974        flags = BATADV_TT_CLIENT_DEL;
 975        /* if this global entry addition is due to a roaming, the node has to
 976         * mark the local entry as "roamed" in order to correctly reroute
 977         * packets later
 978         */
 979        if (roaming) {
 980                flags |= BATADV_TT_CLIENT_ROAM;
 981                /* mark the local client as ROAMed */
 982                tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
 983        }
 984
 985        if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
 986                batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
 987                                            message);
 988                goto out;
 989        }
 990        /* if this client has been added right now, it is possible to
 991         * immediately purge it
 992         */
 993        batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
 994        hlist_del_rcu(&tt_local_entry->common.hash_entry);
 995        batadv_tt_local_entry_free_ref(tt_local_entry);
 996
 997out:
 998        if (tt_local_entry)
 999                batadv_tt_local_entry_free_ref(tt_local_entry);
1000
1001        return curr_flags;
1002}
1003
1004/**
1005 * batadv_tt_local_purge_list - purge inactive tt local entries
1006 * @bat_priv: the bat priv with all the soft interface information
1007 * @head: pointer to the list containing the local tt entries
1008 * @timeout: parameter deciding whether a given tt local entry is considered
1009 *  inactive or not
1010 */
1011static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
1012                                       struct hlist_head *head,
1013                                       int timeout)
1014{
1015        struct batadv_tt_local_entry *tt_local_entry;
1016        struct batadv_tt_common_entry *tt_common_entry;
1017        struct hlist_node *node_tmp;
1018
1019        hlist_for_each_entry_safe(tt_common_entry, node_tmp, head,
1020                                  hash_entry) {
1021                tt_local_entry = container_of(tt_common_entry,
1022                                              struct batadv_tt_local_entry,
1023                                              common);
1024                if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE)
1025                        continue;
1026
1027                /* entry already marked for deletion */
1028                if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
1029                        continue;
1030
1031                if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
1032                        continue;
1033
1034                batadv_tt_local_set_pending(bat_priv, tt_local_entry,
1035                                            BATADV_TT_CLIENT_DEL, "timed out");
1036        }
1037}
1038
1039/**
1040 * batadv_tt_local_purge - purge inactive tt local entries
1041 * @bat_priv: the bat priv with all the soft interface information
1042 * @timeout: parameter deciding whether a given tt local entry is considered
1043 *  inactive or not
1044 */
1045static void batadv_tt_local_purge(struct batadv_priv *bat_priv,
1046                                  int timeout)
1047{
1048        struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1049        struct hlist_head *head;
1050        spinlock_t *list_lock; /* protects write access to the hash lists */
1051        uint32_t i;
1052
1053        for (i = 0; i < hash->size; i++) {
1054                head = &hash->table[i];
1055                list_lock = &hash->list_locks[i];
1056
1057                spin_lock_bh(list_lock);
1058                batadv_tt_local_purge_list(bat_priv, head, timeout);
1059                spin_unlock_bh(list_lock);
1060        }
1061}
1062
1063static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
1064{
1065        struct batadv_hashtable *hash;
1066        spinlock_t *list_lock; /* protects write access to the hash lists */
1067        struct batadv_tt_common_entry *tt_common_entry;
1068        struct batadv_tt_local_entry *tt_local;
1069        struct hlist_node *node_tmp;
1070        struct hlist_head *head;
1071        uint32_t i;
1072
1073        if (!bat_priv->tt.local_hash)
1074                return;
1075
1076        hash = bat_priv->tt.local_hash;
1077
1078        for (i = 0; i < hash->size; i++) {
1079                head = &hash->table[i];
1080                list_lock = &hash->list_locks[i];
1081
1082                spin_lock_bh(list_lock);
1083                hlist_for_each_entry_safe(tt_common_entry, node_tmp,
1084                                          head, hash_entry) {
1085                        hlist_del_rcu(&tt_common_entry->hash_entry);
1086                        tt_local = container_of(tt_common_entry,
1087                                                struct batadv_tt_local_entry,
1088                                                common);
1089                        batadv_tt_local_entry_free_ref(tt_local);
1090                }
1091                spin_unlock_bh(list_lock);
1092        }
1093
1094        batadv_hash_destroy(hash);
1095
1096        bat_priv->tt.local_hash = NULL;
1097}
1098
1099static int batadv_tt_global_init(struct batadv_priv *bat_priv)
1100{
1101        if (bat_priv->tt.global_hash)
1102                return 0;
1103
1104        bat_priv->tt.global_hash = batadv_hash_new(1024);
1105
1106        if (!bat_priv->tt.global_hash)
1107                return -ENOMEM;
1108
1109        batadv_hash_set_lock_class(bat_priv->tt.global_hash,
1110                                   &batadv_tt_global_hash_lock_class_key);
1111
1112        return 0;
1113}
1114
1115static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
1116{
1117        struct batadv_tt_change_node *entry, *safe;
1118
1119        spin_lock_bh(&bat_priv->tt.changes_list_lock);
1120
1121        list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
1122                                 list) {
1123                list_del(&entry->list);
1124                kfree(entry);
1125        }
1126
1127        atomic_set(&bat_priv->tt.local_changes, 0);
1128        spin_unlock_bh(&bat_priv->tt.changes_list_lock);
1129}
1130
1131/* retrieves the orig_tt_list_entry belonging to orig_node from the
1132 * batadv_tt_global_entry list
1133 *
1134 * returns it with an increased refcounter, NULL if not found
1135 */
1136static struct batadv_tt_orig_list_entry *
1137batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
1138                                 const struct batadv_orig_node *orig_node)
1139{
1140        struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
1141        const struct hlist_head *head;
1142
1143        rcu_read_lock();
1144        head = &entry->orig_list;
1145        hlist_for_each_entry_rcu(tmp_orig_entry, head, list) {
1146                if (tmp_orig_entry->orig_node != orig_node)
1147                        continue;
1148                if (!atomic_inc_not_zero(&tmp_orig_entry->refcount))
1149                        continue;
1150
1151                orig_entry = tmp_orig_entry;
1152                break;
1153        }
1154        rcu_read_unlock();
1155
1156        return orig_entry;
1157}
1158
1159/* find out if an orig_node is already in the list of a tt_global_entry.
1160 * returns true if found, false otherwise
1161 */
1162static bool
1163batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
1164                                const struct batadv_orig_node *orig_node)
1165{
1166        struct batadv_tt_orig_list_entry *orig_entry;
1167        bool found = false;
1168
1169        orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
1170        if (orig_entry) {
1171                found = true;
1172                batadv_tt_orig_list_entry_free_ref(orig_entry);
1173        }
1174
1175        return found;
1176}
1177
1178static void
1179batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
1180                                struct batadv_orig_node *orig_node, int ttvn)
1181{
1182        struct batadv_tt_orig_list_entry *orig_entry;
1183
1184        orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
1185        if (orig_entry) {
1186                /* refresh the ttvn: the current value could be a bogus one that
1187                 * was added during a "temporary client detection"
1188                 */
1189                orig_entry->ttvn = ttvn;
1190                goto out;
1191        }
1192
1193        orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
1194        if (!orig_entry)
1195                goto out;
1196
1197        INIT_HLIST_NODE(&orig_entry->list);
1198        atomic_inc(&orig_node->refcount);
1199        batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
1200        orig_entry->orig_node = orig_node;
1201        orig_entry->ttvn = ttvn;
1202        atomic_set(&orig_entry->refcount, 2);
1203
1204        spin_lock_bh(&tt_global->list_lock);
1205        hlist_add_head_rcu(&orig_entry->list,
1206                           &tt_global->orig_list);
1207        spin_unlock_bh(&tt_global->list_lock);
1208out:
1209        if (orig_entry)
1210                batadv_tt_orig_list_entry_free_ref(orig_entry);
1211}
1212
1213/**
1214 * batadv_tt_global_add - add a new TT global entry or update an existing one
1215 * @bat_priv: the bat priv with all the soft interface information
1216 * @orig_node: the originator announcing the client
1217 * @tt_addr: the mac address of the non-mesh client
1218 * @vid: VLAN identifier
1219 * @flags: TT flags that have to be set for this non-mesh client
1220 * @ttvn: the tt version number ever announcing this non-mesh client
1221 *
1222 * Add a new TT global entry for the given originator. If the entry already
1223 * exists add a new reference to the given originator (a global entry can have
1224 * references to multiple originators) and adjust the flags attribute to reflect
1225 * the function argument.
1226 * If a TT local entry exists for this non-mesh client remove it.
1227 *
1228 * The caller must hold orig_node refcount.
1229 *
1230 * Return true if the new entry has been added, false otherwise
1231 */
1232static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
1233                                 struct batadv_orig_node *orig_node,
1234                                 const unsigned char *tt_addr,
1235                                 unsigned short vid, uint16_t flags,
1236                                 uint8_t ttvn)
1237{
1238        struct batadv_tt_global_entry *tt_global_entry;
1239        struct batadv_tt_local_entry *tt_local_entry;
1240        bool ret = false;
1241        int hash_added;
1242        struct batadv_tt_common_entry *common;
1243        uint16_t local_flags;
1244
1245        /* ignore global entries from backbone nodes */
1246        if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid))
1247                return true;
1248
1249        tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
1250        tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
1251
1252        /* if the node already has a local client for this entry, it has to wait
1253         * for a roaming advertisement instead of manually messing up the global
1254         * table
1255         */
1256        if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
1257            !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
1258                goto out;
1259
1260        if (!tt_global_entry) {
1261                tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
1262                if (!tt_global_entry)
1263                        goto out;
1264
1265                common = &tt_global_entry->common;
1266                memcpy(common->addr, tt_addr, ETH_ALEN);
1267                common->vid = vid;
1268
1269                common->flags = flags;
1270                tt_global_entry->roam_at = 0;
1271                /* node must store current time in case of roaming. This is
1272                 * needed to purge this entry out on timeout (if nobody claims
1273                 * it)
1274                 */
1275                if (flags & BATADV_TT_CLIENT_ROAM)
1276                        tt_global_entry->roam_at = jiffies;
1277                atomic_set(&common->refcount, 2);
1278                common->added_at = jiffies;
1279
1280                INIT_HLIST_HEAD(&tt_global_entry->orig_list);
1281                spin_lock_init(&tt_global_entry->list_lock);
1282
1283                hash_added = batadv_hash_add(bat_priv->tt.global_hash,
1284                                             batadv_compare_tt,
1285                                             batadv_choose_tt, common,
1286                                             &common->hash_entry);
1287
1288                if (unlikely(hash_added != 0)) {
1289                        /* remove the reference for the hash */
1290                        batadv_tt_global_entry_free_ref(tt_global_entry);
1291                        goto out_remove;
1292                }
1293        } else {
1294                common = &tt_global_entry->common;
1295                /* If there is already a global entry, we can use this one for
1296                 * our processing.
1297                 * But if we are trying to add a temporary client then here are
1298                 * two options at this point:
1299                 * 1) the global client is not a temporary client: the global
1300                 *    client has to be left as it is, temporary information
1301                 *    should never override any already known client state
1302                 * 2) the global client is a temporary client: purge the
1303                 *    originator list and add the new one orig_entry
1304                 */
1305                if (flags & BATADV_TT_CLIENT_TEMP) {
1306                        if (!(common->flags & BATADV_TT_CLIENT_TEMP))
1307                                goto out;
1308                        if (batadv_tt_global_entry_has_orig(tt_global_entry,
1309                                                            orig_node))
1310                                goto out_remove;
1311                        batadv_tt_global_del_orig_list(tt_global_entry);
1312                        goto add_orig_entry;
1313                }
1314
1315                /* if the client was temporary added before receiving the first
1316                 * OGM announcing it, we have to clear the TEMP flag
1317                 */
1318                common->flags &= ~BATADV_TT_CLIENT_TEMP;
1319
1320                /* the change can carry possible "attribute" flags like the
1321                 * TT_CLIENT_WIFI, therefore they have to be copied in the
1322                 * client entry
1323                 */
1324                tt_global_entry->common.flags |= flags;
1325
1326                /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
1327                 * one originator left in the list and we previously received a
1328                 * delete + roaming change for this originator.
1329                 *
1330                 * We should first delete the old originator before adding the
1331                 * new one.
1332                 */
1333                if (common->flags & BATADV_TT_CLIENT_ROAM) {
1334                        batadv_tt_global_del_orig_list(tt_global_entry);
1335                        common->flags &= ~BATADV_TT_CLIENT_ROAM;
1336                        tt_global_entry->roam_at = 0;
1337                }
1338        }
1339add_orig_entry:
1340        /* add the new orig_entry (if needed) or update it */
1341        batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
1342
1343        batadv_dbg(BATADV_DBG_TT, bat_priv,
1344                   "Creating new global tt entry: %pM (vid: %d, via %pM)\n",
1345                   common->addr, BATADV_PRINT_VID(common->vid),
1346                   orig_node->orig);
1347        ret = true;
1348
1349out_remove:
1350
1351        /* remove address from local hash if present */
1352        local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
1353                                             "global tt received",
1354                                             flags & BATADV_TT_CLIENT_ROAM);
1355        tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
1356
1357        if (!(flags & BATADV_TT_CLIENT_ROAM))
1358                /* this is a normal global add. Therefore the client is not in a
1359                 * roaming state anymore.
1360                 */
1361                tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
1362
1363out:
1364        if (tt_global_entry)
1365                batadv_tt_global_entry_free_ref(tt_global_entry);
1366        if (tt_local_entry)
1367                batadv_tt_local_entry_free_ref(tt_local_entry);
1368        return ret;
1369}
1370
1371/* batadv_transtable_best_orig - Get best originator list entry from tt entry
1372 * @bat_priv: the bat priv with all the soft interface information
1373 * @tt_global_entry: global translation table entry to be analyzed
1374 *
1375 * This functon assumes the caller holds rcu_read_lock().
1376 * Returns best originator list entry or NULL on errors.
1377 */
1378static struct batadv_tt_orig_list_entry *
1379batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1380                            struct batadv_tt_global_entry *tt_global_entry)
1381{
1382        struct batadv_neigh_node *router, *best_router = NULL;
1383        struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
1384        struct hlist_head *head;
1385        struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
1386
1387        head = &tt_global_entry->orig_list;
1388        hlist_for_each_entry_rcu(orig_entry, head, list) {
1389                router = batadv_orig_node_get_router(orig_entry->orig_node);
1390                if (!router)
1391                        continue;
1392
1393                if (best_router &&
1394                    bao->bat_neigh_cmp(router, best_router) <= 0) {
1395                        batadv_neigh_node_free_ref(router);
1396                        continue;
1397                }
1398
1399                /* release the refcount for the "old" best */
1400                if (best_router)
1401                        batadv_neigh_node_free_ref(best_router);
1402
1403                best_entry = orig_entry;
1404                best_router = router;
1405        }
1406
1407        if (best_router)
1408                batadv_neigh_node_free_ref(best_router);
1409
1410        return best_entry;
1411}
1412
1413/* batadv_tt_global_print_entry - print all orig nodes who announce the address
1414 * for this global entry
1415 * @bat_priv: the bat priv with all the soft interface information
1416 * @tt_global_entry: global translation table entry to be printed
1417 * @seq: debugfs table seq_file struct
1418 *
1419 * This functon assumes the caller holds rcu_read_lock().
1420 */
1421static void
1422batadv_tt_global_print_entry(struct batadv_priv *bat_priv,
1423                             struct batadv_tt_global_entry *tt_global_entry,
1424                             struct seq_file *seq)
1425{
1426        struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
1427        struct batadv_tt_common_entry *tt_common_entry;
1428        struct batadv_orig_node_vlan *vlan;
1429        struct hlist_head *head;
1430        uint8_t last_ttvn;
1431        uint16_t flags;
1432
1433        tt_common_entry = &tt_global_entry->common;
1434        flags = tt_common_entry->flags;
1435
1436        best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
1437        if (best_entry) {
1438                vlan = batadv_orig_node_vlan_get(best_entry->orig_node,
1439                                                 tt_common_entry->vid);
1440                if (!vlan) {
1441                        seq_printf(seq,
1442                                   " * Cannot retrieve VLAN %d for originator %pM\n",
1443                                   BATADV_PRINT_VID(tt_common_entry->vid),
1444                                   best_entry->orig_node->orig);
1445                        goto print_list;
1446                }
1447
1448                last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
1449                seq_printf(seq,
1450                           " %c %pM %4i   (%3u) via %pM     (%3u)   (%#.8x) [%c%c%c]\n",
1451                           '*', tt_global_entry->common.addr,
1452                           BATADV_PRINT_VID(tt_global_entry->common.vid),
1453                           best_entry->ttvn, best_entry->orig_node->orig,
1454                           last_ttvn, vlan->tt.crc,
1455                           (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1456                           (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1457                           (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1458
1459                batadv_orig_node_vlan_free_ref(vlan);
1460        }
1461
1462print_list:
1463        head = &tt_global_entry->orig_list;
1464
1465        hlist_for_each_entry_rcu(orig_entry, head, list) {
1466                if (best_entry == orig_entry)
1467                        continue;
1468
1469                vlan = batadv_orig_node_vlan_get(orig_entry->orig_node,
1470                                                 tt_common_entry->vid);
1471                if (!vlan) {
1472                        seq_printf(seq,
1473                                   " + Cannot retrieve VLAN %d for originator %pM\n",
1474                                   BATADV_PRINT_VID(tt_common_entry->vid),
1475                                   orig_entry->orig_node->orig);
1476                        continue;
1477                }
1478
1479                last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
1480                seq_printf(seq,
1481                           " %c %pM %4d   (%3u) via %pM     (%3u)   (%#.8x) [%c%c%c]\n",
1482                           '+', tt_global_entry->common.addr,
1483                           BATADV_PRINT_VID(tt_global_entry->common.vid),
1484                           orig_entry->ttvn, orig_entry->orig_node->orig,
1485                           last_ttvn, vlan->tt.crc,
1486                           (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1487                           (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1488                           (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1489
1490                batadv_orig_node_vlan_free_ref(vlan);
1491        }
1492}
1493
1494int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
1495{
1496        struct net_device *net_dev = (struct net_device *)seq->private;
1497        struct batadv_priv *bat_priv = netdev_priv(net_dev);
1498        struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1499        struct batadv_tt_common_entry *tt_common_entry;
1500        struct batadv_tt_global_entry *tt_global;
1501        struct batadv_hard_iface *primary_if;
1502        struct hlist_head *head;
1503        uint32_t i;
1504
1505        primary_if = batadv_seq_print_text_primary_if_get(seq);
1506        if (!primary_if)
1507                goto out;
1508
1509        seq_printf(seq,
1510                   "Globally announced TT entries received via the mesh %s\n",
1511                   net_dev->name);
1512        seq_printf(seq, "       %-13s  %s  %s       %-15s %s (%-10s) %s\n",
1513                   "Client", "VID", "(TTVN)", "Originator", "(Curr TTVN)",
1514                   "CRC", "Flags");
1515
1516        for (i = 0; i < hash->size; i++) {
1517                head = &hash->table[i];
1518
1519                rcu_read_lock();
1520                hlist_for_each_entry_rcu(tt_common_entry,
1521                                         head, hash_entry) {
1522                        tt_global = container_of(tt_common_entry,
1523                                                 struct batadv_tt_global_entry,
1524                                                 common);
1525                        batadv_tt_global_print_entry(bat_priv, tt_global, seq);
1526                }
1527                rcu_read_unlock();
1528        }
1529out:
1530        if (primary_if)
1531                batadv_hardif_free_ref(primary_if);
1532        return 0;
1533}
1534
1535/* deletes the orig list of a tt_global_entry */
1536static void
1537batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
1538{
1539        struct hlist_head *head;
1540        struct hlist_node *safe;
1541        struct batadv_tt_orig_list_entry *orig_entry;
1542
1543        spin_lock_bh(&tt_global_entry->list_lock);
1544        head = &tt_global_entry->orig_list;
1545        hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1546                hlist_del_rcu(&orig_entry->list);
1547                batadv_tt_global_size_dec(orig_entry->orig_node,
1548                                          tt_global_entry->common.vid);
1549                batadv_tt_orig_list_entry_free_ref(orig_entry);
1550        }
1551        spin_unlock_bh(&tt_global_entry->list_lock);
1552}
1553
1554static void
1555batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
1556                                struct batadv_tt_global_entry *tt_global_entry,
1557                                struct batadv_orig_node *orig_node,
1558                                const char *message)
1559{
1560        struct hlist_head *head;
1561        struct hlist_node *safe;
1562        struct batadv_tt_orig_list_entry *orig_entry;
1563        unsigned short vid;
1564
1565        spin_lock_bh(&tt_global_entry->list_lock);
1566        head = &tt_global_entry->orig_list;
1567        hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1568                if (orig_entry->orig_node == orig_node) {
1569                        vid = tt_global_entry->common.vid;
1570                        batadv_dbg(BATADV_DBG_TT, bat_priv,
1571                                   "Deleting %pM from global tt entry %pM (vid: %d): %s\n",
1572                                   orig_node->orig,
1573                                   tt_global_entry->common.addr,
1574                                   BATADV_PRINT_VID(vid), message);
1575                        hlist_del_rcu(&orig_entry->list);
1576                        batadv_tt_global_size_dec(orig_node,
1577                                                  tt_global_entry->common.vid);
1578                        batadv_tt_orig_list_entry_free_ref(orig_entry);
1579                }
1580        }
1581        spin_unlock_bh(&tt_global_entry->list_lock);
1582}
1583
1584/* If the client is to be deleted, we check if it is the last origantor entry
1585 * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
1586 * timer, otherwise we simply remove the originator scheduled for deletion.
1587 */
1588static void
1589batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
1590                             struct batadv_tt_global_entry *tt_global_entry,
1591                             struct batadv_orig_node *orig_node,
1592                             const char *message)
1593{
1594        bool last_entry = true;
1595        struct hlist_head *head;
1596        struct batadv_tt_orig_list_entry *orig_entry;
1597
1598        /* no local entry exists, case 1:
1599         * Check if this is the last one or if other entries exist.
1600         */
1601
1602        rcu_read_lock();
1603        head = &tt_global_entry->orig_list;
1604        hlist_for_each_entry_rcu(orig_entry, head, list) {
1605                if (orig_entry->orig_node != orig_node) {
1606                        last_entry = false;
1607                        break;
1608                }
1609        }
1610        rcu_read_unlock();
1611
1612        if (last_entry) {
1613                /* its the last one, mark for roaming. */
1614                tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
1615                tt_global_entry->roam_at = jiffies;
1616        } else
1617                /* there is another entry, we can simply delete this
1618                 * one and can still use the other one.
1619                 */
1620                batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1621                                                orig_node, message);
1622}
1623
1624/**
1625 * batadv_tt_global_del - remove a client from the global table
1626 * @bat_priv: the bat priv with all the soft interface information
1627 * @orig_node: an originator serving this client
1628 * @addr: the mac address of the client
1629 * @vid: VLAN identifier
1630 * @message: a message explaining the reason for deleting the client to print
1631 *  for debugging purpose
1632 * @roaming: true if the deletion has been triggered by a roaming event
1633 */
1634static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1635                                 struct batadv_orig_node *orig_node,
1636                                 const unsigned char *addr, unsigned short vid,
1637                                 const char *message, bool roaming)
1638{
1639        struct batadv_tt_global_entry *tt_global_entry;
1640        struct batadv_tt_local_entry *local_entry = NULL;
1641
1642        tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1643        if (!tt_global_entry)
1644                goto out;
1645
1646        if (!roaming) {
1647                batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1648                                                orig_node, message);
1649
1650                if (hlist_empty(&tt_global_entry->orig_list))
1651                        batadv_tt_global_free(bat_priv, tt_global_entry,
1652                                              message);
1653
1654                goto out;
1655        }
1656
1657        /* if we are deleting a global entry due to a roam
1658         * event, there are two possibilities:
1659         * 1) the client roamed from node A to node B => if there
1660         *    is only one originator left for this client, we mark
1661         *    it with BATADV_TT_CLIENT_ROAM, we start a timer and we
1662         *    wait for node B to claim it. In case of timeout
1663         *    the entry is purged.
1664         *
1665         *    If there are other originators left, we directly delete
1666         *    the originator.
1667         * 2) the client roamed to us => we can directly delete
1668         *    the global entry, since it is useless now.
1669         */
1670        local_entry = batadv_tt_local_hash_find(bat_priv,
1671                                                tt_global_entry->common.addr,
1672                                                vid);
1673        if (local_entry) {
1674                /* local entry exists, case 2: client roamed to us. */
1675                batadv_tt_global_del_orig_list(tt_global_entry);
1676                batadv_tt_global_free(bat_priv, tt_global_entry, message);
1677        } else
1678                /* no local entry exists, case 1: check for roaming */
1679                batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
1680                                             orig_node, message);
1681
1682
1683out:
1684        if (tt_global_entry)
1685                batadv_tt_global_entry_free_ref(tt_global_entry);
1686        if (local_entry)
1687                batadv_tt_local_entry_free_ref(local_entry);
1688}
1689
1690/**
1691 * batadv_tt_global_del_orig - remove all the TT global entries belonging to the
1692 *  given originator matching the provided vid
1693 * @bat_priv: the bat priv with all the soft interface information
1694 * @orig_node: the originator owning the entries to remove
1695 * @match_vid: the VLAN identifier to match. If negative all the entries will be
1696 *  removed
1697 * @message: debug message to print as "reason"
1698 */
1699void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1700                               struct batadv_orig_node *orig_node,
1701                               int32_t match_vid,
1702                               const char *message)
1703{
1704        struct batadv_tt_global_entry *tt_global;
1705        struct batadv_tt_common_entry *tt_common_entry;
1706        uint32_t i;
1707        struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1708        struct hlist_node *safe;
1709        struct hlist_head *head;
1710        spinlock_t *list_lock; /* protects write access to the hash lists */
1711        unsigned short vid;
1712
1713        if (!hash)
1714                return;
1715
1716        for (i = 0; i < hash->size; i++) {
1717                head = &hash->table[i];
1718                list_lock = &hash->list_locks[i];
1719
1720                spin_lock_bh(list_lock);
1721                hlist_for_each_entry_safe(tt_common_entry, safe,
1722                                          head, hash_entry) {
1723                        /* remove only matching entries */
1724                        if (match_vid >= 0 && tt_common_entry->vid != match_vid)
1725                                continue;
1726
1727                        tt_global = container_of(tt_common_entry,
1728                                                 struct batadv_tt_global_entry,
1729                                                 common);
1730
1731                        batadv_tt_global_del_orig_entry(bat_priv, tt_global,
1732                                                        orig_node, message);
1733
1734                        if (hlist_empty(&tt_global->orig_list)) {
1735                                vid = tt_global->common.vid;
1736                                batadv_dbg(BATADV_DBG_TT, bat_priv,
1737                                           "Deleting global tt entry %pM (vid: %d): %s\n",
1738                                           tt_global->common.addr,
1739                                           BATADV_PRINT_VID(vid), message);
1740                                hlist_del_rcu(&tt_common_entry->hash_entry);
1741                                batadv_tt_global_entry_free_ref(tt_global);
1742                        }
1743                }
1744                spin_unlock_bh(list_lock);
1745        }
1746        orig_node->tt_initialised = false;
1747}
1748
1749static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
1750                                      char **msg)
1751{
1752        bool purge = false;
1753        unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
1754        unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
1755
1756        if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
1757            batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
1758                purge = true;
1759                *msg = "Roaming timeout\n";
1760        }
1761
1762        if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
1763            batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
1764                purge = true;
1765                *msg = "Temporary client timeout\n";
1766        }
1767
1768        return purge;
1769}
1770
1771static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
1772{
1773        struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1774        struct hlist_head *head;
1775        struct hlist_node *node_tmp;
1776        spinlock_t *list_lock; /* protects write access to the hash lists */
1777        uint32_t i;
1778        char *msg = NULL;
1779        struct batadv_tt_common_entry *tt_common;
1780        struct batadv_tt_global_entry *tt_global;
1781
1782        for (i = 0; i < hash->size; i++) {
1783                head = &hash->table[i];
1784                list_lock = &hash->list_locks[i];
1785
1786                spin_lock_bh(list_lock);
1787                hlist_for_each_entry_safe(tt_common, node_tmp, head,
1788                                          hash_entry) {
1789                        tt_global = container_of(tt_common,
1790                                                 struct batadv_tt_global_entry,
1791                                                 common);
1792
1793                        if (!batadv_tt_global_to_purge(tt_global, &msg))
1794                                continue;
1795
1796                        batadv_dbg(BATADV_DBG_TT, bat_priv,
1797                                   "Deleting global tt entry %pM (vid: %d): %s\n",
1798                                   tt_global->common.addr,
1799                                   BATADV_PRINT_VID(tt_global->common.vid),
1800                                   msg);
1801
1802                        hlist_del_rcu(&tt_common->hash_entry);
1803
1804                        batadv_tt_global_entry_free_ref(tt_global);
1805                }
1806                spin_unlock_bh(list_lock);
1807        }
1808}
1809
1810static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1811{
1812        struct batadv_hashtable *hash;
1813        spinlock_t *list_lock; /* protects write access to the hash lists */
1814        struct batadv_tt_common_entry *tt_common_entry;
1815        struct batadv_tt_global_entry *tt_global;
1816        struct hlist_node *node_tmp;
1817        struct hlist_head *head;
1818        uint32_t i;
1819
1820        if (!bat_priv->tt.global_hash)
1821                return;
1822
1823        hash = bat_priv->tt.global_hash;
1824
1825        for (i = 0; i < hash->size; i++) {
1826                head = &hash->table[i];
1827                list_lock = &hash->list_locks[i];
1828
1829                spin_lock_bh(list_lock);
1830                hlist_for_each_entry_safe(tt_common_entry, node_tmp,
1831                                          head, hash_entry) {
1832                        hlist_del_rcu(&tt_common_entry->hash_entry);
1833                        tt_global = container_of(tt_common_entry,
1834                                                 struct batadv_tt_global_entry,
1835                                                 common);
1836                        batadv_tt_global_entry_free_ref(tt_global);
1837                }
1838                spin_unlock_bh(list_lock);
1839        }
1840
1841        batadv_hash_destroy(hash);
1842
1843        bat_priv->tt.global_hash = NULL;
1844}
1845
1846static bool
1847_batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
1848                       struct batadv_tt_global_entry *tt_global_entry)
1849{
1850        bool ret = false;
1851
1852        if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
1853            tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
1854                ret = true;
1855
1856        return ret;
1857}
1858
1859/**
1860 * batadv_transtable_search - get the mesh destination for a given client
1861 * @bat_priv: the bat priv with all the soft interface information
1862 * @src: mac address of the source client
1863 * @addr: mac address of the destination client
1864 * @vid: VLAN identifier
1865 *
1866 * Returns a pointer to the originator that was selected as destination in the
1867 * mesh for contacting the client 'addr', NULL otherwise.
1868 * In case of multiple originators serving the same client, the function returns
1869 * the best one (best in terms of metric towards the destination node).
1870 *
1871 * If the two clients are AP isolated the function returns NULL.
1872 */
1873struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1874                                                  const uint8_t *src,
1875                                                  const uint8_t *addr,
1876                                                  unsigned short vid)
1877{
1878        struct batadv_tt_local_entry *tt_local_entry = NULL;
1879        struct batadv_tt_global_entry *tt_global_entry = NULL;
1880        struct batadv_orig_node *orig_node = NULL;
1881        struct batadv_tt_orig_list_entry *best_entry;
1882        bool ap_isolation_enabled = false;
1883        struct batadv_softif_vlan *vlan;
1884
1885        /* if the AP isolation is requested on a VLAN, then check for its
1886         * setting in the proper VLAN private data structure
1887         */
1888        vlan = batadv_softif_vlan_get(bat_priv, vid);
1889        if (vlan) {
1890                ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
1891                batadv_softif_vlan_free_ref(vlan);
1892        }
1893
1894        if (src && ap_isolation_enabled) {
1895                tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
1896                if (!tt_local_entry ||
1897                    (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
1898                        goto out;
1899        }
1900
1901        tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1902        if (!tt_global_entry)
1903                goto out;
1904
1905        /* check whether the clients should not communicate due to AP
1906         * isolation
1907         */
1908        if (tt_local_entry &&
1909            _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
1910                goto out;
1911
1912        rcu_read_lock();
1913        best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
1914        /* found anything? */
1915        if (best_entry)
1916                orig_node = best_entry->orig_node;
1917        if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
1918                orig_node = NULL;
1919        rcu_read_unlock();
1920
1921out:
1922        if (tt_global_entry)
1923                batadv_tt_global_entry_free_ref(tt_global_entry);
1924        if (tt_local_entry)
1925                batadv_tt_local_entry_free_ref(tt_local_entry);
1926
1927        return orig_node;
1928}
1929
1930/**
1931 * batadv_tt_global_crc - calculates the checksum of the local table belonging
1932 *  to the given orig_node
1933 * @bat_priv: the bat priv with all the soft interface information
1934 * @orig_node: originator for which the CRC should be computed
1935 * @vid: VLAN identifier for which the CRC32 has to be computed
1936 *
1937 * This function computes the checksum for the global table corresponding to a
1938 * specific originator. In particular, the checksum is computed as follows: For
1939 * each client connected to the originator the CRC32C of the MAC address and the
1940 * VID is computed and then all the CRC32Cs of the various clients are xor'ed
1941 * together.
1942 *
1943 * The idea behind is that CRC32C should be used as much as possible in order to
1944 * produce a unique hash of the table, but since the order which is used to feed
1945 * the CRC32C function affects the result and since every node in the network
1946 * probably sorts the clients differently, the hash function cannot be directly
1947 * computed over the entire table. Hence the CRC32C is used only on
1948 * the single client entry, while all the results are then xor'ed together
1949 * because the XOR operation can combine them all while trying to reduce the
1950 * noise as much as possible.
1951 *
1952 * Returns the checksum of the global table of a given originator.
1953 */
1954static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1955                                     struct batadv_orig_node *orig_node,
1956                                     unsigned short vid)
1957{
1958        struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1959        struct batadv_tt_common_entry *tt_common;
1960        struct batadv_tt_global_entry *tt_global;
1961        struct hlist_head *head;
1962        uint32_t i, crc_tmp, crc = 0;
1963        uint8_t flags;
1964
1965        for (i = 0; i < hash->size; i++) {
1966                head = &hash->table[i];
1967
1968                rcu_read_lock();
1969                hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
1970                        tt_global = container_of(tt_common,
1971                                                 struct batadv_tt_global_entry,
1972                                                 common);
1973                        /* compute the CRC only for entries belonging to the
1974                         * VLAN identified by the vid passed as parameter
1975                         */
1976                        if (tt_common->vid != vid)
1977                                continue;
1978
1979                        /* Roaming clients are in the global table for
1980                         * consistency only. They don't have to be
1981                         * taken into account while computing the
1982                         * global crc
1983                         */
1984                        if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
1985                                continue;
1986                        /* Temporary clients have not been announced yet, so
1987                         * they have to be skipped while computing the global
1988                         * crc
1989                         */
1990                        if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
1991                                continue;
1992
1993                        /* find out if this global entry is announced by this
1994                         * originator
1995                         */
1996                        if (!batadv_tt_global_entry_has_orig(tt_global,
1997                                                             orig_node))
1998                                continue;
1999
2000                        crc_tmp = crc32c(0, &tt_common->vid,
2001                                         sizeof(tt_common->vid));
2002
2003                        /* compute the CRC on flags that have to be kept in sync
2004                         * among nodes
2005                         */
2006                        flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2007                        crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2008
2009                        crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2010                }
2011                rcu_read_unlock();
2012        }
2013
2014        return crc;
2015}
2016
2017/**
2018 * batadv_tt_local_crc - calculates the checksum of the local table
2019 * @bat_priv: the bat priv with all the soft interface information
2020 * @vid: VLAN identifier for which the CRC32 has to be computed
2021 *
2022 * For details about the computation, please refer to the documentation for
2023 * batadv_tt_global_crc().
2024 *
2025 * Returns the checksum of the local table
2026 */
2027static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
2028                                    unsigned short vid)
2029{
2030        struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2031        struct batadv_tt_common_entry *tt_common;
2032        struct hlist_head *head;
2033        uint32_t i, crc_tmp, crc = 0;
2034        uint8_t flags;
2035
2036        for (i = 0; i < hash->size; i++) {
2037                head = &hash->table[i];
2038
2039                rcu_read_lock();
2040                hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
2041                        /* compute the CRC only for entries belonging to the
2042                         * VLAN identified by vid
2043                         */
2044                        if (tt_common->vid != vid)
2045                                continue;
2046
2047                        /* not yet committed clients have not to be taken into
2048                         * account while computing the CRC
2049                         */
2050                        if (tt_common->flags & BATADV_TT_CLIENT_NEW)
2051                                continue;
2052
2053                        crc_tmp = crc32c(0, &tt_common->vid,
2054                                         sizeof(tt_common->vid));
2055
2056                        /* compute the CRC on flags that have to be kept in sync
2057                         * among nodes
2058                         */
2059                        flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2060                        crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2061
2062                        crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2063                }
2064                rcu_read_unlock();
2065        }
2066
2067        return crc;
2068}
2069
2070static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
2071{
2072        struct batadv_tt_req_node *node, *safe;
2073
2074        spin_lock_bh(&bat_priv->tt.req_list_lock);
2075
2076        list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2077                list_del(&node->list);
2078                kfree(node);
2079        }
2080
2081        spin_unlock_bh(&bat_priv->tt.req_list_lock);
2082}
2083
2084static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
2085                                       struct batadv_orig_node *orig_node,
2086                                       const void *tt_buff,
2087                                       uint16_t tt_buff_len)
2088{
2089        /* Replace the old buffer only if I received something in the
2090         * last OGM (the OGM could carry no changes)
2091         */
2092        spin_lock_bh(&orig_node->tt_buff_lock);
2093        if (tt_buff_len > 0) {
2094                kfree(orig_node->tt_buff);
2095                orig_node->tt_buff_len = 0;
2096                orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
2097                if (orig_node->tt_buff) {
2098                        memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
2099                        orig_node->tt_buff_len = tt_buff_len;
2100                }
2101        }
2102        spin_unlock_bh(&orig_node->tt_buff_lock);
2103}
2104
2105static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
2106{
2107        struct batadv_tt_req_node *node, *safe;
2108
2109        spin_lock_bh(&bat_priv->tt.req_list_lock);
2110        list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2111                if (batadv_has_timed_out(node->issued_at,
2112                                         BATADV_TT_REQUEST_TIMEOUT)) {
2113                        list_del(&node->list);
2114                        kfree(node);
2115                }
2116        }
2117        spin_unlock_bh(&bat_priv->tt.req_list_lock);
2118}
2119
2120/* returns the pointer to the new tt_req_node struct if no request
2121 * has already been issued for this orig_node, NULL otherwise
2122 */
2123static struct batadv_tt_req_node *
2124batadv_new_tt_req_node(struct batadv_priv *bat_priv,
2125                       struct batadv_orig_node *orig_node)
2126{
2127        struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
2128
2129        spin_lock_bh(&bat_priv->tt.req_list_lock);
2130        list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
2131                if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
2132                    !batadv_has_timed_out(tt_req_node_tmp->issued_at,
2133                                          BATADV_TT_REQUEST_TIMEOUT))
2134                        goto unlock;
2135        }
2136
2137        tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
2138        if (!tt_req_node)
2139                goto unlock;
2140
2141        memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
2142        tt_req_node->issued_at = jiffies;
2143
2144        list_add(&tt_req_node->list, &bat_priv->tt.req_list);
2145unlock:
2146        spin_unlock_bh(&bat_priv->tt.req_list_lock);
2147        return tt_req_node;
2148}
2149
2150/**
2151 * batadv_tt_local_valid - verify that given tt entry is a valid one
2152 * @entry_ptr: to be checked local tt entry
2153 * @data_ptr: not used but definition required to satisfy the callback prototype
2154 *
2155 * Returns 1 if the entry is a valid, 0 otherwise.
2156 */
2157static int batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
2158{
2159        const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2160
2161        if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
2162                return 0;
2163        return 1;
2164}
2165
2166static int batadv_tt_global_valid(const void *entry_ptr,
2167                                  const void *data_ptr)
2168{
2169        const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2170        const struct batadv_tt_global_entry *tt_global_entry;
2171        const struct batadv_orig_node *orig_node = data_ptr;
2172
2173        if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
2174            tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
2175                return 0;
2176
2177        tt_global_entry = container_of(tt_common_entry,
2178                                       struct batadv_tt_global_entry,
2179                                       common);
2180
2181        return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
2182}
2183
2184/**
2185 * batadv_tt_tvlv_generate - fill the tvlv buff with the tt entries from the
2186 *  specified tt hash
2187 * @bat_priv: the bat priv with all the soft interface information
2188 * @hash: hash table containing the tt entries
2189 * @tt_len: expected tvlv tt data buffer length in number of bytes
2190 * @tvlv_buff: pointer to the buffer to fill with the TT data
2191 * @valid_cb: function to filter tt change entries
2192 * @cb_data: data passed to the filter function as argument
2193 */
2194static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2195                                    struct batadv_hashtable *hash,
2196                                    void *tvlv_buff, uint16_t tt_len,
2197                                    int (*valid_cb)(const void *, const void *),
2198                                    void *cb_data)
2199{
2200        struct batadv_tt_common_entry *tt_common_entry;
2201        struct batadv_tvlv_tt_change *tt_change;
2202        struct hlist_head *head;
2203        uint16_t tt_tot, tt_num_entries = 0;
2204        uint32_t i;
2205
2206        tt_tot = batadv_tt_entries(tt_len);
2207        tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
2208
2209        rcu_read_lock();
2210        for (i = 0; i < hash->size; i++) {
2211                head = &hash->table[i];
2212
2213                hlist_for_each_entry_rcu(tt_common_entry,
2214                                         head, hash_entry) {
2215                        if (tt_tot == tt_num_entries)
2216                                break;
2217
2218                        if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
2219                                continue;
2220
2221                        memcpy(tt_change->addr, tt_common_entry->addr,
2222                               ETH_ALEN);
2223                        tt_change->flags = tt_common_entry->flags;
2224                        tt_change->vid = htons(tt_common_entry->vid);
2225                        memset(tt_change->reserved, 0,
2226                               sizeof(tt_change->reserved));
2227
2228                        tt_num_entries++;
2229                        tt_change++;
2230                }
2231        }
2232        rcu_read_unlock();
2233}
2234
2235/**
2236 * batadv_tt_global_check_crc - check if all the CRCs are correct
2237 * @orig_node: originator for which the CRCs have to be checked
2238 * @tt_vlan: pointer to the first tvlv VLAN entry
2239 * @num_vlan: number of tvlv VLAN entries
2240 * @create: if true, create VLAN objects if not found
2241 *
2242 * Return true if all the received CRCs match the locally stored ones, false
2243 * otherwise
2244 */
2245static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
2246                                       struct batadv_tvlv_tt_vlan_data *tt_vlan,
2247                                       uint16_t num_vlan)
2248{
2249        struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
2250        struct batadv_orig_node_vlan *vlan;
2251        int i;
2252
2253        /* check if each received CRC matches the locally stored one */
2254        for (i = 0; i < num_vlan; i++) {
2255                tt_vlan_tmp = tt_vlan + i;
2256
2257                /* if orig_node is a backbone node for this VLAN, don't check
2258                 * the CRC as we ignore all the global entries over it
2259                 */
2260                if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv,
2261                                                   orig_node->orig,
2262                                                   ntohs(tt_vlan_tmp->vid)))
2263                        continue;
2264
2265                vlan = batadv_orig_node_vlan_get(orig_node,
2266                                                 ntohs(tt_vlan_tmp->vid));
2267                if (!vlan)
2268                        return false;
2269
2270                if (vlan->tt.crc != ntohl(tt_vlan_tmp->crc))
2271                        return false;
2272        }
2273
2274        return true;
2275}
2276
2277/**
2278 * batadv_tt_local_update_crc - update all the local CRCs
2279 * @bat_priv: the bat priv with all the soft interface information
2280 */
2281static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv)
2282{
2283        struct batadv_softif_vlan *vlan;
2284
2285        /* recompute the global CRC for each VLAN */
2286        rcu_read_lock();
2287        hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
2288                vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid);
2289        }
2290        rcu_read_unlock();
2291}
2292
2293/**
2294 * batadv_tt_global_update_crc - update all the global CRCs for this orig_node
2295 * @bat_priv: the bat priv with all the soft interface information
2296 * @orig_node: the orig_node for which the CRCs have to be updated
2297 */
2298static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv,
2299                                        struct batadv_orig_node *orig_node)
2300{
2301        struct batadv_orig_node_vlan *vlan;
2302        uint32_t crc;
2303
2304        /* recompute the global CRC for each VLAN */
2305        rcu_read_lock();
2306        list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
2307                /* if orig_node is a backbone node for this VLAN, don't compute
2308                 * the CRC as we ignore all the global entries over it
2309                 */
2310                if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig,
2311                                                   vlan->vid))
2312                        continue;
2313
2314                crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid);
2315                vlan->tt.crc = crc;
2316        }
2317        rcu_read_unlock();
2318}
2319
2320/**
2321 * batadv_send_tt_request - send a TT Request message to a given node
2322 * @bat_priv: the bat priv with all the soft interface information
2323 * @dst_orig_node: the destination of the message
2324 * @ttvn: the version number that the source of the message is looking for
2325 * @tt_vlan: pointer to the first tvlv VLAN object to request
2326 * @num_vlan: number of tvlv VLAN entries
2327 * @full_table: ask for the entire translation table if true, while only for the
2328 *  last TT diff otherwise
2329 */
2330static int batadv_send_tt_request(struct batadv_priv *bat_priv,
2331                                  struct batadv_orig_node *dst_orig_node,
2332                                  uint8_t ttvn,
2333                                  struct batadv_tvlv_tt_vlan_data *tt_vlan,
2334                                  uint16_t num_vlan, bool full_table)
2335{
2336        struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2337        struct batadv_tt_req_node *tt_req_node = NULL;
2338        struct batadv_tvlv_tt_vlan_data *tt_vlan_req;
2339        struct batadv_hard_iface *primary_if;
2340        bool ret = false;
2341        int i, size;
2342
2343        primary_if = batadv_primary_if_get_selected(bat_priv);
2344        if (!primary_if)
2345                goto out;
2346
2347        /* The new tt_req will be issued only if I'm not waiting for a
2348         * reply from the same orig_node yet
2349         */
2350        tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node);
2351        if (!tt_req_node)
2352                goto out;
2353
2354        size = sizeof(*tvlv_tt_data) + sizeof(*tt_vlan_req) * num_vlan;
2355        tvlv_tt_data = kzalloc(size, GFP_ATOMIC);
2356        if (!tvlv_tt_data)
2357                goto out;
2358
2359        tvlv_tt_data->flags = BATADV_TT_REQUEST;
2360        tvlv_tt_data->ttvn = ttvn;
2361        tvlv_tt_data->num_vlan = htons(num_vlan);
2362
2363        /* send all the CRCs within the request. This is needed by intermediate
2364         * nodes to ensure they have the correct table before replying
2365         */
2366        tt_vlan_req = (struct batadv_tvlv_tt_vlan_data *)(tvlv_tt_data + 1);
2367        for (i = 0; i < num_vlan; i++) {
2368                tt_vlan_req->vid = tt_vlan->vid;
2369                tt_vlan_req->crc = tt_vlan->crc;
2370
2371                tt_vlan_req++;
2372                tt_vlan++;
2373        }
2374
2375        if (full_table)
2376                tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2377
2378        batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
2379                   dst_orig_node->orig, full_table ? 'F' : '.');
2380
2381        batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
2382        batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2383                                 dst_orig_node->orig, BATADV_TVLV_TT, 1,
2384                                 tvlv_tt_data, size);
2385        ret = true;
2386
2387out:
2388        if (primary_if)
2389                batadv_hardif_free_ref(primary_if);
2390        if (ret && tt_req_node) {
2391                spin_lock_bh(&bat_priv->tt.req_list_lock);
2392                list_del(&tt_req_node->list);
2393                spin_unlock_bh(&bat_priv->tt.req_list_lock);
2394                kfree(tt_req_node);
2395        }
2396        kfree(tvlv_tt_data);
2397        return ret;
2398}
2399
2400/**
2401 * batadv_send_other_tt_response - send reply to tt request concerning another
2402 *  node's translation table
2403 * @bat_priv: the bat priv with all the soft interface information
2404 * @tt_data: tt data containing the tt request information
2405 * @req_src: mac address of tt request sender
2406 * @req_dst: mac address of tt request recipient
2407 *
2408 * Returns true if tt request reply was sent, false otherwise.
2409 */
2410static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
2411                                          struct batadv_tvlv_tt_data *tt_data,
2412                                          uint8_t *req_src, uint8_t *req_dst)
2413{
2414        struct batadv_orig_node *req_dst_orig_node;
2415        struct batadv_orig_node *res_dst_orig_node = NULL;
2416        struct batadv_tvlv_tt_change *tt_change;
2417        struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2418        struct batadv_tvlv_tt_vlan_data *tt_vlan;
2419        bool ret = false, full_table;
2420        uint8_t orig_ttvn, req_ttvn;
2421        uint16_t tvlv_len;
2422        int32_t tt_len;
2423
2424        batadv_dbg(BATADV_DBG_TT, bat_priv,
2425                   "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
2426                   req_src, tt_data->ttvn, req_dst,
2427                   (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2428
2429        /* Let's get the orig node of the REAL destination */
2430        req_dst_orig_node = batadv_orig_hash_find(bat_priv, req_dst);
2431        if (!req_dst_orig_node)
2432                goto out;
2433
2434        res_dst_orig_node = batadv_orig_hash_find(bat_priv, req_src);
2435        if (!res_dst_orig_node)
2436                goto out;
2437
2438        orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
2439        req_ttvn = tt_data->ttvn;
2440
2441        tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
2442        /* this node doesn't have the requested data */
2443        if (orig_ttvn != req_ttvn ||
2444            !batadv_tt_global_check_crc(req_dst_orig_node, tt_vlan,
2445                                        ntohs(tt_data->num_vlan)))
2446                goto out;
2447
2448        /* If the full table has been explicitly requested */
2449        if (tt_data->flags & BATADV_TT_FULL_TABLE ||
2450            !req_dst_orig_node->tt_buff)
2451                full_table = true;
2452        else
2453                full_table = false;
2454
2455        /* TT fragmentation hasn't been implemented yet, so send as many
2456         * TT entries fit a single packet as possible only
2457         */
2458        if (!full_table) {
2459                spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
2460                tt_len = req_dst_orig_node->tt_buff_len;
2461
2462                tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
2463                                                              &tvlv_tt_data,
2464                                                              &tt_change,
2465                                                              &tt_len);
2466                if (!tt_len)
2467                        goto unlock;
2468
2469                /* Copy the last orig_node's OGM buffer */
2470                memcpy(tt_change, req_dst_orig_node->tt_buff,
2471                       req_dst_orig_node->tt_buff_len);
2472                spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
2473        } else {
2474                /* allocate the tvlv, put the tt_data and all the tt_vlan_data
2475                 * in the initial part
2476                 */
2477                tt_len = -1;
2478                tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
2479                                                              &tvlv_tt_data,
2480                                                              &tt_change,
2481                                                              &tt_len);
2482                if (!tt_len)
2483                        goto out;
2484
2485                /* fill the rest of the tvlv with the real TT entries */
2486                batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash,
2487                                        tt_change, tt_len,
2488                                        batadv_tt_global_valid,
2489                                        req_dst_orig_node);
2490        }
2491
2492        /* Don't send the response, if larger than fragmented packet. */
2493        tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
2494        if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
2495                net_ratelimited_function(batadv_info, bat_priv->soft_iface,
2496                                         "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
2497                                         res_dst_orig_node->orig);
2498                goto out;
2499        }
2500
2501        tvlv_tt_data->flags = BATADV_TT_RESPONSE;
2502        tvlv_tt_data->ttvn = req_ttvn;
2503
2504        if (full_table)
2505                tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2506
2507        batadv_dbg(BATADV_DBG_TT, bat_priv,
2508                   "Sending TT_RESPONSE %pM for %pM [%c] (ttvn: %u)\n",
2509                   res_dst_orig_node->orig, req_dst_orig_node->orig,
2510                   full_table ? 'F' : '.', req_ttvn);
2511
2512        batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
2513
2514        batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig,
2515                                 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
2516                                 tvlv_len);
2517
2518        ret = true;
2519        goto out;
2520
2521unlock:
2522        spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
2523
2524out:
2525        if (res_dst_orig_node)
2526                batadv_orig_node_free_ref(res_dst_orig_node);
2527        if (req_dst_orig_node)
2528                batadv_orig_node_free_ref(req_dst_orig_node);
2529        kfree(tvlv_tt_data);
2530        return ret;
2531}
2532
2533/**
2534 * batadv_send_my_tt_response - send reply to tt request concerning this node's
2535 *  translation table
2536 * @bat_priv: the bat priv with all the soft interface information
2537 * @tt_data: tt data containing the tt request information
2538 * @req_src: mac address of tt request sender
2539 *
2540 * Returns true if tt request reply was sent, false otherwise.
2541 */
2542static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
2543                                       struct batadv_tvlv_tt_data *tt_data,
2544                                       uint8_t *req_src)
2545{
2546        struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2547        struct batadv_hard_iface *primary_if = NULL;
2548        struct batadv_tvlv_tt_change *tt_change;
2549        struct batadv_orig_node *orig_node;
2550        uint8_t my_ttvn, req_ttvn;
2551        uint16_t tvlv_len;
2552        bool full_table;
2553        int32_t tt_len;
2554
2555        batadv_dbg(BATADV_DBG_TT, bat_priv,
2556                   "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
2557                   req_src, tt_data->ttvn,
2558                   (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2559
2560        spin_lock_bh(&bat_priv->tt.commit_lock);
2561
2562        my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
2563        req_ttvn = tt_data->ttvn;
2564
2565        orig_node = batadv_orig_hash_find(bat_priv, req_src);
2566        if (!orig_node)
2567                goto out;
2568
2569        primary_if = batadv_primary_if_get_selected(bat_priv);
2570        if (!primary_if)
2571                goto out;
2572
2573        /* If the full table has been explicitly requested or the gap
2574         * is too big send the whole local translation table
2575         */
2576        if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
2577            !bat_priv->tt.last_changeset)
2578                full_table = true;
2579        else
2580                full_table = false;
2581
2582        /* TT fragmentation hasn't been implemented yet, so send as many
2583         * TT entries fit a single packet as possible only
2584         */
2585        if (!full_table) {
2586                spin_lock_bh(&bat_priv->tt.last_changeset_lock);
2587
2588                tt_len = bat_priv->tt.last_changeset_len;
2589                tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
2590                                                             &tvlv_tt_data,
2591                                                             &tt_change,
2592                                                             &tt_len);
2593                if (!tt_len)
2594                        goto unlock;
2595
2596                /* Copy the last orig_node's OGM buffer */
2597                memcpy(tt_change, bat_priv->tt.last_changeset,
2598                       bat_priv->tt.last_changeset_len);
2599                spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
2600        } else {
2601                req_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
2602
2603                /* allocate the tvlv, put the tt_data and all the tt_vlan_data
2604                 * in the initial part
2605                 */
2606                tt_len = -1;
2607                tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
2608                                                             &tvlv_tt_data,
2609                                                             &tt_change,
2610                                                             &tt_len);
2611                if (!tt_len)
2612                        goto out;
2613
2614                /* fill the rest of the tvlv with the real TT entries */
2615                batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash,
2616                                        tt_change, tt_len,
2617                                        batadv_tt_local_valid, NULL);
2618        }
2619
2620        tvlv_tt_data->flags = BATADV_TT_RESPONSE;
2621        tvlv_tt_data->ttvn = req_ttvn;
2622
2623        if (full_table)
2624                tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2625
2626        batadv_dbg(BATADV_DBG_TT, bat_priv,
2627                   "Sending TT_RESPONSE to %pM [%c] (ttvn: %u)\n",
2628                   orig_node->orig, full_table ? 'F' : '.', req_ttvn);
2629
2630        batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
2631
2632        batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2633                                 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
2634                                 tvlv_len);
2635
2636        goto out;
2637
2638unlock:
2639        spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
2640out:
2641        spin_unlock_bh(&bat_priv->tt.commit_lock);
2642        if (orig_node)
2643                batadv_orig_node_free_ref(orig_node);
2644        if (primary_if)
2645                batadv_hardif_free_ref(primary_if);
2646        kfree(tvlv_tt_data);
2647        /* The packet was for this host, so it doesn't need to be re-routed */
2648        return true;
2649}
2650
2651/**
2652 * batadv_send_tt_response - send reply to tt request
2653 * @bat_priv: the bat priv with all the soft interface information
2654 * @tt_data: tt data containing the tt request information
2655 * @req_src: mac address of tt request sender
2656 * @req_dst: mac address of tt request recipient
2657 *
2658 * Returns true if tt request reply was sent, false otherwise.
2659 */
2660static bool batadv_send_tt_response(struct batadv_priv *bat_priv,
2661                                    struct batadv_tvlv_tt_data *tt_data,
2662                                    uint8_t *req_src, uint8_t *req_dst)
2663{
2664        if (batadv_is_my_mac(bat_priv, req_dst))
2665                return batadv_send_my_tt_response(bat_priv, tt_data, req_src);
2666        else
2667                return batadv_send_other_tt_response(bat_priv, tt_data,
2668                                                     req_src, req_dst);
2669}
2670
2671static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
2672                                      struct batadv_orig_node *orig_node,
2673                                      struct batadv_tvlv_tt_change *tt_change,
2674                                      uint16_t tt_num_changes, uint8_t ttvn)
2675{
2676        int i;
2677        int roams;
2678
2679        for (i = 0; i < tt_num_changes; i++) {
2680                if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
2681                        roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
2682                        batadv_tt_global_del(bat_priv, orig_node,
2683                                             (tt_change + i)->addr,
2684                                             ntohs((tt_change + i)->vid),
2685                                             "tt removed by changes",
2686                                             roams);
2687                } else {
2688                        if (!batadv_tt_global_add(bat_priv, orig_node,
2689                                                  (tt_change + i)->addr,
2690                                                  ntohs((tt_change + i)->vid),
2691                                                  (tt_change + i)->flags, ttvn))
2692                                /* In case of problem while storing a
2693                                 * global_entry, we stop the updating
2694                                 * procedure without committing the
2695                                 * ttvn change. This will avoid to send
2696                                 * corrupted data on tt_request
2697                                 */
2698                                return;
2699                }
2700        }
2701        orig_node->tt_initialised = true;
2702}
2703
2704static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
2705                                  struct batadv_tvlv_tt_change *tt_change,
2706                                  uint8_t ttvn, uint8_t *resp_src,
2707                                  uint16_t num_entries)
2708{
2709        struct batadv_orig_node *orig_node;
2710
2711        orig_node = batadv_orig_hash_find(bat_priv, resp_src);
2712        if (!orig_node)
2713                goto out;
2714
2715        /* Purge the old table first.. */
2716        batadv_tt_global_del_orig(bat_priv, orig_node, -1,
2717                                  "Received full table");
2718
2719        _batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
2720                                  ttvn);
2721
2722        spin_lock_bh(&orig_node->tt_buff_lock);
2723        kfree(orig_node->tt_buff);
2724        orig_node->tt_buff_len = 0;
2725        orig_node->tt_buff = NULL;
2726        spin_unlock_bh(&orig_node->tt_buff_lock);
2727
2728        atomic_set(&orig_node->last_ttvn, ttvn);
2729
2730out:
2731        if (orig_node)
2732                batadv_orig_node_free_ref(orig_node);
2733}
2734
2735static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
2736                                     struct batadv_orig_node *orig_node,
2737                                     uint16_t tt_num_changes, uint8_t ttvn,
2738                                     struct batadv_tvlv_tt_change *tt_change)
2739{
2740        _batadv_tt_update_changes(bat_priv, orig_node, tt_change,
2741                                  tt_num_changes, ttvn);
2742
2743        batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
2744                                   batadv_tt_len(tt_num_changes));
2745        atomic_set(&orig_node->last_ttvn, ttvn);
2746}
2747
2748/**
2749 * batadv_is_my_client - check if a client is served by the local node
2750 * @bat_priv: the bat priv with all the soft interface information
2751 * @addr: the mac adress of the client to check
2752 * @vid: VLAN identifier
2753 *
2754 * Returns true if the client is served by this node, false otherwise.
2755 */
2756bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
2757                         unsigned short vid)
2758{
2759        struct batadv_tt_local_entry *tt_local_entry;
2760        bool ret = false;
2761
2762        tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
2763        if (!tt_local_entry)
2764                goto out;
2765        /* Check if the client has been logically deleted (but is kept for
2766         * consistency purpose)
2767         */
2768        if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
2769            (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
2770                goto out;
2771        ret = true;
2772out:
2773        if (tt_local_entry)
2774                batadv_tt_local_entry_free_ref(tt_local_entry);
2775        return ret;
2776}
2777
2778/**
2779 * batadv_handle_tt_response - process incoming tt reply
2780 * @bat_priv: the bat priv with all the soft interface information
2781 * @tt_data: tt data containing the tt request information
2782 * @resp_src: mac address of tt reply sender
2783 * @num_entries: number of tt change entries appended to the tt data
2784 */
2785static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
2786                                      struct batadv_tvlv_tt_data *tt_data,
2787                                      uint8_t *resp_src, uint16_t num_entries)
2788{
2789        struct batadv_tt_req_node *node, *safe;
2790        struct batadv_orig_node *orig_node = NULL;
2791        struct batadv_tvlv_tt_change *tt_change;
2792        uint8_t *tvlv_ptr = (uint8_t *)tt_data;
2793        uint16_t change_offset;
2794
2795        batadv_dbg(BATADV_DBG_TT, bat_priv,
2796                   "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
2797                   resp_src, tt_data->ttvn, num_entries,
2798                   (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2799
2800        orig_node = batadv_orig_hash_find(bat_priv, resp_src);
2801        if (!orig_node)
2802                goto out;
2803
2804        spin_lock_bh(&orig_node->tt_lock);
2805
2806        change_offset = sizeof(struct batadv_tvlv_tt_vlan_data);
2807        change_offset *= ntohs(tt_data->num_vlan);
2808        change_offset += sizeof(*tt_data);
2809        tvlv_ptr += change_offset;
2810
2811        tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr;
2812        if (tt_data->flags & BATADV_TT_FULL_TABLE) {
2813                batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn,
2814                                      resp_src, num_entries);
2815        } else {
2816                batadv_tt_update_changes(bat_priv, orig_node, num_entries,
2817                                         tt_data->ttvn, tt_change);
2818        }
2819
2820        /* Recalculate the CRC for this orig_node and store it */
2821        batadv_tt_global_update_crc(bat_priv, orig_node);
2822
2823        spin_unlock_bh(&orig_node->tt_lock);
2824
2825        /* Delete the tt_req_node from pending tt_requests list */
2826        spin_lock_bh(&bat_priv->tt.req_list_lock);
2827        list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2828                if (!batadv_compare_eth(node->addr, resp_src))
2829                        continue;
2830                list_del(&node->list);
2831                kfree(node);
2832        }
2833
2834        spin_unlock_bh(&bat_priv->tt.req_list_lock);
2835out:
2836        if (orig_node)
2837                batadv_orig_node_free_ref(orig_node);
2838}
2839
2840static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
2841{
2842        struct batadv_tt_roam_node *node, *safe;
2843
2844        spin_lock_bh(&bat_priv->tt.roam_list_lock);
2845
2846        list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
2847                list_del(&node->list);
2848                kfree(node);
2849        }
2850
2851        spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2852}
2853
2854static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
2855{
2856        struct batadv_tt_roam_node *node, *safe;
2857
2858        spin_lock_bh(&bat_priv->tt.roam_list_lock);
2859        list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
2860                if (!batadv_has_timed_out(node->first_time,
2861                                          BATADV_ROAMING_MAX_TIME))
2862                        continue;
2863
2864                list_del(&node->list);
2865                kfree(node);
2866        }
2867        spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2868}
2869
2870/* This function checks whether the client already reached the
2871 * maximum number of possible roaming phases. In this case the ROAMING_ADV
2872 * will not be sent.
2873 *
2874 * returns true if the ROAMING_ADV can be sent, false otherwise
2875 */
2876static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
2877                                       uint8_t *client)
2878{
2879        struct batadv_tt_roam_node *tt_roam_node;
2880        bool ret = false;
2881
2882        spin_lock_bh(&bat_priv->tt.roam_list_lock);
2883        /* The new tt_req will be issued only if I'm not waiting for a
2884         * reply from the same orig_node yet
2885         */
2886        list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
2887                if (!batadv_compare_eth(tt_roam_node->addr, client))
2888                        continue;
2889
2890                if (batadv_has_timed_out(tt_roam_node->first_time,
2891                                         BATADV_ROAMING_MAX_TIME))
2892                        continue;
2893
2894                if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter))
2895                        /* Sorry, you roamed too many times! */
2896                        goto unlock;
2897                ret = true;
2898                break;
2899        }
2900
2901        if (!ret) {
2902                tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
2903                if (!tt_roam_node)
2904                        goto unlock;
2905
2906                tt_roam_node->first_time = jiffies;
2907                atomic_set(&tt_roam_node->counter,
2908                           BATADV_ROAMING_MAX_COUNT - 1);
2909                memcpy(tt_roam_node->addr, client, ETH_ALEN);
2910
2911                list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
2912                ret = true;
2913        }
2914
2915unlock:
2916        spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2917        return ret;
2918}
2919
2920/**
2921 * batadv_send_roam_adv - send a roaming advertisement message
2922 * @bat_priv: the bat priv with all the soft interface information
2923 * @client: mac address of the roaming client
2924 * @vid: VLAN identifier
2925 * @orig_node: message destination
2926 *
2927 * Send a ROAMING_ADV message to the node which was previously serving this
2928 * client. This is done to inform the node that from now on all traffic destined
2929 * for this particular roamed client has to be forwarded to the sender of the
2930 * roaming message.
2931 */
2932static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2933                                 unsigned short vid,
2934                                 struct batadv_orig_node *orig_node)
2935{
2936        struct batadv_hard_iface *primary_if;
2937        struct batadv_tvlv_roam_adv tvlv_roam;
2938
2939        primary_if = batadv_primary_if_get_selected(bat_priv);
2940        if (!primary_if)
2941                goto out;
2942
2943        /* before going on we have to check whether the client has
2944         * already roamed to us too many times
2945         */
2946        if (!batadv_tt_check_roam_count(bat_priv, client))
2947                goto out;
2948
2949        batadv_dbg(BATADV_DBG_TT, bat_priv,
2950                   "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n",
2951                   orig_node->orig, client, BATADV_PRINT_VID(vid));
2952
2953        batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
2954
2955        memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
2956        tvlv_roam.vid = htons(vid);
2957
2958        batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2959                                 orig_node->orig, BATADV_TVLV_ROAM, 1,
2960                                 &tvlv_roam, sizeof(tvlv_roam));
2961
2962out:
2963        if (primary_if)
2964                batadv_hardif_free_ref(primary_if);
2965}
2966
2967static void batadv_tt_purge(struct work_struct *work)
2968{
2969        struct delayed_work *delayed_work;
2970        struct batadv_priv_tt *priv_tt;
2971        struct batadv_priv *bat_priv;
2972
2973        delayed_work = container_of(work, struct delayed_work, work);
2974        priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
2975        bat_priv = container_of(priv_tt, struct batadv_priv, tt);
2976
2977        batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT);
2978        batadv_tt_global_purge(bat_priv);
2979        batadv_tt_req_purge(bat_priv);
2980        batadv_tt_roam_purge(bat_priv);
2981
2982        queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2983                           msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2984}
2985
2986void batadv_tt_free(struct batadv_priv *bat_priv)
2987{
2988        batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
2989        batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
2990
2991        cancel_delayed_work_sync(&bat_priv->tt.work);
2992
2993        batadv_tt_local_table_free(bat_priv);
2994        batadv_tt_global_table_free(bat_priv);
2995        batadv_tt_req_list_free(bat_priv);
2996        batadv_tt_changes_list_free(bat_priv);
2997        batadv_tt_roam_list_free(bat_priv);
2998
2999        kfree(bat_priv->tt.last_changeset);
3000}
3001
3002/**
3003 * batadv_tt_local_set_flags - set or unset the specified flags on the local
3004 *  table and possibly count them in the TT size
3005 * @bat_priv: the bat priv with all the soft interface information
3006 * @flags: the flag to switch
3007 * @enable: whether to set or unset the flag
3008 * @count: whether to increase the TT size by the number of changed entries
3009 */
3010static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv,
3011                                      uint16_t flags, bool enable, bool count)
3012{
3013        struct batadv_hashtable *hash = bat_priv->tt.local_hash;
3014        struct batadv_tt_common_entry *tt_common_entry;
3015        uint16_t changed_num = 0;
3016        struct hlist_head *head;
3017        uint32_t i;
3018
3019        if (!hash)
3020                return;
3021
3022        for (i = 0; i < hash->size; i++) {
3023                head = &hash->table[i];
3024
3025                rcu_read_lock();
3026                hlist_for_each_entry_rcu(tt_common_entry,
3027                                         head, hash_entry) {
3028                        if (enable) {
3029                                if ((tt_common_entry->flags & flags) == flags)
3030                                        continue;
3031                                tt_common_entry->flags |= flags;
3032                        } else {
3033                                if (!(tt_common_entry->flags & flags))
3034                                        continue;
3035                                tt_common_entry->flags &= ~flags;
3036                        }
3037                        changed_num++;
3038
3039                        if (!count)
3040                                continue;
3041
3042                        batadv_tt_local_size_inc(bat_priv,
3043                                                 tt_common_entry->vid);
3044                }
3045                rcu_read_unlock();
3046        }
3047}
3048
3049/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
3050static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
3051{
3052        struct batadv_hashtable *hash = bat_priv->tt.local_hash;
3053        struct batadv_tt_common_entry *tt_common;
3054        struct batadv_tt_local_entry *tt_local;
3055        struct hlist_node *node_tmp;
3056        struct hlist_head *head;
3057        spinlock_t *list_lock; /* protects write access to the hash lists */
3058        uint32_t i;
3059
3060        if (!hash)
3061                return;
3062
3063        for (i = 0; i < hash->size; i++) {
3064                head = &hash->table[i];
3065                list_lock = &hash->list_locks[i];
3066
3067                spin_lock_bh(list_lock);
3068                hlist_for_each_entry_safe(tt_common, node_tmp, head,
3069                                          hash_entry) {
3070                        if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
3071                                continue;
3072
3073                        batadv_dbg(BATADV_DBG_TT, bat_priv,
3074                                   "Deleting local tt entry (%pM, vid: %d): pending\n",
3075                                   tt_common->addr,
3076                                   BATADV_PRINT_VID(tt_common->vid));
3077
3078                        batadv_tt_local_size_dec(bat_priv, tt_common->vid);
3079                        hlist_del_rcu(&tt_common->hash_entry);
3080                        tt_local = container_of(tt_common,
3081                                                struct batadv_tt_local_entry,
3082                                                common);
3083                        batadv_tt_local_entry_free_ref(tt_local);
3084                }
3085                spin_unlock_bh(list_lock);
3086        }
3087}
3088
3089/**
3090 * batadv_tt_local_commit_changes_nolock - commit all pending local tt changes
3091 *  which have been queued in the time since the last commit
3092 * @bat_priv: the bat priv with all the soft interface information
3093 *
3094 * Caller must hold tt->commit_lock.
3095 */
3096static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
3097{
3098        if (atomic_read(&bat_priv->tt.local_changes) < 1) {
3099                if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
3100                        batadv_tt_tvlv_container_update(bat_priv);
3101                return;
3102        }
3103
3104        batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
3105
3106        batadv_tt_local_purge_pending_clients(bat_priv);
3107        batadv_tt_local_update_crc(bat_priv);
3108
3109        /* Increment the TTVN only once per OGM interval */
3110        atomic_inc(&bat_priv->tt.vn);
3111        batadv_dbg(BATADV_DBG_TT, bat_priv,
3112                   "Local changes committed, updating to ttvn %u\n",
3113                   (uint8_t)atomic_read(&bat_priv->tt.vn));
3114
3115        /* reset the sending counter */
3116        atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
3117        batadv_tt_tvlv_container_update(bat_priv);
3118}
3119
3120/**
3121 * batadv_tt_local_commit_changes - commit all pending local tt changes which
3122 *  have been queued in the time since the last commit
3123 * @bat_priv: the bat priv with all the soft interface information
3124 */
3125void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
3126{
3127        spin_lock_bh(&bat_priv->tt.commit_lock);
3128        batadv_tt_local_commit_changes_nolock(bat_priv);
3129        spin_unlock_bh(&bat_priv->tt.commit_lock);
3130}
3131
3132bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
3133                           uint8_t *dst, unsigned short vid)
3134{
3135        struct batadv_tt_local_entry *tt_local_entry = NULL;
3136        struct batadv_tt_global_entry *tt_global_entry = NULL;
3137        struct batadv_softif_vlan *vlan;
3138        bool ret = false;
3139
3140        vlan = batadv_softif_vlan_get(bat_priv, vid);
3141        if (!vlan || !atomic_read(&vlan->ap_isolation))
3142                goto out;
3143
3144        tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
3145        if (!tt_local_entry)
3146                goto out;
3147
3148        tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
3149        if (!tt_global_entry)
3150                goto out;
3151
3152        if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
3153                goto out;
3154
3155        ret = true;
3156
3157out:
3158        if (vlan)
3159                batadv_softif_vlan_free_ref(vlan);
3160        if (tt_global_entry)
3161                batadv_tt_global_entry_free_ref(tt_global_entry);
3162        if (tt_local_entry)
3163                batadv_tt_local_entry_free_ref(tt_local_entry);
3164        return ret;
3165}
3166
3167/**
3168 * batadv_tt_update_orig - update global translation table with new tt
3169 *  information received via ogms
3170 * @bat_priv: the bat priv with all the soft interface information
3171 * @orig: the orig_node of the ogm
3172 * @tt_vlan: pointer to the first tvlv VLAN entry
3173 * @tt_num_vlan: number of tvlv VLAN entries
3174 * @tt_change: pointer to the first entry in the TT buffer
3175 * @tt_num_changes: number of tt changes inside the tt buffer
3176 * @ttvn: translation table version number of this changeset
3177 * @tt_crc: crc32 checksum of orig node's translation table
3178 */
3179static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
3180                                  struct batadv_orig_node *orig_node,
3181                                  const void *tt_buff, uint16_t tt_num_vlan,
3182                                  struct batadv_tvlv_tt_change *tt_change,
3183                                  uint16_t tt_num_changes, uint8_t ttvn)
3184{
3185        uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
3186        struct batadv_tvlv_tt_vlan_data *tt_vlan;
3187        bool full_table = true;
3188
3189        tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
3190        /* orig table not initialised AND first diff is in the OGM OR the ttvn
3191         * increased by one -> we can apply the attached changes
3192         */
3193        if ((!orig_node->tt_initialised && ttvn == 1) ||
3194            ttvn - orig_ttvn == 1) {
3195                /* the OGM could not contain the changes due to their size or
3196                 * because they have already been sent BATADV_TT_OGM_APPEND_MAX
3197                 * times.
3198                 * In this case send a tt request
3199                 */
3200                if (!tt_num_changes) {
3201                        full_table = false;
3202                        goto request_table;
3203                }
3204
3205                spin_lock_bh(&orig_node->tt_lock);
3206
3207                tt_change = (struct batadv_tvlv_tt_change *)tt_buff;
3208                batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
3209                                         ttvn, tt_change);
3210
3211                /* Even if we received the precomputed crc with the OGM, we
3212                 * prefer to recompute it to spot any possible inconsistency
3213                 * in the global table
3214                 */
3215                batadv_tt_global_update_crc(bat_priv, orig_node);
3216
3217                spin_unlock_bh(&orig_node->tt_lock);
3218
3219                /* The ttvn alone is not enough to guarantee consistency
3220                 * because a single value could represent different states
3221                 * (due to the wrap around). Thus a node has to check whether
3222                 * the resulting table (after applying the changes) is still
3223                 * consistent or not. E.g. a node could disconnect while its
3224                 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
3225                 * checking the CRC value is mandatory to detect the
3226                 * inconsistency
3227                 */
3228                if (!batadv_tt_global_check_crc(orig_node, tt_vlan,
3229                                                tt_num_vlan))
3230                        goto request_table;
3231        } else {
3232                /* if we missed more than one change or our tables are not
3233                 * in sync anymore -> request fresh tt data
3234                 */
3235                if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
3236                    !batadv_tt_global_check_crc(orig_node, tt_vlan,
3237                                                tt_num_vlan)) {
3238request_table:
3239                        batadv_dbg(BATADV_DBG_TT, bat_priv,
3240                                   "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n",
3241                                   orig_node->orig, ttvn, orig_ttvn,
3242                                   tt_num_changes);
3243                        batadv_send_tt_request(bat_priv, orig_node, ttvn,
3244                                               tt_vlan, tt_num_vlan,
3245                                               full_table);
3246                        return;
3247                }
3248        }
3249}
3250
3251/**
3252 * batadv_tt_global_client_is_roaming - check if a client is marked as roaming
3253 * @bat_priv: the bat priv with all the soft interface information
3254 * @addr: the mac address of the client to check
3255 * @vid: VLAN identifier
3256 *
3257 * Returns true if we know that the client has moved from its old originator
3258 * to another one. This entry is still kept for consistency purposes and will be
3259 * deleted later by a DEL or because of timeout
3260 */
3261bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
3262                                        uint8_t *addr, unsigned short vid)
3263{
3264        struct batadv_tt_global_entry *tt_global_entry;
3265        bool ret = false;
3266
3267        tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
3268        if (!tt_global_entry)
3269                goto out;
3270
3271        ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
3272        batadv_tt_global_entry_free_ref(tt_global_entry);
3273out:
3274        return ret;
3275}
3276
3277/**
3278 * batadv_tt_local_client_is_roaming - tells whether the client is roaming
3279 * @bat_priv: the bat priv with all the soft interface information
3280 * @addr: the mac address of the local client to query
3281 * @vid: VLAN identifier
3282 *
3283 * Returns true if the local client is known to be roaming (it is not served by
3284 * this node anymore) or not. If yes, the client is still present in the table
3285 * to keep the latter consistent with the node TTVN
3286 */
3287bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
3288                                       uint8_t *addr, unsigned short vid)
3289{
3290        struct batadv_tt_local_entry *tt_local_entry;
3291        bool ret = false;
3292
3293        tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
3294        if (!tt_local_entry)
3295                goto out;
3296
3297        ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
3298        batadv_tt_local_entry_free_ref(tt_local_entry);
3299out:
3300        return ret;
3301}
3302
3303bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
3304                                          struct batadv_orig_node *orig_node,
3305                                          const unsigned char *addr,
3306                                          unsigned short vid)
3307{
3308        bool ret = false;
3309
3310        if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
3311                                  BATADV_TT_CLIENT_TEMP,
3312                                  atomic_read(&orig_node->last_ttvn)))
3313                goto out;
3314
3315        batadv_dbg(BATADV_DBG_TT, bat_priv,
3316                   "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n",
3317                   addr, BATADV_PRINT_VID(vid), orig_node->orig);
3318        ret = true;
3319out:
3320        return ret;
3321}
3322
3323/**
3324 * batadv_tt_local_resize_to_mtu - resize the local translation table fit the
3325 *  maximum packet size that can be transported through the mesh
3326 * @soft_iface: netdev struct of the mesh interface
3327 *
3328 * Remove entries older than 'timeout' and half timeout if more entries need
3329 * to be removed.
3330 */
3331void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface)
3332{
3333        struct batadv_priv *bat_priv = netdev_priv(soft_iface);
3334        int packet_size_max = atomic_read(&bat_priv->packet_size_max);
3335        int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
3336        bool reduced = false;
3337
3338        spin_lock_bh(&bat_priv->tt.commit_lock);
3339
3340        while (true) {
3341                table_size = batadv_tt_local_table_transmit_size(bat_priv);
3342                if (packet_size_max >= table_size)
3343                        break;
3344
3345                batadv_tt_local_purge(bat_priv, timeout);
3346                batadv_tt_local_purge_pending_clients(bat_priv);
3347
3348                timeout /= 2;
3349                reduced = true;
3350                net_ratelimited_function(batadv_info, soft_iface,
3351                                         "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
3352                                         packet_size_max);
3353        }
3354
3355        /* commit these changes immediately, to avoid synchronization problem
3356         * with the TTVN
3357         */
3358        if (reduced)
3359                batadv_tt_local_commit_changes_nolock(bat_priv);
3360
3361        spin_unlock_bh(&bat_priv->tt.commit_lock);
3362}
3363
3364/**
3365 * batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container
3366 * @bat_priv: the bat priv with all the soft interface information
3367 * @orig: the orig_node of the ogm
3368 * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
3369 * @tvlv_value: tvlv buffer containing the gateway data
3370 * @tvlv_value_len: tvlv buffer length
3371 */
3372static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
3373                                          struct batadv_orig_node *orig,
3374                                          uint8_t flags, void *tvlv_value,
3375                                          uint16_t tvlv_value_len)
3376{
3377        struct batadv_tvlv_tt_vlan_data *tt_vlan;
3378        struct batadv_tvlv_tt_change *tt_change;
3379        struct batadv_tvlv_tt_data *tt_data;
3380        uint16_t num_entries, num_vlan;
3381
3382        if (tvlv_value_len < sizeof(*tt_data))
3383                return;
3384
3385        tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
3386        tvlv_value_len -= sizeof(*tt_data);
3387
3388        num_vlan = ntohs(tt_data->num_vlan);
3389
3390        if (tvlv_value_len < sizeof(*tt_vlan) * num_vlan)
3391                return;
3392
3393        tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
3394        tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan);
3395        tvlv_value_len -= sizeof(*tt_vlan) * num_vlan;
3396
3397        num_entries = batadv_tt_entries(tvlv_value_len);
3398
3399        batadv_tt_update_orig(bat_priv, orig, tt_vlan, num_vlan, tt_change,
3400                              num_entries, tt_data->ttvn);
3401}
3402
3403/**
3404 * batadv_tt_tvlv_unicast_handler_v1 - process incoming (unicast) tt tvlv
3405 *  container
3406 * @bat_priv: the bat priv with all the soft interface information
3407 * @src: mac address of tt tvlv sender
3408 * @dst: mac address of tt tvlv recipient
3409 * @tvlv_value: tvlv buffer containing the tt data
3410 * @tvlv_value_len: tvlv buffer length
3411 *
3412 * Returns NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
3413 * otherwise.
3414 */
3415static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
3416                                             uint8_t *src, uint8_t *dst,
3417                                             void *tvlv_value,
3418                                             uint16_t tvlv_value_len)
3419{
3420        struct batadv_tvlv_tt_data *tt_data;
3421        uint16_t tt_vlan_len, tt_num_entries;
3422        char tt_flag;
3423        bool ret;
3424
3425        if (tvlv_value_len < sizeof(*tt_data))
3426                return NET_RX_SUCCESS;
3427
3428        tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
3429        tvlv_value_len -= sizeof(*tt_data);
3430
3431        tt_vlan_len = sizeof(struct batadv_tvlv_tt_vlan_data);
3432        tt_vlan_len *= ntohs(tt_data->num_vlan);
3433
3434        if (tvlv_value_len < tt_vlan_len)
3435                return NET_RX_SUCCESS;
3436
3437        tvlv_value_len -= tt_vlan_len;
3438        tt_num_entries = batadv_tt_entries(tvlv_value_len);
3439
3440        switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) {
3441        case BATADV_TT_REQUEST:
3442                batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX);
3443
3444                /* If this node cannot provide a TT response the tt_request is
3445                 * forwarded
3446                 */
3447                ret = batadv_send_tt_response(bat_priv, tt_data, src, dst);
3448                if (!ret) {
3449                        if (tt_data->flags & BATADV_TT_FULL_TABLE)
3450                                tt_flag = 'F';
3451                        else
3452                                tt_flag = '.';
3453
3454                        batadv_dbg(BATADV_DBG_TT, bat_priv,
3455                                   "Routing TT_REQUEST to %pM [%c]\n",
3456                                   dst, tt_flag);
3457                        /* tvlv API will re-route the packet */
3458                        return NET_RX_DROP;
3459                }
3460                break;
3461        case BATADV_TT_RESPONSE:
3462                batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
3463
3464                if (batadv_is_my_mac(bat_priv, dst)) {
3465                        batadv_handle_tt_response(bat_priv, tt_data,
3466                                                  src, tt_num_entries);
3467                        return NET_RX_SUCCESS;
3468                }
3469
3470                if (tt_data->flags & BATADV_TT_FULL_TABLE)
3471                        tt_flag =  'F';
3472                else
3473                        tt_flag = '.';
3474
3475                batadv_dbg(BATADV_DBG_TT, bat_priv,
3476                           "Routing TT_RESPONSE to %pM [%c]\n", dst, tt_flag);
3477
3478                /* tvlv API will re-route the packet */
3479                return NET_RX_DROP;
3480        }
3481
3482        return NET_RX_SUCCESS;
3483}
3484
3485/**
3486 * batadv_roam_tvlv_unicast_handler_v1 - process incoming tt roam tvlv container
3487 * @bat_priv: the bat priv with all the soft interface information
3488 * @src: mac address of tt tvlv sender
3489 * @dst: mac address of tt tvlv recipient
3490 * @tvlv_value: tvlv buffer containing the tt data
3491 * @tvlv_value_len: tvlv buffer length
3492 *
3493 * Returns NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
3494 * otherwise.
3495 */
3496static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
3497                                               uint8_t *src, uint8_t *dst,
3498                                               void *tvlv_value,
3499                                               uint16_t tvlv_value_len)
3500{
3501        struct batadv_tvlv_roam_adv *roaming_adv;
3502        struct batadv_orig_node *orig_node = NULL;
3503
3504        /* If this node is not the intended recipient of the
3505         * roaming advertisement the packet is forwarded
3506         * (the tvlv API will re-route the packet).
3507         */
3508        if (!batadv_is_my_mac(bat_priv, dst))
3509                return NET_RX_DROP;
3510
3511        if (tvlv_value_len < sizeof(*roaming_adv))
3512                goto out;
3513
3514        orig_node = batadv_orig_hash_find(bat_priv, src);
3515        if (!orig_node)
3516                goto out;
3517
3518        batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
3519        roaming_adv = (struct batadv_tvlv_roam_adv *)tvlv_value;
3520
3521        batadv_dbg(BATADV_DBG_TT, bat_priv,
3522                   "Received ROAMING_ADV from %pM (client %pM)\n",
3523                   src, roaming_adv->client);
3524
3525        batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
3526                             ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
3527                             atomic_read(&orig_node->last_ttvn) + 1);
3528
3529out:
3530        if (orig_node)
3531                batadv_orig_node_free_ref(orig_node);
3532        return NET_RX_SUCCESS;
3533}
3534
3535/**
3536 * batadv_tt_init - initialise the translation table internals
3537 * @bat_priv: the bat priv with all the soft interface information
3538 *
3539 * Return 0 on success or negative error number in case of failure.
3540 */
3541int batadv_tt_init(struct batadv_priv *bat_priv)
3542{
3543        int ret;
3544
3545        /* synchronized flags must be remote */
3546        BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK));
3547
3548        ret = batadv_tt_local_init(bat_priv);
3549        if (ret < 0)
3550                return ret;
3551
3552        ret = batadv_tt_global_init(bat_priv);
3553        if (ret < 0)
3554                return ret;
3555
3556        batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
3557                                     batadv_tt_tvlv_unicast_handler_v1,
3558                                     BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
3559
3560        batadv_tvlv_handler_register(bat_priv, NULL,
3561                                     batadv_roam_tvlv_unicast_handler_v1,
3562                                     BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
3563
3564        INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
3565        queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
3566                           msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
3567
3568        return 1;
3569}
3570