batman-adv: bugfixes for the 2011.3.1 release
authorMarek Lindner <lindner_marek@yahoo.de>
Tue, 25 Oct 2011 12:37:44 +0000 (12:37 +0000)
committerMarek Lindner <lindner_marek@yahoo.de>
Tue, 25 Oct 2011 12:37:44 +0000 (12:37 +0000)
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
git-svn-id: svn://svn.openwrt.org/openwrt/packages/net/batman-adv@28575 3c298f89-4303-0410-b956-a3cf2f4a3e73

Makefile
patches/0001-batman-adv_unify_hash_entry_field_position_in_tt_local_global_entry.patch [new file with mode: 0644]
patches/0002-batman-adv_add_sanity_check_when_removing_global_tts.patch [new file with mode: 0644]
patches/0003-batman-adv_remove_references_for_global_tt_entries.patch [new file with mode: 0644]

index 2c04d87a09533bbbe6829c2dae0f46c54994485d..e5a4147a7bb74c59fc79e2498a8108a9af6cde36 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_VERSION)
-PKG_TOOL_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/batctl-$(BATCTL_VERSION)
+PKG_BATCTL_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/batctl-$(BATCTL_VERSION)
 
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/kernel.mk
@@ -76,7 +76,7 @@ $(eval $(call Download,batctl))
 
 EXTRACT_BATCTL = tar xzf "$(DL_DIR)/batctl-$(BATCTL_VERSION).tar.gz" -C "$(BUILD_DIR)/$(PKG_NAME)"
 PATCH_BATCTL = $(call Build/DoPatch,"$(PKG_BATCTL_BUILD_DIR)","$(PATCH_DIR)","*batctl*")
-BUILD_BATCTL = $(MAKE) -C $(PKG_TOOL_BUILD_DIR) $(MAKE_BATCTL_ARGS)
+BUILD_BATCTL = $(MAKE) -C $(PKG_BATCTL_BUILD_DIR) $(MAKE_BATCTL_ARGS)
 endif
 
 KPATCH ?= $(PATCH)
diff --git a/patches/0001-batman-adv_unify_hash_entry_field_position_in_tt_local_global_entry.patch b/patches/0001-batman-adv_unify_hash_entry_field_position_in_tt_local_global_entry.patch
new file mode 100644 (file)
index 0000000..310e281
--- /dev/null
@@ -0,0 +1,41 @@
+
+Function tt_response_fill_table() actually uses a tt_local_entry pointer to
+iterate either over the local or the global table entries (it depends on the
+what hash table is passed as argument). To iterate over such entries the
+hlist_for_each_entry_rcu() macro has to access their "hash_entry" field which
+MUST be at the same position in both the tt_global/local_entry structures.
+
+Reported-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+---
+ types.h |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/types.h
++++ b/types.h
+@@ -224,22 +224,22 @@ struct socket_packet {
+ struct tt_local_entry {
+       uint8_t addr[ETH_ALEN];
++      struct hlist_node hash_entry;
+       unsigned long last_seen;
+       uint16_t flags;
+       atomic_t refcount;
+       struct rcu_head rcu;
+-      struct hlist_node hash_entry;
+ };
+ struct tt_global_entry {
+       uint8_t addr[ETH_ALEN];
++      struct hlist_node hash_entry; /* entry in the global table */
+       struct orig_node *orig_node;
+       uint8_t ttvn;
+       uint16_t flags; /* only TT_GLOBAL_ROAM is used */
+       unsigned long roam_at; /* time at which TT_GLOBAL_ROAM was set */
+       atomic_t refcount;
+       struct rcu_head rcu;
+-      struct hlist_node hash_entry; /* entry in the global table */
+ };
+ struct tt_change_node {
+
diff --git a/patches/0002-batman-adv_add_sanity_check_when_removing_global_tts.patch b/patches/0002-batman-adv_add_sanity_check_when_removing_global_tts.patch
new file mode 100644 (file)
index 0000000..9f43083
--- /dev/null
@@ -0,0 +1,23 @@
+
+After removing the batman-adv module, the hash may be already gone
+when tt_global_del_orig() tries to clean the hash. This patch adds
+a sanity check to avoid this.
+
+Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+---
+ translation-table.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+--- a/translation-table.c
++++ b/translation-table.c
+@@ -712,6 +712,9 @@ void tt_global_del_orig(struct bat_priv *bat_priv,
+       struct hlist_head *head;
+       spinlock_t *list_lock; /* protects write access to the hash lists */
++      if (!hash)
++              return;
++
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+               list_lock = &hash->list_locks[i];
+
diff --git a/patches/0003-batman-adv_remove_references_for_global_tt_entries.patch b/patches/0003-batman-adv_remove_references_for_global_tt_entries.patch
new file mode 100644 (file)
index 0000000..e155686
--- /dev/null
@@ -0,0 +1,63 @@
+
+struct tt_global_entry holds a reference to an orig_node which must be
+decremented before deallocating the structure.
+
+Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+---
+ compat.c            |    8 --------
+ compat.h            |    1 -
+ translation-table.c |   14 +++++++++++++-
+ 3 files changed, 13 insertions(+), 10 deletions(-)
+
+--- a/compat.c
++++ b/compat.c
+@@ -36,12 +36,4 @@ void free_rcu_tt_local_entry(struct rcu_head *rcu)
+       kfree(tt_local_entry);
+ }
+-void free_rcu_tt_global_entry(struct rcu_head *rcu)
+-{
+-      struct tt_global_entry *tt_global_entry;
+-
+-      tt_global_entry = container_of(rcu, struct tt_global_entry, rcu);
+-      kfree(tt_global_entry);
+-}
+-
+ #endif /* < KERNEL_VERSION(3, 0, 0) */
+--- a/compat.h
++++ b/compat.h
+@@ -63,7 +63,6 @@ void free_rcu_gw_node(struct rcu_head *rcu);
+ void free_rcu_neigh_node(struct rcu_head *rcu);
+ void free_rcu_softif_neigh(struct rcu_head *rcu);
+ void free_rcu_tt_local_entry(struct rcu_head *rcu);
+-void free_rcu_tt_global_entry(struct rcu_head *rcu);
+ #endif /* < KERNEL_VERSION(3, 0, 0) */
+--- a/translation-table.c
++++ b/translation-table.c
+@@ -137,10 +137,22 @@ static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry)
+               kfree_rcu(tt_local_entry, rcu);
+ }
++static void tt_global_entry_free_rcu(struct rcu_head *rcu)
++{
++      struct tt_global_entry *tt_global_entry;
++
++      tt_global_entry = container_of(rcu, struct tt_global_entry, rcu);
++
++      if (tt_global_entry->orig_node)
++              orig_node_free_ref(tt_global_entry->orig_node);
++
++      kfree(tt_global_entry);
++}
++
+ static void tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry)
+ {
+       if (atomic_dec_and_test(&tt_global_entry->refcount))
+-              kfree_rcu(tt_global_entry, rcu);
++              call_rcu(&tt_global_entry->rcu, tt_global_entry_free_rcu);
+ }
+ static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr,
+