linux/net/batman-adv/originator.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (C) 2009-2020  B.A.T.M.A.N. contributors:
   3 *
   4 * Marek Lindner, Simon Wunderlich
   5 */
   6
   7#include "originator.h"
   8#include "main.h"
   9
  10#include <linux/atomic.h>
  11#include <linux/errno.h>
  12#include <linux/etherdevice.h>
  13#include <linux/gfp.h>
  14#include <linux/jiffies.h>
  15#include <linux/kernel.h>
  16#include <linux/kref.h>
  17#include <linux/list.h>
  18#include <linux/lockdep.h>
  19#include <linux/netdevice.h>
  20#include <linux/netlink.h>
  21#include <linux/rculist.h>
  22#include <linux/rcupdate.h>
  23#include <linux/seq_file.h>
  24#include <linux/skbuff.h>
  25#include <linux/slab.h>
  26#include <linux/spinlock.h>
  27#include <linux/stddef.h>
  28#include <linux/workqueue.h>
  29#include <net/sock.h>
  30#include <uapi/linux/batadv_packet.h>
  31#include <uapi/linux/batman_adv.h>
  32
  33#include "bat_algo.h"
  34#include "distributed-arp-table.h"
  35#include "fragmentation.h"
  36#include "gateway_client.h"
  37#include "hard-interface.h"
  38#include "hash.h"
  39#include "log.h"
  40#include "multicast.h"
  41#include "netlink.h"
  42#include "network-coding.h"
  43#include "routing.h"
  44#include "soft-interface.h"
  45#include "translation-table.h"
  46
  47/* hash class keys */
  48static struct lock_class_key batadv_orig_hash_lock_class_key;
  49
  50/**
  51 * batadv_orig_hash_find() - Find and return originator from orig_hash
  52 * @bat_priv: the bat priv with all the soft interface information
  53 * @data: mac address of the originator
  54 *
  55 * Return: orig_node (with increased refcnt), NULL on errors
  56 */
  57struct batadv_orig_node *
  58batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
  59{
  60        struct batadv_hashtable *hash = bat_priv->orig_hash;
  61        struct hlist_head *head;
  62        struct batadv_orig_node *orig_node, *orig_node_tmp = NULL;
  63        int index;
  64
  65        if (!hash)
  66                return NULL;
  67
  68        index = batadv_choose_orig(data, hash->size);
  69        head = &hash->table[index];
  70
  71        rcu_read_lock();
  72        hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
  73                if (!batadv_compare_eth(orig_node, data))
  74                        continue;
  75
  76                if (!kref_get_unless_zero(&orig_node->refcount))
  77                        continue;
  78
  79                orig_node_tmp = orig_node;
  80                break;
  81        }
  82        rcu_read_unlock();
  83
  84        return orig_node_tmp;
  85}
  86
  87static void batadv_purge_orig(struct work_struct *work);
  88
  89/**
  90 * batadv_compare_orig() - comparing function used in the originator hash table
  91 * @node: node in the local table
  92 * @data2: second object to compare the node to
  93 *
  94 * Return: true if they are the same originator
  95 */
  96bool batadv_compare_orig(const struct hlist_node *node, const void *data2)
  97{
  98        const void *data1 = container_of(node, struct batadv_orig_node,
  99                                         hash_entry);
 100
 101        return batadv_compare_eth(data1, data2);
 102}
 103
 104/**
 105 * batadv_orig_node_vlan_get() - get an orig_node_vlan object
 106 * @orig_node: the originator serving the VLAN
 107 * @vid: the VLAN identifier
 108 *
 109 * Return: the vlan object identified by vid and belonging to orig_node or NULL
 110 * if it does not exist.
 111 */
 112struct batadv_orig_node_vlan *
 113batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
 114                          unsigned short vid)
 115{
 116        struct batadv_orig_node_vlan *vlan = NULL, *tmp;
 117
 118        rcu_read_lock();
 119        hlist_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
 120                if (tmp->vid != vid)
 121                        continue;
 122
 123                if (!kref_get_unless_zero(&tmp->refcount))
 124                        continue;
 125
 126                vlan = tmp;
 127
 128                break;
 129        }
 130        rcu_read_unlock();
 131
 132        return vlan;
 133}
 134
 135/**
 136 * batadv_orig_node_vlan_new() - search and possibly create an orig_node_vlan
 137 *  object
 138 * @orig_node: the originator serving the VLAN
 139 * @vid: the VLAN identifier
 140 *
 141 * Return: NULL in case of failure or the vlan object identified by vid and
 142 * belonging to orig_node otherwise. The object is created and added to the list
 143 * if it does not exist.
 144 *
 145 * The object is returned with refcounter increased by 1.
 146 */
 147struct batadv_orig_node_vlan *
 148batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
 149                          unsigned short vid)
 150{
 151        struct batadv_orig_node_vlan *vlan;
 152
 153        spin_lock_bh(&orig_node->vlan_list_lock);
 154
 155        /* first look if an object for this vid already exists */
 156        vlan = batadv_orig_node_vlan_get(orig_node, vid);
 157        if (vlan)
 158                goto out;
 159
 160        vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
 161        if (!vlan)
 162                goto out;
 163
 164        kref_init(&vlan->refcount);
 165        vlan->vid = vid;
 166
 167        kref_get(&vlan->refcount);
 168        hlist_add_head_rcu(&vlan->list, &orig_node->vlan_list);
 169
 170out:
 171        spin_unlock_bh(&orig_node->vlan_list_lock);
 172
 173        return vlan;
 174}
 175
 176/**
 177 * batadv_orig_node_vlan_release() - release originator-vlan object from lists
 178 *  and queue for free after rcu grace period
 179 * @ref: kref pointer of the originator-vlan object
 180 */
 181static void batadv_orig_node_vlan_release(struct kref *ref)
 182{
 183        struct batadv_orig_node_vlan *orig_vlan;
 184
 185        orig_vlan = container_of(ref, struct batadv_orig_node_vlan, refcount);
 186
 187        kfree_rcu(orig_vlan, rcu);
 188}
 189
 190/**
 191 * batadv_orig_node_vlan_put() - decrement the refcounter and possibly release
 192 *  the originator-vlan object
 193 * @orig_vlan: the originator-vlan object to release
 194 */
 195void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan)
 196{
 197        kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release);
 198}
 199
 200/**
 201 * batadv_originator_init() - Initialize all originator structures
 202 * @bat_priv: the bat priv with all the soft interface information
 203 *
 204 * Return: 0 on success or negative error number in case of failure
 205 */
 206int batadv_originator_init(struct batadv_priv *bat_priv)
 207{
 208        if (bat_priv->orig_hash)
 209                return 0;
 210
 211        bat_priv->orig_hash = batadv_hash_new(1024);
 212
 213        if (!bat_priv->orig_hash)
 214                goto err;
 215
 216        batadv_hash_set_lock_class(bat_priv->orig_hash,
 217                                   &batadv_orig_hash_lock_class_key);
 218
 219        INIT_DELAYED_WORK(&bat_priv->orig_work, batadv_purge_orig);
 220        queue_delayed_work(batadv_event_workqueue,
 221                           &bat_priv->orig_work,
 222                           msecs_to_jiffies(BATADV_ORIG_WORK_PERIOD));
 223
 224        return 0;
 225
 226err:
 227        return -ENOMEM;
 228}
 229
 230/**
 231 * batadv_neigh_ifinfo_release() - release neigh_ifinfo from lists and queue for
 232 *  free after rcu grace period
 233 * @ref: kref pointer of the neigh_ifinfo
 234 */
 235static void batadv_neigh_ifinfo_release(struct kref *ref)
 236{
 237        struct batadv_neigh_ifinfo *neigh_ifinfo;
 238
 239        neigh_ifinfo = container_of(ref, struct batadv_neigh_ifinfo, refcount);
 240
 241        if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
 242                batadv_hardif_put(neigh_ifinfo->if_outgoing);
 243
 244        kfree_rcu(neigh_ifinfo, rcu);
 245}
 246
 247/**
 248 * batadv_neigh_ifinfo_put() - decrement the refcounter and possibly release
 249 *  the neigh_ifinfo
 250 * @neigh_ifinfo: the neigh_ifinfo object to release
 251 */
 252void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo)
 253{
 254        kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release);
 255}
 256
 257/**
 258 * batadv_hardif_neigh_release() - release hardif neigh node from lists and
 259 *  queue for free after rcu grace period
 260 * @ref: kref pointer of the neigh_node
 261 */
 262static void batadv_hardif_neigh_release(struct kref *ref)
 263{
 264        struct batadv_hardif_neigh_node *hardif_neigh;
 265
 266        hardif_neigh = container_of(ref, struct batadv_hardif_neigh_node,
 267                                    refcount);
 268
 269        spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
 270        hlist_del_init_rcu(&hardif_neigh->list);
 271        spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
 272
 273        batadv_hardif_put(hardif_neigh->if_incoming);
 274        kfree_rcu(hardif_neigh, rcu);
 275}
 276
 277/**
 278 * batadv_hardif_neigh_put() - decrement the hardif neighbors refcounter
 279 *  and possibly release it
 280 * @hardif_neigh: hardif neigh neighbor to free
 281 */
 282void batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh)
 283{
 284        kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release);
 285}
 286
 287/**
 288 * batadv_neigh_node_release() - release neigh_node from lists and queue for
 289 *  free after rcu grace period
 290 * @ref: kref pointer of the neigh_node
 291 */
 292static void batadv_neigh_node_release(struct kref *ref)
 293{
 294        struct hlist_node *node_tmp;
 295        struct batadv_neigh_node *neigh_node;
 296        struct batadv_neigh_ifinfo *neigh_ifinfo;
 297
 298        neigh_node = container_of(ref, struct batadv_neigh_node, refcount);
 299
 300        hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
 301                                  &neigh_node->ifinfo_list, list) {
 302                batadv_neigh_ifinfo_put(neigh_ifinfo);
 303        }
 304
 305        batadv_hardif_neigh_put(neigh_node->hardif_neigh);
 306
 307        batadv_hardif_put(neigh_node->if_incoming);
 308
 309        kfree_rcu(neigh_node, rcu);
 310}
 311
 312/**
 313 * batadv_neigh_node_put() - decrement the neighbors refcounter and possibly
 314 *  release it
 315 * @neigh_node: neigh neighbor to free
 316 */
 317void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node)
 318{
 319        kref_put(&neigh_node->refcount, batadv_neigh_node_release);
 320}
 321
 322/**
 323 * batadv_orig_router_get() - router to the originator depending on iface
 324 * @orig_node: the orig node for the router
 325 * @if_outgoing: the interface where the payload packet has been received or
 326 *  the OGM should be sent to
 327 *
 328 * Return: the neighbor which should be router for this orig_node/iface.
 329 *
 330 * The object is returned with refcounter increased by 1.
 331 */
 332struct batadv_neigh_node *
 333batadv_orig_router_get(struct batadv_orig_node *orig_node,
 334                       const struct batadv_hard_iface *if_outgoing)
 335{
 336        struct batadv_orig_ifinfo *orig_ifinfo;
 337        struct batadv_neigh_node *router = NULL;
 338
 339        rcu_read_lock();
 340        hlist_for_each_entry_rcu(orig_ifinfo, &orig_node->ifinfo_list, list) {
 341                if (orig_ifinfo->if_outgoing != if_outgoing)
 342                        continue;
 343
 344                router = rcu_dereference(orig_ifinfo->router);
 345                break;
 346        }
 347
 348        if (router && !kref_get_unless_zero(&router->refcount))
 349                router = NULL;
 350
 351        rcu_read_unlock();
 352        return router;
 353}
 354
 355/**
 356 * batadv_orig_ifinfo_get() - find the ifinfo from an orig_node
 357 * @orig_node: the orig node to be queried
 358 * @if_outgoing: the interface for which the ifinfo should be acquired
 359 *
 360 * Return: the requested orig_ifinfo or NULL if not found.
 361 *
 362 * The object is returned with refcounter increased by 1.
 363 */
 364struct batadv_orig_ifinfo *
 365batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
 366                       struct batadv_hard_iface *if_outgoing)
 367{
 368        struct batadv_orig_ifinfo *tmp, *orig_ifinfo = NULL;
 369
 370        rcu_read_lock();
 371        hlist_for_each_entry_rcu(tmp, &orig_node->ifinfo_list,
 372                                 list) {
 373                if (tmp->if_outgoing != if_outgoing)
 374                        continue;
 375
 376                if (!kref_get_unless_zero(&tmp->refcount))
 377                        continue;
 378
 379                orig_ifinfo = tmp;
 380                break;
 381        }
 382        rcu_read_unlock();
 383
 384        return orig_ifinfo;
 385}
 386
 387/**
 388 * batadv_orig_ifinfo_new() - search and possibly create an orig_ifinfo object
 389 * @orig_node: the orig node to be queried
 390 * @if_outgoing: the interface for which the ifinfo should be acquired
 391 *
 392 * Return: NULL in case of failure or the orig_ifinfo object for the if_outgoing
 393 * interface otherwise. The object is created and added to the list
 394 * if it does not exist.
 395 *
 396 * The object is returned with refcounter increased by 1.
 397 */
 398struct batadv_orig_ifinfo *
 399batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
 400                       struct batadv_hard_iface *if_outgoing)
 401{
 402        struct batadv_orig_ifinfo *orig_ifinfo;
 403        unsigned long reset_time;
 404
 405        spin_lock_bh(&orig_node->neigh_list_lock);
 406
 407        orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_outgoing);
 408        if (orig_ifinfo)
 409                goto out;
 410
 411        orig_ifinfo = kzalloc(sizeof(*orig_ifinfo), GFP_ATOMIC);
 412        if (!orig_ifinfo)
 413                goto out;
 414
 415        if (if_outgoing != BATADV_IF_DEFAULT)
 416                kref_get(&if_outgoing->refcount);
 417
 418        reset_time = jiffies - 1;
 419        reset_time -= msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
 420        orig_ifinfo->batman_seqno_reset = reset_time;
 421        orig_ifinfo->if_outgoing = if_outgoing;
 422        INIT_HLIST_NODE(&orig_ifinfo->list);
 423        kref_init(&orig_ifinfo->refcount);
 424
 425        kref_get(&orig_ifinfo->refcount);
 426        hlist_add_head_rcu(&orig_ifinfo->list,
 427                           &orig_node->ifinfo_list);
 428out:
 429        spin_unlock_bh(&orig_node->neigh_list_lock);
 430        return orig_ifinfo;
 431}
 432
 433/**
 434 * batadv_neigh_ifinfo_get() - find the ifinfo from an neigh_node
 435 * @neigh: the neigh node to be queried
 436 * @if_outgoing: the interface for which the ifinfo should be acquired
 437 *
 438 * The object is returned with refcounter increased by 1.
 439 *
 440 * Return: the requested neigh_ifinfo or NULL if not found
 441 */
 442struct batadv_neigh_ifinfo *
 443batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
 444                        struct batadv_hard_iface *if_outgoing)
 445{
 446        struct batadv_neigh_ifinfo *neigh_ifinfo = NULL,
 447                                   *tmp_neigh_ifinfo;
 448
 449        rcu_read_lock();
 450        hlist_for_each_entry_rcu(tmp_neigh_ifinfo, &neigh->ifinfo_list,
 451                                 list) {
 452                if (tmp_neigh_ifinfo->if_outgoing != if_outgoing)
 453                        continue;
 454
 455                if (!kref_get_unless_zero(&tmp_neigh_ifinfo->refcount))
 456                        continue;
 457
 458                neigh_ifinfo = tmp_neigh_ifinfo;
 459                break;
 460        }
 461        rcu_read_unlock();
 462
 463        return neigh_ifinfo;
 464}
 465
 466/**
 467 * batadv_neigh_ifinfo_new() - search and possibly create an neigh_ifinfo object
 468 * @neigh: the neigh node to be queried
 469 * @if_outgoing: the interface for which the ifinfo should be acquired
 470 *
 471 * Return: NULL in case of failure or the neigh_ifinfo object for the
 472 * if_outgoing interface otherwise. The object is created and added to the list
 473 * if it does not exist.
 474 *
 475 * The object is returned with refcounter increased by 1.
 476 */
 477struct batadv_neigh_ifinfo *
 478batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
 479                        struct batadv_hard_iface *if_outgoing)
 480{
 481        struct batadv_neigh_ifinfo *neigh_ifinfo;
 482
 483        spin_lock_bh(&neigh->ifinfo_lock);
 484
 485        neigh_ifinfo = batadv_neigh_ifinfo_get(neigh, if_outgoing);
 486        if (neigh_ifinfo)
 487                goto out;
 488
 489        neigh_ifinfo = kzalloc(sizeof(*neigh_ifinfo), GFP_ATOMIC);
 490        if (!neigh_ifinfo)
 491                goto out;
 492
 493        if (if_outgoing)
 494                kref_get(&if_outgoing->refcount);
 495
 496        INIT_HLIST_NODE(&neigh_ifinfo->list);
 497        kref_init(&neigh_ifinfo->refcount);
 498        neigh_ifinfo->if_outgoing = if_outgoing;
 499
 500        kref_get(&neigh_ifinfo->refcount);
 501        hlist_add_head_rcu(&neigh_ifinfo->list, &neigh->ifinfo_list);
 502
 503out:
 504        spin_unlock_bh(&neigh->ifinfo_lock);
 505
 506        return neigh_ifinfo;
 507}
 508
 509/**
 510 * batadv_neigh_node_get() - retrieve a neighbour from the list
 511 * @orig_node: originator which the neighbour belongs to
 512 * @hard_iface: the interface where this neighbour is connected to
 513 * @addr: the address of the neighbour
 514 *
 515 * Looks for and possibly returns a neighbour belonging to this originator list
 516 * which is connected through the provided hard interface.
 517 *
 518 * Return: neighbor when found. Othwerwise NULL
 519 */
 520static struct batadv_neigh_node *
 521batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
 522                      const struct batadv_hard_iface *hard_iface,
 523                      const u8 *addr)
 524{
 525        struct batadv_neigh_node *tmp_neigh_node, *res = NULL;
 526
 527        rcu_read_lock();
 528        hlist_for_each_entry_rcu(tmp_neigh_node, &orig_node->neigh_list, list) {
 529                if (!batadv_compare_eth(tmp_neigh_node->addr, addr))
 530                        continue;
 531
 532                if (tmp_neigh_node->if_incoming != hard_iface)
 533                        continue;
 534
 535                if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
 536                        continue;
 537
 538                res = tmp_neigh_node;
 539                break;
 540        }
 541        rcu_read_unlock();
 542
 543        return res;
 544}
 545
 546/**
 547 * batadv_hardif_neigh_create() - create a hardif neighbour node
 548 * @hard_iface: the interface this neighbour is connected to
 549 * @neigh_addr: the interface address of the neighbour to retrieve
 550 * @orig_node: originator object representing the neighbour
 551 *
 552 * Return: the hardif neighbour node if found or created or NULL otherwise.
 553 */
 554static struct batadv_hardif_neigh_node *
 555batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
 556                           const u8 *neigh_addr,
 557                           struct batadv_orig_node *orig_node)
 558{
 559        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 560        struct batadv_hardif_neigh_node *hardif_neigh;
 561
 562        spin_lock_bh(&hard_iface->neigh_list_lock);
 563
 564        /* check if neighbor hasn't been added in the meantime */
 565        hardif_neigh = batadv_hardif_neigh_get(hard_iface, neigh_addr);
 566        if (hardif_neigh)
 567                goto out;
 568
 569        hardif_neigh = kzalloc(sizeof(*hardif_neigh), GFP_ATOMIC);
 570        if (!hardif_neigh)
 571                goto out;
 572
 573        kref_get(&hard_iface->refcount);
 574        INIT_HLIST_NODE(&hardif_neigh->list);
 575        ether_addr_copy(hardif_neigh->addr, neigh_addr);
 576        ether_addr_copy(hardif_neigh->orig, orig_node->orig);
 577        hardif_neigh->if_incoming = hard_iface;
 578        hardif_neigh->last_seen = jiffies;
 579
 580        kref_init(&hardif_neigh->refcount);
 581
 582        if (bat_priv->algo_ops->neigh.hardif_init)
 583                bat_priv->algo_ops->neigh.hardif_init(hardif_neigh);
 584
 585        hlist_add_head_rcu(&hardif_neigh->list, &hard_iface->neigh_list);
 586
 587out:
 588        spin_unlock_bh(&hard_iface->neigh_list_lock);
 589        return hardif_neigh;
 590}
 591
 592/**
 593 * batadv_hardif_neigh_get_or_create() - retrieve or create a hardif neighbour
 594 *  node
 595 * @hard_iface: the interface this neighbour is connected to
 596 * @neigh_addr: the interface address of the neighbour to retrieve
 597 * @orig_node: originator object representing the neighbour
 598 *
 599 * Return: the hardif neighbour node if found or created or NULL otherwise.
 600 */
 601static struct batadv_hardif_neigh_node *
 602batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface,
 603                                  const u8 *neigh_addr,
 604                                  struct batadv_orig_node *orig_node)
 605{
 606        struct batadv_hardif_neigh_node *hardif_neigh;
 607
 608        /* first check without locking to avoid the overhead */
 609        hardif_neigh = batadv_hardif_neigh_get(hard_iface, neigh_addr);
 610        if (hardif_neigh)
 611                return hardif_neigh;
 612
 613        return batadv_hardif_neigh_create(hard_iface, neigh_addr, orig_node);
 614}
 615
 616/**
 617 * batadv_hardif_neigh_get() - retrieve a hardif neighbour from the list
 618 * @hard_iface: the interface where this neighbour is connected to
 619 * @neigh_addr: the address of the neighbour
 620 *
 621 * Looks for and possibly returns a neighbour belonging to this hard interface.
 622 *
 623 * Return: neighbor when found. Othwerwise NULL
 624 */
 625struct batadv_hardif_neigh_node *
 626batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
 627                        const u8 *neigh_addr)
 628{
 629        struct batadv_hardif_neigh_node *tmp_hardif_neigh, *hardif_neigh = NULL;
 630
 631        rcu_read_lock();
 632        hlist_for_each_entry_rcu(tmp_hardif_neigh,
 633                                 &hard_iface->neigh_list, list) {
 634                if (!batadv_compare_eth(tmp_hardif_neigh->addr, neigh_addr))
 635                        continue;
 636
 637                if (!kref_get_unless_zero(&tmp_hardif_neigh->refcount))
 638                        continue;
 639
 640                hardif_neigh = tmp_hardif_neigh;
 641                break;
 642        }
 643        rcu_read_unlock();
 644
 645        return hardif_neigh;
 646}
 647
 648/**
 649 * batadv_neigh_node_create() - create a neigh node object
 650 * @orig_node: originator object representing the neighbour
 651 * @hard_iface: the interface where the neighbour is connected to
 652 * @neigh_addr: the mac address of the neighbour interface
 653 *
 654 * Allocates a new neigh_node object and initialises all the generic fields.
 655 *
 656 * Return: the neighbour node if found or created or NULL otherwise.
 657 */
 658static struct batadv_neigh_node *
 659batadv_neigh_node_create(struct batadv_orig_node *orig_node,
 660                         struct batadv_hard_iface *hard_iface,
 661                         const u8 *neigh_addr)
 662{
 663        struct batadv_neigh_node *neigh_node;
 664        struct batadv_hardif_neigh_node *hardif_neigh = NULL;
 665
 666        spin_lock_bh(&orig_node->neigh_list_lock);
 667
 668        neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
 669        if (neigh_node)
 670                goto out;
 671
 672        hardif_neigh = batadv_hardif_neigh_get_or_create(hard_iface,
 673                                                         neigh_addr, orig_node);
 674        if (!hardif_neigh)
 675                goto out;
 676
 677        neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
 678        if (!neigh_node)
 679                goto out;
 680
 681        INIT_HLIST_NODE(&neigh_node->list);
 682        INIT_HLIST_HEAD(&neigh_node->ifinfo_list);
 683        spin_lock_init(&neigh_node->ifinfo_lock);
 684
 685        kref_get(&hard_iface->refcount);
 686        ether_addr_copy(neigh_node->addr, neigh_addr);
 687        neigh_node->if_incoming = hard_iface;
 688        neigh_node->orig_node = orig_node;
 689        neigh_node->last_seen = jiffies;
 690
 691        /* increment unique neighbor refcount */
 692        kref_get(&hardif_neigh->refcount);
 693        neigh_node->hardif_neigh = hardif_neigh;
 694
 695        /* extra reference for return */
 696        kref_init(&neigh_node->refcount);
 697
 698        kref_get(&neigh_node->refcount);
 699        hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
 700
 701        batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv,
 702                   "Creating new neighbor %pM for orig_node %pM on interface %s\n",
 703                   neigh_addr, orig_node->orig, hard_iface->net_dev->name);
 704
 705out:
 706        spin_unlock_bh(&orig_node->neigh_list_lock);
 707
 708        if (hardif_neigh)
 709                batadv_hardif_neigh_put(hardif_neigh);
 710        return neigh_node;
 711}
 712
 713/**
 714 * batadv_neigh_node_get_or_create() - retrieve or create a neigh node object
 715 * @orig_node: originator object representing the neighbour
 716 * @hard_iface: the interface where the neighbour is connected to
 717 * @neigh_addr: the mac address of the neighbour interface
 718 *
 719 * Return: the neighbour node if found or created or NULL otherwise.
 720 */
 721struct batadv_neigh_node *
 722batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
 723                                struct batadv_hard_iface *hard_iface,
 724                                const u8 *neigh_addr)
 725{
 726        struct batadv_neigh_node *neigh_node;
 727
 728        /* first check without locking to avoid the overhead */
 729        neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
 730        if (neigh_node)
 731                return neigh_node;
 732
 733        return batadv_neigh_node_create(orig_node, hard_iface, neigh_addr);
 734}
 735
 736#ifdef CONFIG_BATMAN_ADV_DEBUGFS
 737/**
 738 * batadv_hardif_neigh_seq_print_text() - print the single hop neighbour list
 739 * @seq: neighbour table seq_file struct
 740 * @offset: not used
 741 *
 742 * Return: always 0
 743 */
 744int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset)
 745{
 746        struct net_device *net_dev = (struct net_device *)seq->private;
 747        struct batadv_priv *bat_priv = netdev_priv(net_dev);
 748        struct batadv_hard_iface *primary_if;
 749
 750        primary_if = batadv_seq_print_text_primary_if_get(seq);
 751        if (!primary_if)
 752                return 0;
 753
 754        seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n",
 755                   BATADV_SOURCE_VERSION, primary_if->net_dev->name,
 756                   primary_if->net_dev->dev_addr, net_dev->name,
 757                   bat_priv->algo_ops->name);
 758
 759        batadv_hardif_put(primary_if);
 760
 761        if (!bat_priv->algo_ops->neigh.print) {
 762                seq_puts(seq,
 763                         "No printing function for this routing protocol\n");
 764                return 0;
 765        }
 766
 767        bat_priv->algo_ops->neigh.print(bat_priv, seq);
 768        return 0;
 769}
 770#endif
 771
 772/**
 773 * batadv_hardif_neigh_dump() - Dump to netlink the neighbor infos for a
 774 *  specific outgoing interface
 775 * @msg: message to dump into
 776 * @cb: parameters for the dump
 777 *
 778 * Return: 0 or error value
 779 */
 780int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb)
 781{
 782        struct net *net = sock_net(cb->skb->sk);
 783        struct net_device *soft_iface;
 784        struct net_device *hard_iface = NULL;
 785        struct batadv_hard_iface *hardif = BATADV_IF_DEFAULT;
 786        struct batadv_priv *bat_priv;
 787        struct batadv_hard_iface *primary_if = NULL;
 788        int ret;
 789        int ifindex, hard_ifindex;
 790
 791        ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
 792        if (!ifindex)
 793                return -EINVAL;
 794
 795        soft_iface = dev_get_by_index(net, ifindex);
 796        if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
 797                ret = -ENODEV;
 798                goto out;
 799        }
 800
 801        bat_priv = netdev_priv(soft_iface);
 802
 803        primary_if = batadv_primary_if_get_selected(bat_priv);
 804        if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
 805                ret = -ENOENT;
 806                goto out;
 807        }
 808
 809        hard_ifindex = batadv_netlink_get_ifindex(cb->nlh,
 810                                                  BATADV_ATTR_HARD_IFINDEX);
 811        if (hard_ifindex) {
 812                hard_iface = dev_get_by_index(net, hard_ifindex);
 813                if (hard_iface)
 814                        hardif = batadv_hardif_get_by_netdev(hard_iface);
 815
 816                if (!hardif) {
 817                        ret = -ENODEV;
 818                        goto out;
 819                }
 820
 821                if (hardif->soft_iface != soft_iface) {
 822                        ret = -ENOENT;
 823                        goto out;
 824                }
 825        }
 826
 827        if (!bat_priv->algo_ops->neigh.dump) {
 828                ret = -EOPNOTSUPP;
 829                goto out;
 830        }
 831
 832        bat_priv->algo_ops->neigh.dump(msg, cb, bat_priv, hardif);
 833
 834        ret = msg->len;
 835
 836 out:
 837        if (hardif)
 838                batadv_hardif_put(hardif);
 839        if (hard_iface)
 840                dev_put(hard_iface);
 841        if (primary_if)
 842                batadv_hardif_put(primary_if);
 843        if (soft_iface)
 844                dev_put(soft_iface);
 845
 846        return ret;
 847}
 848
 849/**
 850 * batadv_orig_ifinfo_release() - release orig_ifinfo from lists and queue for
 851 *  free after rcu grace period
 852 * @ref: kref pointer of the orig_ifinfo
 853 */
 854static void batadv_orig_ifinfo_release(struct kref *ref)
 855{
 856        struct batadv_orig_ifinfo *orig_ifinfo;
 857        struct batadv_neigh_node *router;
 858
 859        orig_ifinfo = container_of(ref, struct batadv_orig_ifinfo, refcount);
 860
 861        if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
 862                batadv_hardif_put(orig_ifinfo->if_outgoing);
 863
 864        /* this is the last reference to this object */
 865        router = rcu_dereference_protected(orig_ifinfo->router, true);
 866        if (router)
 867                batadv_neigh_node_put(router);
 868
 869        kfree_rcu(orig_ifinfo, rcu);
 870}
 871
 872/**
 873 * batadv_orig_ifinfo_put() - decrement the refcounter and possibly release
 874 *  the orig_ifinfo
 875 * @orig_ifinfo: the orig_ifinfo object to release
 876 */
 877void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo)
 878{
 879        kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release);
 880}
 881
 882/**
 883 * batadv_orig_node_free_rcu() - free the orig_node
 884 * @rcu: rcu pointer of the orig_node
 885 */
 886static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
 887{
 888        struct batadv_orig_node *orig_node;
 889
 890        orig_node = container_of(rcu, struct batadv_orig_node, rcu);
 891
 892        batadv_mcast_purge_orig(orig_node);
 893
 894        batadv_frag_purge_orig(orig_node, NULL);
 895
 896        kfree(orig_node->tt_buff);
 897        kfree(orig_node);
 898}
 899
 900/**
 901 * batadv_orig_node_release() - release orig_node from lists and queue for
 902 *  free after rcu grace period
 903 * @ref: kref pointer of the orig_node
 904 */
 905static void batadv_orig_node_release(struct kref *ref)
 906{
 907        struct hlist_node *node_tmp;
 908        struct batadv_neigh_node *neigh_node;
 909        struct batadv_orig_node *orig_node;
 910        struct batadv_orig_ifinfo *orig_ifinfo;
 911        struct batadv_orig_node_vlan *vlan;
 912        struct batadv_orig_ifinfo *last_candidate;
 913
 914        orig_node = container_of(ref, struct batadv_orig_node, refcount);
 915
 916        spin_lock_bh(&orig_node->neigh_list_lock);
 917
 918        /* for all neighbors towards this originator ... */
 919        hlist_for_each_entry_safe(neigh_node, node_tmp,
 920                                  &orig_node->neigh_list, list) {
 921                hlist_del_rcu(&neigh_node->list);
 922                batadv_neigh_node_put(neigh_node);
 923        }
 924
 925        hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
 926                                  &orig_node->ifinfo_list, list) {
 927                hlist_del_rcu(&orig_ifinfo->list);
 928                batadv_orig_ifinfo_put(orig_ifinfo);
 929        }
 930
 931        last_candidate = orig_node->last_bonding_candidate;
 932        orig_node->last_bonding_candidate = NULL;
 933        spin_unlock_bh(&orig_node->neigh_list_lock);
 934
 935        if (last_candidate)
 936                batadv_orig_ifinfo_put(last_candidate);
 937
 938        spin_lock_bh(&orig_node->vlan_list_lock);
 939        hlist_for_each_entry_safe(vlan, node_tmp, &orig_node->vlan_list, list) {
 940                hlist_del_rcu(&vlan->list);
 941                batadv_orig_node_vlan_put(vlan);
 942        }
 943        spin_unlock_bh(&orig_node->vlan_list_lock);
 944
 945        /* Free nc_nodes */
 946        batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
 947
 948        call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
 949}
 950
 951/**
 952 * batadv_orig_node_put() - decrement the orig node refcounter and possibly
 953 *  release it
 954 * @orig_node: the orig node to free
 955 */
 956void batadv_orig_node_put(struct batadv_orig_node *orig_node)
 957{
 958        kref_put(&orig_node->refcount, batadv_orig_node_release);
 959}
 960
 961/**
 962 * batadv_originator_free() - Free all originator structures
 963 * @bat_priv: the bat priv with all the soft interface information
 964 */
 965void batadv_originator_free(struct batadv_priv *bat_priv)
 966{
 967        struct batadv_hashtable *hash = bat_priv->orig_hash;
 968        struct hlist_node *node_tmp;
 969        struct hlist_head *head;
 970        spinlock_t *list_lock; /* spinlock to protect write access */
 971        struct batadv_orig_node *orig_node;
 972        u32 i;
 973
 974        if (!hash)
 975                return;
 976
 977        cancel_delayed_work_sync(&bat_priv->orig_work);
 978
 979        bat_priv->orig_hash = NULL;
 980
 981        for (i = 0; i < hash->size; i++) {
 982                head = &hash->table[i];
 983                list_lock = &hash->list_locks[i];
 984
 985                spin_lock_bh(list_lock);
 986                hlist_for_each_entry_safe(orig_node, node_tmp,
 987                                          head, hash_entry) {
 988                        hlist_del_rcu(&orig_node->hash_entry);
 989                        batadv_orig_node_put(orig_node);
 990                }
 991                spin_unlock_bh(list_lock);
 992        }
 993
 994        batadv_hash_destroy(hash);
 995}
 996
 997/**
 998 * batadv_orig_node_new() - creates a new orig_node
 999 * @bat_priv: the bat priv with all the soft interface information
1000 * @addr: the mac address of the originator
1001 *
1002 * Creates a new originator object and initialise all the generic fields.
1003 * The new object is not added to the originator list.
1004 *
1005 * Return: the newly created object or NULL on failure.
1006 */
1007struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
1008                                              const u8 *addr)
1009{
1010        struct batadv_orig_node *orig_node;
1011        struct batadv_orig_node_vlan *vlan;
1012        unsigned long reset_time;
1013        int i;
1014
1015        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1016                   "Creating new originator: %pM\n", addr);
1017
1018        orig_node = kzalloc(sizeof(*orig_node), GFP_ATOMIC);
1019        if (!orig_node)
1020                return NULL;
1021
1022        INIT_HLIST_HEAD(&orig_node->neigh_list);
1023        INIT_HLIST_HEAD(&orig_node->vlan_list);
1024        INIT_HLIST_HEAD(&orig_node->ifinfo_list);
1025        spin_lock_init(&orig_node->bcast_seqno_lock);
1026        spin_lock_init(&orig_node->neigh_list_lock);
1027        spin_lock_init(&orig_node->tt_buff_lock);
1028        spin_lock_init(&orig_node->tt_lock);
1029        spin_lock_init(&orig_node->vlan_list_lock);
1030
1031        batadv_nc_init_orig(orig_node);
1032
1033        /* extra reference for return */
1034        kref_init(&orig_node->refcount);
1035
1036        orig_node->bat_priv = bat_priv;
1037        ether_addr_copy(orig_node->orig, addr);
1038        batadv_dat_init_orig_node_addr(orig_node);
1039        atomic_set(&orig_node->last_ttvn, 0);
1040        orig_node->tt_buff = NULL;
1041        orig_node->tt_buff_len = 0;
1042        orig_node->last_seen = jiffies;
1043        reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
1044        orig_node->bcast_seqno_reset = reset_time;
1045
1046#ifdef CONFIG_BATMAN_ADV_MCAST
1047        orig_node->mcast_flags = BATADV_MCAST_WANT_NO_RTR4;
1048        orig_node->mcast_flags |= BATADV_MCAST_WANT_NO_RTR6;
1049        INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node);
1050        INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node);
1051        INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node);
1052        spin_lock_init(&orig_node->mcast_handler_lock);
1053#endif
1054
1055        /* create a vlan object for the "untagged" LAN */
1056        vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
1057        if (!vlan)
1058                goto free_orig_node;
1059        /* batadv_orig_node_vlan_new() increases the refcounter.
1060         * Immediately release vlan since it is not needed anymore in this
1061         * context
1062         */
1063        batadv_orig_node_vlan_put(vlan);
1064
1065        for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
1066                INIT_HLIST_HEAD(&orig_node->fragments[i].fragment_list);
1067                spin_lock_init(&orig_node->fragments[i].lock);
1068                orig_node->fragments[i].size = 0;
1069        }
1070
1071        return orig_node;
1072free_orig_node:
1073        kfree(orig_node);
1074        return NULL;
1075}
1076
1077/**
1078 * batadv_purge_neigh_ifinfo() - purge obsolete ifinfo entries from neighbor
1079 * @bat_priv: the bat priv with all the soft interface information
1080 * @neigh: orig node which is to be checked
1081 */
1082static void
1083batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
1084                          struct batadv_neigh_node *neigh)
1085{
1086        struct batadv_neigh_ifinfo *neigh_ifinfo;
1087        struct batadv_hard_iface *if_outgoing;
1088        struct hlist_node *node_tmp;
1089
1090        spin_lock_bh(&neigh->ifinfo_lock);
1091
1092        /* for all ifinfo objects for this neighinator */
1093        hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
1094                                  &neigh->ifinfo_list, list) {
1095                if_outgoing = neigh_ifinfo->if_outgoing;
1096
1097                /* always keep the default interface */
1098                if (if_outgoing == BATADV_IF_DEFAULT)
1099                        continue;
1100
1101                /* don't purge if the interface is not (going) down */
1102                if (if_outgoing->if_status != BATADV_IF_INACTIVE &&
1103                    if_outgoing->if_status != BATADV_IF_NOT_IN_USE &&
1104                    if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)
1105                        continue;
1106
1107                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1108                           "neighbor/ifinfo purge: neighbor %pM, iface: %s\n",
1109                           neigh->addr, if_outgoing->net_dev->name);
1110
1111                hlist_del_rcu(&neigh_ifinfo->list);
1112                batadv_neigh_ifinfo_put(neigh_ifinfo);
1113        }
1114
1115        spin_unlock_bh(&neigh->ifinfo_lock);
1116}
1117
1118/**
1119 * batadv_purge_orig_ifinfo() - purge obsolete ifinfo entries from originator
1120 * @bat_priv: the bat priv with all the soft interface information
1121 * @orig_node: orig node which is to be checked
1122 *
1123 * Return: true if any ifinfo entry was purged, false otherwise.
1124 */
1125static bool
1126batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
1127                         struct batadv_orig_node *orig_node)
1128{
1129        struct batadv_orig_ifinfo *orig_ifinfo;
1130        struct batadv_hard_iface *if_outgoing;
1131        struct hlist_node *node_tmp;
1132        bool ifinfo_purged = false;
1133
1134        spin_lock_bh(&orig_node->neigh_list_lock);
1135
1136        /* for all ifinfo objects for this originator */
1137        hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
1138                                  &orig_node->ifinfo_list, list) {
1139                if_outgoing = orig_ifinfo->if_outgoing;
1140
1141                /* always keep the default interface */
1142                if (if_outgoing == BATADV_IF_DEFAULT)
1143                        continue;
1144
1145                /* don't purge if the interface is not (going) down */
1146                if (if_outgoing->if_status != BATADV_IF_INACTIVE &&
1147                    if_outgoing->if_status != BATADV_IF_NOT_IN_USE &&
1148                    if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)
1149                        continue;
1150
1151                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1152                           "router/ifinfo purge: originator %pM, iface: %s\n",
1153                           orig_node->orig, if_outgoing->net_dev->name);
1154
1155                ifinfo_purged = true;
1156
1157                hlist_del_rcu(&orig_ifinfo->list);
1158                batadv_orig_ifinfo_put(orig_ifinfo);
1159                if (orig_node->last_bonding_candidate == orig_ifinfo) {
1160                        orig_node->last_bonding_candidate = NULL;
1161                        batadv_orig_ifinfo_put(orig_ifinfo);
1162                }
1163        }
1164
1165        spin_unlock_bh(&orig_node->neigh_list_lock);
1166
1167        return ifinfo_purged;
1168}
1169
1170/**
1171 * batadv_purge_orig_neighbors() - purges neighbors from originator
1172 * @bat_priv: the bat priv with all the soft interface information
1173 * @orig_node: orig node which is to be checked
1174 *
1175 * Return: true if any neighbor was purged, false otherwise
1176 */
1177static bool
1178batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
1179                            struct batadv_orig_node *orig_node)
1180{
1181        struct hlist_node *node_tmp;
1182        struct batadv_neigh_node *neigh_node;
1183        bool neigh_purged = false;
1184        unsigned long last_seen;
1185        struct batadv_hard_iface *if_incoming;
1186
1187        spin_lock_bh(&orig_node->neigh_list_lock);
1188
1189        /* for all neighbors towards this originator ... */
1190        hlist_for_each_entry_safe(neigh_node, node_tmp,
1191                                  &orig_node->neigh_list, list) {
1192                last_seen = neigh_node->last_seen;
1193                if_incoming = neigh_node->if_incoming;
1194
1195                if (batadv_has_timed_out(last_seen, BATADV_PURGE_TIMEOUT) ||
1196                    if_incoming->if_status == BATADV_IF_INACTIVE ||
1197                    if_incoming->if_status == BATADV_IF_NOT_IN_USE ||
1198                    if_incoming->if_status == BATADV_IF_TO_BE_REMOVED) {
1199                        if (if_incoming->if_status == BATADV_IF_INACTIVE ||
1200                            if_incoming->if_status == BATADV_IF_NOT_IN_USE ||
1201                            if_incoming->if_status == BATADV_IF_TO_BE_REMOVED)
1202                                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1203                                           "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n",
1204                                           orig_node->orig, neigh_node->addr,
1205                                           if_incoming->net_dev->name);
1206                        else
1207                                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1208                                           "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n",
1209                                           orig_node->orig, neigh_node->addr,
1210                                           jiffies_to_msecs(last_seen));
1211
1212                        neigh_purged = true;
1213
1214                        hlist_del_rcu(&neigh_node->list);
1215                        batadv_neigh_node_put(neigh_node);
1216                } else {
1217                        /* only necessary if not the whole neighbor is to be
1218                         * deleted, but some interface has been removed.
1219                         */
1220                        batadv_purge_neigh_ifinfo(bat_priv, neigh_node);
1221                }
1222        }
1223
1224        spin_unlock_bh(&orig_node->neigh_list_lock);
1225        return neigh_purged;
1226}
1227
1228/**
1229 * batadv_find_best_neighbor() - finds the best neighbor after purging
1230 * @bat_priv: the bat priv with all the soft interface information
1231 * @orig_node: orig node which is to be checked
1232 * @if_outgoing: the interface for which the metric should be compared
1233 *
1234 * Return: the current best neighbor, with refcount increased.
1235 */
1236static struct batadv_neigh_node *
1237batadv_find_best_neighbor(struct batadv_priv *bat_priv,
1238                          struct batadv_orig_node *orig_node,
1239                          struct batadv_hard_iface *if_outgoing)
1240{
1241        struct batadv_neigh_node *best = NULL, *neigh;
1242        struct batadv_algo_ops *bao = bat_priv->algo_ops;
1243
1244        rcu_read_lock();
1245        hlist_for_each_entry_rcu(neigh, &orig_node->neigh_list, list) {
1246                if (best && (bao->neigh.cmp(neigh, if_outgoing, best,
1247                                            if_outgoing) <= 0))
1248                        continue;
1249
1250                if (!kref_get_unless_zero(&neigh->refcount))
1251                        continue;
1252
1253                if (best)
1254                        batadv_neigh_node_put(best);
1255
1256                best = neigh;
1257        }
1258        rcu_read_unlock();
1259
1260        return best;
1261}
1262
1263/**
1264 * batadv_purge_orig_node() - purges obsolete information from an orig_node
1265 * @bat_priv: the bat priv with all the soft interface information
1266 * @orig_node: orig node which is to be checked
1267 *
1268 * This function checks if the orig_node or substructures of it have become
1269 * obsolete, and purges this information if that's the case.
1270 *
1271 * Return: true if the orig_node is to be removed, false otherwise.
1272 */
1273static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
1274                                   struct batadv_orig_node *orig_node)
1275{
1276        struct batadv_neigh_node *best_neigh_node;
1277        struct batadv_hard_iface *hard_iface;
1278        bool changed_ifinfo, changed_neigh;
1279
1280        if (batadv_has_timed_out(orig_node->last_seen,
1281                                 2 * BATADV_PURGE_TIMEOUT)) {
1282                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1283                           "Originator timeout: originator %pM, last_seen %u\n",
1284                           orig_node->orig,
1285                           jiffies_to_msecs(orig_node->last_seen));
1286                return true;
1287        }
1288        changed_ifinfo = batadv_purge_orig_ifinfo(bat_priv, orig_node);
1289        changed_neigh = batadv_purge_orig_neighbors(bat_priv, orig_node);
1290
1291        if (!changed_ifinfo && !changed_neigh)
1292                return false;
1293
1294        /* first for NULL ... */
1295        best_neigh_node = batadv_find_best_neighbor(bat_priv, orig_node,
1296                                                    BATADV_IF_DEFAULT);
1297        batadv_update_route(bat_priv, orig_node, BATADV_IF_DEFAULT,
1298                            best_neigh_node);
1299        if (best_neigh_node)
1300                batadv_neigh_node_put(best_neigh_node);
1301
1302        /* ... then for all other interfaces. */
1303        rcu_read_lock();
1304        list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1305                if (hard_iface->if_status != BATADV_IF_ACTIVE)
1306                        continue;
1307
1308                if (hard_iface->soft_iface != bat_priv->soft_iface)
1309                        continue;
1310
1311                if (!kref_get_unless_zero(&hard_iface->refcount))
1312                        continue;
1313
1314                best_neigh_node = batadv_find_best_neighbor(bat_priv,
1315                                                            orig_node,
1316                                                            hard_iface);
1317                batadv_update_route(bat_priv, orig_node, hard_iface,
1318                                    best_neigh_node);
1319                if (best_neigh_node)
1320                        batadv_neigh_node_put(best_neigh_node);
1321
1322                batadv_hardif_put(hard_iface);
1323        }
1324        rcu_read_unlock();
1325
1326        return false;
1327}
1328
1329/**
1330 * batadv_purge_orig_ref() - Purge all outdated originators
1331 * @bat_priv: the bat priv with all the soft interface information
1332 */
1333void batadv_purge_orig_ref(struct batadv_priv *bat_priv)
1334{
1335        struct batadv_hashtable *hash = bat_priv->orig_hash;
1336        struct hlist_node *node_tmp;
1337        struct hlist_head *head;
1338        spinlock_t *list_lock; /* spinlock to protect write access */
1339        struct batadv_orig_node *orig_node;
1340        u32 i;
1341
1342        if (!hash)
1343                return;
1344
1345        /* for all origins... */
1346        for (i = 0; i < hash->size; i++) {
1347                head = &hash->table[i];
1348                list_lock = &hash->list_locks[i];
1349
1350                spin_lock_bh(list_lock);
1351                hlist_for_each_entry_safe(orig_node, node_tmp,
1352                                          head, hash_entry) {
1353                        if (batadv_purge_orig_node(bat_priv, orig_node)) {
1354                                batadv_gw_node_delete(bat_priv, orig_node);
1355                                hlist_del_rcu(&orig_node->hash_entry);
1356                                batadv_tt_global_del_orig(orig_node->bat_priv,
1357                                                          orig_node, -1,
1358                                                          "originator timed out");
1359                                batadv_orig_node_put(orig_node);
1360                                continue;
1361                        }
1362
1363                        batadv_frag_purge_orig(orig_node,
1364                                               batadv_frag_check_entry);
1365                }
1366                spin_unlock_bh(list_lock);
1367        }
1368
1369        batadv_gw_election(bat_priv);
1370}
1371
1372static void batadv_purge_orig(struct work_struct *work)
1373{
1374        struct delayed_work *delayed_work;
1375        struct batadv_priv *bat_priv;
1376
1377        delayed_work = to_delayed_work(work);
1378        bat_priv = container_of(delayed_work, struct batadv_priv, orig_work);
1379        batadv_purge_orig_ref(bat_priv);
1380        queue_delayed_work(batadv_event_workqueue,
1381                           &bat_priv->orig_work,
1382                           msecs_to_jiffies(BATADV_ORIG_WORK_PERIOD));
1383}
1384
1385#ifdef CONFIG_BATMAN_ADV_DEBUGFS
1386
1387/**
1388 * batadv_orig_seq_print_text() - Print the originator table in a seq file
1389 * @seq: seq file to print on
1390 * @offset: not used
1391 *
1392 * Return: always 0
1393 */
1394int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
1395{
1396        struct net_device *net_dev = (struct net_device *)seq->private;
1397        struct batadv_priv *bat_priv = netdev_priv(net_dev);
1398        struct batadv_hard_iface *primary_if;
1399
1400        primary_if = batadv_seq_print_text_primary_if_get(seq);
1401        if (!primary_if)
1402                return 0;
1403
1404        seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n",
1405                   BATADV_SOURCE_VERSION, primary_if->net_dev->name,
1406                   primary_if->net_dev->dev_addr, net_dev->name,
1407                   bat_priv->algo_ops->name);
1408
1409        batadv_hardif_put(primary_if);
1410
1411        if (!bat_priv->algo_ops->orig.print) {
1412                seq_puts(seq,
1413                         "No printing function for this routing protocol\n");
1414                return 0;
1415        }
1416
1417        bat_priv->algo_ops->orig.print(bat_priv, seq, BATADV_IF_DEFAULT);
1418
1419        return 0;
1420}
1421
1422/**
1423 * batadv_orig_hardif_seq_print_text() - writes originator infos for a specific
1424 *  outgoing interface
1425 * @seq: debugfs table seq_file struct
1426 * @offset: not used
1427 *
1428 * Return: 0
1429 */
1430int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset)
1431{
1432        struct net_device *net_dev = (struct net_device *)seq->private;
1433        struct batadv_hard_iface *hard_iface;
1434        struct batadv_priv *bat_priv;
1435
1436        hard_iface = batadv_hardif_get_by_netdev(net_dev);
1437
1438        if (!hard_iface || !hard_iface->soft_iface) {
1439                seq_puts(seq, "Interface not known to B.A.T.M.A.N.\n");
1440                goto out;
1441        }
1442
1443        bat_priv = netdev_priv(hard_iface->soft_iface);
1444        if (!bat_priv->algo_ops->orig.print) {
1445                seq_puts(seq,
1446                         "No printing function for this routing protocol\n");
1447                goto out;
1448        }
1449
1450        if (hard_iface->if_status != BATADV_IF_ACTIVE) {
1451                seq_puts(seq, "Interface not active\n");
1452                goto out;
1453        }
1454
1455        seq_printf(seq, "[B.A.T.M.A.N. adv %s, IF/MAC: %s/%pM (%s %s)]\n",
1456                   BATADV_SOURCE_VERSION, hard_iface->net_dev->name,
1457                   hard_iface->net_dev->dev_addr,
1458                   hard_iface->soft_iface->name, bat_priv->algo_ops->name);
1459
1460        bat_priv->algo_ops->orig.print(bat_priv, seq, hard_iface);
1461
1462out:
1463        if (hard_iface)
1464                batadv_hardif_put(hard_iface);
1465        return 0;
1466}
1467#endif
1468
1469/**
1470 * batadv_orig_dump() - Dump to netlink the originator infos for a specific
1471 *  outgoing interface
1472 * @msg: message to dump into
1473 * @cb: parameters for the dump
1474 *
1475 * Return: 0 or error value
1476 */
1477int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
1478{
1479        struct net *net = sock_net(cb->skb->sk);
1480        struct net_device *soft_iface;
1481        struct net_device *hard_iface = NULL;
1482        struct batadv_hard_iface *hardif = BATADV_IF_DEFAULT;
1483        struct batadv_priv *bat_priv;
1484        struct batadv_hard_iface *primary_if = NULL;
1485        int ret;
1486        int ifindex, hard_ifindex;
1487
1488        ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
1489        if (!ifindex)
1490                return -EINVAL;
1491
1492        soft_iface = dev_get_by_index(net, ifindex);
1493        if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
1494                ret = -ENODEV;
1495                goto out;
1496        }
1497
1498        bat_priv = netdev_priv(soft_iface);
1499
1500        primary_if = batadv_primary_if_get_selected(bat_priv);
1501        if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
1502                ret = -ENOENT;
1503                goto out;
1504        }
1505
1506        hard_ifindex = batadv_netlink_get_ifindex(cb->nlh,
1507                                                  BATADV_ATTR_HARD_IFINDEX);
1508        if (hard_ifindex) {
1509                hard_iface = dev_get_by_index(net, hard_ifindex);
1510                if (hard_iface)
1511                        hardif = batadv_hardif_get_by_netdev(hard_iface);
1512
1513                if (!hardif) {
1514                        ret = -ENODEV;
1515                        goto out;
1516                }
1517
1518                if (hardif->soft_iface != soft_iface) {
1519                        ret = -ENOENT;
1520                        goto out;
1521                }
1522        }
1523
1524        if (!bat_priv->algo_ops->orig.dump) {
1525                ret = -EOPNOTSUPP;
1526                goto out;
1527        }
1528
1529        bat_priv->algo_ops->orig.dump(msg, cb, bat_priv, hardif);
1530
1531        ret = msg->len;
1532
1533 out:
1534        if (hardif)
1535                batadv_hardif_put(hardif);
1536        if (hard_iface)
1537                dev_put(hard_iface);
1538        if (primary_if)
1539                batadv_hardif_put(primary_if);
1540        if (soft_iface)
1541                dev_put(soft_iface);
1542
1543        return ret;
1544}
1545