138 lines
4.8 KiB
Diff
138 lines
4.8 KiB
Diff
From: Andreas Pape <APape@phoenixcontact.com>
|
|
Date: Mon, 5 Sep 2016 13:20:25 +0200
|
|
Subject: batman-adv: prevent multiple ARP replies sent by gateways if dat enabled
|
|
|
|
If dat is enabled it must be made sure that only the backbone gw which has
|
|
claimed the remote destination for the ARP request answers the ARP request
|
|
directly if the MAC address is known due to the local dat table. This
|
|
prevents multiple ARP replies in a common backbone if more than one
|
|
gateway already knows the remote mac searched for in the ARP request.
|
|
|
|
Signed-off-by: Andreas Pape <apape@phoenixcontact.com>
|
|
Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
|
|
[sven@narfation.org: fix conflicts with current version]
|
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
|
|
|
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0c794961bc0d32386cffdc6d41c5ee21d9638e5b
|
|
|
|
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
|
|
index e7f690b571ea9be8ace25843d6e187a907486b99..41ab4a67a07b264bccdc5bccf73920909ff35c40 100644
|
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
|
@@ -2450,3 +2450,52 @@ out:
|
|
|
|
return ret;
|
|
}
|
|
+
|
|
+#ifdef CONFIG_BATMAN_ADV_DAT
|
|
+/**
|
|
+ * batadv_bla_check_claim - check if address is claimed
|
|
+ *
|
|
+ * @bat_priv: the bat priv with all the soft interface information
|
|
+ * @addr: mac address of which the claim status is checked
|
|
+ * @vid: the VLAN ID
|
|
+ *
|
|
+ * addr is checked if this address is claimed by the local device itself.
|
|
+ *
|
|
+ * Return: true if bla is disabled or the mac is claimed by the device,
|
|
+ * false if the device addr is already claimed by another gateway
|
|
+ */
|
|
+bool batadv_bla_check_claim(struct batadv_priv *bat_priv,
|
|
+ u8 *addr, unsigned short vid)
|
|
+{
|
|
+ struct batadv_bla_claim search_claim;
|
|
+ struct batadv_bla_claim *claim = NULL;
|
|
+ struct batadv_hard_iface *primary_if = NULL;
|
|
+ bool ret = true;
|
|
+
|
|
+ if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
|
+ return ret;
|
|
+
|
|
+ primary_if = batadv_primary_if_get_selected(bat_priv);
|
|
+ if (!primary_if)
|
|
+ return ret;
|
|
+
|
|
+ /* First look if the mac address is claimed */
|
|
+ ether_addr_copy(search_claim.addr, addr);
|
|
+ search_claim.vid = vid;
|
|
+
|
|
+ claim = batadv_claim_hash_find(bat_priv, &search_claim);
|
|
+
|
|
+ /* If there is a claim and we are not owner of the claim,
|
|
+ * return false.
|
|
+ */
|
|
+ if (claim) {
|
|
+ if (!batadv_compare_eth(claim->backbone_gw->orig,
|
|
+ primary_if->net_dev->dev_addr))
|
|
+ ret = false;
|
|
+ batadv_claim_put(claim);
|
|
+ }
|
|
+
|
|
+ batadv_hardif_put(primary_if);
|
|
+ return ret;
|
|
+}
|
|
+#endif
|
|
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
|
|
index 2827cd3c13d2a35a3b296340a0aa123dbd032926..133227c578e73fb998b540fdf361472a21e0c602 100644
|
|
--- a/net/batman-adv/bridge_loop_avoidance.h
|
|
+++ b/net/batman-adv/bridge_loop_avoidance.h
|
|
@@ -69,6 +69,10 @@ void batadv_bla_status_update(struct net_device *net_dev);
|
|
int batadv_bla_init(struct batadv_priv *bat_priv);
|
|
void batadv_bla_free(struct batadv_priv *bat_priv);
|
|
int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb);
|
|
+#ifdef CONFIG_BATMAN_ADV_DAT
|
|
+bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
|
|
+ unsigned short vid);
|
|
+#endif
|
|
#define BATADV_BLA_CRC_INIT 0
|
|
#else /* ifdef CONFIG_BATMAN_ADV_BLA */
|
|
|
|
@@ -145,6 +149,13 @@ static inline int batadv_bla_backbone_dump(struct sk_buff *msg,
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
+static inline
|
|
+bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
|
|
+ unsigned short vid)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
+
|
|
#endif /* ifdef CONFIG_BATMAN_ADV_BLA */
|
|
|
|
#endif /* ifndef _NET_BATMAN_ADV_BLA_H_ */
|
|
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
|
|
index 3641765d55df049a5dbac35d322ebc537a0f0322..4cfc9672507ba718d975a2f869bb89fc38e0d934 100644
|
|
--- a/net/batman-adv/distributed-arp-table.c
|
|
+++ b/net/batman-adv/distributed-arp-table.c
|
|
@@ -43,6 +43,7 @@
|
|
#include <linux/workqueue.h>
|
|
#include <net/arp.h>
|
|
|
|
+#include "bridge_loop_avoidance.h"
|
|
#include "hard-interface.h"
|
|
#include "hash.h"
|
|
#include "log.h"
|
|
@@ -1041,6 +1042,20 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
|
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,
|
|
+ dat_entry->mac_addr, vid)) {
|
|
+ batadv_dbg(BATADV_DBG_DAT, bat_priv,
|
|
+ "Device %pM claimed by another backbone gw. Don't send ARP reply!",
|
|
+ dat_entry->mac_addr);
|
|
+ ret = true;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
skb_new = batadv_dat_arp_create_reply(bat_priv, ip_dst, ip_src,
|
|
dat_entry->mac_addr,
|
|
hw_src, vid);
|