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