lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 17 Apr 2011 21:30:11 +0200
From:	Sven Eckelmann <sven@...fation.org>
To:	davem@...emloft.net
Cc:	netdev@...r.kernel.org, b.a.t.m.a.n@...ts.open-mesh.org,
	Linus Lüssing <linus.luessing@....de>,
	Marek Lindner <lindner_marek@...oo.de>,
	Sven Eckelmann <sven@...fation.org>
Subject: [PATCH 1/8] batman-adv: Move bonding / iface alternating router search to own functions

From: Linus Lüssing <linus.luessing@....de>

This decreases the size of find_router() by outsourcing the router
search for the bonding and interface alternating modes to their own sub
functions. This shall make it easier to keep track of the correct
refcounting later.

Signed-off-by: Linus Lüssing <linus.luessing@....de>
Signed-off-by: Marek Lindner <lindner_marek@...oo.de>
Signed-off-by: Sven Eckelmann <sven@...fation.org>
---
 net/batman-adv/routing.c |  180 +++++++++++++++++++++++++++-------------------
 1 files changed, 105 insertions(+), 75 deletions(-)

diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index c172f5d..f212abe 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1092,6 +1092,106 @@ out:
 	return ret;
 }
 
+/* In the bonding case, send the packets in a round
+ * robin fashion over the remaining interfaces.
+ *
+ * This method rotates the bonding list and increases the
+ * returned router's refcount. */
+static struct neigh_node *find_bond_router(struct orig_node *primary_orig,
+					   struct hard_iface *recv_if)
+{
+	struct neigh_node *tmp_neigh_node;
+	struct neigh_node *router = NULL, *first_candidate = NULL;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
+				bonding_list) {
+		if (!first_candidate)
+			first_candidate = tmp_neigh_node;
+
+		/* recv_if == NULL on the first node. */
+		if (tmp_neigh_node->if_incoming == recv_if)
+			continue;
+
+		if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+			continue;
+
+		router = tmp_neigh_node;
+		break;
+	}
+
+	/* use the first candidate if nothing was found. */
+	if (!router && first_candidate &&
+	    atomic_inc_not_zero(&first_candidate->refcount))
+		router = first_candidate;
+
+	if (!router)
+		goto out;
+
+	/* selected should point to the next element
+	 * after the current router */
+	spin_lock_bh(&primary_orig->neigh_list_lock);
+	/* this is a list_move(), which unfortunately
+	 * does not exist as rcu version */
+	list_del_rcu(&primary_orig->bond_list);
+	list_add_rcu(&primary_orig->bond_list,
+		     &router->bonding_list);
+	spin_unlock_bh(&primary_orig->neigh_list_lock);
+
+out:
+	rcu_read_unlock();
+	return router;
+}
+
+/* Interface Alternating: Use the best of the
+ * remaining candidates which are not using
+ * this interface.
+ *
+ * Increases the returned router's refcount */
+static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
+					      struct hard_iface *recv_if)
+{
+	struct neigh_node *tmp_neigh_node;
+	struct neigh_node *router = NULL, *first_candidate = NULL;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
+				bonding_list) {
+		if (!first_candidate)
+			first_candidate = tmp_neigh_node;
+
+		/* recv_if == NULL on the first node. */
+		if (tmp_neigh_node->if_incoming == recv_if)
+			continue;
+
+		if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+			continue;
+
+		/* if we don't have a router yet
+		 * or this one is better, choose it. */
+		if ((!router) ||
+		    (tmp_neigh_node->tq_avg > router->tq_avg)) {
+			/* decrement refcount of
+			 * previously selected router */
+			if (router)
+				neigh_node_free_ref(router);
+
+			router = tmp_neigh_node;
+			atomic_inc_not_zero(&router->refcount);
+		}
+
+		neigh_node_free_ref(tmp_neigh_node);
+	}
+
+	/* use the first candidate if nothing was found. */
+	if (!router && first_candidate &&
+	    atomic_inc_not_zero(&first_candidate->refcount))
+		router = first_candidate;
+
+	rcu_read_unlock();
+	return router;
+}
+
 /* find a suitable router for this originator, and use
  * bonding if possible. increases the found neighbors
  * refcount.*/
@@ -1101,7 +1201,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
 {
 	struct orig_node *primary_orig_node;
 	struct orig_node *router_orig;
-	struct neigh_node *router, *first_candidate, *tmp_neigh_node;
+	struct neigh_node *router;
 	static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
 	int bonding_enabled;
 
@@ -1157,82 +1257,12 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
 	 * in. */
 
 	neigh_node_free_ref(router);
-	first_candidate = NULL;
-	router = NULL;
 
-	if (bonding_enabled) {
-		/* in the bonding case, send the packets in a round
-		 * robin fashion over the remaining interfaces. */
+	if (bonding_enabled)
+		router = find_bond_router(primary_orig_node, recv_if);
+	else
+		router = find_ifalter_router(primary_orig_node, recv_if);
 
-		list_for_each_entry_rcu(tmp_neigh_node,
-				&primary_orig_node->bond_list, bonding_list) {
-			if (!first_candidate)
-				first_candidate = tmp_neigh_node;
-			/* recv_if == NULL on the first node. */
-			if (tmp_neigh_node->if_incoming != recv_if &&
-			    atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
-				router = tmp_neigh_node;
-				break;
-			}
-		}
-
-		/* use the first candidate if nothing was found. */
-		if (!router && first_candidate &&
-		    atomic_inc_not_zero(&first_candidate->refcount))
-			router = first_candidate;
-
-		if (!router) {
-			rcu_read_unlock();
-			return NULL;
-		}
-
-		/* selected should point to the next element
-		 * after the current router */
-		spin_lock_bh(&primary_orig_node->neigh_list_lock);
-		/* this is a list_move(), which unfortunately
-		 * does not exist as rcu version */
-		list_del_rcu(&primary_orig_node->bond_list);
-		list_add_rcu(&primary_orig_node->bond_list,
-				&router->bonding_list);
-		spin_unlock_bh(&primary_orig_node->neigh_list_lock);
-
-	} else {
-		/* if bonding is disabled, use the best of the
-		 * remaining candidates which are not using
-		 * this interface. */
-		list_for_each_entry_rcu(tmp_neigh_node,
-			&primary_orig_node->bond_list, bonding_list) {
-			if (!first_candidate)
-				first_candidate = tmp_neigh_node;
-
-			/* recv_if == NULL on the first node. */
-			if (tmp_neigh_node->if_incoming == recv_if)
-				continue;
-
-			if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
-				continue;
-
-			/* if we don't have a router yet
-			 * or this one is better, choose it. */
-			if ((!router) ||
-			    (tmp_neigh_node->tq_avg > router->tq_avg)) {
-				/* decrement refcount of
-				 * previously selected router */
-				if (router)
-					neigh_node_free_ref(router);
-
-				router = tmp_neigh_node;
-				atomic_inc_not_zero(&router->refcount);
-			}
-
-			neigh_node_free_ref(tmp_neigh_node);
-		}
-
-		/* use the first candidate if nothing was found. */
-		if (!router && first_candidate &&
-		    atomic_inc_not_zero(&first_candidate->refcount))
-			router = first_candidate;
-	}
 return_router:
 	rcu_read_unlock();
 	return router;
-- 
1.7.4.4

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