cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

originator.c (37504B)


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