[1/7] batman-adv: prevent multiple ARP replies sent by gateways if dat enabled

Message ID 1456381687-29637-1-git-send-email-apape@phoenixcontact.com (mailing list archive)
State Superseded, archived
Delegated to: Marek Lindner
Headers

Commit Message

Andreas Pape Feb. 25, 2016, 6:28 a.m. UTC
  This patch makes 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>
---
 net/batman-adv/bridge_loop_avoidance.c |   59 ++++++++++++++++++++++++++++++++
 net/batman-adv/bridge_loop_avoidance.h |    8 ++++
 net/batman-adv/distributed-arp-table.c |   15 ++++++++
 3 files changed, 82 insertions(+), 0 deletions(-)

--
1.7.0.4



..................................................................
PHOENIX CONTACT ELECTRONICS GmbH

Sitz der Gesellschaft / registered office of the company: 31812 Bad Pyrmont
USt-Id-Nr.: DE811742156
Amtsgericht Hannover HRB 100528 / district court Hannover HRB 100528
Geschäftsführer / Executive Board: Roland Bent, Dr. Martin Heubeck
  

Comments

Sven Eckelmann Feb. 25, 2016, 10:30 a.m. UTC | #1
On Thursday 25 February 2016 07:28:07 Andreas Pape wrote:
> This patch makes 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>
> ---
>  net/batman-adv/bridge_loop_avoidance.c |   59 ++++++++++++++++++++++++++++++++
>  net/batman-adv/bridge_loop_avoidance.h |    8 ++++
>  net/batman-adv/distributed-arp-table.c |   15 ++++++++
>  3 files changed, 82 insertions(+), 0 deletions(-)

I will answer to the first patch only because this patchset doesn't have a
cover letter. But it is about the whole patchset.

First thing: Good that you could convince the IT department that you have to
use git-send-email as alternative mailer.

I have not checked the actual content of the patchset ("This patch makes" in
the commit messages looks odd) but just started the build_test [1] on your
patchset. It looks like your patchset doesn't build in some configurations.
See the attached mail for more details.

And the test run without your patches looked good [2].

Kind regards,
	Sven

[1] https://git.open-mesh.org/build_test.git
[2] https://lists.open-mesh.org/pipermail/linux-merge/2016-February/002983.html
  
Andreas Pape Feb. 25, 2016, 1:06 p.m. UTC | #2
Hello Sven,

Sven Eckelmann <sven@narfation.org> schrieb am 25.02.2016 11:30:01:


> I will answer to the first patch only because this patchset doesn't have
a
> cover letter. But it is about the whole patchset.
>
> First thing: Good that you could convince the IT department that you
have to
> use git-send-email as alternative mailer.
>
> I have not checked the actual content of the patchset ("This patch
makes" in
> the commit messages looks odd) but just started the build_test [1] on
your
> patchset. It looks like your patchset doesn't build in some
configurations.
> See the attached mail for more details.
>

I wasn't aware that there is something like the build_test to be used
before
sending patches.... But I'm willing to learn.

Is there a documentation available how I can use this myself for testing
before
making another attempt to send the patches (including a cover letter)?

In my buildenvironment using an older kernel I have no issues. But of
course
I did not test every possible configuration....

> And the test run without your patches looked good [2].
>
> Kind regards,
>    Sven
>
> [1] https://git.open-mesh.org/build_test.git
> [2] https://lists.open-mesh.org/pipermail/linux-merge/2016-February/
> 002983.html
> [Anhang "build-test_andreas-pape_bla-fixes.mbox" gelöscht von
> Andreas Pape/Phoenix Contact] [Anhang "signature.asc" gelöscht von
> Andreas Pape/Phoenix Contact]


..................................................................
PHOENIX CONTACT ELECTRONICS GmbH

Sitz der Gesellschaft / registered office of the company: 31812 Bad Pyrmont
USt-Id-Nr.: DE811742156
Amtsgericht Hannover HRB 100528 / district court Hannover HRB 100528
Geschäftsführer / Executive Board: Roland Bent, Dr. Martin Heubeck
  
Sven Eckelmann Feb. 25, 2016, 1:47 p.m. UTC | #3
On Thursday 25 February 2016 14:06:39 Andreas Pape wrote:
> I wasn't aware that there is something like the build_test to be used
> before
> sending patches.... But I'm willing to learn.

