Hi Stephen,
On Fri, Apr 19, 2013 at 01:21:27PM +1000, Stephen Rothwell wrote:
>
> Caused by commits 612d2b4fe0a1 ("batman-adv: network coding - save
> overheard and tx packets for decoding") and 2df5278b0267 ("batman-adv:
> network coding - receive coded packets and decode them") from the
> net-next tree interacting with commit fe8a93b95145 ("batman-adv: make
> is_my_mac() check for the current mesh only") from the net tree.
>
> I added the following merge fix patch and can carry it as necessary:
thank you very much for taking care of this.
However, as I wrote to David in the pull request which generated this noise
(http://patchwork.ozlabs.org/patch/237363/), I am now going to send a second
pull request which fixes this problem properly and adds the related kernel doc.
Your patch looks good, but I'd prefer to send my already prepared pull request.
Is it ok with you?
Cheers,
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara
Hi David,
here you have a patch intended for net/linux-3.9 (if it can still make it..).
It is fixing a MAC address check routine which does not behave
correctly in case of multiple mesh interfaces in the same node.
This patch will generate some conflicts the next time you will merge net in
net-next and will also break it (this happens because the function this patch is
changing is used by some patches existing in net-next only).
I will send some instruction on how to solve the merge conflicts and a patch to
fix net-next soon.
Please pull or let me know if there is any problem.
Thanks a lot,
Antonio
The following changes since commit 361cd29cf9363505c2a35bbf9a034a22feebfb07:
qlcnic: fix beaconing test for 82xx adapter (2013-04-17 01:15:29 -0400)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-fix-for-davem
for you to fetch changes up to fe8a93b95145c66adf196eea4a919dfe0b7c57db:
batman-adv: make is_my_mac() check for the current mesh only (2013-04-17 22:31:22 +0200)
----------------------------------------------------------------
Included changes:
- fix MAC address check in case of multiple mesh interfaces
----------------------------------------------------------------
Antonio Quartulli (1):
batman-adv: make is_my_mac() check for the current mesh only
net/batman-adv/main.c | 5 ++++-
net/batman-adv/main.h | 2 +-
net/batman-adv/routing.c | 38 ++++++++++++++++++++------------------
net/batman-adv/translation-table.c | 2 +-
net/batman-adv/vis.c | 4 ++--
5 files changed, 28 insertions(+), 23 deletions(-)
it may be the case that we want to store some local TT client flags in a global
entry, therefore the tt_global_add needs to get a proper argument for this
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
v2:
- added kernel doc
translation-table.c | 19 +++++++++++++++++--
translation-table.h | 2 +-
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/translation-table.c b/translation-table.c
index 52808c4..bbda424 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -798,10 +798,25 @@ out:
batadv_tt_orig_list_entry_free_ref(orig_entry);
}
-/* caller must hold orig_node refcount */
+/**
+ * batadv_tt_global_add - add a new TT global entry or update it
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: the originator announcing the client
+ * @tt_addr: the MAC address of the client
+ * @flags: TT flags that have to be set for this client
+ * @ttvn: the first originator's TT version number having this client
+ *
+ * Add a new TT global entry for the given originator. If the entry already
+ * exists add a new reference to the given originator (a global entry can have
+ * references to multiple originators) and adjust the flags attribute to reflect
+ * the function argument.
+ * If a TT local entry exists for this client remove it.
+ *
+ * The caller must hold orig_node refcount.
+ */
int batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *tt_addr, uint8_t flags,
+ const unsigned char *tt_addr, uint16_t flags,
uint8_t ttvn)
{
struct batadv_tt_global_entry *tt_global_entry;
diff --git a/translation-table.h b/translation-table.h
index ab8e683..659a3bb 100644
--- a/translation-table.h
+++ b/translation-table.h
@@ -33,7 +33,7 @@ void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
const unsigned char *tt_buff, int tt_buff_len);
int batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *addr, uint8_t flags,
+ const unsigned char *addr, uint16_t flags,
uint8_t ttvn);
int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
--
1.8.1.5
it may be the case that we want to store some local TT client flags in a global
entry, therefore the tt_global_add needs to get a proper argument for this
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
Based on top of the TVLV patches sent by Marek (but they may apply on maser as
well)
Cheers,
translation-table.c | 2 +-
translation-table.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/translation-table.c b/translation-table.c
index 5d99c64..c1a8a10 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -786,7 +786,7 @@ out:
/* caller must hold orig_node refcount */
int batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *tt_addr, uint8_t flags,
+ const unsigned char *tt_addr, uint16_t flags,
uint8_t ttvn)
{
struct batadv_tt_global_entry *tt_global_entry;
diff --git a/translation-table.h b/translation-table.h
index 597a5d6..b4b6dea 100644
--- a/translation-table.h
+++ b/translation-table.h
@@ -32,7 +32,7 @@ void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
const unsigned char *tt_buff, int tt_buff_len);
int batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *addr, uint8_t flags,
+ const unsigned char *addr, uint16_t flags,
uint8_t ttvn);
int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
--
1.8.1.5
batadv_mesh_free() schedules some RCU callbacks which need the bat_priv struct
to do their jobs, while free_netdev(), which is called immediately after, is
destroying the private data.
Put an rcu_barrier() in the middle so that free_netdev() is invoked only after
all the callbacks returned.
This bug has been introduced by ab8f433dd39be94e8617cff2dfe9f7eca162eb15
("batman-adv: Move deinitialization of soft-interface to destructor")
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
soft-interface.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/soft-interface.c b/soft-interface.c
index 403b8c4..6f20d33 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -582,6 +582,13 @@ static void batadv_softif_free(struct net_device *dev)
{
batadv_debugfs_del_meshif(dev);
batadv_mesh_free(dev);
+
+ /* some scheduled RCU callbacks need the bat_priv struct to accomplish
+ * their tasks. Wait for them all to be finished before freeing the
+ * netdev and its private data (bat_priv)
+ */
+ rcu_barrier();
+
free_netdev(dev);
}
--
1.8.1.5
On errors in batadv_mesh_init(), bat_counters will be freed in both
batadv_mesh_free() and batadv_softif_init_late(). This patch fixes this
by returning earlier from batadv_softif_init_late() in case of errors in
batadv_mesh_init().
Signed-off-by: Martin Hundebøll <martin(a)hundeboll.net>
---
soft-interface.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/soft-interface.c b/soft-interface.c
index c2a9c20..4de4d0f 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -503,6 +503,9 @@ static int batadv_softif_init_late(struct net_device *dev)
unreg_debugfs:
batadv_debugfs_del_meshif(dev);
+
+ return ret;
+
free_bat_counters:
free_percpu(bat_priv->bat_counters);
--
1.8.2.1
From: Antonio Quartulli <antonio(a)open-mesh.com>
Instead of passing a generic combination of flags as
argument, it is easier to pass the entire tt_common
structure (containing the flags already set) plus a
bitfield of additional flags that will be unified with
the already existing ones before inserting the client
in the event queue.
In this way invocations of the modified function can be
simplified.
Signed-off-by: Antonio Quartulli <antonio(a)open-mesh.com>
---
translation-table.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/translation-table.c b/translation-table.c
index 9322320..3bebdcc 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -158,10 +158,19 @@ batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
}
+/**
+ * batadv_tt_local_event - store a local TT event (ADD/DEL)
+ * @bat_priv: the bat priv with all the soft interface information
+ * @tt_local_entry: the TT entry involved in the event
+ * @additional_flags: other flag to store in the event structure
+ */
static void batadv_tt_local_event(struct batadv_priv *bat_priv,
- const uint8_t *addr, uint8_t flags)
+ struct batadv_tt_local_entry *tt_local_entry,
+ uint8_t additional_flags)
{
struct batadv_tt_change_node *tt_change_node, *entry, *safe;
+ struct batadv_tt_common_entry *common = &tt_local_entry->common;
+ uint8_t flags = common->flags | additional_flags;
bool event_removed = false;
bool del_op_requested, del_op_entry;
@@ -171,7 +180,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
return;
tt_change_node->change.flags = flags;
- memcpy(tt_change_node->change.addr, addr, ETH_ALEN);
+ memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
del_op_requested = flags & BATADV_TT_CLIENT_DEL;
@@ -179,7 +188,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
spin_lock_bh(&bat_priv->tt.changes_list_lock);
list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
list) {
- if (!batadv_compare_eth(entry->change.addr, addr))
+ if (!batadv_compare_eth(entry->change.addr, common->addr))
continue;
/* DEL+ADD in the same orig interval have no effect and can be
@@ -327,7 +336,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
}
add_event:
- batadv_tt_local_event(bat_priv, addr, tt_local->common.flags);
+ batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
check_roaming:
/* Check whether it is a roaming, but don't do anything if the roaming
@@ -524,8 +533,7 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
struct batadv_tt_local_entry *tt_local_entry,
uint16_t flags, const char *message)
{
- batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
- tt_local_entry->common.flags | flags);
+ batadv_tt_local_event(bat_priv, tt_local_entry, flags);
/* The local client has to be marked as "pending to be removed" but has
* to be kept in the table in order to send it in a full table
@@ -579,8 +587,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
/* if this client has been added right now, it is possible to
* immediately purge it
*/
- batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
- curr_flags | BATADV_TT_CLIENT_DEL);
+ batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
hlist_del_rcu(&tt_local_entry->common.hash_entry);
batadv_tt_local_entry_free_ref(tt_local_entry);
--
1.8.1.5