[linux-next] LinuxNextTracking branch, master, updated. next-20120629

batman at open-mesh.org batman at open-mesh.org
Sat Jun 30 00:17:03 CEST 2012


The following commit has been merged in the master branch:
commit 3b643de541d4051f236f1e422f3329cccb7bd9c5
Author: Antonio Quartulli <ordex at autistici.org>
Date:   Fri May 25 00:00:42 2012 +0200

    batman-adv: clear ADD+DEL (and viceversa) events in the same orig-interval
    
    During an OGM-interval (time between two different OGM sendings) the same client
    could roam away and then roam back to us. In this case the node would add two
    events to the events list (that is going to be sent appended to the next OGM). A
    DEL one and an ADD one. Obviously they will only increase the overhead (either in
    the air and on the receiver side) and eventually trigger wrong states/events
    without producing any real effect.
    
    For this reason we can safely delete any ADD event with its related DEL one.
    
    Signed-off-by: Antonio Quartulli <ordex at autistici.org>
    Signed-off-by: Sven Eckelmann <sven at narfation.org>

diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 074936f..d82766b 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -157,7 +157,9 @@ batadv_tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry)
 static void batadv_tt_local_event(struct bat_priv *bat_priv,
 				  const uint8_t *addr, uint8_t flags)
 {
-	struct tt_change_node *tt_change_node;
+	struct tt_change_node *tt_change_node, *entry, *safe;
+	bool event_removed = false;
+	bool del_op_requested, del_op_entry;
 
 	tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
 
@@ -167,13 +169,45 @@ static void batadv_tt_local_event(struct bat_priv *bat_priv,
 	tt_change_node->change.flags = flags;
 	memcpy(tt_change_node->change.addr, addr, ETH_ALEN);
 
+	del_op_requested = flags & TT_CLIENT_DEL;
+
+	/* check for ADD+DEL or DEL+ADD events */
 	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))
+			continue;
+
+		/* DEL+ADD in the same orig interval have no effect and can be
+		 * removed to avoid silly behaviour on the receiver side. The
+		 * other way around (ADD+DEL) can happen in case of roaming of
+		 * a client still in the NEW state. Roaming of NEW clients is
+		 * now possible due to automatically recognition of "temporary"
+		 * clients
+		 */
+		del_op_entry = entry->change.flags & TT_CLIENT_DEL;
+		if (!del_op_requested && del_op_entry)
+			goto del;
+		if (del_op_requested && !del_op_entry)
+			goto del;
+		continue;
+del:
+		list_del(&entry->list);
+		kfree(entry);
+		event_removed = true;
+		goto unlock;
+	}
+
 	/* track the change in the OGMinterval list */
 	list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list);
-	atomic_inc(&bat_priv->tt_local_changes);
+
+unlock:
 	spin_unlock_bh(&bat_priv->tt_changes_list_lock);
 
-	atomic_set(&bat_priv->tt_ogm_append_cnt, 0);
+	if (event_removed)
+		atomic_dec(&bat_priv->tt_local_changes);
+	else
+		atomic_inc(&bat_priv->tt_local_changes);
 }
 
 int batadv_tt_len(int changes_num)

-- 
LinuxNextTracking


More information about the linux-merge mailing list