[B.A.T.M.A.N.] [PATCH 1/2] batman-adv: drop useless argument seqno in neighbor creation
by Antonio Quartulli
From: Antonio Quartulli <antonio(a)open-mesh.com>
the sequence number is not stored in struct neigh_node,
therefore there is no need to pass such value to the
neigh_node creation procedure.
At the moment the value is only used by a debug message, but
given the fact that the seqno is not related to the neighbor
object, it is better to print it elsewhere.
Signed-off-by: Antonio Quartulli <antonio(a)open-mesh.com>
---
do we really want to pass the seqno over every function just to print it at the
end? If this value is really important (debug? don't know) it should be printed
in a proper place, e.g. in the function that triggered the creation and that
possibly has the seqno for other purposes...
Otherwise we would not be able to create a neigh_nod unless we have a seqno to
pass.
Cheers,
bat_iv_ogm.c | 11 ++++-------
originator.c | 5 ++---
originator.h | 2 +-
3 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
index 071f288..da239c5 100644
--- a/bat_iv_ogm.c
+++ b/bat_iv_ogm.c
@@ -33,12 +33,11 @@ static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr,
struct batadv_orig_node *orig_node,
- struct batadv_orig_node *orig_neigh, __be32 seqno)
+ struct batadv_orig_node *orig_neigh)
{
struct batadv_neigh_node *neigh_node;
- neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr,
- ntohl(seqno));
+ neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr);
if (!neigh_node)
goto out;
@@ -696,8 +695,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
ethhdr->h_source,
- orig_node, orig_tmp,
- batadv_ogm_packet->seqno);
+ orig_node, orig_tmp);
batadv_orig_node_free_ref(orig_tmp);
if (!neigh_node)
@@ -829,8 +827,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
orig_neigh_node->orig,
orig_neigh_node,
- orig_neigh_node,
- batadv_ogm_packet->seqno);
+ orig_neigh_node);
if (!neigh_node)
goto out;
diff --git a/originator.c b/originator.c
index 2f34525..ddd417c 100644
--- a/originator.c
+++ b/originator.c
@@ -92,7 +92,7 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
- const uint8_t *neigh_addr, uint32_t seqno)
+ const uint8_t *neigh_addr)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_neigh_node *neigh_node;
@@ -110,8 +110,7 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
atomic_set(&neigh_node->refcount, 2);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
- "Creating new neighbor %pM, initial seqno %d\n",
- neigh_addr, seqno);
+ "Creating new neighbor %pM\n", neigh_addr);
out:
return neigh_node;
diff --git a/originator.h b/originator.h
index 7df48fa..476c623 100644
--- a/originator.h
+++ b/originator.h
@@ -30,7 +30,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
const uint8_t *addr);
struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
- const uint8_t *neigh_addr, uint32_t seqno);
+ const uint8_t *neigh_addr);
void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
struct batadv_neigh_node *
batadv_orig_node_get_router(struct batadv_orig_node *orig_node);
--
1.8.1.5
7 years, 11 months
[B.A.T.M.A.N.] [RFCv2] batman-adv: Modified DAT structures and functions in order to support both IPv4 and IPv6
by Mihail Costea
Subject: [RFCv2] batman-adv: Modified DAT structures and functions in order
to support both IPv4 and IPv6
Signed-off-by: Mihail Costea <mihail.costea90(a)gmail.com>
---
Modified the debug message macro to a function and made it more generic
(in order to support seq_printf too).
Added IPv6 macros in order to NOT add IPv6 dependent code if support
is disabled. Also, removed as many switch-cases as possible to have less
"if defined(IPv6)" tests.
Added call_rcu for kfree dat_entry.
For compare function, test if both data fields have the same type.
distributed-arp-table.c | 338 +++++++++++++++++++++++++++++++++++++++--------
types.h | 23 +++-
2 files changed, 301 insertions(+), 60 deletions(-)
diff --git a/distributed-arp-table.c b/distributed-arp-table.c
index 3a3e1d8..30b683e 100644
--- a/distributed-arp-table.c
+++ b/distributed-arp-table.c
@@ -20,6 +20,7 @@
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <net/arp.h>
+#include <net/ipv6.h>
#include "main.h"
#include "hash.h"
@@ -31,6 +32,115 @@
#include "translation-table.h"
#include "unicast.h"
+/**
+ * batadv_dat_ip_format_string - construct a generic ip format string
+ * for printing
+ * @ip_type: IPv4 / IPv6 address
+ * @format_prefix: format before IP field
+ * @format_suffix: format after IP field
+ * @width: padding blank spaces for IP field or 0 if none
+ *
+ * format_string is allocated dynamically. It should be kfree when
+ * there is no more need for it.
+ *
+ * Returns the format string with an IP field inside, or NULL
+ * if allocation failed.
+ */
+static char *batadv_dat_ip_format_string(uint8_t ip_type,
+ char *format_prefix, char *format_suffix, int width)
+{
+ char *format_string, *tmp_string;
+ char ipv4[] = "pI4", ipv6[] = "pI6c";
+ int width_length = 0, tmp_witdh = width;
+ int ipv4_len = strlen(ipv4), ipv6_len = strlen(ipv6);
+ int ip_str_size = (ipv4_len > ipv6_len) ? ipv4_len : ipv6_len;
+
+ /* calculate number of chars need for width */
+ if (tmp_witdh < 0) {
+ width_length++;
+ tmp_witdh *= -1;
+ }
+ while (tmp_witdh > 0) {
+ width_length++;
+ tmp_witdh /= 10;
+ }
+
+ /* construct format string */
+ format_string = kmalloc(strlen(format_prefix) + width_length +
+ ip_str_size + strlen(format_suffix) +
+ 2, /* "%" and NULL chars */
+ GFP_ATOMIC);
+ if (!format_string)
+ goto out;
+
+ tmp_string = format_string;
+ sprintf(tmp_string, "%s%%", format_prefix);
+ tmp_string += strlen(tmp_string);
+ if (width != 0) {
+ sprintf(tmp_string, "%i", width);
+ tmp_string += strlen(tmp_string);
+ }
+
+ switch (ip_type) {
+ case BATADV_DAT_IPV4:
+ sprintf(tmp_string, "%s%s", ipv4, format_suffix);
+ break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ case BATADV_DAT_IPV6:
+ sprintf(tmp_string, "%s%s", ipv6, format_suffix);
+ break;
+#endif
+ default:
+ goto out;
+ }
+
+ return format_string;
+out:
+ kfree(format_string);
+ return NULL;
+}
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+
+/* batadv_dat_dbg_ip - print similar debug message for IPv4 and IPv6.
+ * @bat_priv: the bat priv with all the soft interface information
+ * @ip_type: IPv4 / IPv6 address
+ * @format_prefix: format before IP field
+ * @format_suffix: format after IP field
+ *
+ * At list one variable parameter should be the IP itself, and it should
+ * be placed correctly based on format prefix and format suffix arguments.
+ */
+static void batadv_dat_dbg_ip(struct batadv_priv *bat_priv,
+ uint8_t ip_type, char *format_prefix,
+ char *format_suffix, ...)
+{
+ va_list arg_va_list;
+ char *format_string;
+
+ va_start(arg_va_list, format_suffix);
+
+ format_string = batadv_dat_ip_format_string(ip_type,
+ format_prefix, format_suffix, 0);
+ if (format_string) {
+ batadv_dbg(BATADV_DBG_DAT, bat_priv, format_string,
+ arg_va_list);
+ kfree(format_string);
+ }
+
+ va_end(arg_va_list);
+}
+
+#else
+
+static void batadv_dat_dbg_ip(struct batadv_priv *bat_priv,
+ uint8_t ip_type, char *format_prefix,
+ char *format_suffix, ...)
+{
+}
+
+#endif /* CONFIG_BATMAN_ADV_DEBUG */
+
static void batadv_dat_purge(struct work_struct *work);
/**
@@ -45,6 +155,19 @@ static void batadv_dat_start_timer(struct
batadv_priv *bat_priv)
}
/**
+ * batadv_dat_entry_free_ref_rcu - free a dat entry using its rcu
+ * @rcu: the dat entry rcu
+ */
+static void batadv_dat_entry_free_ref_rcu(struct rcu_head *rcu)
+{
+ struct batadv_dat_entry *dat_entry;
+
+ dat_entry = container_of(rcu, struct batadv_dat_entry, rcu);
+ kfree(dat_entry->ip);
+ kfree(dat_entry);
+}
+
+/**
* batadv_dat_entry_free_ref - decrement the dat_entry refcounter and possibly
* free it
* @dat_entry: the entry to free
@@ -52,7 +175,7 @@ static void batadv_dat_start_timer(struct
batadv_priv *bat_priv)
static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry)
{
if (atomic_dec_and_test(&dat_entry->refcount))
- kfree_rcu(dat_entry, rcu);
+ call_rcu(&dat_entry->rcu, batadv_dat_entry_free_ref_rcu);
}
/**
@@ -130,19 +253,62 @@ static void batadv_dat_purge(struct work_struct *work)
}
/**
+ * batadv_sizeof_ip - get sizeof IP based on its type (IPv4 / IPv6)
+ * @ip_type: type of IP address
+ *
+ * Returns sizeof IP, or sizeof IPv4 if ip_type is invalid.
+ */
+static size_t batadv_sizeof_ip(uint8_t ip_type)
+{
+ switch (ip_type) {
+ case BATADV_DAT_IPV4:
+ return sizeof(__be32);
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ case BATADV_DAT_IPV6:
+ return sizeof(struct in6_addr);
+#endif
+ default:
+ return sizeof(__be32); /* fallback to IPv4 */
+ }
+}
+
+/**
* batadv_compare_dat - comparing function used in the local DAT hash table
* @node: node in the local table
* @data2: second object to compare the node to
+ * @ip_type: type of IP address
*
* Returns 1 if the two entries are the same, 0 otherwise.
*/
-static int batadv_compare_dat(const struct hlist_node *node, const void *data2)
+static int batadv_compare_dat(const struct hlist_node *node, const void *data2,
+ uint8_t ip_type)
{
- const void *data1 = container_of(node, struct batadv_dat_entry,
- hash_entry);
+ struct batadv_dat_entry *dat_entry1 = container_of(node,
+ struct batadv_dat_entry, hash_entry);
+ struct batadv_dat_entry *dat_entry2 = container_of(data2,
+ struct batadv_dat_entry, ip);
+ size_t ip_size;
- return (memcmp(data1, data2, sizeof(__be32)) == 0 ? 1 : 0);
+ if (dat_entry1->type != dat_entry2->type)
+ return 0;
+
+ ip_size = batadv_sizeof_ip(ip_type);
+ return (memcmp(dat_entry1->ip, dat_entry2->ip, ip_size) == 0 ? 1 : 0);
+}
+
+static int batadv_compare_dat_ipv4(const struct hlist_node *node,
+ const void *data2)
+{
+ return batadv_compare_dat(node, data2, BATADV_DAT_IPV4);
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static int batadv_compare_dat_ipv6(const struct hlist_node *node,
+ const void *data2)
+{
+ return batadv_compare_dat(node, data2, BATADV_DAT_IPV6);
}
+#endif
/**
* batadv_arp_hw_src - extract the hw_src field from an ARP packet
@@ -201,16 +367,19 @@ static __be32 batadv_arp_ip_dst(struct sk_buff
*skb, int hdr_size)
* batadv_hash_dat - compute the hash value for an IP address
* @data: data to hash
* @size: size of the hash table
+ * @ip_type: type of IP address
*
* Returns the selected index in the hash table for the given data.
*/
-static uint32_t batadv_hash_dat(const void *data, uint32_t size)
+static uint32_t batadv_hash_dat(const void *data, uint32_t size,
+ uint8_t ip_type)
{
const unsigned char *key = data;
uint32_t hash = 0;
- size_t i;
+ size_t i, ip_size;
- for (i = 0; i < 4; i++) {
+ ip_size = batadv_sizeof_ip(ip_type);
+ for (i = 0; i < ip_size; i++) {
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
@@ -223,31 +392,47 @@ static uint32_t batadv_hash_dat(const void
*data, uint32_t size)
return hash % size;
}
+static uint32_t batadv_hash_dat_ipv4(const void *data, uint32_t size)
+{
+ return batadv_hash_dat(data, size, BATADV_DAT_IPV4);
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static uint32_t batadv_hash_dat_ipv6(const void *data, uint32_t size)
+{
+ return batadv_hash_dat(data, size, BATADV_DAT_IPV6);
+}
+#endif
+
/**
* batadv_dat_entry_hash_find - look for a given dat_entry in the local hash
* table
* @bat_priv: the bat priv with all the soft interface information
* @ip: search key
+ * @ip_type: type of IP address
*
* Returns the dat_entry if found, NULL otherwise.
*/
static struct batadv_dat_entry *
-batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
+batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, unsigned char *ip,
+ uint8_t ip_type)
{
struct hlist_head *head;
struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL;
struct batadv_hashtable *hash = bat_priv->dat.hash;
uint32_t index;
+ size_t ip_size;
if (!hash)
return NULL;
- index = batadv_hash_dat(&ip, hash->size);
+ ip_size = batadv_sizeof_ip(ip_type);
+ index = batadv_hash_dat(ip, hash->size, ip_type);
head = &hash->table[index];
rcu_read_lock();
hlist_for_each_entry_rcu(dat_entry, head, hash_entry) {
- if (dat_entry->ip != ip)
+ if (memcmp(dat_entry->ip, ip, ip_size))
continue;
if (!atomic_inc_not_zero(&dat_entry->refcount))
@@ -264,24 +449,26 @@ batadv_dat_entry_hash_find(struct batadv_priv
*bat_priv, __be32 ip)
/**
* batadv_dat_entry_add - add a new dat entry or update it if already exists
* @bat_priv: the bat priv with all the soft interface information
- * @ip: ipv4 to add/edit
+ * @ip: IP to add/edit
+ * @ip_type: type of IP address
* @mac_addr: mac address to assign to the given ipv4
*/
-static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
- uint8_t *mac_addr)
+static void batadv_dat_entry_add(struct batadv_priv *bat_priv,
+ unsigned char *ip, uint8_t ip_type, uint8_t *mac_addr)
{
struct batadv_dat_entry *dat_entry;
int hash_added;
+ size_t ip_size;
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, ip_type);
/* if this entry is already known, just update it */
if (dat_entry) {
if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
dat_entry->last_update = jiffies;
- batadv_dbg(BATADV_DBG_DAT, bat_priv,
- "Entry updated: %pI4 %pM\n", &dat_entry->ip,
- dat_entry->mac_addr);
+
+ batadv_dat_dbg_ip(bat_priv, ip_type, "Entry updated: ",
+ " %pM\n", dat_entry->ip, dat_entry->mac_addr);
goto out;
}
@@ -289,14 +476,34 @@ static void batadv_dat_entry_add(struct
batadv_priv *bat_priv, __be32 ip,
if (!dat_entry)
goto out;
- dat_entry->ip = ip;
+ ip_size = batadv_sizeof_ip(ip_type);
+ dat_entry->ip = kmalloc(ip_size, GFP_ATOMIC);
+ if (!dat_entry->ip)
+ goto out;
+ memcpy(dat_entry->ip, ip, ip_size);
+ dat_entry->type = ip_type;
+
memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
dat_entry->last_update = jiffies;
atomic_set(&dat_entry->refcount, 2);
- hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
- batadv_hash_dat, &dat_entry->ip,
- &dat_entry->hash_entry);
+ switch (ip_type) {
+ case BATADV_DAT_IPV4:
+ hash_added = batadv_hash_add(bat_priv->dat.hash,
+ batadv_compare_dat_ipv4, batadv_hash_dat_ipv4,
+ dat_entry->ip, &dat_entry->hash_entry);
+ break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ case BATADV_DAT_IPV6:
+ hash_added = batadv_hash_add(bat_priv->dat.hash,
+ batadv_compare_dat_ipv6, batadv_hash_dat_ipv6,
+ dat_entry->ip, &dat_entry->hash_entry);
+ break;
+#endif
+ default:
+ hash_added = 1; /* in order to catch next if */
+ break;
+ }
if (unlikely(hash_added != 0)) {
/* remove the reference for the hash */
@@ -304,9 +511,8 @@ static void batadv_dat_entry_add(struct
batadv_priv *bat_priv, __be32 ip,
goto out;
}
- batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM\n",
- &dat_entry->ip, dat_entry->mac_addr);
-
+ batadv_dat_dbg_ip(bat_priv, ip_type, "New entry added: ", " %pM\n",
+ dat_entry->ip, dat_entry->mac_addr);
out:
if (dat_entry)
batadv_dat_entry_free_ref(dat_entry);
@@ -513,7 +719,8 @@ static void batadv_choose_next_candidate(struct
batadv_priv *bat_priv,
* batadv_dat_select_candidates - select the nodes which the DHT message has to
* be sent to
* @bat_priv: the bat priv with all the soft interface information
- * @ip_dst: ipv4 to look up in the DHT
+ * @ip_dst: IP to look up in the DHT
+ * @ip_type: type of IP address
*
* An originator O is selected if and only if its DHT_ID value is one of three
* closest values (from the LEFT, with wrap around if needed) then the hash
@@ -522,7 +729,8 @@ static void batadv_choose_next_candidate(struct
batadv_priv *bat_priv,
* Returns the candidate array of size BATADV_DAT_CANDIDATE_NUM.
*/
static struct batadv_dat_candidate *
-batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
+batadv_dat_select_candidates(struct batadv_priv *bat_priv,
+ unsigned char *ip_dst, uint8_t ip_type)
{
int select;
batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
@@ -535,12 +743,11 @@ batadv_dat_select_candidates(struct batadv_priv
*bat_priv, __be32 ip_dst)
if (!res)
return NULL;
- ip_key = (batadv_dat_addr_t)batadv_hash_dat(&ip_dst,
- BATADV_DAT_ADDR_MAX);
+ ip_key = (batadv_dat_addr_t)batadv_hash_dat(ip_dst,
+ BATADV_DAT_ADDR_MAX, ip_type);
- batadv_dbg(BATADV_DBG_DAT, bat_priv,
- "dat_select_candidates(): IP=%pI4 hash(IP)=%u\n", &ip_dst,
- ip_key);
+ batadv_dat_dbg_ip(bat_priv, ip_type, "dat_select_candidates(): IP=",
+ " hash(IP)=%u\n", ip_dst, ip_key);
for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++)
batadv_choose_next_candidate(bat_priv, res, select, ip_key,
@@ -554,6 +761,7 @@ batadv_dat_select_candidates(struct batadv_priv
*bat_priv, __be32 ip_dst)
* @bat_priv: the bat priv with all the soft interface information
* @skb: payload to send
* @ip: the DHT key
+ * @ip_type: type of IP address
* @packet_subtype: unicast4addr packet subtype to use
*
* This function copies the skb with pskb_copy() and is sent as unicast packet
@@ -563,8 +771,8 @@ batadv_dat_select_candidates(struct batadv_priv
*bat_priv, __be32 ip_dst)
* otherwise.
*/
static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
- struct sk_buff *skb, __be32 ip,
- int packet_subtype)
+ struct sk_buff *skb, unsigned char *ip,
+ uint8_t ip_type, int packet_subtype)
{
int i;
bool ret = false;
@@ -573,11 +781,11 @@ static bool batadv_dat_send_data(struct
batadv_priv *bat_priv,
struct sk_buff *tmp_skb;
struct batadv_dat_candidate *cand;
- cand = batadv_dat_select_candidates(bat_priv, ip);
+ cand = batadv_dat_select_candidates(bat_priv, ip, ip_type);
if (!cand)
goto out;
- batadv_dbg(BATADV_DBG_DAT, bat_priv, "DHT_SEND for %pI4\n", &ip);
+ batadv_dat_dbg_ip(bat_priv, ip_type, "DHT_SEND for ", "\n", ip);
for (i = 0; i < BATADV_DAT_CANDIDATES_NUM; i++) {
if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND)
@@ -685,6 +893,7 @@ int batadv_dat_cache_seq_print_text(struct
seq_file *seq, void *offset)
struct batadv_hard_iface *primary_if;
struct hlist_head *head;
unsigned long last_seen_jiffies;
+ char *format_string;
int last_seen_msecs, last_seen_secs, last_seen_mins;
uint32_t i;
@@ -693,8 +902,8 @@ int batadv_dat_cache_seq_print_text(struct
seq_file *seq, void *offset)
goto out;
seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
- seq_printf(seq, " %-7s %-13s %5s\n", "IPv4", "MAC",
- "last-seen");
+ seq_printf(seq, " %-26s %-15s %5s\n",
+ "IPv4/IPv6", "MAC", "last-seen");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -707,9 +916,16 @@ int batadv_dat_cache_seq_print_text(struct
seq_file *seq, void *offset)
last_seen_msecs = last_seen_msecs % 60000;
last_seen_secs = last_seen_msecs / 1000;
- seq_printf(seq, " * %15pI4 %14pM %6i:%02i\n",
- &dat_entry->ip, dat_entry->mac_addr,
- last_seen_mins, last_seen_secs);
+ format_string =
+ batadv_dat_ip_format_string(dat_entry->type,
+ " * ", " %15pM %6i:%02i\n", -40);
+ if (format_string) {
+ seq_printf(seq, format_string, dat_entry->ip,
+ dat_entry->mac_addr,
+ last_seen_mins,
+ last_seen_secs);
+ kfree(format_string);
+ }
}
rcu_read_unlock();
}
@@ -830,9 +1046,11 @@ bool
batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
hw_src = batadv_arp_hw_src(skb, 0);
ip_dst = batadv_arp_ip_dst(skb, 0);
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
+ batadv_dat_entry_add(bat_priv, (unsigned char *)&ip_src,
+ BATADV_DAT_IPV4, hw_src);
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv,
+ (unsigned char *)&ip_dst, BATADV_DAT_IPV4);
if (dat_entry) {
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
bat_priv->soft_iface, ip_dst, hw_src,
@@ -851,9 +1069,10 @@ bool
batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
ret = true;
} else {
- /* Send the request to the DHT */
- ret = batadv_dat_send_data(bat_priv, skb, ip_dst,
- BATADV_P_DAT_DHT_GET);
+ /* Send the request on the DHT */
+ ret = batadv_dat_send_data(bat_priv, skb,
+ (unsigned char *)&ip_dst, BATADV_DAT_IPV4,
+ BATADV_P_DAT_DHT_GET);
}
out:
if (dat_entry)
@@ -895,9 +1114,11 @@ bool
batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
batadv_dbg_arp(bat_priv, skb, type, hdr_size,
"Parsing incoming ARP REQUEST");
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
+ batadv_dat_entry_add(bat_priv, (unsigned char *)&ip_src,
+ BATADV_DAT_IPV4, hw_src);
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv,
+ (unsigned char *)&ip_dst, BATADV_DAT_IPV4);
if (!dat_entry)
goto out;
@@ -956,14 +1177,18 @@ void batadv_dat_snoop_outgoing_arp_reply(struct
batadv_priv *bat_priv,
hw_dst = batadv_arp_hw_dst(skb, 0);
ip_dst = batadv_arp_ip_dst(skb, 0);
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
- batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
+ batadv_dat_entry_add(bat_priv, (unsigned char *)&ip_src,
+ BATADV_DAT_IPV4, hw_src);
+ batadv_dat_entry_add(bat_priv, (unsigned char *)&ip_dst,
+ BATADV_DAT_IPV4, hw_dst);
/* Send the ARP reply to the candidates for both the IP addresses that
* the node obtained from the ARP reply
*/
- batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT);
- batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT);
+ batadv_dat_send_data(bat_priv, skb, (unsigned char *)&ip_src,
+ BATADV_DAT_IPV4, BATADV_P_DAT_DHT_PUT);
+ batadv_dat_send_data(bat_priv, skb, (unsigned char *)&ip_dst,
+ BATADV_DAT_IPV4, BATADV_P_DAT_DHT_PUT);
}
/**
* batadv_dat_snoop_incoming_arp_reply - snoop the ARP reply and fill the local
@@ -998,8 +1223,10 @@ bool batadv_dat_snoop_incoming_arp_reply(struct
batadv_priv *bat_priv,
/* Update our internal cache with both the IP addresses the node got
* within the ARP reply
*/
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
- batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
+ batadv_dat_entry_add(bat_priv, (unsigned char *)&ip_src,
+ BATADV_DAT_IPV4, hw_src);
+ batadv_dat_entry_add(bat_priv, (unsigned char *)&ip_dst,
+ BATADV_DAT_IPV4, hw_dst);
/* if this REPLY is directed to a client of mine, let's deliver the
* packet to the interface
@@ -1043,7 +1270,8 @@ bool batadv_dat_drop_broadcast_packet(struct
batadv_priv *bat_priv,
goto out;
ip_dst = batadv_arp_ip_dst(forw_packet->skb, bcast_len);
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv,
+ (unsigned char *)&ip_dst, BATADV_DAT_IPV4);
/* check if the node already got this entry */
if (!dat_entry) {
batadv_dbg(BATADV_DBG_DAT, bat_priv,
diff --git a/types.h b/types.h
index 5f542bd..5f8b183 100644
--- a/types.h
+++ b/types.h
@@ -961,17 +961,18 @@ struct batadv_algo_ops {
};
/**
- * struct batadv_dat_entry - it is a single entry of batman-adv ARP backend. It
- * is used to stored ARP entries needed for the global DAT cache
- * @ip: the IPv4 corresponding to this DAT/ARP entry
- * @mac_addr: the MAC address associated to the stored IPv4
+ * struct batadv_dat_entry - it is a single entry of batman-adv
ARP/NDP backend. It
+ * is used to stored ARP/NDP entries needed for the global DAT cache
+ * @ip: the IPv4 / IPv6 corresponding to this DAT ARP/NDP entry
+ * @mac_addr: the MAC address associated to the stored @ip
* @last_update: time in jiffies when this entry was refreshed last time
* @hash_entry: hlist node for batadv_priv_dat::hash
* @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner
*/
struct batadv_dat_entry {
- __be32 ip;
+ unsigned char *ip;
+ uint8_t type;
uint8_t mac_addr[ETH_ALEN];
unsigned long last_update;
struct hlist_node hash_entry;
@@ -980,6 +981,18 @@ struct batadv_dat_entry {
};
/**
+ * batadv_dat_types - types used in batadv_dat_entry for IP
+ * @BATADV_DAT_IPv4: IPv4 address type
+ * @BATADV_DAT_IPv6: IPv6 address type
+ */
+enum batadv_dat_types {
+ BATADV_DAT_IPV4,
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ BATADV_DAT_IPV6,
+#endif
+};
+
+/**
* struct batadv_dat_candidate - candidate destination for DAT operations
* @type: the type of the selected candidate. It can one of the following:
* - BATADV_DAT_CANDIDATE_NOT_FOUND
--
1.7.10.4
7 years, 11 months
[B.A.T.M.A.N.] [PATCH maint] batman-adv: properly push NET_IP_ALIGN bytes more
by Antonio Quartulli
From: Antonio Quartulli <antonio(a)open-mesh.com>
every batman-adv encapsulated packet is supposed to begin
with an Ethernet header plus 2 bytes for correct alignment
on 4 bytes boundary.
However, even if allocations are made correctly, the final
encapsulation is not made properly since the encapsulating
function does not push NET_IP_ALIGN bytes other than
ETH_HLEN.
Fix it by pushing the correct amount of bytes.
Introduced by 7f91790974c258e71a62f6dee8cb1dbe5dff36c3
("batman-adv: Reserve extra bytes in skb for better alignment")
Signed-off-by: Antonio Quartulli <antonio(a)open-mesh.com>
---
Please review this patch as I am not 100% sure this is correct.
What I understood is that any batman-adv should have this shape:
+--------------+
| ETH_HEADER |
| |
+--------------+
| NET_IP_ALIGN |
+--------------+
| BATADV_HEADER|
+--------------+
| ... |
but by pushing ETH_HLEN only, we end up in a shorter packet, because the head
pointer is not moved up enough to contain the NET_IP_ALIGN bytes too (so we are
back to the situation where our headers are not properly placed in memory).
Cheers,
send.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/send.c b/send.c
index a67cffd..a338093 100644
--- a/send.c
+++ b/send.c
@@ -54,7 +54,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
}
/* push to the ethernet header. */
- if (batadv_skb_head_push(skb, ETH_HLEN) < 0)
+ if (batadv_skb_head_push(skb, ETH_HLEN + NET_IP_ALIGN) < 0)
goto send_skb_err;
skb_reset_mac_header(skb);
--
1.8.1.5
7 years, 11 months
[B.A.T.M.A.N.] [PATCH 1/2] batctl: fix 4addr parsing in tcpdump
by Antonio Quartulli
In the UNICAST4ADDR parsing routing a wrong type is used to
parse the batman header, resulting in a wrong data
visualization. Fix this by using the correct data type.
Introduced by 70aefcf8abefd509e5721c6ae228d3854d5e8b16
("batctl: Add minimal unicast 4addr dissector support")
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
tcpdump.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tcpdump.c b/tcpdump.c
index f357c6d..39239dd 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -545,14 +545,14 @@ static void dump_batman_frag(unsigned char *packet_buff, ssize_t buff_len, int r
static void dump_batman_4addr(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed)
{
struct ether_header *ether_header;
- struct batadv_unicast_packet *unicast_4addr_packet;
+ struct batadv_unicast_4addr_packet *unicast_4addr_packet;
- LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct batadv_unicast_packet), "BAT 4ADDR");
- LEN_CHECK((size_t)buff_len - sizeof(struct ether_header) - sizeof(struct batadv_unicast_packet),
+ LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct batadv_unicast_4addr_packet), "BAT 4ADDR");
+ LEN_CHECK((size_t)buff_len - sizeof(struct ether_header) - sizeof(struct batadv_unicast_4addr_packet),
sizeof(struct ether_header), "BAT 4ADDR (unpacked)");
ether_header = (struct ether_header *)packet_buff;
- unicast_4addr_packet = (struct batadv_unicast_packet *)(packet_buff + sizeof(struct ether_header));
+ unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)(packet_buff + sizeof(struct ether_header));
if (!time_printed)
time_printed = print_time();
@@ -560,12 +560,12 @@ static void dump_batman_4addr(unsigned char *packet_buff, ssize_t buff_len, int
printf("BAT %s > ",
get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt));
- printf("%s: 4ADDR, ttvn %d, ttl %hhu, ",
- get_name_by_macaddr((struct ether_addr *)unicast_4addr_packet->dest, read_opt),
- unicast_4addr_packet->ttvn, unicast_4addr_packet->header.ttl);
+ printf("%s: 4ADDR, subtype %d, ttvn %d, ttl %hhu, ",
+ get_name_by_macaddr((struct ether_addr *)unicast_4addr_packet->u.dest, read_opt),
+ unicast_4addr_packet->u.ttvn, unicast_4addr_packet->u.header.ttl);
- parse_eth_hdr(packet_buff + ETH_HLEN + sizeof(struct batadv_unicast_packet),
- buff_len - ETH_HLEN - sizeof(struct batadv_unicast_packet),
+ parse_eth_hdr(packet_buff + ETH_HLEN + sizeof(struct batadv_unicast_4addr_packet),
+ buff_len - ETH_HLEN - sizeof(struct batadv_unicast_4addr_packet),
read_opt, time_printed);
}
--
1.8.1.5
7 years, 11 months
Re: [B.A.T.M.A.N.] Bug#703540: Inconsistent use of _GNU_SOURCE
by Sven Eckelmann
tags 703540 + pending patch
thanks
On Wednesday 20 March 2013 17:51:54 you wrote:
> While building the package using our research compiler infrastructure we
> noticed conflicting types being used in the linked executable. This is due
> to _GNU_SOURCE being defined in linux/route.c and posix/unix_socket.c, but
> not in any other file. As a result, system headers expand to conflicting
> declarations. (This was at least noticed for the sendto function, but may
> extend to others.)
>
> Either all or no file should #define _GNU_SOURCE.
Please add information how to reproduce this the next time you are adding such
such a bug. Now I can just assume what you are writing is true (even when the
man page about sendto says otherwise). Not knowing how to reproduce it in the
best possible way just makes it harder for everyone to check the impact of the
problem.
I've forwarded it to the upstream maintainer and attached the change for
Debian.
Kind regards,
Sven
7 years, 11 months
[B.A.T.M.A.N.] [PATCH trivial] batman-adv: make indexes variable type homogeneous
by Antonio Quartulli
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
translation-table.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/translation-table.c b/translation-table.c
index 279f0fd..88a697d 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -1391,8 +1391,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
struct batadv_tt_common_entry *tt_common;
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
- uint32_t i;
- int j;
+ int i, j;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
--
1.8.1.5
7 years, 11 months