// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) B.A.T.M.A.N. contributors:
*
* Marek Lindner, Simon Wunderlich
*/
#include "originator.h"
#include "main.h"
#include <linux/atomic.h>
#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/jiffies.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/workqueue.h>
#include <net/sock.h>
#include <uapi/linux/batadv_packet.h>
#include <uapi/linux/batman_adv.h>
#include "bat_algo.h"
#include "distributed-arp-table.h"
#include "fragmentation.h"
#include "gateway_client.h"
#include "hard-interface.h"
#include "hash.h"
#include "log.h"
#include "multicast.h"
#include "netlink.h"
#include "network-coding.h"
#include "routing.h"
#include "soft-interface.h"
#include "translation-table.h"
/* hash class keys */
static struct lock_class_key batadv_orig_hash_lock_class_key;
/**
* batadv_orig_hash_find() - Find and return originator from orig_hash
* @bat_priv: the bat priv with all the soft interface information
* @data: mac address of the originator
*
* Return: orig_node (with increased refcnt), NULL on errors
*/
struct batadv_orig_node *
batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
{
struct batadv_hashtable *hash = bat_priv->orig_hash;
struct hlist_head *head;
struct batadv_orig_node *orig_node, *orig_node_tmp = NULL;
int index;
if (!hash)
return NULL;
index = batadv_choose_orig(data, hash->size);
head = &hash->table[index];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
if (!batadv_compare_eth(orig_node, data))
continue;
if (!kref_get_unless_zero(&orig_node->refcount))
continue;
orig_node_tmp = orig_node;
break;
}
rcu_read_unlock();
return orig_node_tmp;
}
static void batadv_purge_orig(struct work_struct *work);
/**
* batadv_compare_orig() - comparing function used in the originator hash table
* @node: node in the local table
* @data2: second object to compare the node to
*
* Return: true if they are the same originator
*/
bool batadv_compare_orig(const struct hlist_node *node, const void *data2)
{
const void *data1 = container_of(node, struct batadv_orig_node,
hash_entry);
return batadv_compare_eth(