B.A.T.M.A.N Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Linus Lüssing" <linus.luessing@c0d3.blue>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: "Linus Lüssing" <linus.luessing@c0d3.blue>
Subject: [batadv,v13 1/5] batman-adv: move local ARP reply code to subfunctions
Date: Tue,  6 Oct 2026 14:06:42 +0200	[thread overview]
Message-ID: <20261006120647.8646-2-linus.luessing@c0d3.blue> (raw)
In-Reply-To: <20261006120647.8646-1-linus.luessing@c0d3.blue>

Shorten the length of batadv_dat_snoop_outgoing_arp_request() by moving
the checks for and generation of a local ARP reply to a new subfunction.
This is also in preparation for reuseability for the DAT cache/DHT
split.

No functional change.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
 net/batman-adv/distributed-arp-table.c | 181 ++++++++++++++-----------
 1 file changed, 105 insertions(+), 76 deletions(-)

diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 74050bffedbc..1a0eb9d9812e 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -738,6 +738,103 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
 	return res;
 }
 
+/**
+ * batadv_dat_arp_create_reply() - create an ARP Reply
+ * @bat_priv: the bat priv with all the mesh interface information
+ * @ip_src: ARP sender IP
+ * @ip_dst: ARP target IP
+ * @hw_src: Ethernet source and ARP sender MAC
+ * @hw_dst: Ethernet destination and ARP target MAC
+ * @vid: VLAN identifier (optional, set to zero otherwise)
+ *
+ * Creates an ARP Reply from the given values, optionally encapsulated in a
+ * VLAN header.
+ *
+ * Return: An skb containing an ARP Reply.
+ */
+static struct sk_buff *
+batadv_dat_arp_create_reply(struct batadv_priv *bat_priv, __be32 ip_src,
+			    __be32 ip_dst, u8 *hw_src, u8 *hw_dst,
+			    unsigned short vid)
+{
+	struct sk_buff *skb;
+
+	skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->mesh_iface,
+			 ip_src, hw_dst, hw_src, hw_dst);
+	if (!skb)
+		return NULL;
+
+	skb_reset_mac_header(skb);
+
+	if (vid & BATADV_VLAN_HAS_TAG)
+		skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
+				      vid & VLAN_VID_MASK);
+
+	return skb;
+}
+
+/**
+ * batadv_dat_arp_self_reply() - (maybe) reply to a local ARP request
+ * @bat_priv: the bat priv with all the mesh interface information
+ * @ip_src: ARP request sender IP (and ARP reply target IP)
+ * @ip_dst: ARP request target IP (and ARP reply sender IP)
+ * @hw_src: Ethernet source and ARP sender MAC of ARP request
+ * @hw_dst: Ethernet destination and ARP target MAC of ARP request
+ * @vid: VLAN identifier (optional, set to zero otherwise)
+ * @arp_len: ARP packet size, including ethernet frame
+ *
+ * If the ARP request target is not a local client and if BLA is
+ * enabled and we have BLA claimed this target then generate and reply
+ * with an ARP reply locally on our mesh interface.
+ *
+ * Return: 0 if we transmitted an ARP reply, -ENOMEM if we should have but
+ * could not create an ARP reply (e.g. due to out-of-memory), -EACCSS
+ * otherwise (because the client is local or due to BLA suppression).
+ */
+static int
+batadv_dat_arp_self_reply(struct batadv_priv *bat_priv, __be32 ip_src,
+			  __be32 ip_dst, u8 *hw_src, u8 *hw_dst,
+			  unsigned short vid, unsigned int arp_len)
+{
+	struct sk_buff *skb;
+
+	/* If the ARP request is destined for a local client the local
+	 * client will answer itself. DAT would only generate a
+	 * duplicate packet.
+	 *
+	 * Moreover, if the mesh-interface is enslaved into a bridge, an
+	 * additional DAT answer may trigger kernel warnings about
+	 * a packet coming from the wrong port.
+	 */
+	if (batadv_is_my_client(bat_priv, hw_dst, vid))
+		return -EACCES;
+
+	/* If BLA is enabled, only send ARP replies if we have claimed
+	 * the destination for the ARP request or if no one else of
+	 * the backbone gws belonging to our backbone has claimed the
+	 * destination.
+	 */
+	if (!batadv_bla_check_claim(bat_priv, hw_dst, vid)) {
+		batadv_dbg(BATADV_DBG_DAT, bat_priv,
+			   "Device %pM claimed by another backbone gw. Don't send ARP reply!",
+			   hw_dst);
+		return -EACCES;
+	}
+
+	skb = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src, hw_dst,
+					  hw_src, vid);
+	if (!skb)
+		return -ENOMEM;
+
+	skb->protocol = eth_type_trans(skb, bat_priv->mesh_iface);
+
+	batadv_inc_counter(bat_priv, BATADV_CNT_RX);
+	batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, arp_len);
+
+	netif_rx(skb);
+	return 0;
+}
+
 /**
  * batadv_dat_forward_data() - copy and send payload to the selected candidates
  * @bat_priv: the bat priv with all the mesh interface information
@@ -1179,41 +1276,6 @@ static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size)
 	return vid;
 }
 
-/**
- * batadv_dat_arp_create_reply() - create an ARP Reply
- * @bat_priv: the bat priv with all the mesh interface information
- * @ip_src: ARP sender IP
- * @ip_dst: ARP target IP
- * @hw_src: Ethernet source and ARP sender MAC
- * @hw_dst: Ethernet destination and ARP target MAC
- * @vid: VLAN identifier (optional, set to zero otherwise)
- *
- * Creates an ARP Reply from the given values, optionally encapsulated in a
- * VLAN header.
- *
- * Return: An skb containing an ARP Reply.
- */
-static struct sk_buff *
-batadv_dat_arp_create_reply(struct batadv_priv *bat_priv, __be32 ip_src,
-			    __be32 ip_dst, u8 *hw_src, u8 *hw_dst,
-			    unsigned short vid)
-{
-	struct sk_buff *skb;
-
-	skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->mesh_iface,
-			 ip_src, hw_dst, hw_src, hw_dst);
-	if (!skb)
-		return NULL;
-
-	skb_reset_mac_header(skb);
-
-	if (vid & BATADV_VLAN_HAS_TAG)
-		skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
-				      vid & VLAN_VID_MASK);
-
-	return skb;
-}
-
 /**
  * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
  * answer using DAT
@@ -1232,10 +1294,9 @@ batadv_dat_arp_create_reply(struct batadv_priv *bat_priv, __be32 ip_src,
 bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
 					   struct sk_buff *skb)
 {
-	struct net_device *mesh_iface = bat_priv->mesh_iface;
 	struct batadv_dat_entry *dat_entry = NULL;
 	u8 mac[ETH_ALEN] __aligned(2);
-	struct sk_buff *skb_new;
+	unsigned int arp_len;
 	unsigned short vid;
 	bool ret = false;
 	int hdr_size = 0;
@@ -1244,6 +1305,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
 	u16 type = 0;
 	u64 u64_mac;
 	u8 *hw_src;
+	int rep;
 
 	if (!READ_ONCE(bat_priv->distributed_arp_table))
 		goto out;
@@ -1253,6 +1315,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
 		goto out;
 
 	vid = batadv_dat_get_vid(skb, &hdr_size);
+	arp_len = skb->len + ETH_HLEN + hdr_size;
 
 	type = batadv_arp_get_type(bat_priv, skb, hdr_size);
 	/* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast
@@ -1274,46 +1337,12 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
 		u64_mac = atomic64_read(&dat_entry->mac_addr);
 		u64_to_ether_addr(u64_mac, mac);
 
-		/* If the ARP request is destined for a local client the local
-		 * client will answer itself. DAT would only generate a
-		 * duplicate packet.
-		 *
-		 * Moreover, if the mesh-interface is enslaved into a bridge, an
-		 * additional DAT answer may trigger kernel warnings about
-		 * a packet coming from the wrong port.
-		 */
-		if (batadv_is_my_client(bat_priv, mac, vid)) {
-			ret = true;
-			goto out;
-		}
-
-		/* If BLA is enabled, only send ARP replies if we have claimed
-		 * the destination for the ARP request or if no one else of
-		 * the backbone gws belonging to our backbone has claimed the
-		 * destination.
-		 */
-		if (!batadv_bla_check_claim(bat_priv, mac, vid)) {
+		rep = batadv_dat_arp_self_reply(bat_priv, ip_src, ip_dst,
+						hw_src, mac, vid, arp_len);
+		if (!rep)
 			batadv_dbg(BATADV_DBG_DAT, bat_priv,
-				   "Device %pM claimed by another backbone gw. Don't send ARP reply!",
-				   mac);
-			ret = true;
-			goto out;
-		}
-
-		skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src,
-						      mac, hw_src, vid);
-		if (!skb_new)
-			goto out;
-
-		skb_new->protocol = eth_type_trans(skb_new, mesh_iface);
-
-		batadv_inc_counter(bat_priv, BATADV_CNT_RX);
-		batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
-				   skb->len + ETH_HLEN + hdr_size);
-
-		netif_rx(skb_new);
-		batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
-		ret = true;
+				   "ARP request replied locally\n");
+		ret = (rep != -ENOMEM);
 	} else {
 		/* Send the request to the DHT */
 		ret = batadv_dat_forward_data(bat_priv, skb, ip_dst, vid,
-- 
2.55.0


  reply	other threads:[~2026-10-06 12:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-06 12:06 [batadv,v13 0/5] batman-adv: increase DAT DHT timeout Linus Lüssing
2026-10-06 12:06 ` Linus Lüssing [this message]
2026-10-06 12:06 ` [batadv,v13 2/5] batman-adv: split DAT cache into DAT cache and DAT DHT Linus Lüssing
2026-10-06 12:06 ` [batadv,v13 3/5] batman-adv: increase DAT DHT timeout Linus Lüssing
2026-10-06 12:06 ` [batadv,v13 4/5] batman-adv: avoid superfluous DAT DHT_PUT if self-candidate Linus Lüssing
2026-10-06 12:06 ` [batadv,v13 5/5] batman-adv: avoid superfluous DAT DHT_PUT additions to local DAT Linus Lüssing
     [not found]   ` <20261006121937.398DD1F000FF@smtp.kernel.org>
2026-10-06 13:05     ` Sven Eckelmann

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=20261006120647.8646-2-linus.luessing@c0d3.blue \
    --to=linus.luessing@c0d3.blue \
    --cc=b.a.t.m.a.n@lists.open-mesh.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