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:	Mon,  2 Sep 2013 23:39:16 +0200
From:	Veaceslav Falico <vfalico@...hat.com>
To:	netdev@...r.kernel.org
Cc:	Veaceslav Falico <vfalico@...hat.com>,
	"David S. Miller" <davem@...emloft.net>,
	Eric Dumazet <edumazet@...gle.com>,
	Jiri Pirko <jiri@...nulli.us>,
	Alexander Duyck <alexander.h.duyck@...el.com>
Subject: [PATCH RFC net-next 12/21] net: add for_each iterators through neighbour lower link's private

Currently we can only iterate through the devices itself, however it'd be
really costy to first get the next device and then search for the link and
get its private - which is a common method to go through slaves of a
device.

Add both RCU and RTNL/other locking variants of iterators.

CC: "David S. Miller" <davem@...emloft.net>
CC: Eric Dumazet <edumazet@...gle.com>
CC: Jiri Pirko <jiri@...nulli.us>
CC: Alexander Duyck <alexander.h.duyck@...el.com>
Signed-off-by: Veaceslav Falico <vfalico@...hat.com>
---
 include/linux/netdevice.h | 17 ++++++++++++
 net/core/dev.c            | 66 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ef1ddee..1a149ef 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2788,6 +2788,23 @@ extern struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
 	     updev; \
 	     updev = netdev_upper_get_next_dev_rcu(dev, &(iter)))
 
+extern void *netdev_lower_neigh_get_next_private(struct net_device *dev,
+						 struct list_head **iter);
+extern void *netdev_lower_neigh_get_next_private_rcu(struct net_device *dev,
+						     struct list_head **iter);
+
+#define netdev_for_each_lower_neigh_private(dev, priv, iter) \
+	for (iter = &(dev)->neighbour_dev_list.lower, \
+	     priv = netdev_lower_neigh_get_next_private(dev, &(iter)); \
+	     priv; \
+	     priv = netdev_lower_neigh_get_next_private(dev, &(iter)))
+
+#define netdev_for_each_lower_neigh_private_rcu(dev, priv, iter) \
+	for (iter = &(dev)->neighbour_dev_list.lower, \
+	     priv = netdev_lower_neigh_get_next_private_rcu(dev, &(iter)); \
+	     priv; \
+	     priv = netdev_lower_neigh_get_next_private_rcu(dev, &(iter)))
+
 extern struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
 extern struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev);
 extern int netdev_upper_dev_link(struct net_device *dev,
diff --git a/net/core/dev.c b/net/core/dev.c
index 1c3e98d..55f8ac4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4555,6 +4555,72 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
 }
 EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu);
 
+/* netdev_lower_neigh_get_next_private - Get the next ->private from the
+ *					 lower neighbour list
+ * @dev: device
+ * @iter: list_head ** of the current position
+ *
+ * Gets the next netdev_adjacent->private from the dev's lower neighbour
+ * list, starting from iter position. The caller must hold either hold the
+ * RTNL lock or its own locking that guarantees that the neighbour lower
+ * list will remain unchainged. If iter is NULL - return the first private.
+ */
+void *netdev_lower_neigh_get_next_private(struct net_device *dev,
+					  struct list_head **iter)
+{
+	struct netdev_adjacent *lower;
+
+	if (iter)
+		lower = list_entry((*iter)->next, struct netdev_adjacent,
+				   list);
+	else
+		lower = list_entry(dev->neighbour_dev_list.lower.next,
+				   struct netdev_adjacent, list);
+
+	if (&lower->list == &dev->neighbour_dev_list.lower)
+		return NULL;
+
+	if (iter)
+		*iter = &lower->list;
+
+	return lower->private;
+}
+EXPORT_SYMBOL(netdev_lower_neigh_get_next_private);
+
+/* netdev_lower_neigh_get_next_private_rcu - Get the next ->private from the
+ *					     lower neighbour list, RCU
+ *					     variant
+ * @dev: device
+ * @iter: list_head ** of the current position
+ *
+ * Gets the next netdev_adjacent->private from the dev's lower neighbour
+ * list, starting from iter position. The caller must hold RCU read lock.
+ * If iter is NULL - returns the first private.
+ */
+void *netdev_lower_neigh_get_next_private_rcu(struct net_device *dev,
+					      struct list_head **iter)
+{
+	struct netdev_adjacent *lower;
+
+	WARN_ON_ONCE(!rcu_read_lock_held());
+
+	if (iter)
+		lower = list_entry_rcu((*iter)->next, struct netdev_adjacent,
+				       list);
+	else
+		lower = list_entry_rcu(dev->neighbour_dev_list.lower.next,
+				       struct netdev_adjacent, list);
+
+	if (&lower->list == &dev->neighbour_dev_list.lower)
+		return NULL;
+
+	if (iter)
+		*iter = &lower->list;
+
+	return lower->private;
+}
+EXPORT_SYMBOL(netdev_lower_neigh_get_next_private_rcu);
+
 /**
  * netdev_master_upper_dev_get_rcu - Get master upper device
  * @dev: device
-- 
1.8.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