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