* [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table
@ 2011-11-21 22:53 Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 1/7] batman-adv: implement an helper function to forge unicast packets Antonio Quartulli
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
Hello people,
****
This is the third version of this patchset. The whole code has been reviewed
(Thanks Simon!) and a bug related to the skb_mac_header() return value has been
fixed (thanks again Simon!).
****
as most of you may already know, last summer I've been working on the
B.A.T.M.A.N.-Adv GSoC project named "DAT: Distributed ARP Table". For who wants
to get deeper into the details of the project there are two links:
- The GSoC proposal [1]
- The DAT wikipage on open-mesh.org [2], with status and ideas description
Just to recap: DAT is a distributes hash table meant to store ARP entries for
fast lookup. In a normal scenario, whenever a node wants to communicate with
another one, it first needs to issue a broadcast ARP request in order to
retrieve its PHY/MAC address. In a sparse network a broadcast message could be
lost several times before reaching the real destination so creating high
latencies. With DAT, every ARP entries (a pair [IP addr, MAC addr]) is stored on
a "computed" set of nodes, therefore in case of ARP request theses nodes can
directly be contacted (in unicast) and the needed information can be quickly
fetched.
Cheers,
Antonio
[1] http://www.google-melange.com/gsoc/project/google/gsoc2011/ordex/4001
[2] http://www.open-mesh.org/wiki/batman-adv/GSOC2011_DAT
^ permalink raw reply [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 1/7] batman-adv: implement an helper function to forge unicast packets
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 2/7] batman-adv: add a new log level for DAT-ARP debugging Antonio Quartulli
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
A new function named prepare_unicast_packet() has been implemented so that it can
do all the needed operations to set up a skb for unicast sending. It is general
enough to be used in every context. Helpful for later developments
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
unicast.c | 43 ++++++++++++++++++++++++++++++-------------
unicast.h | 2 ++
2 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/unicast.c b/unicast.c
index 07d1c1d..cbadc21 100644
--- a/unicast.c
+++ b/unicast.c
@@ -283,6 +283,33 @@ out:
return ret;
}
+struct sk_buff *prepare_unicast_packet(struct sk_buff *skb,
+ struct orig_node *orig_node)
+{
+ struct unicast_packet *unicast_packet;
+
+ if (my_skb_head_push(skb, sizeof(*unicast_packet)) < 0)
+ goto out;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ unicast_packet->version = COMPAT_VERSION;
+ /* batman packet type: unicast */
+ unicast_packet->packet_type = BAT_UNICAST;
+ /* set unicast ttl */
+ unicast_packet->ttl = TTL;
+ /* copy the destination for faster routing */
+ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+ /* set the destination tt version number */
+ unicast_packet->ttvn =
+ (uint8_t)atomic_read(&orig_node->last_ttvn);
+
+ return skb;
+out:
+ kfree(skb);
+ return NULL;
+}
+
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
{
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
@@ -315,22 +342,12 @@ find_router:
if (!neigh_node)
goto out;
- if (my_skb_head_push(skb, sizeof(*unicast_packet)) < 0)
+ skb = prepare_unicast_packet(skb, orig_node);
+ if (!skb)
goto out;
unicast_packet = (struct unicast_packet *)skb->data;
- unicast_packet->version = COMPAT_VERSION;
- /* batman packet type: unicast */
- unicast_packet->packet_type = BAT_UNICAST;
- /* set unicast ttl */
- unicast_packet->ttl = TTL;
- /* copy the destination for faster routing */
- memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
- /* set the destination tt version number */
- unicast_packet->ttvn =
- (uint8_t)atomic_read(&orig_node->last_ttvn);
-
if (atomic_read(&bat_priv->fragmentation) &&
data_len + sizeof(*unicast_packet) >
neigh_node->if_incoming->net_dev->mtu) {
@@ -350,7 +367,7 @@ out:
neigh_node_free_ref(neigh_node);
if (orig_node)
orig_node_free_ref(orig_node);
- if (ret == 1)
+ if (ret == 1 && skb)
kfree_skb(skb);
return ret;
}
diff --git a/unicast.h b/unicast.h
index 8fd5535..f53a735 100644
--- a/unicast.h
+++ b/unicast.h
@@ -33,6 +33,8 @@ void frag_list_free(struct list_head *head);
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv);
int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
struct hard_iface *hard_iface, const uint8_t dstaddr[]);
+struct sk_buff *prepare_unicast_packet(struct sk_buff *skb,
+ struct orig_node *orig_node);
static inline int frag_can_reassemble(const struct sk_buff *skb, int mtu)
{
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 2/7] batman-adv: add a new log level for DAT-ARP debugging
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 1/7] batman-adv: implement an helper function to forge unicast packets Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 3/7] batman-adv: Distributed ARP Table - create the DHT helper functions Antonio Quartulli
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
A new log level has been added to concentrate messages regarding DAT: ARP
snooping, requests, response and DHT related messages.
The new log level is named DBG_ARP
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
bat_sysfs.c | 2 +-
main.h | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c
index c25492f..ec2e437 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -390,7 +390,7 @@ BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
store_gw_bwidth);
#ifdef CONFIG_BATMAN_ADV_DEBUG
-BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 7, NULL);
+BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
#endif
static struct bat_attribute *mesh_attrs[] = {
diff --git a/main.h b/main.h
index 464439f..e706193 100644
--- a/main.h
+++ b/main.h
@@ -120,7 +120,8 @@ enum dbg_level {
DBG_BATMAN = 1 << 0,
DBG_ROUTES = 1 << 1, /* route added / changed / deleted */
DBG_TT = 1 << 2, /* translation table operations */
- DBG_ALL = 7
+ DBG_ARP = 1 << 3, /* snooped arp messages / dht operations */
+ DBG_ALL = 15
};
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 3/7] batman-adv: Distributed ARP Table - create the DHT helper functions
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 1/7] batman-adv: implement an helper function to forge unicast packets Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 2/7] batman-adv: add a new log level for DAT-ARP debugging Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 4/7] batman-adv: Distributed ARP Table - add ARP parsing functions Antonio Quartulli
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
Add all the relevant functions in order to manage a Distributed Hash Table over
the B.A.T.M.A.N.-adv network. It will later be used to store several ARP entries
and implement DAT (Distributed ARP Table)
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
Makefile.kbuild | 1 +
distributed-arp-table.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++
distributed-arp-table.h | 46 ++++++++++++
hard-interface.c | 2 +
main.h | 7 ++
originator.c | 1 +
soft-interface.c | 2 +
types.h | 7 ++
8 files changed, 247 insertions(+), 0 deletions(-)
create mode 100644 distributed-arp-table.c
create mode 100644 distributed-arp-table.h
diff --git a/Makefile.kbuild b/Makefile.kbuild
index bd7e93c..e8861cb 100644
--- a/Makefile.kbuild
+++ b/Makefile.kbuild
@@ -36,6 +36,7 @@ batman-adv-y += bat_debugfs.o
batman-adv-y += bat_iv_ogm.o
batman-adv-y += bat_sysfs.o
batman-adv-y += bitarray.o
+batman-adv-y += distributed-arp-table.o
batman-adv-y += gateway_client.o
batman-adv-y += gateway_common.o
batman-adv-y += hard-interface.o
diff --git a/distributed-arp-table.c b/distributed-arp-table.c
new file mode 100644
index 0000000..5bc3004
--- /dev/null
+++ b/distributed-arp-table.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 B.A.T.M.A.N. contributors:
+ *
+ * Antonio Quartulli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+
+#include "main.h"
+#include "distributed-arp-table.h"
+#include "hard-interface.h"
+#include "originator.h"
+#include "send.h"
+#include "types.h"
+#include "unicast.h"
+
+/* Given a key, selects the candidates which the DHT message has to be sent to.
+ * An originator O is selected if and only if its DHT_ID value is one of three
+ * closest values (but not greater) then the hash value of the key.
+ * ip_dst is the key.
+ *
+ * return an array of size DHT_CANDIDATES_NUM */
+static struct dht_candidate *dht_select_candidates(struct bat_priv *bat_priv,
+ uint32_t ip_dst)
+{
+ struct hashtable_t *hash = bat_priv->orig_hash;
+ struct hlist_node *node;
+ struct hlist_head *head;
+ struct orig_node *orig_node, *max_orig_node = NULL;
+ int select, i, j;
+ uint16_t last_max = USHRT_MAX, max, tmp_max, ip_key;
+ struct dht_candidate *res;
+ bool chosen_me = false;
+
+ if (!hash)
+ return NULL;
+
+ res = kmalloc(DHT_CANDIDATES_NUM * sizeof(*res), GFP_ATOMIC);
+ if (!res)
+ return NULL;
+
+ ip_key = hash_ipv4(&ip_dst, USHRT_MAX);
+
+ bat_dbg(DBG_ARP, bat_priv, "DHT_SEL_CAND key: %pI4 %u\n", &ip_dst,
+ ip_key);
+
+ for (select = 0; select < DHT_CANDIDATES_NUM; select++) {
+ max = 0;
+ max_orig_node = NULL;
+ if (!chosen_me) {
+ /* if true, wrap around the key space */
+ if (bat_priv->dht_hash > ip_key)
+ max = USHRT_MAX - bat_priv->dht_hash +
+ ip_key;
+ else
+ max = ip_key - bat_priv->dht_hash;
+ max = bat_priv->dht_hash;
+ res[select].type = DHT_CANDIDATE_ME;
+ } else
+ res[select].type = DHT_CANDIDATE_NULL;
+ /* for all origins... */
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(orig_node, node, head,
+ hash_entry) {
+ if (orig_node->dht_hash > ip_key)
+ tmp_max = USHRT_MAX -
+ orig_node->dht_hash + ip_key;
+ else
+ tmp_max = ip_key - orig_node->dht_hash;
+
+ /* this is closest! */
+ if (tmp_max <= max)
+ continue;
+
+ /* this has already been selected */
+ if (tmp_max > last_max)
+ continue;
+
+ /* In case of hash collision we can select two
+ * nodes with the same hash, but we have ensure
+ * they are different */
+ if (tmp_max == last_max) {
+ for (j = 0; j < select; j++)
+ if (res[j].orig_node ==
+ orig_node)
+ break;
+ if (j < select)
+ continue;
+ }
+
+ if (!atomic_inc_not_zero(&orig_node->refcount))
+ continue;
+
+ max = tmp_max;
+ if (max_orig_node)
+ orig_node_free_ref(max_orig_node);
+ max_orig_node = orig_node;
+ }
+ rcu_read_unlock();
+ }
+ last_max = max;
+ if (max_orig_node) {
+ res[select].type = DHT_CANDIDATE_ORIG;
+ res[select].orig_node = max_orig_node;
+ bat_dbg(DBG_ARP, bat_priv, "DHT_SEL_CAND %d: %pM %u\n",
+ select, max_orig_node->orig, max);
+ }
+ if (res[select].type == DHT_CANDIDATE_ME) {
+ chosen_me = true;
+ bat_dbg(DBG_ARP, bat_priv, "DHT_SEL_CAND %d: ME %u\n",
+ select, bat_priv->dht_hash);
+ }
+
+ max_orig_node = NULL;
+ }
+
+ return res;
+}
+
+/*
+ * Sends the skb payload passed as argument to the candidates selected for
+ * 'ip'. The skb is copied by means of pskb_copy() and is sent as unicast packet
+ * to each of the selected candidate. */
+static bool dht_send_data(struct bat_priv *bat_priv, struct sk_buff *skb,
+ uint32_t ip)
+{
+ int i;
+ bool ret = false;
+ struct neigh_node *neigh_node = NULL;
+ struct sk_buff *tmp_skb;
+ struct dht_candidate *cand = dht_select_candidates(bat_priv, ip);
+
+ if (!cand)
+ goto out;
+
+ bat_dbg(DBG_ARP, bat_priv, "DHT_SEND for %pI4\n", &ip);
+
+ for (i = 0; i < DHT_CANDIDATES_NUM; i++) {
+ if (cand[i].type == DHT_CANDIDATE_ME ||
+ cand[i].type == DHT_CANDIDATE_NULL)
+ continue;
+
+ neigh_node = orig_node_get_router(cand[i].orig_node);
+ if (!neigh_node)
+ goto free_orig;
+
+ tmp_skb = pskb_copy(skb, GFP_ATOMIC);
+ tmp_skb = prepare_unicast_packet(tmp_skb, cand[i].orig_node);
+ if (tmp_skb)
+ send_skb_packet(tmp_skb, neigh_node->if_incoming,
+ neigh_node->addr);
+ /* set ret to true only if we send at least one request */
+ ret = true;
+ neigh_node_free_ref(neigh_node);
+free_orig:
+ orig_node_free_ref(cand[i].orig_node);
+ }
+
+out:
+ kfree(cand);
+ return ret;
+}
diff --git a/distributed-arp-table.h b/distributed-arp-table.h
new file mode 100644
index 0000000..ee1a8b3
--- /dev/null
+++ b/distributed-arp-table.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 B.A.T.M.A.N. contributors:
+ *
+ * Antonio Quartulli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_ARP_H_
+#define _NET_BATMAN_ADV_ARP_H_
+
+/* hash function to choose an entry in a hash table of given size */
+/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
+static inline uint32_t hash_ipv4(const void *data, uint32_t size)
+{
+ const unsigned char *key = data;
+ uint32_t hash = 0;
+ size_t i;
+
+ for (i = 0; i < 4; i++) {
+ hash += key[i];
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+
+ return hash % size;
+}
+
+#endif /* _NET_BATMAN_ADV_ARP_H_ */
diff --git a/hard-interface.c b/hard-interface.c
index 7704df4..3508934 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -117,6 +117,8 @@ static void primary_if_update_addr(struct bat_priv *bat_priv)
if (!primary_if)
goto out;
+ bat_priv->dht_hash = choose_orig(bat_priv, USHRT_MAX);
+
vis_packet = (struct vis_packet *)
bat_priv->my_vis_info->skb_packet->data;
memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
diff --git a/main.h b/main.h
index e706193..7b4229c 100644
--- a/main.h
+++ b/main.h
@@ -64,6 +64,9 @@
#define NULL_IFINDEX 0 /* dummy ifindex used to avoid iface checks */
+/* numbers of originator to contact for any STORE/GET DHT operation */
+#define DHT_CANDIDATES_NUM 3
+
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
@@ -106,6 +109,10 @@ enum uev_type {
#define GW_THRESHOLD 50
+#define DHT_CANDIDATE_NULL 0
+#define DHT_CANDIDATE_ME 1
+#define DHT_CANDIDATE_ORIG 2
+
/*
* Debug Messages
*/
diff --git a/originator.c b/originator.c
index 0bc2045..9673b44 100644
--- a/originator.c
+++ b/originator.c
@@ -222,6 +222,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
orig_node->tt_poss_change = false;
orig_node->bat_priv = bat_priv;
memcpy(orig_node->orig, addr, ETH_ALEN);
+ orig_node->dht_hash = choose_orig(addr, USHRT_MAX);
orig_node->router = NULL;
orig_node->tt_crc = 0;
atomic_set(&orig_node->last_ttvn, 0);
diff --git a/soft-interface.c b/soft-interface.c
index 987c75a..cd6c9ea 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -855,6 +855,8 @@ struct net_device *softif_create(const char *name)
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
+ bat_priv->dht_hash = 0;
+
ret = sysfs_add_meshif(soft_iface);
if (ret < 0)
goto unreg_soft_iface;
diff --git a/types.h b/types.h
index e9eb043..5f0030e 100644
--- a/types.h
+++ b/types.h
@@ -67,6 +67,7 @@ struct hard_iface {
struct orig_node {
uint8_t orig[ETH_ALEN];
uint8_t primary_addr[ETH_ALEN];
+ uint16_t dht_hash;
struct neigh_node __rcu *router; /* rcu protected pointer */
unsigned long *bcast_own;
uint8_t *bcast_own_sum;
@@ -204,6 +205,7 @@ struct bat_priv {
struct gw_node __rcu *curr_gw; /* rcu protected pointer */
atomic_t gw_reselect;
struct hard_iface __rcu *primary_if; /* rcu protected pointer */
+ uint16_t dht_hash;
struct vis_info *my_vis_info;
};
@@ -343,4 +345,9 @@ struct softif_neigh {
struct rcu_head rcu;
};
+struct dht_candidate {
+ int type;
+ struct orig_node *orig_node;
+};
+
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 4/7] batman-adv: Distributed ARP Table - add ARP parsing functions
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
` (2 preceding siblings ...)
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 3/7] batman-adv: Distributed ARP Table - create the DHT helper functions Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
2011-11-23 15:47 ` Andrew Lunn
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages Antonio Quartulli
` (2 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
ARP messages are now parsed to make it possible to trigger special actions
depending on their types (snooping).
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
distributed-arp-table.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++
distributed-arp-table.h | 8 +++++++
2 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/distributed-arp-table.c b/distributed-arp-table.c
index 5bc3004..5fad513 100644
--- a/distributed-arp-table.c
+++ b/distributed-arp-table.c
@@ -179,3 +179,54 @@ out:
kfree(cand);
return ret;
}
+
+/* Returns arphdr->ar_op if the skb contains a valid ARP packet, otherwise
+ * returns 0 */
+uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ struct arphdr *arphdr;
+ struct ethhdr *ethhdr;
+ uint16_t type = 0;
+ char buf[30], *type_str[] = { "REQUEST", "REPLY", "RREQUEST", "RREPLY",
+ "InREQUEST", "InREPLY", "NAK" };
+
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ goto out;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ if (ethhdr->h_proto != htons(ETH_P_ARP))
+ goto out;
+
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN + arp_hdr_len(skb->dev))))
+ goto out;
+
+ arphdr = (struct arphdr *)(skb->data + sizeof(struct ethhdr));
+
+ /* Check whether the ARP packet carries a valid
+ * IP information */
+ if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
+ goto out;
+
+ if (arphdr->ar_pro != htons(ETH_P_IP))
+ goto out;
+
+ if (arphdr->ar_hln != ETH_ALEN)
+ goto out;
+
+ if (arphdr->ar_pln != 4)
+ goto out;
+
+ type = ntohs(arphdr->ar_op);
+
+ if (type >= 1 && type <= 10)
+ scnprintf(buf, 30, "%s", type_str[type - 1]);
+ else
+ scnprintf(buf, 30, "UNKNOWN (%hu)", type);
+
+ bat_dbg(DBG_ARP, bat_priv, "ARP message of type %s recognised "
+ "[%pM-%pI4 %pM-%pI4]\n", buf, ARP_HW_SRC(skb), &ARP_IP_SRC(skb),
+ ARP_HW_DST(skb), &ARP_IP_DST(skb));
+out:
+ return type;
+}
diff --git a/distributed-arp-table.h b/distributed-arp-table.h
index ee1a8b3..439af22 100644
--- a/distributed-arp-table.h
+++ b/distributed-arp-table.h
@@ -22,6 +22,14 @@
#ifndef _NET_BATMAN_ADV_ARP_H_
#define _NET_BATMAN_ADV_ARP_H_
+#define ARP_HW_SRC(skb) ((uint8_t *)(skb->data) + sizeof(struct ethhdr) + \
+ sizeof(struct arphdr))
+#define ARP_IP_SRC(skb) (*(uint32_t *)(ARP_HW_SRC(skb) + ETH_ALEN))
+#define ARP_HW_DST(skb) (ARP_HW_SRC(skb) + ETH_ALEN + 4)
+#define ARP_IP_DST(skb) (*(uint32_t *)(ARP_HW_SRC(skb) + ETH_ALEN * 2 + 4))
+
+uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb);
+
/* hash function to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
static inline uint32_t hash_ipv4(const void *data, uint32_t size)
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
` (3 preceding siblings ...)
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 4/7] batman-adv: Distributed ARP Table - add ARP parsing functions Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
2011-11-23 16:11 ` Andrew Lunn
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 6/7] batman-adv: Distributed ARP Table - increase default soft_iface ARP table timeout Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 7/7] batman-adv: add Distributed ARP Table compile option Antonio Quartulli
6 siblings, 1 reply; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
In case of an ARP message going in or out the soft_iface, it is intercepted and
a special action is performed. In particular the DHT helper functions previously
implemented are used to store all the ARP entries belonging to the network in
order to provide a fast and unicast lookup instead of the classic broadcast flooding
mechanism.
Each node stores the entries it is responsible for (following the DHT rules) in
its soft_iface ARP table. This makes it possible to reuse the kernel data
structures and functions for ARP management.
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
distributed-arp-table.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++
distributed-arp-table.h | 6 ++
main.h | 2 +
routing.c | 1 +
send.c | 18 ++++
soft-interface.c | 25 ++++++-
6 files changed, 254 insertions(+), 1 deletions(-)
diff --git a/distributed-arp-table.c b/distributed-arp-table.c
index 5fad513..ea79a3e 100644
--- a/distributed-arp-table.c
+++ b/distributed-arp-table.c
@@ -21,6 +21,8 @@
#include <linux/if_ether.h>
#include <linux/if_arp.h>
+/* needed to use arp_tbl */
+#include <net/arp.h>
#include "main.h"
#include "distributed-arp-table.h"
@@ -180,6 +182,31 @@ out:
return ret;
}
+/* Update the neighbour entry corresponding to the IP passed as parameter with
+ * the hw address hw. If the neighbour entry doesn't exists, then it will be
+ * created */
+static void arp_neigh_update(struct bat_priv *bat_priv, uint32_t ip,
+ uint8_t *hw)
+{
+ struct neighbour *n = NULL;
+ struct hard_iface *primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ n = __neigh_lookup(&arp_tbl, &ip, primary_if->soft_iface, 1);
+ if (!n)
+ goto out;
+
+ bat_dbg(DBG_ARP, bat_priv, "Updating neighbour: %pI4 - %pM\n", &ip, hw);
+
+ neigh_update(n, hw, NUD_CONNECTED, NEIGH_UPDATE_F_OVERRIDE);
+out:
+ if (n && !IS_ERR(n))
+ neigh_release(n);
+ if (primary_if)
+ hardif_free_ref(primary_if);
+}
+
/* Returns arphdr->ar_op if the skb contains a valid ARP packet, otherwise
* returns 0 */
uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb)
@@ -230,3 +257,179 @@ uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb)
out:
return type;
}
+
+/* return true if the message has been sent to the dht candidates, false
+ * otherwise. In case of true the message has to be enqueued to permit the
+ * fallback */
+bool arp_snoop_outgoing_request(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ uint16_t type = 0;
+ uint32_t ip_dst, ip_src;
+ uint8_t *hw_src;
+ bool ret = false;
+ struct neighbour *n = NULL;
+ struct hard_iface *primary_if = NULL;
+ struct sk_buff *skb_new;
+
+ type = arp_get_type(bat_priv, skb);
+ /* If we get an ARP_REQUEST we have to send the unicast message to the
+ * selected DHT candidates */
+ if (type != ARPOP_REQUEST)
+ goto out;
+
+ bat_dbg(DBG_ARP, bat_priv, "Snooped outgoing ARP request\n");
+
+ ip_src = ARP_IP_SRC(skb);
+ hw_src = ARP_HW_SRC(skb);
+ ip_dst = ARP_IP_DST(skb);
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ arp_neigh_update(bat_priv, ip_src, hw_src);
+
+ n = neigh_lookup(&arp_tbl, &ip_dst, primary_if->soft_iface);
+ /* check if it is a valid neigh entry */
+ if (n && (n->nud_state & NUD_CONNECTED)) {
+ skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
+ primary_if->soft_iface, ip_dst, hw_src,
+ n->ha, hw_src);
+ if (!skb_new)
+ goto out;
+
+ skb_reset_mac_header(skb_new);
+ skb_new->protocol = eth_type_trans(skb_new,
+ primary_if->soft_iface);
+ bat_priv->stats.rx_packets++;
+ bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
+ primary_if->soft_iface->last_rx = jiffies;
+
+ netif_rx(skb_new);
+ bat_dbg(DBG_ARP, bat_priv, "ARP request replied locally\n");
+ } else
+ /* Send the request on the DHT */
+ ret = dht_send_data(bat_priv, skb, ip_dst);
+out:
+ if (n)
+ neigh_release(n);
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
+}
+
+/* This function is meant to be invoked for an ARP request which is coming into
+ * the bat0 interfaces from the mesh network. It will check for the needed data
+ * into the local table. If found, an ARP reply is sent immediately, otherwise
+ * the caller has to deliver the ARP request to the upper layer */
+bool arp_snoop_incoming_request(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ uint16_t type;
+ uint32_t ip_src, ip_dst;
+ uint8_t *hw_src;
+ struct hard_iface *primary_if = NULL;
+ struct sk_buff *skb_new;
+ struct neighbour *n = NULL;
+ bool ret = false;
+
+ type = arp_get_type(bat_priv, skb);
+ if (type != ARPOP_REQUEST)
+ goto out;
+
+ hw_src = ARP_HW_SRC(skb);
+ ip_src = ARP_IP_SRC(skb);
+ ip_dst = ARP_IP_DST(skb);
+
+ bat_dbg(DBG_ARP, bat_priv, "Snooped incoming ARP request\n");
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ arp_neigh_update(bat_priv, ip_src, hw_src);
+
+ n = neigh_lookup(&arp_tbl, &ip_dst, primary_if->soft_iface);
+ /* check if it is a valid neigh entry */
+ if (!n || !(n->nud_state & NUD_CONNECTED))
+ goto out;
+
+ skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
+ primary_if->soft_iface, ip_dst, hw_src, n->ha,
+ hw_src);
+
+ unicast_send_skb(skb_new, bat_priv);
+
+ ret = true;
+out:
+ if (n)
+ neigh_release(n);
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ if (ret)
+ kfree_skb(skb);
+ return ret;
+}
+
+/* This function is meant to be invoked on an ARP reply packet going into the
+ * soft interface. The related neighbour entry has to be updated and the DHT has
+ * to be populated as well */
+bool arp_snoop_outgoing_reply(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ uint16_t type;
+ uint32_t ip_src, ip_dst;
+ uint8_t *hw_src, *hw_dst;
+ bool ret = false;
+
+ type = arp_get_type(bat_priv, skb);
+ if (type != ARPOP_REPLY)
+ goto out;
+
+ bat_dbg(DBG_ARP, bat_priv, "Snooped outgoing ARP reply\n");
+
+ hw_src = ARP_HW_SRC(skb);
+ ip_src = ARP_IP_SRC(skb);
+ hw_dst = ARP_HW_DST(skb);
+ ip_dst = ARP_IP_DST(skb);
+
+
+ arp_neigh_update(bat_priv, ip_src, hw_src);
+ arp_neigh_update(bat_priv, ip_dst, hw_dst);
+
+ /* Send the ARP reply to the candidates for both the IP addresses we
+ * fetched from the ARP reply */
+ dht_send_data(bat_priv, skb, ip_src);
+ dht_send_data(bat_priv, skb, ip_dst);
+ ret = true;
+out:
+ return ret;
+}
+
+/* This function has to be invoked on an ARP reply coming into the soft
+ * interface from the mesh network. The local table has to be updated */
+bool arp_snoop_incoming_reply(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+ uint16_t type;
+ uint32_t ip_src, ip_dst;
+ uint8_t *hw_src, *hw_dst;
+ bool ret = false;
+
+ type = arp_get_type(bat_priv, skb);
+ if (type != ARPOP_REPLY)
+ goto out;
+
+ bat_dbg(DBG_ARP, bat_priv, "Snooped incoming ARP reply\n");
+
+ hw_src = ARP_HW_SRC(skb);
+ ip_src = ARP_IP_SRC(skb);
+ hw_dst = ARP_HW_DST(skb);
+ ip_dst = ARP_IP_DST(skb);
+
+ /* Update our internal cache with both the IP addresses we fetched from
+ * the ARP reply */
+ arp_neigh_update(bat_priv, ip_src, hw_src);
+ arp_neigh_update(bat_priv, ip_dst, hw_dst);
+
+ ret = true;
+out:
+ return ret;
+}
diff --git a/distributed-arp-table.h b/distributed-arp-table.h
index 439af22..d3fb8b1 100644
--- a/distributed-arp-table.h
+++ b/distributed-arp-table.h
@@ -29,6 +29,12 @@
#define ARP_IP_DST(skb) (*(uint32_t *)(ARP_HW_SRC(skb) + ETH_ALEN * 2 + 4))
uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb);
+bool arp_snoop_outgoing_request(struct bat_priv *bat_priv,
+ struct sk_buff *skb);
+bool arp_snoop_incoming_request(struct bat_priv *bat_priv,
+ struct sk_buff *skb);
+bool arp_snoop_outgoing_reply(struct bat_priv *bat_priv, struct sk_buff *skb);
+bool arp_snoop_incoming_reply(struct bat_priv *bat_priv, struct sk_buff *skb);
/* hash function to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
diff --git a/main.h b/main.h
index 7b4229c..2b1c4b4 100644
--- a/main.h
+++ b/main.h
@@ -64,6 +64,8 @@
#define NULL_IFINDEX 0 /* dummy ifindex used to avoid iface checks */
+/* msecs after which an ARP_REQUEST is sent in broadcast as fallback */
+#define ARP_REQ_DELAY 250
/* numbers of originator to contact for any STORE/GET DHT operation */
#define DHT_CANDIDATES_NUM 3
diff --git a/routing.c b/routing.c
index ef24a72..ed76406 100644
--- a/routing.c
+++ b/routing.c
@@ -20,6 +20,7 @@
*/
#include "main.h"
+#include "distributed-arp-table.h"
#include "routing.h"
#include "send.h"
#include "soft-interface.h"
diff --git a/send.c b/send.c
index 8a684eb..eaa67f6 100644
--- a/send.c
+++ b/send.c
@@ -20,6 +20,7 @@
*/
#include "main.h"
+#include "distributed-arp-table.h"
#include "send.h"
#include "routing.h"
#include "translation-table.h"
@@ -30,6 +31,8 @@
#include "originator.h"
#include "bat_ogm.h"
+#include <net/arp.h>
+
static void send_outstanding_bcast_packet(struct work_struct *work);
/* send out an already prepared packet to the given address via the
@@ -267,6 +270,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work)
struct sk_buff *skb1;
struct net_device *soft_iface = forw_packet->if_incoming->soft_iface;
struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct neighbour *n;
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
hlist_del(&forw_packet->list);
@@ -275,6 +279,20 @@ static void send_outstanding_bcast_packet(struct work_struct *work)
if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
goto out;
+ /* If this packet is an ARP_REQUEST and we already have the information
+ * that it is going to ask, we can drop the packet */
+ if (!forw_packet->num_packets &&
+ (arp_get_type(bat_priv, forw_packet->skb) ==
+ ARPOP_REQUEST)) {
+ n = neigh_lookup(&arp_tbl, &ARP_IP_DST(forw_packet->skb),
+ soft_iface);
+ /* check if we already know this neigh */
+ if (n && (n->nud_state & NUD_CONNECTED))
+ goto out;
+
+ bat_dbg(DBG_ARP, bat_priv, "ARP request: fallback\n");
+ }
+
/* rebroadcast packet */
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
diff --git a/soft-interface.c b/soft-interface.c
index cd6c9ea..5ef9bba 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -22,6 +22,7 @@
#include "main.h"
#include "soft-interface.h"
#include "hard-interface.h"
+#include "distributed-arp-table.h"
#include "routing.h"
#include "send.h"
#include "bat_debugfs.h"
@@ -564,9 +565,12 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
struct vlan_ethhdr *vhdr;
struct softif_neigh *curr_softif_neigh = NULL;
unsigned int header_len = 0;
+ struct orig_node *orig_node = NULL;
+ struct sk_buff *arp_skb = NULL;
int data_len = skb->len, ret;
short vid = -1;
bool do_bcast = false;
+ unsigned long brd_delay = 1;
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto dropped;
@@ -587,6 +591,8 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
goto end;
}
+ skb_reset_mac_header(skb);
+
/**
* if we have a another chosen mesh exit node in range
* it will transport the packets to the mesh
@@ -628,6 +634,9 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
if (!primary_if)
goto dropped;
+ if (arp_snoop_outgoing_request(bat_priv, skb))
+ brd_delay = msecs_to_jiffies(ARP_REQ_DELAY);
+
if (my_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
goto dropped;
@@ -647,7 +656,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
bcast_packet->seqno =
htonl(atomic_inc_return(&bat_priv->bcast_seqno));
- add_bcast_packet_to_list(bat_priv, skb, 1);
+ add_bcast_packet_to_list(bat_priv, skb, brd_delay);
/* a copy is stored in the bcast list, therefore removing
* the original skb. */
@@ -661,7 +670,12 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
goto dropped;
}
+ /* Increase the refcount to avoid to make the kernel consume
+ * the skb */
+ arp_skb = skb_clone(skb, GFP_ATOMIC);
ret = unicast_send_skb(skb, bat_priv);
+
+ arp_snoop_outgoing_reply(bat_priv, arp_skb);
if (ret != 0)
goto dropped_freed;
}
@@ -679,6 +693,10 @@ end:
softif_neigh_free_ref(curr_softif_neigh);
if (primary_if)
hardif_free_ref(primary_if);
+ if (orig_node)
+ orig_node_free_ref(orig_node);
+ if (arp_skb)
+ kfree_skb(arp_skb);
return NETDEV_TX_OK;
}
@@ -716,6 +734,11 @@ void interface_rx(struct net_device *soft_iface,
goto dropped;
}
+ if (arp_snoop_incoming_request(bat_priv, skb))
+ goto out;
+
+ arp_snoop_incoming_reply(bat_priv, skb);
+
/**
* if we have a another chosen mesh exit node in range
* it will transport the packets to the non-mesh network
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 6/7] batman-adv: Distributed ARP Table - increase default soft_iface ARP table timeout
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
` (4 preceding siblings ...)
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 7/7] batman-adv: add Distributed ARP Table compile option Antonio Quartulli
6 siblings, 0 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
The default timeout value for ARP entries belonging to any soft_iface
ARP table has been incremented by a factor 4. This is necessary because the DHT
will store several network entries in the soft_iface ARP table.
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
main.h | 4 ++++
soft-interface.c | 17 +++++++++++++++++
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/main.h b/main.h
index 2b1c4b4..6216abd 100644
--- a/main.h
+++ b/main.h
@@ -69,6 +69,10 @@
/* numbers of originator to contact for any STORE/GET DHT operation */
#define DHT_CANDIDATES_NUM 3
+/* Factor which default ARP timeout values of the soft_iface table are
+ * multiplied by */
+#define ARP_TIMEOUT_FACTOR 4
+
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
diff --git a/soft-interface.c b/soft-interface.c
index 5ef9bba..786bc71 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -36,6 +36,7 @@
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
+#include <linux/inetdevice.h>
#include "unicast.h"
@@ -834,6 +835,7 @@ static void interface_setup(struct net_device *dev)
struct net_device *softif_create(const char *name)
{
struct net_device *soft_iface;
+ struct in_device *in_dev;
struct bat_priv *bat_priv;
int ret;
@@ -849,6 +851,21 @@ struct net_device *softif_create(const char *name)
goto free_soft_iface;
}
+ in_dev = in_dev_get(soft_iface);
+ if (!in_dev) {
+ pr_err("Unable to set ARP parameters for the batman interface "
+ "'%s'\n", name);
+ goto free_soft_iface;
+ }
+
+ /* Introduce a delay in the ARP state-machine transactions. Entries
+ * will be kept in the ARP table for the default time multiplied by 4 */
+ in_dev->arp_parms->base_reachable_time *= ARP_TIMEOUT_FACTOR;
+ in_dev->arp_parms->gc_staletime *= ARP_TIMEOUT_FACTOR;
+ in_dev->arp_parms->reachable_time *= ARP_TIMEOUT_FACTOR;
+
+ in_dev_put(in_dev);
+
bat_priv = netdev_priv(soft_iface);
atomic_set(&bat_priv->aggregated_ogms, 1);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [B.A.T.M.A.N.] [PATCHv3 7/7] batman-adv: add Distributed ARP Table compile option
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
` (5 preceding siblings ...)
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 6/7] batman-adv: Distributed ARP Table - increase default soft_iface ARP table timeout Antonio Quartulli
@ 2011-11-21 22:53 ` Antonio Quartulli
6 siblings, 0 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-21 22:53 UTC (permalink / raw)
To: b.a.t.m.a.n
This patch makes it possible possible to decide whether to compile DAT or not.
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Reviewed-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
Makefile.kbuild | 8 +++++++-
README | 4 ++++
distributed-arp-table.h | 12 ++++++++++++
3 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/Makefile.kbuild b/Makefile.kbuild
index e8861cb..f09004f 100644
--- a/Makefile.kbuild
+++ b/Makefile.kbuild
@@ -18,6 +18,8 @@
# 02110-1301, USA
#
+# uncomment the following line to enable the related feature
+# CONFIG_BATMAN_ADV_DAT=y # Distributed ARP Table
# openwrt integration
@@ -27,6 +29,10 @@ endif
# ccflags-y += -DCONFIG_BATMAN_ADV_DEBUG
+ifeq ($(CONFIG_BATMAN_ADV_DAT), y)
+ccflags-y += -DCONFIG_BATMAN_ADV_DAT
+endif
+
ifneq ($(REVISION),)
ccflags-y += -DSOURCE_VERSION=\"$(REVISION)\"
endif
@@ -36,7 +42,7 @@ batman-adv-y += bat_debugfs.o
batman-adv-y += bat_iv_ogm.o
batman-adv-y += bat_sysfs.o
batman-adv-y += bitarray.o
-batman-adv-y += distributed-arp-table.o
+batman-adv-$(CONFIG_BATMAN_ADV_DAT) += distributed-arp-table.o
batman-adv-y += gateway_client.o
batman-adv-y += gateway_common.o
batman-adv-y += hard-interface.o
diff --git a/README b/README
index b4fdc8d..8a50eda 100644
--- a/README
+++ b/README
@@ -26,6 +26,10 @@ it. If you work on a backport, feel free to contact us. :-)
COMPILE
-------
+Before compiling you want to have a look at the Makefile.kbuild
+file to enable/disable wanted features. Actually there are:
+- CONFIG_BATMAN_ADV_DAT enables the Distributed ARP Table
+
To compile against your currently installed kernel, just type:
# make
diff --git a/distributed-arp-table.h b/distributed-arp-table.h
index d3fb8b1..bd32c89 100644
--- a/distributed-arp-table.h
+++ b/distributed-arp-table.h
@@ -28,6 +28,8 @@
#define ARP_HW_DST(skb) (ARP_HW_SRC(skb) + ETH_ALEN + 4)
#define ARP_IP_DST(skb) (*(uint32_t *)(ARP_HW_SRC(skb) + ETH_ALEN * 2 + 4))
+#ifdef CONFIG_BATMAN_ADV_DAT
+
uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb);
bool arp_snoop_outgoing_request(struct bat_priv *bat_priv,
struct sk_buff *skb);
@@ -36,6 +38,16 @@ bool arp_snoop_incoming_request(struct bat_priv *bat_priv,
bool arp_snoop_outgoing_reply(struct bat_priv *bat_priv, struct sk_buff *skb);
bool arp_snoop_incoming_reply(struct bat_priv *bat_priv, struct sk_buff *skb);
+#else
+
+#define arp_get_type(...) (0)
+#define arp_snoop_outgoing_request(...) (0)
+#define arp_snoop_incoming_request(...) (0)
+#define arp_snoop_outgoing_reply(...)
+#define arp_snoop_incoming_reply(...)
+
+#endif
+
/* hash function to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
static inline uint32_t hash_ipv4(const void *data, uint32_t size)
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCHv3 4/7] batman-adv: Distributed ARP Table - add ARP parsing functions
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 4/7] batman-adv: Distributed ARP Table - add ARP parsing functions Antonio Quartulli
@ 2011-11-23 15:47 ` Andrew Lunn
0 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2011-11-23 15:47 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
On Mon, Nov 21, 2011 at 11:53:10PM +0100, Antonio Quartulli wrote:
Hi Antonio
> +/* Returns arphdr->ar_op if the skb contains a valid ARP packet, otherwise
> + * returns 0 */
> +uint16_t arp_get_type(struct bat_priv *bat_priv, struct sk_buff *skb)
> +{
> + struct arphdr *arphdr;
> + struct ethhdr *ethhdr;
> + uint16_t type = 0;
> + char buf[30], *type_str[] = { "REQUEST", "REPLY", "RREQUEST", "RREPLY",
> + "InREQUEST", "InREPLY", "NAK" };
type_str could be marked as const. Saves a little bit of space on the
BSS.
> +
> + if (type >= 1 && type <= 10)
> + scnprintf(buf, 30, "%s", type_str[type - 1]);
type_str currently has 6 entries, so if somebody sends you an ARP
request with type greater than 6, you go off the end of the
array. Better to use ARRAY_SIZE().
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages Antonio Quartulli
@ 2011-11-23 16:11 ` Andrew Lunn
2011-11-23 16:19 ` Antonio Quartulli
0 siblings, 1 reply; 11+ messages in thread
From: Andrew Lunn @ 2011-11-23 16:11 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
Hi Antonio
> + n = neigh_lookup(&arp_tbl, &ip_dst, primary_if->soft_iface);
> + /* check if it is a valid neigh entry */
> + if (!n || !(n->nud_state & NUD_CONNECTED))
> + goto out;
> +
> + skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
> + primary_if->soft_iface, ip_dst, hw_src, n->ha,
> + hw_src);
> +
> + unicast_send_skb(skb_new, bat_priv);
Can arp_create fail? Should you check the return value before calling
unicast_send_skb()?
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages
2011-11-23 16:11 ` Andrew Lunn
@ 2011-11-23 16:19 ` Antonio Quartulli
0 siblings, 0 replies; 11+ messages in thread
From: Antonio Quartulli @ 2011-11-23 16:19 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
Hello Andrew,
On Wed, Nov 23, 2011 at 05:11:51 +0100, Andrew Lunn wrote:
> Hi Antonio
>
> > + n = neigh_lookup(&arp_tbl, &ip_dst, primary_if->soft_iface);
> > + /* check if it is a valid neigh entry */
> > + if (!n || !(n->nud_state & NUD_CONNECTED))
> > + goto out;
> > +
> > + skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
> > + primary_if->soft_iface, ip_dst, hw_src, n->ha,
> > + hw_src);
> > +
> > + unicast_send_skb(skb_new, bat_priv);
>
> Can arp_create fail? Should you check the return value before calling
> unicast_send_skb()?
>
Thank you for the comment.
Anyway this patchset is now a bit "old", because after posting it I continued to
work on it and to correct some bugs (like this one).
Therefore I would not go ahead in inspecting these patches. Sorry for this.
Cheers,
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-11-23 16:19 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-21 22:53 [B.A.T.M.A.N.] [PATCHv3 0/7] DAT: Distributed ARP Table Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 1/7] batman-adv: implement an helper function to forge unicast packets Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 2/7] batman-adv: add a new log level for DAT-ARP debugging Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 3/7] batman-adv: Distributed ARP Table - create the DHT helper functions Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 4/7] batman-adv: Distributed ARP Table - add ARP parsing functions Antonio Quartulli
2011-11-23 15:47 ` Andrew Lunn
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 5/7] batman-adv: Distributed ARP Table - add snooping functions for ARP messages Antonio Quartulli
2011-11-23 16:11 ` Andrew Lunn
2011-11-23 16:19 ` Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 6/7] batman-adv: Distributed ARP Table - increase default soft_iface ARP table timeout Antonio Quartulli
2011-11-21 22:53 ` [B.A.T.M.A.N.] [PATCHv3 7/7] batman-adv: add Distributed ARP Table compile option Antonio Quartulli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).