diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 0f899b9..f60fccb 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -1081,6 +1081,8 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
 	u8 *hw_src;
 	struct sk_buff *skb_new;
 	struct batadv_dat_entry *dat_entry = NULL;
+	struct batadv_unicast_4addr_packet *unicast_4addr_packet;
+	struct batadv_orig_node *orig_node = NULL;
 	bool ret = false;
 	unsigned short vid;
 	int err;
@@ -1104,8 +1106,38 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
 	batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);

 	dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
-	if (!dat_entry)
+	if (!dat_entry) {
+		/* Check if this is a 4addr unicast DAT_DHT_GET frame from
+		 * another backbone gw of the same backbone. If yes, drop
+		 * it as this leads to multiplication of arp requests in bla
+		 * setups as long as there is no dat_entry fo this answer.
+		 * In this case better drop the DHT_GET. Normal bla code
+		 * doesn't take care of these packets as they are tunneled
+		 * via unicast.
+		 */
+		unicast_4addr_packet =
+				(struct batadv_unicast_4addr_packet *)skb->data;
+		orig_node =
+			batadv_orig_hash_find(bat_priv,
+					      unicast_4addr_packet->src);
+		if (orig_node) {
+			if ((unicast_4addr_packet->u.packet_type ==
+			     BATADV_UNICAST_4ADDR) &&
+			     (unicast_4addr_packet->subtype ==
+			      BATADV_P_DAT_DHT_GET) &&
+			     (batadv_bla_is_backbone_gw(skb, orig_node,
+							hdr_size))) {
+				batadv_dbg(BATADV_DBG_DAT, bat_priv, "Doubled ARP request removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; originator: %pM\n",
+					   hw_src, &ip_src,
+					   batadv_arp_hw_dst(skb, hdr_size),
+					   &ip_dst, unicast_4addr_packet->src);
+				ret = true;
+			}
+			batadv_orig_node_put(orig_node);
+		}
+
 		goto out;
+	}

 	skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
 			     bat_priv->soft_iface, ip_dst, hw_src,
@@ -1204,6 +1236,7 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
 	__be32 ip_src, ip_dst;
 	u8 *hw_src, *hw_dst;
 	bool dropped = false;
+	struct batadv_dat_entry *dat_entry = NULL;
 	unsigned short vid;

 	if (!atomic_read(&bat_priv->distributed_arp_table))
@@ -1223,12 +1256,40 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
 	hw_dst = batadv_arp_hw_dst(skb, hdr_size);
 	ip_dst = batadv_arp_ip_dst(skb, hdr_size);

+	/* If ip_dst is already in cache and has the right mac address,
+	 * drop this frame if this ARP reply is destined for us. We have
+	 * most probably received already a reply from someone else. Delivering
+	 * this frame would lead to doubled receive of an ARP reply.
+	 */
+	dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_src, vid);
+	if ((dat_entry) && (batadv_compare_eth(hw_src, dat_entry->mac_addr))) {
+		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,
+			   dat_entry->mac_addr,	&dat_entry->ip);
+		dropped = true;
+		goto out;
+	}
+
 	/* Update our internal cache with both the IP addresses the node got
 	 * within the ARP reply
 	 */
 	batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
 	batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);

+	/* If BLA is enabled, only forward ARP replies if we have claimed the
+	 * source of the ARP reply or if no one else of the same backbone has
+	 * already claimed that client. This prevents that different gateways
+	 * to the same backbone all forward the ARP reply leading to multiple
+	 * replies in the backbone.
+	 */
+	if (!batadv_bla_handle_local_claim(bat_priv, hw_src, vid)) {
+		batadv_dbg(BATADV_DBG_DAT, bat_priv,
+			   "Device %pM claimed by another backbone gw. Drop ARP reply.\n",
+			   hw_src);
+		dropped = true;
+		goto out;
+	}
+
 	/* if this REPLY is directed to a client of mine, let's deliver the
 	 * packet to the interface
 	 */
@@ -1241,6 +1302,8 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
 out:
 	if (dropped)
 		kfree_skb(skb);
+	if (dat_entry)
+		batadv_dat_entry_put(dat_entry);
 	/* if dropped == false -> deliver to the interface */
 	return dropped;
 }
