[v4,2/6] batman-adv: speed up dat by snooping received ip traffic
Commit Message
Speeding up dat address lookup is achieved by snooping all incoming ip
traffic. This especially increases the propability in bla setups that
a gateway into a common backbone network already has a fitting dat entry
to answer incoming ARP requests directly coming from the backbone
network thus further reducing ARP traffic in the mesh.
Signed-off-by: Andreas Pape <apape@phoenixcontact.com>
---
net/batman-adv/distributed-arp-table.c | 50 ++++++++++++++++++++++++++++++++
net/batman-adv/distributed-arp-table.h | 9 +++++-
net/batman-adv/soft-interface.c | 3 ++
3 files changed, 61 insertions(+), 1 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
@@ -27,6 +27,7 @@
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
+#include <linux/ip.h>
#include <linux/in.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
@@ -362,6 +363,55 @@ out:
batadv_dat_entry_put(dat_entry);
}
+/**
+ * batadv_dat_entry_check - check and update a dat entry
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: socket buffer
+ * @vid: VLAN identifier
+ *
+ * snoops incoming socket buffer for dat cache updates, if dat is enabled.
+ * Can be called from other modules.
+ */
+void batadv_dat_entry_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
+ unsigned short vid)
+{
+ struct vlan_ethhdr *vhdr = NULL, tmp_vhdr;
+ struct ethhdr *ethhdr = NULL;
+ struct iphdr *iphdr = NULL, tmp_iphdr;
+
+ if (!atomic_read(&bat_priv->distributed_arp_table))
+ return;
+
+ ethhdr = eth_hdr(skb);
+
+ switch (ntohs(ethhdr->h_proto)) {
+ case ETH_P_IP:
+ iphdr = skb_header_pointer(skb, ETH_HLEN, sizeof(tmp_iphdr),
+ &tmp_iphdr);
+ break;
+ case ETH_P_8021Q:
+ vhdr = skb_header_pointer(skb, 0, sizeof(tmp_vhdr),
+ &tmp_vhdr);
+ if (!vhdr)
+ return;
+ if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_IP)
+ return;
+ iphdr = skb_header_pointer(skb, sizeof(tmp_vhdr),
+ sizeof(tmp_iphdr),
+ &tmp_iphdr);
+ break;
+ }
+
+ if (!iphdr)
+ return;
+
+ batadv_dbg(BATADV_DBG_DAT, bat_priv,
+ "Snooped IP address: %pI4 %pM (vid: %d)\n",
+ &iphdr->saddr, ethhdr->h_source,
+ BATADV_PRINT_VID(vid));
+ batadv_dat_entry_add(bat_priv, iphdr->saddr, ethhdr->h_source, vid);
+}
+
#ifdef CONFIG_BATMAN_ADV_DEBUG
/**
@@ -80,7 +80,8 @@ batadv_dat_init_own_addr(struct batadv_priv *bat_priv,
int batadv_dat_init(struct batadv_priv *bat_priv);
void batadv_dat_free(struct batadv_priv *bat_priv);
int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset);
-
+void batadv_dat_entry_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
+ unsigned short vid);
/**
* batadv_dat_inc_counter - increment the correct DAT packet counter
* @bat_priv: the bat priv with all the soft interface information
@@ -173,6 +174,12 @@ static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv,
{
}
+static inline
+void batadv_dat_entry_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
+ unsigned short vid)
+{
+}
+
#endif /* CONFIG_BATMAN_ADV_DAT */
#endif /* _NET_BATMAN_ADV_DISTRIBUTED_ARP_TABLE_H_ */
@@ -442,6 +442,9 @@ void batadv_interface_rx(struct net_device *soft_iface,
goto dropped;
}
+ /* Snoop incoming traffic for dat update */
+ batadv_dat_entry_check(bat_priv, skb, vid);
+
/* skb->dev & skb->pkt_type are set here */
skb->protocol = eth_type_trans(skb, soft_iface);