From: Simon Wunderlich <sw@simonwunderlich.de>
To: netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
b.a.t.m.a.n@lists.open-mesh.org,
Sven Eckelmann <sven@narfation.org>,
Simon Wunderlich <sw@simonwunderlich.de>
Subject: [PATCH net-next 03/15] batman-adv: dat: use dedicated key type for DAT hash
Date: Sat, 14 Nov 2026 10:15:44 +0100 [thread overview]
Message-ID: <20261114091556.3336038-4-sw@simonwunderlich.de> (raw)
In-Reply-To: <20261114091556.3336038-1-sw@simonwunderlich.de>
From: Sven Eckelmann <sven@narfation.org>
The DAT hash and the DHT candidate selection hash a dummy struct
batadv_dat_entry on the stack in which only ip and vid are filled.
batadv_dat_entry_hash_find() then compares ip and vid inline instead of
using batadv_compare_dat(), so the key is spelled out in three places.
Move ip and vid into a new struct batadv_dat_entry_key, embedded as
batadv_dat_entry::key. The helpers are only using this key for
hashing/comparison.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
net/batman-adv/distributed-arp-table.c | 73 ++++++++++++--------------
net/batman-adv/types.h | 19 +++++--
2 files changed, 49 insertions(+), 43 deletions(-)
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 862a3a5eab566..204d48a8257ae 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -276,19 +276,18 @@ static void batadv_dat_purge(struct work_struct *work)
/**
* batadv_compare_dat() - comparing function used in the local DAT hash table
* @node: node in the local table
- * @data2: second object to compare the node to
+ * @data2: &struct batadv_dat_entry_key to compare the node to
*
- * Return: true if the two entries are the same, false otherwise.
+ * Return: true if the entry has the given key, false otherwise.
*/
static bool batadv_compare_dat(const struct hlist_node *node, const void *data2)
{
- const struct batadv_dat_entry *entry1;
- const struct batadv_dat_entry *entry2;
+ const struct batadv_dat_entry_key *key = data2;
+ const struct batadv_dat_entry *entry;
- entry1 = container_of(node, struct batadv_dat_entry, hash_entry);
- entry2 = data2;
+ entry = container_of(node, struct batadv_dat_entry, hash_entry);
- return entry1->ip == entry2->ip && entry1->vid == entry2->vid;
+ return entry->key.ip == key->ip && entry->key.vid == key->vid;
}
/**
@@ -352,30 +351,30 @@ static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
/**
* batadv_hash_dat() - compute the hash value for an IP address
- * @data: data to hash
+ * @data: &struct batadv_dat_entry_key to hash
* @size: size of the hash table
*
* Return: the selected index in the hash table for the given data.
*/
static u32 batadv_hash_dat(const void *data, u32 size)
{
- const struct batadv_dat_entry *dat = data;
- const unsigned char *key;
+ const struct batadv_dat_entry_key *key = data;
+ const unsigned char *buf;
u32 hash = 0;
__be16 vid;
u32 i;
- key = (__force const unsigned char *)&dat->ip;
- for (i = 0; i < sizeof(dat->ip); i++) {
- hash += key[i];
+ buf = (__force const unsigned char *)&key->ip;
+ for (i = 0; i < sizeof(key->ip); i++) {
+ hash += buf[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
- vid = htons(dat->vid);
- key = (__force const unsigned char *)&vid;
- for (i = 0; i < sizeof(dat->vid); i++) {
- hash += key[i];
+ vid = htons(key->vid);
+ buf = (__force const unsigned char *)&vid;
+ for (i = 0; i < sizeof(key->vid); i++) {
+ hash += buf[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
@@ -402,26 +401,23 @@ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip,
{
struct batadv_hashtable *hash = bat_priv->dat.hash;
struct batadv_dat_entry *dat_entry_tmp = NULL;
+ struct batadv_dat_entry_key key = {
+ .ip = ip,
+ .vid = vid,
+ };
struct batadv_dat_entry *dat_entry;
- struct batadv_dat_entry to_find;
struct hlist_head *head;
u32 index;
if (!hash)
return NULL;
- to_find.ip = ip;
- to_find.vid = vid;
-
- index = batadv_hash_dat(&to_find, hash->size);
+ index = batadv_hash_dat(&key, hash->size);
head = &hash->table[index];
rcu_read_lock();
hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
- if (dat_entry->ip != ip)
- continue;
-
- if (dat_entry->vid != vid)
+ if (!batadv_compare_dat(&dat_entry->hash_entry, &key))
continue;
if (!kref_get_unless_zero(&dat_entry->refcount))
@@ -457,7 +453,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
WRITE_ONCE(dat_entry->last_update, jiffies);
batadv_dbg(BATADV_DBG_DAT, bat_priv,
"Entry updated: %pI4 %pM (vid: %d)\n",
- &dat_entry->ip, mac_addr,
+ &dat_entry->key.ip, mac_addr,
batadv_print_vid(vid));
goto out;
}
@@ -466,15 +462,15 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
if (!dat_entry)
goto out;
- dat_entry->ip = ip;
- dat_entry->vid = vid;
+ dat_entry->key.ip = ip;
+ dat_entry->key.vid = vid;
atomic64_set(&dat_entry->mac_addr, u64_mac);
WRITE_ONCE(dat_entry->last_update, jiffies);
kref_init(&dat_entry->refcount);
kref_get(&dat_entry->refcount);
hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
- batadv_hash_dat, dat_entry,
+ batadv_hash_dat, &dat_entry->key,
&dat_entry->hash_entry);
if (unlikely(hash_added != 0)) {
@@ -484,7 +480,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
}
batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n",
- &dat_entry->ip, mac_addr, batadv_print_vid(vid));
+ &dat_entry->key.ip, mac_addr, batadv_print_vid(vid));
out:
batadv_dat_entry_put(dat_entry);
@@ -712,8 +708,11 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
unsigned short vid)
{
batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX;
+ struct batadv_dat_entry_key key = {
+ .ip = ip_dst,
+ .vid = vid,
+ };
struct batadv_dat_candidate *res;
- struct batadv_dat_entry dat;
batadv_dat_addr_t ip_key;
int select;
@@ -724,9 +723,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
if (!res)
return NULL;
- dat.ip = ip_dst;
- dat.vid = vid;
- ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat,
+ ip_key = (batadv_dat_addr_t)batadv_hash_dat(&key,
BATADV_DAT_ADDR_MAX);
batadv_dbg(BATADV_DBG_DAT, bat_priv,
@@ -960,9 +957,9 @@ batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid,
u64_to_ether_addr(u64_mac, mac);
if (nla_put_in_addr(msg, BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
- dat_entry->ip) ||
+ dat_entry->key.ip) ||
nla_put(msg, BATADV_ATTR_DAT_CACHE_HWADDRESS, ETH_ALEN, mac) ||
- nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) ||
+ nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->key.vid) ||
nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) {
genlmsg_cancel(msg, hdr);
return -EMSGSIZE;
@@ -1521,7 +1518,7 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
batadv_dbg(BATADV_DBG_DAT, bat_priv,
"Doubled ARP reply removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; dat_entry: %pM-%pI4\n",
hw_src, &ip_src, hw_dst, &ip_dst,
- mac, &dat_entry->ip);
+ mac, &dat_entry->key.ip);
dropped = true;
}
}
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index aae9c38a96b48..3a340ce9660d9 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -2229,20 +2229,29 @@ struct batadv_algo_ops {
struct batadv_algo_gw_ops gw;
};
+/**
+ * struct batadv_dat_entry_key - key of a DAT entry in &batadv_priv_dat.hash
+ * and in the DHT
+ */
+struct batadv_dat_entry_key {
+ /** @ip: the IPv4 corresponding to this DAT/ARP entry */
+ __be32 ip;
+
+ /** @vid: the vlan ID associated to this entry */
+ unsigned short vid;
+};
+
/**
* struct batadv_dat_entry - it is a single entry of batman-adv ARP backend. It
* is used to stored ARP entries needed for the global DAT cache
*/
struct batadv_dat_entry {
- /** @ip: the IPv4 corresponding to this DAT/ARP entry */
- __be32 ip;
+ /** @key: hash key identifying the DAT entry */
+ struct batadv_dat_entry_key key;
/** @mac_addr: the MAC address associated to the stored IPv4 */
atomic64_t mac_addr;
- /** @vid: the vlan ID associated to this entry */
- unsigned short vid;
-
/**
* @last_update: time in jiffies when this entry was refreshed last time
*/
--
2.47.3
next prev parent reply other threads:[~2026-11-14 9:16 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 9:15 [PATCH net-next 00/15] pull request for net-next: batman-adv 2026-11-14 Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 01/15] batman-adv: bla: use dedicated key type for claim hash Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 02/15] batman-adv: bla: use dedicated key type for backbone gateway hash Simon Wunderlich
[not found] ` <sashiko-outbox-215348@kernel.org>
2026-11-15 9:37 ` Sven Eckelmann
2026-11-14 9:15 ` Simon Wunderlich [this message]
2026-11-14 9:15 ` [PATCH net-next 04/15] batman-adv: tt: use dedicated key type for hashes Simon Wunderlich
[not found] ` <sashiko-outbox-215350@kernel.org>
2026-11-15 9:42 ` Sven Eckelmann
2026-11-14 9:15 ` [PATCH net-next 05/15] batman-adv: originator: pass explicit key to orig_hash Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 06/15] batman-adv: hash: document key argument of hash operations Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 07/15] batman-adv: never consume skb in BLA rx and DAT incoming snooping Simon Wunderlich
[not found] ` <sashiko-outbox-215353@kernel.org>
2026-11-15 9:44 ` Sven Eckelmann
2026-11-14 9:15 ` [PATCH net-next 08/15] batman-adv: always consume skb in batadv_forw_packet_alloc() Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 09/15] batman-adv: split fragment forwarding into lookup and forward Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 10/15] batman-adv: document skb ownership of always-consuming functions Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 11/15] batman-adv: tt: increase hash generation when purging clients Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 12/15] batman-adv: dat: increase hash generation when purging entries Simon Wunderlich
[not found] ` <sashiko-outbox-215358@kernel.org>
2026-11-15 9:50 ` Sven Eckelmann
2026-11-14 9:15 ` [PATCH net-next 13/15] batman-adv: bla: " Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 14/15] batman-adv: increase orig hash generation when purging originators Simon Wunderlich
2026-11-14 9:15 ` [PATCH net-next 15/15] batman-adv: annotate functions returning objects with __must_check Simon Wunderlich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261114091556.3336038-4-sw@simonwunderlich.de \
--to=sw@simonwunderlich.de \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sven@narfation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox