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