Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) 2007-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, Antonio Quartulli
^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 "translation-table.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/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/build_bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/byteorder/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/crc32c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/lockdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <uapi/linux/batadv_packet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <uapi/linux/batman_adv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include "bridge_loop_avoidance.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include "hard-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include "hash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include "originator.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include "soft-interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include "tvlv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) static struct kmem_cache *batadv_tl_cache __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static struct kmem_cache *batadv_tg_cache __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static struct kmem_cache *batadv_tt_orig_cache __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) static struct kmem_cache *batadv_tt_change_cache __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) static struct kmem_cache *batadv_tt_req_cache __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) static struct kmem_cache *batadv_tt_roam_cache __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) /* hash class keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) static struct lock_class_key batadv_tt_local_hash_lock_class_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) static struct lock_class_key batadv_tt_global_hash_lock_class_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static void batadv_send_roam_adv(struct batadv_priv *bat_priv, u8 *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 				 unsigned short vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 				 struct batadv_orig_node *orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) static void batadv_tt_purge(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static void batadv_tt_global_del(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 				 struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 				 const unsigned char *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 				 unsigned short vid, const char *message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 				 bool roaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * batadv_compare_tt() - check if two TT entries are the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * @node: the list element pointer of the first TT entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * @data2: pointer to the tt_common_entry of the second TT entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  * Compare the MAC address and the VLAN ID of the two TT entries and check if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * they are the same TT client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * Return: true if the two TT clients are the same, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static bool batadv_compare_tt(const struct hlist_node *node, const void *data2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	const void *data1 = container_of(node, struct batadv_tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 					 hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	const struct batadv_tt_common_entry *tt1 = data1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	const struct batadv_tt_common_entry *tt2 = data2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	return (tt1->vid == tt2->vid) && batadv_compare_eth(data1, data2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * batadv_choose_tt() - return the index of the tt entry in the hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  * @data: pointer to the tt_common_entry object to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * @size: the size of the hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  * Return: the hash index where the object represented by 'data' should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  * stored at.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) static inline u32 batadv_choose_tt(const void *data, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	struct batadv_tt_common_entry *tt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	u32 hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	tt = (struct batadv_tt_common_entry *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	hash = jhash(&tt->addr, ETH_ALEN, hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	hash = jhash(&tt->vid, sizeof(tt->vid), hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	return hash % size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118)  * batadv_tt_hash_find() - look for a client in the given hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119)  * @hash: the hash table to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120)  * @addr: the mac address of the client to look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  * Return: a pointer to the tt_common struct belonging to the searched client if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * found, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) static struct batadv_tt_common_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) batadv_tt_hash_find(struct batadv_hashtable *hash, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		    unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	if (!hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	ether_addr_copy(to_search.addr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	to_search.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	index = batadv_choose_tt(&to_search, hash->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	head = &hash->table[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	hlist_for_each_entry_rcu(tt, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		if (!batadv_compare_eth(tt, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		if (tt->vid != vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		if (!kref_get_unless_zero(&tt->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		tt_tmp = tt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	return tt_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  * batadv_tt_local_hash_find() - search the local table for a given client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  * @addr: the mac address of the client to look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * Return: a pointer to the corresponding tt_local_entry struct if the client is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * found, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) static struct batadv_tt_local_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 			  unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct batadv_tt_local_entry *tt_local_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 					      vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	if (tt_common_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		tt_local_entry = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 					      struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 					      common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	return tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  * batadv_tt_global_hash_find() - search the global table for a given client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * @addr: the mac address of the client to look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  * Return: a pointer to the corresponding tt_global_entry struct if the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  * is found, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) struct batadv_tt_global_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 			   unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	struct batadv_tt_global_entry *tt_global_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 					      vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	if (tt_common_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		tt_global_entry = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 					       struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 					       common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	return tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)  * batadv_tt_local_entry_free_rcu() - free the tt_local_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214)  * @rcu: rcu pointer of the tt_local_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) static void batadv_tt_local_entry_free_rcu(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	tt_local_entry = container_of(rcu, struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 				      common.rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	kmem_cache_free(batadv_tl_cache, tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  * batadv_tt_local_entry_release() - release tt_local_entry from lists and queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  *  for free after rcu grace period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  * @ref: kref pointer of the nc_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) static void batadv_tt_local_entry_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	tt_local_entry = container_of(ref, struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 				      common.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	batadv_softif_vlan_put(tt_local_entry->vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	call_rcu(&tt_local_entry->common.rcu, batadv_tt_local_entry_free_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)  * batadv_tt_local_entry_put() - decrement the tt_local_entry refcounter and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  *  possibly release it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  * @tt_local_entry: tt_local_entry to be free'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) batadv_tt_local_entry_put(struct batadv_tt_local_entry *tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	if (!tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	kref_put(&tt_local_entry->common.refcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		 batadv_tt_local_entry_release);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)  * batadv_tt_global_entry_free_rcu() - free the tt_global_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260)  * @rcu: rcu pointer of the tt_global_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	tt_global_entry = container_of(rcu, struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 				       common.rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	kmem_cache_free(batadv_tg_cache, tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273)  * batadv_tt_global_entry_release() - release tt_global_entry from lists and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274)  *  queue for free after rcu grace period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275)  * @ref: kref pointer of the nc_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) void batadv_tt_global_entry_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	tt_global_entry = container_of(ref, struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 				       common.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	batadv_tt_global_del_orig_list(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	call_rcu(&tt_global_entry->common.rcu, batadv_tt_global_entry_free_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  * batadv_tt_global_hash_count() - count the number of orig entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  * @addr: the mac address of the client to count entries for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  * Return: the number of originators advertising the given address/data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296)  * (excluding our self).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 				const u8 *addr, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	if (!tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	count = atomic_read(&tt_global_entry->orig_list_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) }
^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)  * batadv_tt_local_size_mod() - change the size by v of the local table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  *  identified by vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  * @vid: the VLAN identifier of the sub-table to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  * @v: the amount to sum to the local table size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 				     unsigned short vid, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	vlan = batadv_softif_vlan_get(bat_priv, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	if (!vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	atomic_add(v, &vlan->tt.num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	batadv_softif_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)  * batadv_tt_local_size_inc() - increase by one the local table size for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337)  *  given vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)  * @vid: the VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 				     unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	batadv_tt_local_size_mod(bat_priv, vid, 1);
^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_tt_local_size_dec() - decrease by one the local table size for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349)  *  given vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351)  * @vid: the VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 				     unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	batadv_tt_local_size_mod(bat_priv, vid, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360)  * batadv_tt_global_size_mod() - change the size by v of the global table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)  *  for orig_node identified by vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * @orig_node: the originator for which the table has to be modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * @vid: the VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  * @v: the amount to sum to the global table size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 				      unsigned short vid, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	struct batadv_orig_node_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	vlan = batadv_orig_node_vlan_new(orig_node, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	if (!vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		spin_lock_bh(&orig_node->vlan_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		if (!hlist_unhashed(&vlan->list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 			hlist_del_init_rcu(&vlan->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 			batadv_orig_node_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		spin_unlock_bh(&orig_node->vlan_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	batadv_orig_node_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  * batadv_tt_global_size_inc() - increase by one the global table size for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389)  *  given vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)  * @orig_node: the originator which global table size has to be decreased
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)  * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 				      unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	batadv_tt_global_size_mod(orig_node, vid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400)  * batadv_tt_global_size_dec() - decrease by one the global table size for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)  *  given vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)  * @orig_node: the originator which global table size has to be decreased
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403)  * @vid: the vlan identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 				      unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	batadv_tt_global_size_mod(orig_node, vid, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)  * batadv_tt_orig_list_entry_free_rcu() - free the orig_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413)  * @rcu: rcu pointer of the orig_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	kmem_cache_free(batadv_tt_orig_cache, orig_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)  * batadv_tt_orig_list_entry_release() - release tt orig entry from lists and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  *  queue for free after rcu grace period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  * @ref: kref pointer of the tt orig entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) static void batadv_tt_orig_list_entry_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	orig_entry = container_of(ref, struct batadv_tt_orig_list_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				  refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	batadv_orig_node_put(orig_entry->orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441)  * batadv_tt_orig_list_entry_put() - decrement the tt orig entry refcounter and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442)  *  possibly release it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443)  * @orig_entry: tt orig entry to be free'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry *orig_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	if (!orig_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	kref_put(&orig_entry->refcount, batadv_tt_orig_list_entry_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  * batadv_tt_local_event() - store a local TT event (ADD/DEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)  * @tt_local_entry: the TT entry involved in the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)  * @event_flags: flags to store in the event structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) static void batadv_tt_local_event(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 				  struct batadv_tt_local_entry *tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 				  u8 event_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	struct batadv_tt_change_node *tt_change_node, *entry, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	struct batadv_tt_common_entry *common = &tt_local_entry->common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	u8 flags = common->flags | event_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	bool event_removed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	bool del_op_requested, del_op_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	tt_change_node = kmem_cache_alloc(batadv_tt_change_cache, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	if (!tt_change_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	tt_change_node->change.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	memset(tt_change_node->change.reserved, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	       sizeof(tt_change_node->change.reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	ether_addr_copy(tt_change_node->change.addr, common->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	tt_change_node->change.vid = htons(common->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	del_op_requested = flags & BATADV_TT_CLIENT_DEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	/* check for ADD+DEL or DEL+ADD events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				 list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		if (!batadv_compare_eth(entry->change.addr, common->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		/* DEL+ADD in the same orig interval have no effect and can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		 * removed to avoid silly behaviour on the receiver side. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		 * other way around (ADD+DEL) can happen in case of roaming of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		 * a client still in the NEW state. Roaming of NEW clients is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		 * now possible due to automatically recognition of "temporary"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		 * clients
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		if (!del_op_requested && del_op_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 			goto del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		if (del_op_requested && !del_op_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			goto del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		/* this is a second add in the same originator interval. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		 * means that flags have been changed: update them!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		if (!del_op_requested && !del_op_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 			entry->change.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) del:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		list_del(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		kmem_cache_free(batadv_tt_change_cache, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		kmem_cache_free(batadv_tt_change_cache, tt_change_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		event_removed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	/* track the change in the OGMinterval list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	if (event_removed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		atomic_dec(&bat_priv->tt.local_changes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		atomic_inc(&bat_priv->tt.local_changes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530)  * batadv_tt_len() - compute length in bytes of given number of tt changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531)  * @changes_num: number of tt changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)  * Return: computed length in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) static int batadv_tt_len(int changes_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	return changes_num * sizeof(struct batadv_tvlv_tt_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  * batadv_tt_entries() - compute the number of entries fitting in tt_len bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  * @tt_len: available space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)  * Return: the number of entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) static u16 batadv_tt_entries(u16 tt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	return tt_len / batadv_tt_len(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) }
^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)  * batadv_tt_local_table_transmit_size() - calculates the local translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)  *  table size when transmitted over the air
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556)  * Return: local translation table size in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	u16 num_vlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	u16 tt_local_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	int hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		num_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		tt_local_entries += atomic_read(&vlan->tt.num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	/* header size of tvlv encapsulated tt response payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	hdr_size = sizeof(struct batadv_unicast_tvlv_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	hdr_size += sizeof(struct batadv_tvlv_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	hdr_size += sizeof(struct batadv_tvlv_tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	return hdr_size + batadv_tt_len(tt_local_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) static int batadv_tt_local_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	if (bat_priv->tt.local_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	bat_priv->tt.local_hash = batadv_hash_new(1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (!bat_priv->tt.local_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	batadv_hash_set_lock_class(bat_priv->tt.local_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 				   &batadv_tt_local_hash_lock_class_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) static void batadv_tt_global_free(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 				  struct batadv_tt_global_entry *tt_global,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 				  const char *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	struct batadv_tt_global_entry *tt_removed_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	struct hlist_node *tt_removed_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		   "Deleting global tt entry %pM (vid: %d): %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		   tt_global->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		   batadv_print_vid(tt_global->common.vid), message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	tt_removed_node = batadv_hash_remove(bat_priv->tt.global_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 					     batadv_compare_tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 					     batadv_choose_tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 					     &tt_global->common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	if (!tt_removed_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	/* drop reference of remove hash entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	tt_removed_entry = hlist_entry(tt_removed_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 				       struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 				       common.hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	batadv_tt_global_entry_put(tt_removed_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)  * batadv_tt_local_add() - add a new client to the local table or update an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  *  existing client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)  * @soft_iface: netdev struct of the mesh interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)  * @addr: the mac address of the client to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)  * @ifindex: index of the interface where the client is connected to (useful to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630)  *  identify wireless clients)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * @mark: the value contained in the skb->mark field of the received packet (if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  *  any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634)  * Return: true if the client was successfully added, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			 unsigned short vid, int ifindex, u32 mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	struct batadv_tt_local_entry *tt_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	struct batadv_tt_global_entry *tt_global = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	struct net *net = dev_net(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	struct net_device *in_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	struct batadv_hard_iface *in_hardif = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	int hash_added, table_size, packet_size_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	bool roamed_back = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	u8 remote_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	u32 match_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	if (ifindex != BATADV_NULL_IFINDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		in_dev = dev_get_by_index(net, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	if (in_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		in_hardif = batadv_hardif_get_by_netdev(in_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	if (!is_multicast_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	if (tt_local) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		tt_local->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				   "Re-adding pending client %pM (vid: %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				   addr, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			/* whatever the reason why the PENDING flag was set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			 * this is a client which was enqueued to be removed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			 * this orig_interval. Since it popped up again, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			 * flag can be reset like it was never enqueued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			goto add_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 				   "Roaming client %pM (vid: %d) came back to its original location\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 				   addr, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 			/* the ROAM flag is set because this client roamed away
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 			 * and the node got a roaming_advertisement message. Now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 			 * that the client popped up again at its original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			 * location such flag can be unset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 			roamed_back = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		goto check_roaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	/* Ignore the client if we cannot send it in a full table response. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	table_size = batadv_tt_local_table_transmit_size(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	table_size += batadv_tt_len(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	packet_size_max = atomic_read(&bat_priv->packet_size_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	if (table_size > packet_size_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		net_ratelimited_function(batadv_info, soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 					 "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 					 table_size, packet_size_max, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	tt_local = kmem_cache_alloc(batadv_tl_cache, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	if (!tt_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	/* increase the refcounter of the related vlan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	vlan = batadv_softif_vlan_get(bat_priv, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	if (!vlan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		net_ratelimited_function(batadv_info, soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 					 "adding TT local entry %pM to non-existent VLAN %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 					 addr, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		kmem_cache_free(batadv_tl_cache, tt_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		tt_local = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		   "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		   addr, batadv_print_vid(vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		   (u8)atomic_read(&bat_priv->tt.vn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	ether_addr_copy(tt_local->common.addr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	/* The local entry has to be marked as NEW to avoid to send it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	 * a full table response going out before the next ttvn increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	 * (consistency check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	tt_local->common.flags = BATADV_TT_CLIENT_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	tt_local->common.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	if (batadv_is_wifi_hardif(in_hardif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	kref_init(&tt_local->common.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	tt_local->last_seen = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	tt_local->common.added_at = tt_local->last_seen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	tt_local->vlan = vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	/* the batman interface mac and multicast addresses should never be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	 * purged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	if (batadv_compare_eth(addr, soft_iface->dev_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	    is_multicast_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	kref_get(&tt_local->common.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 				     batadv_choose_tt, &tt_local->common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 				     &tt_local->common.hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (unlikely(hash_added != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		/* remove the reference for the hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		batadv_tt_local_entry_put(tt_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) add_event:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) check_roaming:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	/* Check whether it is a roaming, but don't do anything if the roaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	 * process has already been handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		/* These node are probably going to update their tt table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		head = &tt_global->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		hlist_for_each_entry_rcu(orig_entry, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			batadv_send_roam_adv(bat_priv, tt_global->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 					     tt_global->common.vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 					     orig_entry->orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		if (roamed_back) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			batadv_tt_global_free(bat_priv, tt_global,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 					      "Roaming canceled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			tt_global = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			/* The global entry has to be marked as ROAMING and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			 * has to be kept for consistency purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			tt_global->roam_at = jiffies;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	/* store the current remote flags before altering them. This helps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	 * understanding is flags are changing or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	if (batadv_is_wifi_hardif(in_hardif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	/* check the mark in the skb: if it's equal to the configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	 * isolation_mark, it means the packet is coming from an isolated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	 * non-mesh client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	match_mark = (mark & bat_priv->isolation_mark_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	if (bat_priv->isolation_mark_mask &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	    match_mark == bat_priv->isolation_mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		tt_local->common.flags |= BATADV_TT_CLIENT_ISOLA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		tt_local->common.flags &= ~BATADV_TT_CLIENT_ISOLA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	/* if any "dynamic" flag has been modified, resend an ADD event for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	 * entry so that all the nodes can get the new flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	if (in_hardif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		batadv_hardif_put(in_hardif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (in_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		dev_put(in_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	if (tt_local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		batadv_tt_local_entry_put(tt_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	if (tt_global)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		batadv_tt_global_entry_put(tt_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829)  * batadv_tt_prepare_tvlv_global_data() - prepare the TVLV TT header to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830)  *  within a TT Response directed to another node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831)  * @orig_node: originator for which the TT data has to be prepared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832)  * @tt_data: uninitialised pointer to the address of the TVLV buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833)  * @tt_change: uninitialised pointer to the address of the area where the TT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834)  *  changed can be stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  *  function reserves the amount of space needed to send the entire global TT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  *  table. In case of success the value is updated with the real amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)  *  reserved bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)  * Allocate the needed amount of memory for the entire TT TVLV and write its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  * header made up of one tvlv_tt_data object and a series of tvlv_tt_vlan_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  * objects, one per active VLAN served by the originator node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843)  * Return: the size of the allocated buffer or 0 in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) static u16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 				   struct batadv_tvlv_tt_data **tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 				   struct batadv_tvlv_tt_change **tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 				   s32 *tt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	u16 num_vlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	u16 num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	u16 change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	struct batadv_orig_node_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	u8 *tt_change_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	spin_lock_bh(&orig_node->vlan_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		num_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		num_entries += atomic_read(&vlan->tt.num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	change_offset = sizeof(**tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	change_offset += num_vlan * sizeof(*tt_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	/* if tt_len is negative, allocate the space needed by the full table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	if (*tt_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		*tt_len = batadv_tt_len(num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	tvlv_len = *tt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	tvlv_len += change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	*tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	if (!*tt_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		*tt_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		goto out;
^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) 	(*tt_data)->flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	(*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	(*tt_data)->num_vlan = htons(num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		tt_vlan->vid = htons(vlan->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		tt_vlan->crc = htonl(vlan->tt.crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		tt_vlan->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		tt_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	tt_change_ptr = (u8 *)*tt_data + change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	spin_unlock_bh(&orig_node->vlan_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	return tvlv_len;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)  * batadv_tt_prepare_tvlv_local_data() - allocate and prepare the TT TVLV for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904)  *  this node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)  * @tt_data: uninitialised pointer to the address of the TVLV buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)  * @tt_change: uninitialised pointer to the address of the area where the TT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)  *  changes can be stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909)  * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)  *  function reserves the amount of space needed to send the entire local TT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)  *  table. In case of success the value is updated with the real amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)  *  reserved bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  * Allocate the needed amount of memory for the entire TT TVLV and write its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)  * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  * objects, one per active VLAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918)  * Return: the size of the allocated buffer or 0 in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static u16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 				  struct batadv_tvlv_tt_data **tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 				  struct batadv_tvlv_tt_change **tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 				  s32 *tt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	u16 num_vlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	u16 vlan_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	u16 total_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	u8 *tt_change_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	int change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	spin_lock_bh(&bat_priv->softif_vlan_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		vlan_entries = atomic_read(&vlan->tt.num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		if (vlan_entries < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		num_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		total_entries += vlan_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	change_offset = sizeof(**tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	change_offset += num_vlan * sizeof(*tt_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	/* if tt_len is negative, allocate the space needed by the full table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if (*tt_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		*tt_len = batadv_tt_len(total_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	tvlv_len = *tt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	tvlv_len += change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	*tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	if (!*tt_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		tvlv_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	(*tt_data)->flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	(*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	(*tt_data)->num_vlan = htons(num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	hlist_for_each_entry(vlan, &bat_priv->softif_vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		vlan_entries = atomic_read(&vlan->tt.num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if (vlan_entries < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		tt_vlan->vid = htons(vlan->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		tt_vlan->crc = htonl(vlan->tt.crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		tt_vlan->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		tt_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	tt_change_ptr = (u8 *)*tt_data + change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	return tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987)  * batadv_tt_tvlv_container_update() - update the translation table tvlv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988)  *  container after local tt changes have been committed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	struct batadv_tt_change_node *entry, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	struct batadv_tvlv_tt_data *tt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	struct batadv_tvlv_tt_change *tt_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	int tt_diff_len, tt_change_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	int tt_diff_entries_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	int tt_diff_entries_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	tt_diff_len = batadv_tt_len(tt_diff_entries_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	/* if we have too many changes for one packet don't send any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	 * and wait for the tt table request which will be fragmented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	if (tt_diff_len > bat_priv->soft_iface->mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		tt_diff_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 						     &tt_change, &tt_diff_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	if (!tvlv_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	tt_data->flags = BATADV_TT_OGM_DIFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	if (tt_diff_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		goto container_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	atomic_set(&bat_priv->tt.local_changes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 				 list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		if (tt_diff_entries_count < tt_diff_entries_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			memcpy(tt_change + tt_diff_entries_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 			       &entry->change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 			       sizeof(struct batadv_tvlv_tt_change));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			tt_diff_entries_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		list_del(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		kmem_cache_free(batadv_tt_change_cache, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	/* Keep the buffer for possible tt_request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	spin_lock_bh(&bat_priv->tt.last_changeset_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	kfree(bat_priv->tt.last_changeset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	bat_priv->tt.last_changeset_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	bat_priv->tt.last_changeset = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	tt_change_len = batadv_tt_len(tt_diff_entries_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	/* check whether this new OGM has no changes due to size problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (tt_diff_entries_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		/* if kmalloc() fails we will reply with the full table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		 * instead of providing the diff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		if (bat_priv->tt.last_changeset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			memcpy(bat_priv->tt.last_changeset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			       tt_change, tt_change_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			bat_priv->tt.last_changeset_len = tt_diff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) container_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 				       tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	kfree(tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)  * batadv_tt_local_seq_print_text() - Print the local tt table in a seq file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)  * @seq: seq file to print on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)  * @offset: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)  * Return: always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	struct net_device *net_dev = (struct net_device *)seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	struct batadv_priv *bat_priv = netdev_priv(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	struct batadv_tt_local_entry *tt_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	int last_seen_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	int last_seen_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	unsigned long last_seen_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	bool no_purge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	u16 np_flag = BATADV_TT_CLIENT_NOPURGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	primary_if = batadv_seq_print_text_primary_if_get(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		   "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		   net_dev->name, (u8)atomic_read(&bat_priv->tt.vn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		 "       Client         VID Flags    Last seen (CRC       )\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		hlist_for_each_entry_rcu(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 					 head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			tt_local = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 						struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 						common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 			last_seen_jiffies = jiffies - tt_local->last_seen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 			last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 			last_seen_secs = last_seen_msecs / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			last_seen_msecs = last_seen_msecs % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			no_purge = tt_common_entry->flags & np_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 				   " * %pM %4i [%c%c%c%c%c%c] %3u.%03u   (%#.8x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				   tt_common_entry->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 				   batadv_print_vid(tt_common_entry->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 				   ((tt_common_entry->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 				     BATADV_TT_CLIENT_ROAM) ? 'R' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 				   no_purge ? 'P' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				   ((tt_common_entry->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 				     BATADV_TT_CLIENT_NEW) ? 'N' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 				   ((tt_common_entry->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 				     BATADV_TT_CLIENT_PENDING) ? 'X' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 				   ((tt_common_entry->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 				     BATADV_TT_CLIENT_WIFI) ? 'W' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 				   ((tt_common_entry->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 				     BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 				   no_purge ? 0 : last_seen_secs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 				   no_purge ? 0 : last_seen_msecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 				   tt_local->vlan->tt.crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * batadv_tt_local_dump_entry() - Dump one TT local entry into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  * @msg :Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)  * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)  * @common: tt local & tt global common data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)  * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) batadv_tt_local_dump_entry(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 			   struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			   struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 			   struct batadv_tt_common_entry *common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	struct batadv_tt_local_entry *local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	unsigned int last_seen_msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	local = container_of(common, struct batadv_tt_local_entry, common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	last_seen_msecs = jiffies_to_msecs(jiffies - local->last_seen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	vlan = batadv_softif_vlan_get(bat_priv, common->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	if (!vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	crc = vlan->tt.crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	batadv_softif_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			  &batadv_netlink_family,  NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 			  BATADV_CMD_GET_TRANSTABLE_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	    nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	    nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	    nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	if (!(common->flags & BATADV_TT_CLIENT_NOPURGE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, last_seen_msecs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)  * batadv_tt_local_dump_bucket() - Dump one TT local bucket into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)  * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)  * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)  * @cb: Control block containing additional options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)  * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)  * @hash: hash to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)  * @bucket: bucket index to dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)  * @idx_s: Number of entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)  * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) batadv_tt_local_dump_bucket(struct sk_buff *msg, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			    struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 			    struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			    struct batadv_hashtable *hash, unsigned int bucket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			    int *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	struct batadv_tt_common_entry *common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	spin_lock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	cb->seq = atomic_read(&hash->generation) << 1 | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	hlist_for_each_entry(common, &hash->table[bucket], hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		if (idx++ < *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		if (batadv_tt_local_dump_entry(msg, portid, cb, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 					       common)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			spin_unlock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			*idx_s = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	spin_unlock_bh(&hash->list_locks[bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	*idx_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)  * batadv_tt_local_dump() - Dump TT local entries into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)  * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)  * @cb: Parameters from query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)  * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) int batadv_tt_local_dump(struct sk_buff *msg, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	struct net *net = sock_net(cb->skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	struct net_device *soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	struct batadv_hashtable *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	int ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	int bucket = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	if (!ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	soft_iface = dev_get_by_index(net, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	while (bucket < hash->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		if (batadv_tt_local_dump_bucket(msg, portid, cb, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 						hash, bucket, &idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		bucket++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	ret = msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	if (soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		dev_put(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	cb->args[0] = bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	return ret;
^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) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 			    struct batadv_tt_local_entry *tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 			    u16 flags, const char *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	batadv_tt_local_event(bat_priv, tt_local_entry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	/* The local client has to be marked as "pending to be removed" but has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	 * to be kept in the table in order to send it in a full table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	 * response issued before the net ttvn increment (consistency check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		   "Local tt entry (%pM, vid: %d) pending to be removed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		   tt_local_entry->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		   batadv_print_vid(tt_local_entry->common.vid), message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)  * batadv_tt_local_remove() - logically remove an entry from the local table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)  * @addr: the MAC address of the client to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)  * @message: message to append to the log on deletion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)  * @roaming: true if the deletion is due to a roaming event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)  * Return: the flags assigned to the local entry before being deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 			   unsigned short vid, const char *message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 			   bool roaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	struct batadv_tt_local_entry *tt_removed_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	u16 flags, curr_flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	struct hlist_node *tt_removed_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (!tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	curr_flags = tt_local_entry->common.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	flags = BATADV_TT_CLIENT_DEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	/* if this global entry addition is due to a roaming, the node has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	 * mark the local entry as "roamed" in order to correctly reroute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	 * packets later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	if (roaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 		flags |= BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		/* mark the local client as ROAMed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 					    message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	/* if this client has been added right now, it is possible to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	 * immediately purge it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 					     batadv_compare_tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 					     batadv_choose_tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 					     &tt_local_entry->common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	if (!tt_removed_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	/* drop reference of remove hash entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	tt_removed_entry = hlist_entry(tt_removed_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 				       struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 				       common.hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	batadv_tt_local_entry_put(tt_removed_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	if (tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		batadv_tt_local_entry_put(tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	return curr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)  * batadv_tt_local_purge_list() - purge inactive tt local entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)  * @head: pointer to the list containing the local tt entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)  * @timeout: parameter deciding whether a given tt local entry is considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)  *  inactive or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 				       struct hlist_head *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 				       int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	struct hlist_node *node_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	hlist_for_each_entry_safe(tt_common_entry, node_tmp, head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 				  hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		tt_local_entry = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 					      struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 					      common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		/* entry already marked for deletion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		batadv_tt_local_set_pending(bat_priv, tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 					    BATADV_TT_CLIENT_DEL, "timed out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)  * batadv_tt_local_purge() - purge inactive tt local entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)  * @timeout: parameter deciding whether a given tt local entry is considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)  *  inactive or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) static void batadv_tt_local_purge(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 				  int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		list_lock = &hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		batadv_tt_local_purge_list(bat_priv, head, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		spin_unlock_bh(list_lock);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	struct batadv_hashtable *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	struct batadv_tt_local_entry *tt_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	struct hlist_node *node_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	if (!bat_priv->tt.local_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		list_lock = &hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		hlist_for_each_entry_safe(tt_common_entry, node_tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 					  head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 			hlist_del_rcu(&tt_common_entry->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 			tt_local = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 						struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 						common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 			batadv_tt_local_entry_put(tt_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		spin_unlock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	batadv_hash_destroy(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	bat_priv->tt.local_hash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) static int batadv_tt_global_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	if (bat_priv->tt.global_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	bat_priv->tt.global_hash = batadv_hash_new(1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	if (!bat_priv->tt.global_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	batadv_hash_set_lock_class(bat_priv->tt.global_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 				   &batadv_tt_global_hash_lock_class_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	struct batadv_tt_change_node *entry, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 				 list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		list_del(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		kmem_cache_free(batadv_tt_change_cache, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	atomic_set(&bat_priv->tt.local_changes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	spin_unlock_bh(&bat_priv->tt.changes_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)  * batadv_tt_global_orig_entry_find() - find a TT orig_list_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)  * @entry: the TT global entry where the orig_list_entry has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)  *  extracted from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)  * @orig_node: the originator for which the orig_list_entry has to be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)  * retrieve the orig_tt_list_entry belonging to orig_node from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)  * batadv_tt_global_entry list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)  * Return: it with an increased refcounter, NULL if not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) static struct batadv_tt_orig_list_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 				 const struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	const struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	head = &entry->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	hlist_for_each_entry_rcu(tmp_orig_entry, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 		if (tmp_orig_entry->orig_node != orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		if (!kref_get_unless_zero(&tmp_orig_entry->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		orig_entry = tmp_orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	return orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)  * batadv_tt_global_entry_has_orig() - check if a TT global entry is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)  *  handled by a given originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)  * @entry: the TT global entry to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)  * @orig_node: the originator to search in the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)  * @flags: a pointer to store TT flags for the given @entry received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)  *  from @orig_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)  * find out if an orig_node is already in the list of a tt_global_entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)  * Return: true if found, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 				const struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 				u8 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	if (orig_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 			*flags = orig_entry->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		batadv_tt_orig_list_entry_put(orig_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)  * batadv_tt_global_sync_flags() - update TT sync flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)  * @tt_global: the TT global entry to update sync flags in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)  * Updates the sync flag bits in the tt_global flag attribute with a logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)  * OR of all sync flags from any of its TT orig entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	const struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	u16 flags = BATADV_NO_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	head = &tt_global->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	hlist_for_each_entry_rcu(orig_entry, head, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		flags |= orig_entry->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	tt_global->common.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)  * batadv_tt_global_orig_entry_add() - add or update a TT orig entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)  * @tt_global: the TT global entry to add an orig entry in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)  * @orig_node: the originator to add an orig entry for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)  * @ttvn: translation table version number of this changeset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)  * @flags: TT sync flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 				struct batadv_orig_node *orig_node, int ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 				u8 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	spin_lock_bh(&tt_global->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	if (orig_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		/* refresh the ttvn: the current value could be a bogus one that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		 * was added during a "temporary client detection"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		orig_entry->ttvn = ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		orig_entry->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		goto sync_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	if (!orig_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	INIT_HLIST_NODE(&orig_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	kref_get(&orig_node->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	orig_entry->orig_node = orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	orig_entry->ttvn = ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	orig_entry->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	kref_init(&orig_entry->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	kref_get(&orig_entry->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	hlist_add_head_rcu(&orig_entry->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			   &tt_global->orig_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	atomic_inc(&tt_global->orig_list_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) sync_flags:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	batadv_tt_global_sync_flags(tt_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	if (orig_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		batadv_tt_orig_list_entry_put(orig_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	spin_unlock_bh(&tt_global->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)  * batadv_tt_global_add() - add a new TT global entry or update an existing one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)  * @orig_node: the originator announcing the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)  * @tt_addr: the mac address of the non-mesh client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)  * @flags: TT flags that have to be set for this non-mesh client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)  * @ttvn: the tt version number ever announcing this non-mesh client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)  * Add a new TT global entry for the given originator. If the entry already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)  * exists add a new reference to the given originator (a global entry can have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)  * references to multiple originators) and adjust the flags attribute to reflect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)  * the function argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)  * If a TT local entry exists for this non-mesh client remove it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)  * The caller must hold the orig_node refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)  * Return: true if the new entry has been added, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 				 struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 				 const unsigned char *tt_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 				 unsigned short vid, u16 flags, u8 ttvn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	int hash_added;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	struct batadv_tt_common_entry *common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	u16 local_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	/* ignore global entries from backbone nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	/* if the node already has a local client for this entry, it has to wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	 * for a roaming advertisement instead of manually messing up the global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	 * table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	    !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	if (!tt_global_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		tt_global_entry = kmem_cache_zalloc(batadv_tg_cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 						    GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 		if (!tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		common = &tt_global_entry->common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		ether_addr_copy(common->addr, tt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		common->vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		if (!is_multicast_ether_addr(common->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 			common->flags = flags & (~BATADV_TT_SYNC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 		tt_global_entry->roam_at = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 		/* node must store current time in case of roaming. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		 * needed to purge this entry out on timeout (if nobody claims
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		 * it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		if (flags & BATADV_TT_CLIENT_ROAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 			tt_global_entry->roam_at = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		kref_init(&common->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		common->added_at = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 		INIT_HLIST_HEAD(&tt_global_entry->orig_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		atomic_set(&tt_global_entry->orig_list_count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		spin_lock_init(&tt_global_entry->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		kref_get(&common->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		hash_added = batadv_hash_add(bat_priv->tt.global_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 					     batadv_compare_tt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 					     batadv_choose_tt, common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 					     &common->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		if (unlikely(hash_added != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 			/* remove the reference for the hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 			batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 			goto out_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		common = &tt_global_entry->common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		/* If there is already a global entry, we can use this one for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		 * our processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		 * But if we are trying to add a temporary client then here are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		 * two options at this point:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		 * 1) the global client is not a temporary client: the global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		 *    client has to be left as it is, temporary information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		 *    should never override any already known client state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		 * 2) the global client is a temporary client: purge the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 		 *    originator list and add the new one orig_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		if (flags & BATADV_TT_CLIENT_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 			if (!(common->flags & BATADV_TT_CLIENT_TEMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 			if (batadv_tt_global_entry_has_orig(tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 							    orig_node, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 				goto out_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			batadv_tt_global_del_orig_list(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 			goto add_orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		/* if the client was temporary added before receiving the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 		 * OGM announcing it, we have to clear the TEMP flag. Also,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		 * remove the previous temporary orig node and re-add it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		 * if required. If the orig entry changed, the new one which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 		 * is a non-temporary entry is preferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		if (common->flags & BATADV_TT_CLIENT_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 			batadv_tt_global_del_orig_list(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 			common->flags &= ~BATADV_TT_CLIENT_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		/* the change can carry possible "attribute" flags like the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		 * TT_CLIENT_TEMP, therefore they have to be copied in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		 * client entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 		if (!is_multicast_ether_addr(common->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 			common->flags |= flags & (~BATADV_TT_SYNC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		 * one originator left in the list and we previously received a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		 * delete + roaming change for this originator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 		 * We should first delete the old originator before adding the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 		 * new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		if (common->flags & BATADV_TT_CLIENT_ROAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 			batadv_tt_global_del_orig_list(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 			common->flags &= ~BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 			tt_global_entry->roam_at = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) add_orig_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	/* add the new orig_entry (if needed) or update it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 					flags & BATADV_TT_SYNC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 		   "Creating new global tt entry: %pM (vid: %d, via %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 		   common->addr, batadv_print_vid(common->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 		   orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) out_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	/* Do not remove multicast addresses from the local hash on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	 * global additions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	if (is_multicast_ether_addr(tt_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	/* remove address from local hash if present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 					     "global tt received",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 					     flags & BATADV_TT_CLIENT_ROAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	if (!(flags & BATADV_TT_CLIENT_ROAM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 		/* this is a normal global add. Therefore the client is not in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 		 * roaming state anymore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 		tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	if (tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	if (tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		batadv_tt_local_entry_put(tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)  * batadv_transtable_best_orig() - Get best originator list entry from tt entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)  * @tt_global_entry: global translation table entry to be analyzed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)  * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)  * Return: best originator list entry or NULL on errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) static struct batadv_tt_orig_list_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) batadv_transtable_best_orig(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 			    struct batadv_tt_global_entry *tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	struct batadv_neigh_node *router, *best_router = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	struct batadv_algo_ops *bao = bat_priv->algo_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	head = &tt_global_entry->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	hlist_for_each_entry_rcu(orig_entry, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 		router = batadv_orig_router_get(orig_entry->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 						BATADV_IF_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		if (!router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 		if (best_router &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 		    bao->neigh.cmp(router, BATADV_IF_DEFAULT, best_router,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 				   BATADV_IF_DEFAULT) <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			batadv_neigh_node_put(router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		/* release the refcount for the "old" best */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		if (best_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 			batadv_neigh_node_put(best_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		best_entry = orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 		best_router = router;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	if (best_router)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 		batadv_neigh_node_put(best_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	return best_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) #ifdef CONFIG_BATMAN_ADV_DEBUGFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)  * batadv_tt_global_print_entry() - print all orig nodes who announce the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)  *  address for this global entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)  * @tt_global_entry: global translation table entry to be printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)  * @seq: debugfs table seq_file struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)  * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) batadv_tt_global_print_entry(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 			     struct batadv_tt_global_entry *tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 			     struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	struct batadv_orig_node_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	u8 last_ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	u16 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	tt_common_entry = &tt_global_entry->common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	flags = tt_common_entry->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	if (best_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 		vlan = batadv_orig_node_vlan_get(best_entry->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 						 tt_common_entry->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		if (!vlan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 				   " * Cannot retrieve VLAN %d for originator %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 				   batadv_print_vid(tt_common_entry->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 				   best_entry->orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 			goto print_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 			   " %c %pM %4i   (%3u) via %pM     (%3u)   (%#.8x) [%c%c%c%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 			   '*', tt_global_entry->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 			   batadv_print_vid(tt_global_entry->common.vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 			   best_entry->ttvn, best_entry->orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 			   last_ttvn, vlan->tt.crc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 			   ((flags & BATADV_TT_CLIENT_ROAM) ? 'R' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 			   ((flags & BATADV_TT_CLIENT_WIFI) ? 'W' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 			   ((flags & BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 			   ((flags & BATADV_TT_CLIENT_TEMP) ? 'T' : '.'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		batadv_orig_node_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) print_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	head = &tt_global_entry->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	hlist_for_each_entry_rcu(orig_entry, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 		if (best_entry == orig_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		vlan = batadv_orig_node_vlan_get(orig_entry->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 						 tt_common_entry->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 		if (!vlan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 			seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 				   " + Cannot retrieve VLAN %d for originator %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 				   batadv_print_vid(tt_common_entry->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 				   orig_entry->orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 		last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 		seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 			   " %c %pM %4d   (%3u) via %pM     (%3u)   (%#.8x) [%c%c%c%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 			   '+', tt_global_entry->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 			   batadv_print_vid(tt_global_entry->common.vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 			   orig_entry->ttvn, orig_entry->orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 			   last_ttvn, vlan->tt.crc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 			   ((flags & BATADV_TT_CLIENT_ROAM) ? 'R' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 			   ((flags & BATADV_TT_CLIENT_WIFI) ? 'W' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 			   ((flags & BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 			   ((flags & BATADV_TT_CLIENT_TEMP) ? 'T' : '.'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 		batadv_orig_node_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)  * batadv_tt_global_seq_print_text() - Print the global tt table in a seq file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)  * @seq: seq file to print on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)  * @offset: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)  * Return: always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	struct net_device *net_dev = (struct net_device *)seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	struct batadv_priv *bat_priv = netdev_priv(net_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	struct batadv_tt_global_entry *tt_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	primary_if = batadv_seq_print_text_primary_if_get(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 		   "Globally announced TT entries received via the mesh %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 		   net_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		 "       Client         VID  (TTVN)       Originator      (Curr TTVN) (CRC       ) Flags\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		hlist_for_each_entry_rcu(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 					 head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			tt_global = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 						 struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 						 common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 			batadv_tt_global_print_entry(bat_priv, tt_global, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)  * batadv_tt_global_dump_subentry() - Dump all TT local entries into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)  * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)  * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)  * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)  * @common: tt local & tt global common data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)  * @orig: Originator node announcing a non-mesh client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)  * @best: Is the best originator for the TT entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)  * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			       struct batadv_tt_common_entry *common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 			       struct batadv_tt_orig_list_entry *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 			       bool best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	struct batadv_orig_node_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	u8 last_ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	vlan = batadv_orig_node_vlan_get(orig->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 					 common->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	if (!vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	crc = vlan->tt.crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	batadv_orig_node_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 			  NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 			  BATADV_CMD_GET_TRANSTABLE_GLOBAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	last_ttvn = atomic_read(&orig->orig_node->last_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	    nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 		    orig->orig_node->orig) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	    nla_put_u8(msg, BATADV_ATTR_TT_TTVN, orig->ttvn) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	    nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	    nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	    nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	    nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)  * batadv_tt_global_dump_entry() - Dump one TT global entry into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)  * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)  * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)  * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)  * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)  * @common: tt local & tt global common data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)  * @sub_s: Number of entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)  * This function assumes the caller holds rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)  * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) batadv_tt_global_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 			    struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 			    struct batadv_tt_common_entry *common, int *sub_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	struct batadv_tt_global_entry *global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	int sub = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	bool best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	global = container_of(common, struct batadv_tt_global_entry, common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	best_entry = batadv_transtable_best_orig(bat_priv, global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	head = &global->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	hlist_for_each_entry_rcu(orig_entry, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		if (sub++ < *sub_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		best = (orig_entry == best_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		if (batadv_tt_global_dump_subentry(msg, portid, seq, common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 						   orig_entry, best)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			*sub_s = sub - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 			return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	*sub_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)  * batadv_tt_global_dump_bucket() - Dump one TT local bucket into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)  * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)  * @portid: Port making netlink request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)  * @seq: Sequence number of netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)  * @bat_priv: The bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)  * @head: Pointer to the list containing the global tt entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)  * @idx_s: Number of entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)  * @sub: Number of entries to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)  * Return: Error code, or 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) batadv_tt_global_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 			     struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 			     struct hlist_head *head, int *idx_s, int *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	struct batadv_tt_common_entry *common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	hlist_for_each_entry_rcu(common, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		if (idx++ < *idx_s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		if (batadv_tt_global_dump_entry(msg, portid, seq, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 						common, sub)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 			*idx_s = idx - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 			return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	*idx_s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	*sub = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)  * batadv_tt_global_dump() -  Dump TT global entries into a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)  * @msg: Netlink message to dump into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)  * @cb: Parameters from query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)  * Return: Error code, or length of message on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) int batadv_tt_global_dump(struct sk_buff *msg, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	struct net *net = sock_net(cb->skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	struct net_device *soft_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	struct batadv_hashtable *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	int ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	int bucket = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	int idx = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	int sub = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	int portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	if (!ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	soft_iface = dev_get_by_index(net, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	hash = bat_priv->tt.global_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	while (bucket < hash->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		head = &hash->table[bucket];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		if (batadv_tt_global_dump_bucket(msg, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 						 cb->nlh->nlmsg_seq, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 						 head, &idx, &sub))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 		bucket++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	ret = msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	if (soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 		dev_put(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	cb->args[0] = bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	cb->args[1] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	cb->args[2] = sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)  * _batadv_tt_global_del_orig_entry() - remove and free an orig_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)  * @tt_global_entry: the global entry to remove the orig_entry from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)  * @orig_entry: the orig entry to remove and free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)  * Remove an orig_entry from its list in the given tt_global_entry and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)  * free this orig_entry afterwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)  * Caller must hold tt_global_entry->list_lock and ensure orig_entry->list is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)  * part of a list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) _batadv_tt_global_del_orig_entry(struct batadv_tt_global_entry *tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 				 struct batadv_tt_orig_list_entry *orig_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	lockdep_assert_held(&tt_global_entry->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	batadv_tt_global_size_dec(orig_entry->orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 				  tt_global_entry->common.vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	atomic_dec(&tt_global_entry->orig_list_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	/* requires holding tt_global_entry->list_lock and orig_entry->list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	 * being part of a list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	hlist_del_rcu(&orig_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	batadv_tt_orig_list_entry_put(orig_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* deletes the orig list of a tt_global_entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	struct hlist_node *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	spin_lock_bh(&tt_global_entry->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	head = &tt_global_entry->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	hlist_for_each_entry_safe(orig_entry, safe, head, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 		_batadv_tt_global_del_orig_entry(tt_global_entry, orig_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	spin_unlock_bh(&tt_global_entry->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)  * batadv_tt_global_del_orig_node() - remove orig_node from a global tt entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)  * @tt_global_entry: the global entry to remove the orig_node from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)  * @orig_node: the originator announcing the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)  * @message: message to append to the log on deletion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)  * Remove the given orig_node and its according orig_entry from the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)  * global tt entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) batadv_tt_global_del_orig_node(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 			       struct batadv_tt_global_entry *tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 			       struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 			       const char *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	struct hlist_node *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	spin_lock_bh(&tt_global_entry->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	head = &tt_global_entry->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	hlist_for_each_entry_safe(orig_entry, safe, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		if (orig_entry->orig_node == orig_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 			vid = tt_global_entry->common.vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 				   "Deleting %pM from global tt entry %pM (vid: %d): %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 				   orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 				   tt_global_entry->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 				   batadv_print_vid(vid), message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 			_batadv_tt_global_del_orig_entry(tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 							 orig_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	spin_unlock_bh(&tt_global_entry->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) /* If the client is to be deleted, we check if it is the last origantor entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)  * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)  * timer, otherwise we simply remove the originator scheduled for deletion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 			     struct batadv_tt_global_entry *tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 			     struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 			     const char *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	bool last_entry = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	struct batadv_tt_orig_list_entry *orig_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	/* no local entry exists, case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	 * Check if this is the last one or if other entries exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	head = &tt_global_entry->orig_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	hlist_for_each_entry_rcu(orig_entry, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		if (orig_entry->orig_node != orig_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 			last_entry = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	if (last_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		/* its the last one, mark for roaming. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		tt_global_entry->roam_at = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		/* there is another entry, we can simply delete this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 		 * one and can still use the other one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 		batadv_tt_global_del_orig_node(bat_priv, tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 					       orig_node, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)  * batadv_tt_global_del() - remove a client from the global table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)  * @orig_node: an originator serving this client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)  * @addr: the mac address of the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)  * @message: a message explaining the reason for deleting the client to print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)  *  for debugging purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354)  * @roaming: true if the deletion has been triggered by a roaming event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) static void batadv_tt_global_del(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 				 struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 				 const unsigned char *addr, unsigned short vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 				 const char *message, bool roaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	struct batadv_tt_local_entry *local_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	if (!tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	if (!roaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		batadv_tt_global_del_orig_node(bat_priv, tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 					       orig_node, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		if (hlist_empty(&tt_global_entry->orig_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 			batadv_tt_global_free(bat_priv, tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 					      message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	/* if we are deleting a global entry due to a roam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	 * event, there are two possibilities:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	 * 1) the client roamed from node A to node B => if there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	 *    is only one originator left for this client, we mark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	 *    it with BATADV_TT_CLIENT_ROAM, we start a timer and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	 *    wait for node B to claim it. In case of timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	 *    the entry is purged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	 *    If there are other originators left, we directly delete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	 *    the originator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	 * 2) the client roamed to us => we can directly delete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	 *    the global entry, since it is useless now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	local_entry = batadv_tt_local_hash_find(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 						tt_global_entry->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 						vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	if (local_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 		/* local entry exists, case 2: client roamed to us. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 		batadv_tt_global_del_orig_list(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		batadv_tt_global_free(bat_priv, tt_global_entry, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 		/* no local entry exists, case 1: check for roaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 		batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 					     orig_node, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	if (tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 		batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	if (local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 		batadv_tt_local_entry_put(local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413)  * batadv_tt_global_del_orig() - remove all the TT global entries belonging to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)  *  the given originator matching the provided vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)  * @orig_node: the originator owning the entries to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417)  * @match_vid: the VLAN identifier to match. If negative all the entries will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)  *  removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)  * @message: debug message to print as "reason"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 			       struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 			       s32 match_vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 			       const char *message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	struct batadv_tt_global_entry *tt_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	struct hlist_node *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	if (!hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 		list_lock = &hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 		spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 		hlist_for_each_entry_safe(tt_common_entry, safe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 					  head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 			/* remove only matching entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 			if (match_vid >= 0 && tt_common_entry->vid != match_vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 			tt_global = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 						 struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 						 common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 			batadv_tt_global_del_orig_node(bat_priv, tt_global,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 						       orig_node, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 			if (hlist_empty(&tt_global->orig_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 				vid = tt_global->common.vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 				batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 					   "Deleting global tt entry %pM (vid: %d): %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 					   tt_global->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 					   batadv_print_vid(vid), message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 				hlist_del_rcu(&tt_common_entry->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 				batadv_tt_global_entry_put(tt_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		spin_unlock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 				      char **msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	bool purge = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	    batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		purge = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		*msg = "Roaming timeout\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	    batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		purge = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		*msg = "Temporary client timeout\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	return purge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	struct hlist_node *node_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	char *msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	struct batadv_tt_common_entry *tt_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	struct batadv_tt_global_entry *tt_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		list_lock = &hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 		spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 		hlist_for_each_entry_safe(tt_common, node_tmp, head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 					  hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 			tt_global = container_of(tt_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 						 struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 						 common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 			if (!batadv_tt_global_to_purge(tt_global, &msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 				   "Deleting global tt entry %pM (vid: %d): %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 				   tt_global->common.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 				   batadv_print_vid(tt_global->common.vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 				   msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 			hlist_del_rcu(&tt_common->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 			batadv_tt_global_entry_put(tt_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		spin_unlock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	struct batadv_hashtable *hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	struct batadv_tt_global_entry *tt_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	struct hlist_node *node_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	if (!bat_priv->tt.global_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	hash = bat_priv->tt.global_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 		list_lock = &hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 		hlist_for_each_entry_safe(tt_common_entry, node_tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 					  head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 			hlist_del_rcu(&tt_common_entry->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 			tt_global = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 						 struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 						 common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 			batadv_tt_global_entry_put(tt_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		spin_unlock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	batadv_hash_destroy(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	bat_priv->tt.global_hash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 		       struct batadv_tt_global_entry *tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	    tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	/* check if the two clients are marked as isolated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	    tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)  * batadv_transtable_search() - get the mesh destination for a given client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)  * @src: mac address of the source client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)  * @addr: mac address of the destination client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)  * Return: a pointer to the originator that was selected as destination in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)  * mesh for contacting the client 'addr', NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)  * In case of multiple originators serving the same client, the function returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)  * the best one (best in terms of metric towards the destination node).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)  * If the two clients are AP isolated the function returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 						  const u8 *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 						  const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 						  unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	struct batadv_tt_local_entry *tt_local_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	struct batadv_tt_global_entry *tt_global_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	struct batadv_orig_node *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	struct batadv_tt_orig_list_entry *best_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	if (src && batadv_vlan_ap_isola_get(bat_priv, vid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 		if (!tt_local_entry ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 		    (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	if (!tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	/* check whether the clients should not communicate due to AP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	 * isolation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	if (tt_local_entry &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	    _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	/* found anything? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	if (best_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 		orig_node = best_entry->orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	if (orig_node && !kref_get_unless_zero(&orig_node->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 		orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	if (tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	if (tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 		batadv_tt_local_entry_put(tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	return orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)  * batadv_tt_global_crc() - calculates the checksum of the local table belonging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646)  *  to the given orig_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)  * @orig_node: originator for which the CRC should be computed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)  * @vid: VLAN identifier for which the CRC32 has to be computed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)  * This function computes the checksum for the global table corresponding to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)  * specific originator. In particular, the checksum is computed as follows: For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)  * each client connected to the originator the CRC32C of the MAC address and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)  * VID is computed and then all the CRC32Cs of the various clients are xor'ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655)  * together.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)  * The idea behind is that CRC32C should be used as much as possible in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)  * produce a unique hash of the table, but since the order which is used to feed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)  * the CRC32C function affects the result and since every node in the network
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)  * probably sorts the clients differently, the hash function cannot be directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)  * computed over the entire table. Hence the CRC32C is used only on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)  * the single client entry, while all the results are then xor'ed together
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)  * because the XOR operation can combine them all while trying to reduce the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)  * noise as much as possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)  * Return: the checksum of the global table of a given originator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 				struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 				unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	struct batadv_hashtable *hash = bat_priv->tt.global_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	struct batadv_tt_orig_list_entry *tt_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	struct batadv_tt_common_entry *tt_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	struct batadv_tt_global_entry *tt_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	u32 i, crc_tmp, crc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	__be16 tmp_vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 		hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 			tt_global = container_of(tt_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 						 struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 						 common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 			/* compute the CRC only for entries belonging to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 			 * VLAN identified by the vid passed as parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 			if (tt_common->vid != vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 			/* Roaming clients are in the global table for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			 * consistency only. They don't have to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 			 * taken into account while computing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 			 * global crc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 			if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 			/* Temporary clients have not been announced yet, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 			 * they have to be skipped while computing the global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			 * crc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 			if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 			/* find out if this global entry is announced by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 			 * originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 			tt_orig = batadv_tt_global_orig_entry_find(tt_global,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 								   orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			if (!tt_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 			/* use network order to read the VID: this ensures that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 			 * every node reads the bytes in the same order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 			tmp_vid = htons(tt_common->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 			crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 			/* compute the CRC on flags that have to be kept in sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 			 * among nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 			flags = tt_orig->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 			crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 			crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 			batadv_tt_orig_list_entry_put(tt_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	return crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)  * batadv_tt_local_crc() - calculates the checksum of the local table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)  * @vid: VLAN identifier for which the CRC32 has to be computed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)  * For details about the computation, please refer to the documentation for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)  * batadv_tt_global_crc().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747)  * Return: the checksum of the local table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) static u32 batadv_tt_local_crc(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 			       unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	struct batadv_tt_common_entry *tt_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	u32 i, crc_tmp, crc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	__be16 tmp_vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 			/* compute the CRC only for entries belonging to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 			 * VLAN identified by vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 			if (tt_common->vid != vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 			/* not yet committed clients have not to be taken into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 			 * account while computing the CRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 			if (tt_common->flags & BATADV_TT_CLIENT_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 			/* use network order to read the VID: this ensures that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 			 * every node reads the bytes in the same order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 			tmp_vid = htons(tt_common->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			crc_tmp = crc32c(0, &tmp_vid, sizeof(tmp_vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 			/* compute the CRC on flags that have to be kept in sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 			 * among nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 			flags = tt_common->flags & BATADV_TT_SYNC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 			crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 			crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	return crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)  * batadv_tt_req_node_release() - free tt_req node entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)  * @ref: kref pointer of the tt req_node entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) static void batadv_tt_req_node_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	struct batadv_tt_req_node *tt_req_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	tt_req_node = container_of(ref, struct batadv_tt_req_node, refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	kmem_cache_free(batadv_tt_req_cache, tt_req_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)  * batadv_tt_req_node_put() - decrement the tt_req_node refcounter and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)  *  possibly release it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)  * @tt_req_node: tt_req_node to be free'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	if (!tt_req_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	struct batadv_tt_req_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	struct hlist_node *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	spin_lock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		hlist_del_init(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		batadv_tt_req_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 				       struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 				       const void *tt_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 				       u16 tt_buff_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 	/* Replace the old buffer only if I received something in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	 * last OGM (the OGM could carry no changes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	spin_lock_bh(&orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	if (tt_buff_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		kfree(orig_node->tt_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 		orig_node->tt_buff_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 		if (orig_node->tt_buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 			memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 			orig_node->tt_buff_len = tt_buff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	spin_unlock_bh(&orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	struct batadv_tt_req_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	struct hlist_node *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	spin_lock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		if (batadv_has_timed_out(node->issued_at,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 					 BATADV_TT_REQUEST_TIMEOUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 			hlist_del_init(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 			batadv_tt_req_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)  * batadv_tt_req_node_new() - search and possibly create a tt_req_node object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)  * @orig_node: orig node this request is being issued for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)  * Return: the pointer to the new tt_req_node struct if no request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)  * has already been issued for this orig_node, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) static struct batadv_tt_req_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) batadv_tt_req_node_new(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		       struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	spin_lock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	hlist_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 		    !batadv_has_timed_out(tt_req_node_tmp->issued_at,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 					  BATADV_TT_REQUEST_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	tt_req_node = kmem_cache_alloc(batadv_tt_req_cache, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	if (!tt_req_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	kref_init(&tt_req_node->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	ether_addr_copy(tt_req_node->addr, orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	tt_req_node->issued_at = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	kref_get(&tt_req_node->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	return tt_req_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)  * batadv_tt_local_valid() - verify local tt entry and get flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913)  * @entry_ptr: to be checked local tt entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)  * @data_ptr: not used but definition required to satisfy the callback prototype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)  * @flags: a pointer to store TT flags for this client to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)  * Checks the validity of the given local TT entry. If it is, then the provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)  * flags pointer is updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)  * Return: true if the entry is a valid, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) static bool batadv_tt_local_valid(const void *entry_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 				  const void *data_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 				  u8 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 		*flags = tt_common_entry->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)  * batadv_tt_global_valid() - verify global tt entry and get flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)  * @entry_ptr: to be checked global tt entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)  * @data_ptr: an orig_node object (may be NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)  * @flags: a pointer to store TT flags for this client to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)  * Checks the validity of the given global TT entry. If it is, then the provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)  * flags pointer is updated either with the common (summed) TT flags if data_ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)  * is NULL or the specific, per originator TT flags otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)  * Return: true if the entry is a valid, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) static bool batadv_tt_global_valid(const void *entry_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 				   const void *data_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 				   u8 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	const struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 	const struct batadv_orig_node *orig_node = data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	    tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	tt_global_entry = container_of(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 				       struct batadv_tt_global_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 				       common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 					       flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)  * batadv_tt_tvlv_generate() - fill the tvlv buff with the tt entries from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)  *  specified tt hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973)  * @hash: hash table containing the tt entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)  * @tt_len: expected tvlv tt data buffer length in number of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)  * @tvlv_buff: pointer to the buffer to fill with the TT data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)  * @valid_cb: function to filter tt change entries and to return TT flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)  * @cb_data: data passed to the filter function as argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)  * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)  * is not provided then this becomes a no-op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 				    struct batadv_hashtable *hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 				    void *tvlv_buff, u16 tt_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 				    bool (*valid_cb)(const void *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 						     const void *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 						     u8 *flags),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 				    void *cb_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	struct batadv_tvlv_tt_change *tt_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	u16 tt_tot, tt_num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	tt_tot = batadv_tt_entries(tt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	if (!valid_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 		hlist_for_each_entry_rcu(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 					 head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 			if (tt_tot == tt_num_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 			ret = valid_cb(tt_common_entry, cb_data, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 			if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 			ether_addr_copy(tt_change->addr, tt_common_entry->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 			tt_change->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 			tt_change->vid = htons(tt_common_entry->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 			memset(tt_change->reserved, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 			       sizeof(tt_change->reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 			tt_num_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 			tt_change++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031)  * batadv_tt_global_check_crc() - check if all the CRCs are correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)  * @orig_node: originator for which the CRCs have to be checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033)  * @tt_vlan: pointer to the first tvlv VLAN entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)  * @num_vlan: number of tvlv VLAN entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036)  * Return: true if all the received CRCs match the locally stored ones, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)  * otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 				       struct batadv_tvlv_tt_vlan_data *tt_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 				       u16 num_vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 	struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 	struct batadv_orig_node_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 	int i, orig_num_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 	u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	/* check if each received CRC matches the locally stored one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	for (i = 0; i < num_vlan; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 		tt_vlan_tmp = tt_vlan + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		/* if orig_node is a backbone node for this VLAN, don't check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 		 * the CRC as we ignore all the global entries over it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 		if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 						   orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 						   ntohs(tt_vlan_tmp->vid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 		vlan = batadv_orig_node_vlan_get(orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 						 ntohs(tt_vlan_tmp->vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		if (!vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		crc = vlan->tt.crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		batadv_orig_node_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		if (crc != ntohl(tt_vlan_tmp->crc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	/* check if any excess VLANs exist locally for the originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 	 * which are not mentioned in the TVLV from the originator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	orig_num_vlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 		orig_num_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	if (orig_num_vlan > num_vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088)  * batadv_tt_local_update_crc() - update all the local CRCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	/* recompute the global CRC for each VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 		vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104)  * batadv_tt_global_update_crc() - update all the global CRCs for this orig_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106)  * @orig_node: the orig_node for which the CRCs have to be updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 					struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	struct batadv_orig_node_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 	/* recompute the global CRC for each VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 		/* if orig_node is a backbone node for this VLAN, don't compute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		 * the CRC as we ignore all the global entries over it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 		if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 						   vlan->vid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 		crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 		vlan->tt.crc = crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131)  * batadv_send_tt_request() - send a TT Request message to a given node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133)  * @dst_orig_node: the destination of the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)  * @ttvn: the version number that the source of the message is looking for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135)  * @tt_vlan: pointer to the first tvlv VLAN object to request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)  * @num_vlan: number of tvlv VLAN entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137)  * @full_table: ask for the entire translation table if true, while only for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)  *  last TT diff otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140)  * Return: true if the TT Request was sent, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) static bool batadv_send_tt_request(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 				   struct batadv_orig_node *dst_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 				   u8 ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 				   struct batadv_tvlv_tt_vlan_data *tt_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 				   u16 num_vlan, bool full_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	struct batadv_tt_req_node *tt_req_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	struct batadv_tvlv_tt_vlan_data *tt_vlan_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	int i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 	/* The new tt_req will be issued only if I'm not waiting for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	 * reply from the same orig_node yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	tt_req_node = batadv_tt_req_node_new(bat_priv, dst_orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	if (!tt_req_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	size = sizeof(*tvlv_tt_data) + sizeof(*tt_vlan_req) * num_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	tvlv_tt_data = kzalloc(size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	if (!tvlv_tt_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	tvlv_tt_data->flags = BATADV_TT_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	tvlv_tt_data->ttvn = ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	tvlv_tt_data->num_vlan = htons(num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 	/* send all the CRCs within the request. This is needed by intermediate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	 * nodes to ensure they have the correct table before replying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	tt_vlan_req = (struct batadv_tvlv_tt_vlan_data *)(tvlv_tt_data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	for (i = 0; i < num_vlan; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		tt_vlan_req->vid = tt_vlan->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		tt_vlan_req->crc = tt_vlan->crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 		tt_vlan_req++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 		tt_vlan++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	if (full_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 		   dst_orig_node->orig, full_table ? 'F' : '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 				 dst_orig_node->orig, BATADV_TVLV_TT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 				 tvlv_tt_data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 	if (ret && tt_req_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 		spin_lock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 		if (!hlist_unhashed(&tt_req_node->list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 			hlist_del_init(&tt_req_node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 			batadv_tt_req_node_put(tt_req_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 		spin_unlock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	if (tt_req_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 		batadv_tt_req_node_put(tt_req_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	kfree(tvlv_tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)  * batadv_send_other_tt_response() - send reply to tt request concerning another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)  *  node's translation table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)  * @tt_data: tt data containing the tt request information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224)  * @req_src: mac address of tt request sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)  * @req_dst: mac address of tt request recipient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)  * Return: true if tt request reply was sent, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 					  struct batadv_tvlv_tt_data *tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 					  u8 *req_src, u8 *req_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	struct batadv_orig_node *req_dst_orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	struct batadv_orig_node *res_dst_orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	struct batadv_tvlv_tt_change *tt_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 	bool ret = false, full_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 	u8 orig_ttvn, req_ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 	u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 	s32 tt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 		   "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 		   req_src, tt_data->ttvn, req_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 		   ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	/* Let's get the orig node of the REAL destination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	req_dst_orig_node = batadv_orig_hash_find(bat_priv, req_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	if (!req_dst_orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	res_dst_orig_node = batadv_orig_hash_find(bat_priv, req_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 	if (!res_dst_orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 	orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 	req_ttvn = tt_data->ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	/* this node doesn't have the requested data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	if (orig_ttvn != req_ttvn ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	    !batadv_tt_global_check_crc(req_dst_orig_node, tt_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 					ntohs(tt_data->num_vlan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	/* If the full table has been explicitly requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	if (tt_data->flags & BATADV_TT_FULL_TABLE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 	    !req_dst_orig_node->tt_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 		full_table = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 		full_table = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 	/* TT fragmentation hasn't been implemented yet, so send as many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	 * TT entries fit a single packet as possible only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	if (!full_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 		spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 		tt_len = req_dst_orig_node->tt_buff_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 		tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 							      &tvlv_tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 							      &tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 							      &tt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 		if (!tt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 		/* Copy the last orig_node's OGM buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 		memcpy(tt_change, req_dst_orig_node->tt_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 		       req_dst_orig_node->tt_buff_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 		spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 		/* allocate the tvlv, put the tt_data and all the tt_vlan_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 		 * in the initial part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		tt_len = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 		tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 							      &tvlv_tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 							      &tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 							      &tt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		if (!tt_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		/* fill the rest of the tvlv with the real TT entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 		batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 					tt_change, tt_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 					batadv_tt_global_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 					req_dst_orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 	/* Don't send the response, if larger than fragmented packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 	tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 		net_ratelimited_function(batadv_info, bat_priv->soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 					 "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 					 res_dst_orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	tvlv_tt_data->flags = BATADV_TT_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 	tvlv_tt_data->ttvn = req_ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	if (full_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 		tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 		   "Sending TT_RESPONSE %pM for %pM [%c] (ttvn: %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 		   res_dst_orig_node->orig, req_dst_orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 		   full_table ? 'F' : '.', req_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 	batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 				 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 				 tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 	spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	if (res_dst_orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 		batadv_orig_node_put(res_dst_orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	if (req_dst_orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 		batadv_orig_node_put(req_dst_orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	kfree(tvlv_tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)  * batadv_send_my_tt_response() - send reply to tt request concerning this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)  *  node's translation table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)  * @tt_data: tt data containing the tt request information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357)  * @req_src: mac address of tt request sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)  * Return: true if tt request reply was sent, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 				       struct batadv_tvlv_tt_data *tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 				       u8 *req_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	struct batadv_hard_iface *primary_if = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	struct batadv_tvlv_tt_change *tt_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	u8 my_ttvn, req_ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	u16 tvlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	bool full_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	s32 tt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		   "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 		   req_src, tt_data->ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 		   ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	spin_lock_bh(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 	my_ttvn = (u8)atomic_read(&bat_priv->tt.vn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	req_ttvn = tt_data->ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 	orig_node = batadv_orig_hash_find(bat_priv, req_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 	primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 	/* If the full table has been explicitly requested or the gap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	 * is too big send the whole local translation table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 	if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 	    !bat_priv->tt.last_changeset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 		full_table = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 		full_table = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	/* TT fragmentation hasn't been implemented yet, so send as many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	 * TT entries fit a single packet as possible only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	if (!full_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 		spin_lock_bh(&bat_priv->tt.last_changeset_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 		tt_len = bat_priv->tt.last_changeset_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 		tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 							     &tvlv_tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 							     &tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 							     &tt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 		if (!tt_len || !tvlv_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 		/* Copy the last orig_node's OGM buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 		memcpy(tt_change, bat_priv->tt.last_changeset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 		       bat_priv->tt.last_changeset_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 		spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 		req_ttvn = (u8)atomic_read(&bat_priv->tt.vn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 		/* allocate the tvlv, put the tt_data and all the tt_vlan_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 		 * in the initial part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 		tt_len = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 		tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 							     &tvlv_tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 							     &tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 							     &tt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 		if (!tt_len || !tvlv_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 		/* fill the rest of the tvlv with the real TT entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 		batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 					tt_change, tt_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 					batadv_tt_local_valid, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 	tvlv_tt_data->flags = BATADV_TT_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	tvlv_tt_data->ttvn = req_ttvn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	if (full_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 		   "Sending TT_RESPONSE to %pM [%c] (ttvn: %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 		   orig_node->orig, full_table ? 'F' : '.', req_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 				 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 				 tvlv_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 	spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 	spin_unlock_bh(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 	if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 		batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	kfree(tvlv_tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	/* The packet was for this host, so it doesn't need to be re-routed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471)  * batadv_send_tt_response() - send reply to tt request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473)  * @tt_data: tt data containing the tt request information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)  * @req_src: mac address of tt request sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475)  * @req_dst: mac address of tt request recipient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477)  * Return: true if tt request reply was sent, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) static bool batadv_send_tt_response(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 				    struct batadv_tvlv_tt_data *tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 				    u8 *req_src, u8 *req_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	if (batadv_is_my_mac(bat_priv, req_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 		return batadv_send_my_tt_response(bat_priv, tt_data, req_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 	return batadv_send_other_tt_response(bat_priv, tt_data, req_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 					     req_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 				      struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 				      struct batadv_tvlv_tt_change *tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 				      u16 tt_num_changes, u8 ttvn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 	int roams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	for (i = 0; i < tt_num_changes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 		if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 			roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 			batadv_tt_global_del(bat_priv, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 					     (tt_change + i)->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 					     ntohs((tt_change + i)->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 					     "tt removed by changes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 					     roams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 			if (!batadv_tt_global_add(bat_priv, orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 						  (tt_change + i)->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 						  ntohs((tt_change + i)->vid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 						  (tt_change + i)->flags, ttvn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 				/* In case of problem while storing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 				 * global_entry, we stop the updating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 				 * procedure without committing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 				 * ttvn change. This will avoid to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 				 * corrupted data on tt_request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 				  struct batadv_tvlv_tt_change *tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 				  u8 ttvn, u8 *resp_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 				  u16 num_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	struct batadv_orig_node *orig_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	orig_node = batadv_orig_hash_find(bat_priv, resp_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	/* Purge the old table first.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 	batadv_tt_global_del_orig(bat_priv, orig_node, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 				  "Received full table");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	_batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 				  ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	spin_lock_bh(&orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	kfree(orig_node->tt_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	orig_node->tt_buff_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 	orig_node->tt_buff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 	spin_unlock_bh(&orig_node->tt_buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 	atomic_set(&orig_node->last_ttvn, ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 		batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 				     struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 				     u16 tt_num_changes, u8 ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 				     struct batadv_tvlv_tt_change *tt_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	_batadv_tt_update_changes(bat_priv, orig_node, tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 				  tt_num_changes, ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 				   batadv_tt_len(tt_num_changes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 	atomic_set(&orig_node->last_ttvn, ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)  * batadv_is_my_client() - check if a client is served by the local node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569)  * @addr: the mac address of the client to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572)  * Return: true if the client is served by this node, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) bool batadv_is_my_client(struct batadv_priv *bat_priv, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 			 unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 	if (!tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	/* Check if the client has been logically deleted (but is kept for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	 * consistency purpose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	    (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	if (tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 		batadv_tt_local_entry_put(tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597)  * batadv_handle_tt_response() - process incoming tt reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599)  * @tt_data: tt data containing the tt request information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600)  * @resp_src: mac address of tt reply sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601)  * @num_entries: number of tt change entries appended to the tt data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 				      struct batadv_tvlv_tt_data *tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 				      u8 *resp_src, u16 num_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	struct batadv_tt_req_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 	struct hlist_node *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 	struct batadv_orig_node *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	struct batadv_tvlv_tt_change *tt_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	u8 *tvlv_ptr = (u8 *)tt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	u16 change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 		   "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 		   resp_src, tt_data->ttvn, num_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 		   ((tt_data->flags & BATADV_TT_FULL_TABLE) ? 'F' : '.'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	orig_node = batadv_orig_hash_find(bat_priv, resp_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 	if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	spin_lock_bh(&orig_node->tt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	change_offset = sizeof(struct batadv_tvlv_tt_vlan_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	change_offset *= ntohs(tt_data->num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 	change_offset += sizeof(*tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	tvlv_ptr += change_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 	tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 	if (tt_data->flags & BATADV_TT_FULL_TABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 		batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 				      resp_src, num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 		batadv_tt_update_changes(bat_priv, orig_node, num_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 					 tt_data->ttvn, tt_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	/* Recalculate the CRC for this orig_node and store it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	batadv_tt_global_update_crc(bat_priv, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	spin_unlock_bh(&orig_node->tt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 	/* Delete the tt_req_node from pending tt_requests list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 	spin_lock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 		if (!batadv_compare_eth(node->addr, resp_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 		hlist_del_init(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 		batadv_tt_req_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 	struct batadv_tt_roam_node *node, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 	list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 		list_del(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 		kmem_cache_free(batadv_tt_roam_cache, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	struct batadv_tt_roam_node *node, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 		if (!batadv_has_timed_out(node->first_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 					  BATADV_ROAMING_MAX_TIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 		list_del(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 		kmem_cache_free(batadv_tt_roam_cache, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690)  * batadv_tt_check_roam_count() - check if a client has roamed too frequently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692)  * @client: mac address of the roaming client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694)  * This function checks whether the client already reached the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695)  * maximum number of possible roaming phases. In this case the ROAMING_ADV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696)  * will not be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)  * Return: true if the ROAMING_ADV can be sent, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, u8 *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 	struct batadv_tt_roam_node *tt_roam_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 	spin_lock_bh(&bat_priv->tt.roam_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 	/* The new tt_req will be issued only if I'm not waiting for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	 * reply from the same orig_node yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 	list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 		if (!batadv_compare_eth(tt_roam_node->addr, client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 		if (batadv_has_timed_out(tt_roam_node->first_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 					 BATADV_ROAMING_MAX_TIME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 		if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 			/* Sorry, you roamed too many times! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 		ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 		tt_roam_node = kmem_cache_alloc(batadv_tt_roam_cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 						GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 		if (!tt_roam_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 		tt_roam_node->first_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 		atomic_set(&tt_roam_node->counter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 			   BATADV_ROAMING_MAX_COUNT - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 		ether_addr_copy(tt_roam_node->addr, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 		list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 		ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	spin_unlock_bh(&bat_priv->tt.roam_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745)  * batadv_send_roam_adv() - send a roaming advertisement message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747)  * @client: mac address of the roaming client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749)  * @orig_node: message destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751)  * Send a ROAMING_ADV message to the node which was previously serving this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752)  * client. This is done to inform the node that from now on all traffic destined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)  * for this particular roamed client has to be forwarded to the sender of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)  * roaming message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) static void batadv_send_roam_adv(struct batadv_priv *bat_priv, u8 *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 				 unsigned short vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 				 struct batadv_orig_node *orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	struct batadv_hard_iface *primary_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 	struct batadv_tvlv_roam_adv tvlv_roam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 	primary_if = batadv_primary_if_get_selected(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 	if (!primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	/* before going on we have to check whether the client has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 	 * already roamed to us too many times
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	if (!batadv_tt_check_roam_count(bat_priv, client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 		   "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 		   orig_node->orig, client, batadv_print_vid(vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	tvlv_roam.vid = htons(vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 	batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 				 orig_node->orig, BATADV_TVLV_ROAM, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 				 &tvlv_roam, sizeof(tvlv_roam));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 	if (primary_if)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 		batadv_hardif_put(primary_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) static void batadv_tt_purge(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	struct delayed_work *delayed_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 	struct batadv_priv_tt *priv_tt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	struct batadv_priv *bat_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	delayed_work = to_delayed_work(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 	priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	bat_priv = container_of(priv_tt, struct batadv_priv, tt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 	batadv_tt_global_purge(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 	batadv_tt_req_purge(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 	batadv_tt_roam_purge(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 			   msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811)  * batadv_tt_free() - Free translation table of soft interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) void batadv_tt_free(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 	batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_ROAM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	cancel_delayed_work_sync(&bat_priv->tt.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 	batadv_tt_local_table_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 	batadv_tt_global_table_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 	batadv_tt_req_list_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 	batadv_tt_changes_list_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 	batadv_tt_roam_list_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 	kfree(bat_priv->tt.last_changeset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)  * batadv_tt_local_set_flags() - set or unset the specified flags on the local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834)  *  table and possibly count them in the TT size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)  * @flags: the flag to switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)  * @enable: whether to set or unset the flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)  * @count: whether to increase the TT size by the number of changed entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv, u16 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 				      bool enable, bool count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 	struct batadv_tt_common_entry *tt_common_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 	if (!hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		hlist_for_each_entry_rcu(tt_common_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 					 head, hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 			if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 				if ((tt_common_entry->flags & flags) == flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 				tt_common_entry->flags |= flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 				if (!(tt_common_entry->flags & flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 				tt_common_entry->flags &= ~flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 			if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 			batadv_tt_local_size_inc(bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 						 tt_common_entry->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 	struct batadv_hashtable *hash = bat_priv->tt.local_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	struct batadv_tt_common_entry *tt_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 	struct batadv_tt_local_entry *tt_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	struct hlist_node *node_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 	struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	spinlock_t *list_lock; /* protects write access to the hash lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 	if (!hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	for (i = 0; i < hash->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 		head = &hash->table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 		list_lock = &hash->list_locks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 		spin_lock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 		hlist_for_each_entry_safe(tt_common, node_tmp, head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 					  hash_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 			if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 				   "Deleting local tt entry (%pM, vid: %d): pending\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 				   tt_common->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 				   batadv_print_vid(tt_common->vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 			batadv_tt_local_size_dec(bat_priv, tt_common->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 			hlist_del_rcu(&tt_common->hash_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 			tt_local = container_of(tt_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 						struct batadv_tt_local_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 						common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 			batadv_tt_local_entry_put(tt_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 		spin_unlock_bh(list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)  * batadv_tt_local_commit_changes_nolock() - commit all pending local tt changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920)  *  which have been queued in the time since the last commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923)  * Caller must hold tt->commit_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 	lockdep_assert_held(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 	if (atomic_read(&bat_priv->tt.local_changes) < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 			batadv_tt_tvlv_container_update(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 	batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 	batadv_tt_local_purge_pending_clients(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	batadv_tt_local_update_crc(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 	/* Increment the TTVN only once per OGM interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 	atomic_inc(&bat_priv->tt.vn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		   "Local changes committed, updating to ttvn %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		   (u8)atomic_read(&bat_priv->tt.vn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 	/* reset the sending counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 	atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	batadv_tt_tvlv_container_update(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952)  * batadv_tt_local_commit_changes() - commit all pending local tt changes which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953)  *  have been queued in the time since the last commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 	spin_lock_bh(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	batadv_tt_local_commit_changes_nolock(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	spin_unlock_bh(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964)  * batadv_is_ap_isolated() - Check if packet from upper layer should be dropped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966)  * @src: source mac address of packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967)  * @dst: destination mac address of packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968)  * @vid: vlan id of packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970)  * Return: true when src+dst(+vid) pair should be isolated, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, u8 *src, u8 *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 			   unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 	struct batadv_softif_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 	vlan = batadv_softif_vlan_get(bat_priv, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	if (!vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 	if (!atomic_read(&vlan->ap_isolation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		goto vlan_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 	if (!tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 		goto vlan_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 	if (!tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 		goto local_entry_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	if (_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 		ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 	batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) local_entry_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 	batadv_tt_local_entry_put(tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) vlan_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 	batadv_softif_vlan_put(vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007)  * batadv_tt_update_orig() - update global translation table with new tt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008)  *  information received via ogms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010)  * @orig_node: the orig_node of the ogm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011)  * @tt_buff: pointer to the first tvlv VLAN entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012)  * @tt_num_vlan: number of tvlv VLAN entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013)  * @tt_change: pointer to the first entry in the TT buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014)  * @tt_num_changes: number of tt changes inside the tt buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015)  * @ttvn: translation table version number of this changeset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 				  struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 				  const void *tt_buff, u16 tt_num_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 				  struct batadv_tvlv_tt_change *tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 				  u16 tt_num_changes, u8 ttvn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 	bool full_table = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	bool has_tt_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 	tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 	has_tt_init = test_bit(BATADV_ORIG_CAPA_HAS_TT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 			       &orig_node->capa_initialized);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 	/* orig table not initialised AND first diff is in the OGM OR the ttvn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 	 * increased by one -> we can apply the attached changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 	if ((!has_tt_init && ttvn == 1) || ttvn - orig_ttvn == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 		/* the OGM could not contain the changes due to their size or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 		 * because they have already been sent BATADV_TT_OGM_APPEND_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 		 * times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 		 * In this case send a tt request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 		if (!tt_num_changes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 			full_table = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 			goto request_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 		spin_lock_bh(&orig_node->tt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 		batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 					 ttvn, tt_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 		/* Even if we received the precomputed crc with the OGM, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 		 * prefer to recompute it to spot any possible inconsistency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 		 * in the global table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 		batadv_tt_global_update_crc(bat_priv, orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 		spin_unlock_bh(&orig_node->tt_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 		/* The ttvn alone is not enough to guarantee consistency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 		 * because a single value could represent different states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 		 * (due to the wrap around). Thus a node has to check whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		 * the resulting table (after applying the changes) is still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 		 * consistent or not. E.g. a node could disconnect while its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 		 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 		 * checking the CRC value is mandatory to detect the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 		 * inconsistency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 		if (!batadv_tt_global_check_crc(orig_node, tt_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 						tt_num_vlan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 			goto request_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 		/* if we missed more than one change or our tables are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 		 * in sync anymore -> request fresh tt data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 		if (!has_tt_init || ttvn != orig_ttvn ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 		    !batadv_tt_global_check_crc(orig_node, tt_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 						tt_num_vlan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) request_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 				   "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 				   orig_node->orig, ttvn, orig_ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 				   tt_num_changes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 			batadv_send_tt_request(bat_priv, orig_node, ttvn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 					       tt_vlan, tt_num_vlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 					       full_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092)  * batadv_tt_global_client_is_roaming() - check if a client is marked as roaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094)  * @addr: the mac address of the client to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097)  * Return: true if we know that the client has moved from its old originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098)  * to another one. This entry is still kept for consistency purposes and will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099)  * deleted later by a DEL or because of timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 					u8 *addr, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	struct batadv_tt_global_entry *tt_global_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	if (!tt_global_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 	ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	batadv_tt_global_entry_put(tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118)  * batadv_tt_local_client_is_roaming() - tells whether the client is roaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120)  * @addr: the mac address of the local client to query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121)  * @vid: VLAN identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123)  * Return: true if the local client is known to be roaming (it is not served by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124)  * this node anymore) or not. If yes, the client is still present in the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125)  * to keep the latter consistent with the node TTVN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 				       u8 *addr, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 	struct batadv_tt_local_entry *tt_local_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 	if (!tt_local_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 	ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 	batadv_tt_local_entry_put(tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144)  * batadv_tt_add_temporary_global_entry() - Add temporary entry to global TT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146)  * @orig_node: orig node which the temporary entry should be associated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147)  * @addr: mac address of the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148)  * @vid: VLAN id of the new temporary global translation table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150)  * Return: true when temporary tt entry could be added, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 					  struct batadv_orig_node *orig_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 					  const unsigned char *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 					  unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 	/* ignore loop detect macs, they are not supposed to be in the tt local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 	 * data as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 	if (batadv_bla_is_loopdetect_mac(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 	if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 				  BATADV_TT_CLIENT_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 				  atomic_read(&orig_node->last_ttvn)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 		   "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 		   addr, batadv_print_vid(vid), orig_node->orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176)  * batadv_tt_local_resize_to_mtu() - resize the local translation table fit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177)  *  maximum packet size that can be transported through the mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178)  * @soft_iface: netdev struct of the mesh interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)  * Remove entries older than 'timeout' and half timeout if more entries need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181)  * to be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 	int packet_size_max = atomic_read(&bat_priv->packet_size_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 	int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	bool reduced = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	spin_lock_bh(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 	while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 		table_size = batadv_tt_local_table_transmit_size(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 		if (packet_size_max >= table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 		batadv_tt_local_purge(bat_priv, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 		batadv_tt_local_purge_pending_clients(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 		timeout /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 		reduced = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 		net_ratelimited_function(batadv_info, soft_iface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 					 "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 					 packet_size_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 	/* commit these changes immediately, to avoid synchronization problem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	 * with the TTVN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 	if (reduced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 		batadv_tt_local_commit_changes_nolock(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	spin_unlock_bh(&bat_priv->tt.commit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217)  * batadv_tt_tvlv_ogm_handler_v1() - process incoming tt tvlv container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219)  * @orig: the orig_node of the ogm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220)  * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221)  * @tvlv_value: tvlv buffer containing the gateway data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222)  * @tvlv_value_len: tvlv buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 					  struct batadv_orig_node *orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 					  u8 flags, void *tvlv_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 					  u16 tvlv_value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 	struct batadv_tvlv_tt_vlan_data *tt_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 	struct batadv_tvlv_tt_change *tt_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 	struct batadv_tvlv_tt_data *tt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 	u16 num_entries, num_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	if (tvlv_value_len < sizeof(*tt_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 	tvlv_value_len -= sizeof(*tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 	num_vlan = ntohs(tt_data->num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 	if (tvlv_value_len < sizeof(*tt_vlan) * num_vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 	tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 	tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 	tvlv_value_len -= sizeof(*tt_vlan) * num_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	num_entries = batadv_tt_entries(tvlv_value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 	batadv_tt_update_orig(bat_priv, orig, tt_vlan, num_vlan, tt_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 			      num_entries, tt_data->ttvn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256)  * batadv_tt_tvlv_unicast_handler_v1() - process incoming (unicast) tt tvlv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257)  *  container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259)  * @src: mac address of tt tvlv sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260)  * @dst: mac address of tt tvlv recipient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261)  * @tvlv_value: tvlv buffer containing the tt data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262)  * @tvlv_value_len: tvlv buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264)  * Return: NET_RX_DROP if the tt tvlv is to be re-routed, NET_RX_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265)  * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 					     u8 *src, u8 *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 					     void *tvlv_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 					     u16 tvlv_value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 	struct batadv_tvlv_tt_data *tt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	u16 tt_vlan_len, tt_num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	char tt_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 	if (tvlv_value_len < sizeof(*tt_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 		return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 	tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 	tvlv_value_len -= sizeof(*tt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 	tt_vlan_len = sizeof(struct batadv_tvlv_tt_vlan_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 	tt_vlan_len *= ntohs(tt_data->num_vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	if (tvlv_value_len < tt_vlan_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 	tvlv_value_len -= tt_vlan_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 	tt_num_entries = batadv_tt_entries(tvlv_value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 	switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 	case BATADV_TT_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 		batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 		/* If this node cannot provide a TT response the tt_request is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 		 * forwarded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 		ret = batadv_send_tt_response(bat_priv, tt_data, src, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 			if (tt_data->flags & BATADV_TT_FULL_TABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 				tt_flag = 'F';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 				tt_flag = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 			batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 				   "Routing TT_REQUEST to %pM [%c]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 				   dst, tt_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 			/* tvlv API will re-route the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 			return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 	case BATADV_TT_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 		batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 		if (batadv_is_my_mac(bat_priv, dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 			batadv_handle_tt_response(bat_priv, tt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 						  src, tt_num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 			return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 		if (tt_data->flags & BATADV_TT_FULL_TABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 			tt_flag =  'F';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 			tt_flag = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 		batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 			   "Routing TT_RESPONSE to %pM [%c]\n", dst, tt_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 		/* tvlv API will re-route the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 		return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 	return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338)  * batadv_roam_tvlv_unicast_handler_v1() - process incoming tt roam tvlv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)  *  container
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341)  * @src: mac address of tt tvlv sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)  * @dst: mac address of tt tvlv recipient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343)  * @tvlv_value: tvlv buffer containing the tt data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344)  * @tvlv_value_len: tvlv buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346)  * Return: NET_RX_DROP if the tt roam tvlv is to be re-routed, NET_RX_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347)  * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 					       u8 *src, u8 *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 					       void *tvlv_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 					       u16 tvlv_value_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 	struct batadv_tvlv_roam_adv *roaming_adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	struct batadv_orig_node *orig_node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 	/* If this node is not the intended recipient of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 	 * roaming advertisement the packet is forwarded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	 * (the tvlv API will re-route the packet).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	if (!batadv_is_my_mac(bat_priv, dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 		return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	if (tvlv_value_len < sizeof(*roaming_adv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 	orig_node = batadv_orig_hash_find(bat_priv, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	if (!orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 	roaming_adv = (struct batadv_tvlv_roam_adv *)tvlv_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 	batadv_dbg(BATADV_DBG_TT, bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 		   "Received ROAMING_ADV from %pM (client %pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 		   src, roaming_adv->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 	batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 			     ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 			     atomic_read(&orig_node->last_ttvn) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 	if (orig_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 		batadv_orig_node_put(orig_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 	return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389)  * batadv_tt_init() - initialise the translation table internals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392)  * Return: 0 on success or negative error number in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) int batadv_tt_init(struct batadv_priv *bat_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 	/* synchronized flags must be remote */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 	BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 	ret = batadv_tt_local_init(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 	ret = batadv_tt_global_init(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 		batadv_tt_local_table_free(bat_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 				     batadv_tt_tvlv_unicast_handler_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 				     BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	batadv_tvlv_handler_register(bat_priv, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 				     batadv_roam_tvlv_unicast_handler_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 				     BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 			   msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427)  * batadv_tt_global_is_isolated() - check if a client is marked as isolated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428)  * @bat_priv: the bat priv with all the soft interface information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429)  * @addr: the mac address of the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430)  * @vid: the identifier of the VLAN where this client is connected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432)  * Return: true if the client is marked with the TT_CLIENT_ISOLA flag, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433)  * otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) bool batadv_tt_global_is_isolated(struct batadv_priv *bat_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 				  const u8 *addr, unsigned short vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	struct batadv_tt_global_entry *tt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 	bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 	tt = batadv_tt_global_hash_find(bat_priv, addr, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	if (!tt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	ret = tt->common.flags & BATADV_TT_CLIENT_ISOLA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 	batadv_tt_global_entry_put(tt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453)  * batadv_tt_cache_init() - Initialize tt memory object cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455)  * Return: 0 on success or negative error number in case of failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) int __init batadv_tt_cache_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 	size_t tl_size = sizeof(struct batadv_tt_local_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 	size_t tg_size = sizeof(struct batadv_tt_global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 	size_t tt_orig_size = sizeof(struct batadv_tt_orig_list_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 	size_t tt_change_size = sizeof(struct batadv_tt_change_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 	size_t tt_req_size = sizeof(struct batadv_tt_req_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 	size_t tt_roam_size = sizeof(struct batadv_tt_roam_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	batadv_tl_cache = kmem_cache_create("batadv_tl_cache", tl_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 					    SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	if (!batadv_tl_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	batadv_tg_cache = kmem_cache_create("batadv_tg_cache", tg_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 					    SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 	if (!batadv_tg_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		goto err_tt_tl_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 	batadv_tt_orig_cache = kmem_cache_create("batadv_tt_orig_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 						 tt_orig_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 						 SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 	if (!batadv_tt_orig_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 		goto err_tt_tg_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 	batadv_tt_change_cache = kmem_cache_create("batadv_tt_change_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 						   tt_change_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 						   SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 	if (!batadv_tt_change_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 		goto err_tt_orig_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 	batadv_tt_req_cache = kmem_cache_create("batadv_tt_req_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 						tt_req_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 						SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 	if (!batadv_tt_req_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 		goto err_tt_change_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 	batadv_tt_roam_cache = kmem_cache_create("batadv_tt_roam_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 						 tt_roam_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 						 SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 	if (!batadv_tt_roam_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 		goto err_tt_req_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) err_tt_req_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 	kmem_cache_destroy(batadv_tt_req_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 	batadv_tt_req_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) err_tt_change_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 	kmem_cache_destroy(batadv_tt_change_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 	batadv_tt_change_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) err_tt_orig_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 	kmem_cache_destroy(batadv_tt_orig_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 	batadv_tt_orig_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) err_tt_tg_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	kmem_cache_destroy(batadv_tg_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 	batadv_tg_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) err_tt_tl_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 	kmem_cache_destroy(batadv_tl_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 	batadv_tl_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522)  * batadv_tt_cache_destroy() - Destroy tt memory object cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) void batadv_tt_cache_destroy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	kmem_cache_destroy(batadv_tl_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 	kmem_cache_destroy(batadv_tg_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 	kmem_cache_destroy(batadv_tt_orig_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 	kmem_cache_destroy(batadv_tt_change_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 	kmem_cache_destroy(batadv_tt_req_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 	kmem_cache_destroy(batadv_tt_roam_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) }