From 178148f7ef4847484be3fc25c4b6e3aed91e0dbd Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 2 Jul 2012 15:51:27 +0000 Subject: [PATCH] batman-adv: stability patches Signed-off-by: Marek Lindner git-svn-id: svn://svn.openwrt.org/openwrt/packages/net/batman-adv@32578 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...y-drop-packets-of-known-wifi-clients.patch | 50 ++++++++++++++ ...ace-condition-in-TT-full-table-repla.patch | 65 +++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 patches/0002-batman-adv-only-drop-packets-of-known-wifi-clients.patch create mode 100644 patches/0003-batman-adv-fix-race-condition-in-TT-full-table-repla.patch diff --git a/patches/0002-batman-adv-only-drop-packets-of-known-wifi-clients.patch b/patches/0002-batman-adv-only-drop-packets-of-known-wifi-clients.patch new file mode 100644 index 0000000..adb7958 --- /dev/null +++ b/patches/0002-batman-adv-only-drop-packets-of-known-wifi-clients.patch @@ -0,0 +1,50 @@ +From 7c6c6db94848497178cc246585b59fad4368c3e2 Mon Sep 17 00:00:00 2001 +From: Marek Lindner +Date: Wed, 20 Jun 2012 16:56:04 +0200 +Subject: [PATCH] batman-adv: only drop packets of known wifi clients + +If the source or destination mac address of an ethernet packet +could not be found in the translation table the packet was +dropped if AP isolation was turned on. This behavior would +make it impossible to send broadcast packets over the mesh +as the broadcast address will never enter the translation +table. + +Signed-off-by: Marek Lindner +--- + translation-table.c | 8 ++++---- + 1 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/translation-table.c b/translation-table.c +index a66c2dc..660c40f 100644 +--- a/translation-table.c ++++ b/translation-table.c +@@ -2031,10 +2031,10 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) + { + struct tt_local_entry *tt_local_entry = NULL; + struct tt_global_entry *tt_global_entry = NULL; +- bool ret = true; ++ bool ret = false; + + if (!atomic_read(&bat_priv->ap_isolation)) +- return false; ++ goto out; + + tt_local_entry = tt_local_hash_find(bat_priv, dst); + if (!tt_local_entry) +@@ -2044,10 +2044,10 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) + if (!tt_global_entry) + goto out; + +- if (_is_ap_isolated(tt_local_entry, tt_global_entry)) ++ if (!_is_ap_isolated(tt_local_entry, tt_global_entry)) + goto out; + +- ret = false; ++ ret = true; + + out: + if (tt_global_entry) +-- +1.7.9.1 + diff --git a/patches/0003-batman-adv-fix-race-condition-in-TT-full-table-repla.patch b/patches/0003-batman-adv-fix-race-condition-in-TT-full-table-repla.patch new file mode 100644 index 0000000..170ce2f --- /dev/null +++ b/patches/0003-batman-adv-fix-race-condition-in-TT-full-table-repla.patch @@ -0,0 +1,65 @@ +From d1f13e24ec3ebdadc2bc08c9d4708197279096fa Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Wed, 20 Jun 2012 14:12:56 +0200 +Subject: [PATCH] batman-adv: fix race condition in TT full-table replacement + +bug introduced with cea194d90b11aff7fc289149e4c7f305fad3535a + +In the current TT code, when a TT_Response containing a full table is received +from an originator, first the node purges all the clients for that originator in +the global translation-table and then merges the newly received table. +During the purging phase each client deletion is done by means of a call_rcu() +invocation and at the end of this phase the global entry counter for that +originator is set to 0. However the invoked rcu function decreases the global +entry counter for that originator by one too and since the rcu invocation is +likely to be postponed, the node will end up in first setting the counter to 0 +and then decreasing it one by one for each deleted client. + +This bug leads to having a wrong global entry counter for the related node, say +X. Then when the node with the broken counter will answer to a TT_REQUEST on +behalf of node X, it will create faulty TT_RESPONSE that will generate an +unrecoverable situation on the node that asked for the full table recover. + +The non-recoverability is given by the fact that the node with the broken +counter will keep answering on behalf of X because its knowledge about X's state +(ttvn + tt_crc) is correct. + +To solve this problem the counter is not explicitly set to 0 anymore and the +counter decrement is performed right before the invocation of call_rcu(). + +Signed-off-by: Antonio Quartulli +--- + translation-table.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/translation-table.c b/translation-table.c +index 660c40f..2ab83d7 100644 +--- a/translation-table.c ++++ b/translation-table.c +@@ -141,13 +141,14 @@ static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu) + struct tt_orig_list_entry *orig_entry; + + orig_entry = container_of(rcu, struct tt_orig_list_entry, rcu); +- atomic_dec(&orig_entry->orig_node->tt_size); + orig_node_free_ref(orig_entry->orig_node); + kfree(orig_entry); + } + + static void tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) + { ++ /* to avoid race conditions, immediately decrease the tt counter */ ++ atomic_dec(&orig_entry->orig_node->tt_size); + call_rcu(&orig_entry->rcu, tt_orig_list_entry_free_rcu); + } + +@@ -910,7 +911,6 @@ void tt_global_del_orig(struct bat_priv *bat_priv, + } + spin_unlock_bh(list_lock); + } +- atomic_set(&orig_node->tt_size, 0); + orig_node->tt_initialised = false; + } + +-- +1.7.9.1 + -- 2.30.2