batman-adv: Merge bugfixes from 2017.4
[feed/routing.git] / batman-adv / patches / 0011-batman-adv-prevent-duplication-of-ARP-replies-when-D.patch
1 From: Andreas Pape <APape@phoenixcontact.com>
2 Date: Mon, 5 Sep 2016 13:20:26 +0200
3 Subject: [PATCH] batman-adv: prevent duplication of ARP replies when DAT is used
4
5 If none of the backbone gateways in a bla setup has already knowledge of
6 the mac address searched for in an incoming ARP request from the backbone
7 an address resolution via the DHT of DAT is started. The gateway can send
8 several ARP requests to different DHT nodes and therefore can get several
9 replies. This patch assures that not all of the possible ARP replies are
10 returned to the backbone by checking the local DAT cache of the gateway.
11 If there is an entry in the local cache the gateway has already learned
12 the requested address and there is no need to forward the additional reply
13 to the backbone.
14 Furthermore it is checked if this gateway has claimed the source of the ARP
15 reply and only forwards it to the backbone if it has claimed the source or
16 if there is no claim at all.
17
18 Signed-off-by: Andreas Pape <apape@phoenixcontact.com>
19 Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
20 [sven@narfation.org: fix conflicts with current version]
21 Signed-off-by: Sven Eckelmann <sven@narfation.org>
22 Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
23
24 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/81e422051cf0403e40615eb306d0ddaaddfee611
25 ---
26 net/batman-adv/distributed-arp-table.c | 32 ++++++++++++++++++++++++++++++++
27 1 file changed, 32 insertions(+)
28
29 diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
30 index 4cfc9672507ba718d975a2f869bb89fc38e0d934..16216532c1d82c09337a9c5e7a4cd5b4ad3ded5d 100644
31 --- a/net/batman-adv/distributed-arp-table.c
32 +++ b/net/batman-adv/distributed-arp-table.c
33 @@ -1205,6 +1205,7 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
34 bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
35 struct sk_buff *skb, int hdr_size)
36 {
37 + struct batadv_dat_entry *dat_entry = NULL;
38 u16 type;
39 __be32 ip_src, ip_dst;
40 u8 *hw_src, *hw_dst;
41 @@ -1227,12 +1228,41 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
42 hw_dst = batadv_arp_hw_dst(skb, hdr_size);
43 ip_dst = batadv_arp_ip_dst(skb, hdr_size);
44
45 + /* If ip_dst is already in cache and has the right mac address,
46 + * drop this frame if this ARP reply is destined for us because it's
47 + * most probably an ARP reply generated by another node of the DHT.
48 + * We have most probably received already a reply earlier. Delivering
49 + * this frame would lead to doubled receive of an ARP reply.
50 + */
51 + dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_src, vid);
52 + if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) {
53 + batadv_dbg(BATADV_DBG_DAT, bat_priv, "Doubled ARP reply removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; dat_entry: %pM-%pI4\n",
54 + hw_src, &ip_src, hw_dst, &ip_dst,
55 + dat_entry->mac_addr, &dat_entry->ip);
56 + dropped = true;
57 + goto out;
58 + }
59 +
60 /* Update our internal cache with both the IP addresses the node got
61 * within the ARP reply
62 */
63 batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
64 batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
65
66 + /* If BLA is enabled, only forward ARP replies if we have claimed the
67 + * source of the ARP reply or if no one else of the same backbone has
68 + * already claimed that client. This prevents that different gateways
69 + * to the same backbone all forward the ARP reply leading to multiple
70 + * replies in the backbone.
71 + */
72 + if (!batadv_bla_check_claim(bat_priv, hw_src, vid)) {
73 + batadv_dbg(BATADV_DBG_DAT, bat_priv,
74 + "Device %pM claimed by another backbone gw. Drop ARP reply.\n",
75 + hw_src);
76 + dropped = true;
77 + goto out;
78 + }
79 +
80 /* if this REPLY is directed to a client of mine, let's deliver the
81 * packet to the interface
82 */
83 @@ -1245,6 +1275,8 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
84 out:
85 if (dropped)
86 kfree_skb(skb);
87 + if (dat_entry)
88 + batadv_dat_entry_put(dat_entry);
89 /* if dropped == false -> deliver to the interface */
90 return dropped;
91 }