No, build_test is not something which has be used. It is actually quite hacky
and only used in the daily tests (and by brave people still wanting to use
it).

But you should [1] compile your stuff with sparse. Install it and run the compile
with:

   make C=2 CHECK="sparse -Wsparse-all -Wno-ptr-subtraction-blows -D__CHECK_ENDIAN__"

You can ignore the "shadows an earlier one" in the external headers and the
one about __ret.

And you should definitely use the checkpatch.pl from linux-next:

    ~/linux-next/scripts/checkpatch.pl --strict 000*.patch

> Is there a documentation available how I can use this myself for testing
> before
> making another attempt to send the patches (including a cover letter)?

If you really want to test it with build_test then you have to clone it on
an amd64 system, install iwyu (3.5+), python and the standard build tools.
This example expects that you have a working mail server on your system
which at least can send mails to a local account (YOUR_MAIL_ACCOUNT). The
patches in YOUR_BATMAN_ADV_TREE should be in the master branch to avoid too
many changes checkstuff.sh.

    git clone git://git.open-mesh.org/build_test.git
    cd build_test
    git clone git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git linux-next
    git --git-dir=linux-next/.git/ remote add net-next git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
    LINUX_REPOSITORY=`pwd`/linux-next ./generate_linux_headers.sh
    sudo mkdir linux-build
    sudo mount linux-build.img -o loop linux-build
    # edit checkstuff.sh and remove: testbranch "next"
    TO=YOUR_MAIL_ACCOUNT REMOTE=YOUR_BATMAN_ADV_TREE ./checkstuff.sh
    # fix all the stuff regarding sparse, cppcheck, smatch and try again:
    TO=YOUR_MAIL_ACCOUNT REMOTE=YOUR_BATMAN_ADV_TREE ./checkstuff.sh

Cover letter can be generated in git sendmail by running:

   git send-email --compose 0001-.... 0002-... ....

It is not really required. I just wanted to tell you that the result is not
really about this single patch. But please add all patches to the call of
`git send-email` to automatically create a single thread.

Kind regards,
	Sven

[1] https://www.open-mesh.org/projects/open-mesh/wiki/Contribute#Submitting-patches
  

Patch

diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 0a6c8b8..6c29ec2 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1906,3 +1906,62 @@  out:
 		batadv_hardif_put(primary_if);
 	return 0;
 }
+
+/**
+ * batadv_bla_handle_local_claim
+ * @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.
+ * If the address is not claimed at all, claim it.
+ *
+ * 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_handle_local_claim(struct batadv_priv *bat_priv, uint8_t *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)
+		goto out;
+
+	/* 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;
+	} else {
+		/* If there is no claim, claim the device */
+		batadv_dbg(BATADV_DBG_BLA, bat_priv,
+				"Handle claim locally for currently not claimed mac %pM.\n",
+				search_claim.addr);
+
+		batadv_handle_claim(bat_priv, primary_if,
+				primary_if->net_dev->dev_addr, addr, vid);
+	}
+
+out:
+	if (claim)
+		batadv_claim_put(claim);
+	if (primary_if)
+		batadv_hardif_put(primary_if);
+	return ret;
+}
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
index 579f0fa..c6d498b 100644
--- a/net/batman-adv/bridge_loop_avoidance.h
+++ b/net/batman-adv/bridge_loop_avoidance.h
@@ -46,6 +46,8 @@  void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
 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);
+bool batadv_bla_handle_local_claim(struct batadv_priv *bat_priv, u8 *addr,
+		unsigned short vid);

 #define BATADV_BLA_CRC_INIT	0
 #else /* ifdef CONFIG_BATMAN_ADV_BLA */
@@ -111,6 +113,12 @@  static inline void batadv_bla_free(struct batadv_priv *bat_priv)
 {
 }

+bool batadv_bla_handle_local_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 e96d7c7..aab9548 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -48,6 +48,7 @@ 
 #include "originator.h"
 #include "send.h"
 #include "translation-table.h"
+#include "bridge_loop_avoidance.h"

 static void batadv_dat_purge(struct work_struct *work);

@@ -1000,6 +1001,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_handle_local_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 = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
 				     bat_priv->soft_iface, ip_dst, hw_src,
 				     dat_entry->mac_addr, hw_src);