^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) }