diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ed928e846559..6ee3ac25ed72 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -4623,6 +4623,32 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev, | |||
4623 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); | 4623 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); |
4624 | 4624 | ||
4625 | /** | 4625 | /** |
4626 | * netdev_lower_get_next - Get the next device from the lower neighbour | ||
4627 | * list | ||
4628 | * @dev: device | ||
4629 | * @iter: list_head ** of the current position | ||
4630 | * | ||
4631 | * Gets the next netdev_adjacent from the dev's lower neighbour | ||
4632 | * list, starting from iter position. The caller must hold RTNL lock or | ||
4633 | * its own locking that guarantees that the neighbour lower | ||
4634 | * list will remain unchainged. | ||
4635 | */ | ||
4636 | void *netdev_lower_get_next(struct net_device *dev, struct list_head **iter) | ||
4637 | { | ||
4638 | struct netdev_adjacent *lower; | ||
4639 | |||
4640 | lower = list_entry((*iter)->next, struct netdev_adjacent, list); | ||
4641 | |||
4642 | if (&lower->list == &dev->adj_list.lower) | ||
4643 | return NULL; | ||
4644 | |||
4645 | *iter = &lower->list; | ||
4646 | |||
4647 | return lower->dev; | ||
4648 | } | ||
4649 | EXPORT_SYMBOL(netdev_lower_get_next); | ||
4650 | |||
4651 | /** | ||
4626 | * netdev_lower_get_first_private_rcu - Get the first ->private from the | 4652 | * netdev_lower_get_first_private_rcu - Get the first ->private from the |
4627 | * lower neighbour list, RCU | 4653 | * lower neighbour list, RCU |
4628 | * variant | 4654 | * variant |
@@ -5072,6 +5098,30 @@ void *netdev_lower_dev_get_private(struct net_device *dev, | |||
5072 | } | 5098 | } |
5073 | EXPORT_SYMBOL(netdev_lower_dev_get_private); | 5099 | EXPORT_SYMBOL(netdev_lower_dev_get_private); |
5074 | 5100 | ||
5101 | |||
5102 | int dev_get_nest_level(struct net_device *dev, | ||
5103 | bool (*type_check)(struct net_device *dev)) | ||
5104 | { | ||
5105 | struct net_device *lower = NULL; | ||
5106 | struct list_head *iter; | ||
5107 | int max_nest = -1; | ||
5108 | int nest; | ||
5109 | |||
5110 | ASSERT_RTNL(); | ||
5111 | |||
5112 | netdev_for_each_lower_dev(dev, lower, iter) { | ||
5113 | nest = dev_get_nest_level(lower, type_check); | ||
5114 | if (max_nest < nest) | ||
5115 | max_nest = nest; | ||
5116 | } | ||
5117 | |||
5118 | if (type_check(dev)) | ||
5119 | max_nest++; | ||
5120 | |||
5121 | return max_nest; | ||
5122 | } | ||
5123 | EXPORT_SYMBOL(dev_get_nest_level); | ||
5124 | |||
5075 | static void dev_change_rx_flags(struct net_device *dev, int flags) | 5125 | static void dev_change_rx_flags(struct net_device *dev, int flags) |
5076 | { | 5126 | { |
5077 | const struct net_device_ops *ops = dev->netdev_ops; | 5127 | const struct net_device_ops *ops = dev->netdev_ops; |