aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorVeaceslav Falico <vfalico@redhat.com>2013-09-25 03:20:12 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-26 16:02:04 -0400
commit31088a113c2a948856ed2047d8c21c217b13e85d (patch)
tree15847ff3e7b82f578f4a06cb801a5dccc0fd961e /net/core
parent46bb4807b5d95a049b008efd639ff8942970d815 (diff)
net: add for_each iterators through neighbour lower link's private
Add a possibility to iterate through netdev_adjacent's private, currently only for lower neighbours. Add both RCU and RTNL/other locking variants of iterators, and make the non-rcu variant to be safe from removal. CC: "David S. Miller" <davem@davemloft.net> CC: Eric Dumazet <edumazet@google.com> CC: Jiri Pirko <jiri@resnulli.us> CC: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Veaceslav Falico <vfalico@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index c69ab74fb201..0aa844aae40b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4466,7 +4466,8 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
4466} 4466}
4467EXPORT_SYMBOL(netdev_master_upper_dev_get); 4467EXPORT_SYMBOL(netdev_master_upper_dev_get);
4468 4468
4469/* netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list 4469/**
4470 * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list
4470 * @dev: device 4471 * @dev: device
4471 * @iter: list_head ** of the current position 4472 * @iter: list_head ** of the current position
4472 * 4473 *
@@ -4492,6 +4493,63 @@ struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
4492EXPORT_SYMBOL(netdev_all_upper_get_next_dev_rcu); 4493EXPORT_SYMBOL(netdev_all_upper_get_next_dev_rcu);
4493 4494
4494/** 4495/**
4496 * netdev_lower_get_next_private - Get the next ->private from the
4497 * lower neighbour list
4498 * @dev: device
4499 * @iter: list_head ** of the current position
4500 *
4501 * Gets the next netdev_adjacent->private from the dev's lower neighbour
4502 * list, starting from iter position. The caller must hold either hold the
4503 * RTNL lock or its own locking that guarantees that the neighbour lower
4504 * list will remain unchainged.
4505 */
4506void *netdev_lower_get_next_private(struct net_device *dev,
4507 struct list_head **iter)
4508{
4509 struct netdev_adjacent *lower;
4510
4511 lower = list_entry(*iter, struct netdev_adjacent, list);
4512
4513 if (&lower->list == &dev->adj_list.lower)
4514 return NULL;
4515
4516 if (iter)
4517 *iter = lower->list.next;
4518
4519 return lower->private;
4520}
4521EXPORT_SYMBOL(netdev_lower_get_next_private);
4522
4523/**
4524 * netdev_lower_get_next_private_rcu - Get the next ->private from the
4525 * lower neighbour list, RCU
4526 * variant
4527 * @dev: device
4528 * @iter: list_head ** of the current position
4529 *
4530 * Gets the next netdev_adjacent->private from the dev's lower neighbour
4531 * list, starting from iter position. The caller must hold RCU read lock.
4532 */
4533void *netdev_lower_get_next_private_rcu(struct net_device *dev,
4534 struct list_head **iter)
4535{
4536 struct netdev_adjacent *lower;
4537
4538 WARN_ON_ONCE(!rcu_read_lock_held());
4539
4540 lower = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
4541
4542 if (&lower->list == &dev->adj_list.lower)
4543 return NULL;
4544
4545 if (iter)
4546 *iter = &lower->list;
4547
4548 return lower->private;
4549}
4550EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
4551
4552/**
4495 * netdev_master_upper_dev_get_rcu - Get master upper device 4553 * netdev_master_upper_dev_get_rcu - Get master upper device
4496 * @dev: device 4554 * @dev: device
4497 * 4555 *