|
@@ -4622,6 +4622,32 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
|
|
|
}
|
|
|
EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
|
|
|
|
|
|
+/**
|
|
|
+ * netdev_lower_get_next - Get the next device from the lower neighbour
|
|
|
+ * list
|
|
|
+ * @dev: device
|
|
|
+ * @iter: list_head ** of the current position
|
|
|
+ *
|
|
|
+ * Gets the next netdev_adjacent from the dev's lower neighbour
|
|
|
+ * list, starting from iter position. The caller must hold RTNL lock or
|
|
|
+ * its own locking that guarantees that the neighbour lower
|
|
|
+ * list will remain unchainged.
|
|
|
+ */
|
|
|
+void *netdev_lower_get_next(struct net_device *dev, struct list_head **iter)
|
|
|
+{
|
|
|
+ struct netdev_adjacent *lower;
|
|
|
+
|
|
|
+ lower = list_entry((*iter)->next, struct netdev_adjacent, list);
|
|
|
+
|
|
|
+ if (&lower->list == &dev->adj_list.lower)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ *iter = &lower->list;
|
|
|
+
|
|
|
+ return lower->dev;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(netdev_lower_get_next);
|
|
|
+
|
|
|
/**
|
|
|
* netdev_lower_get_first_private_rcu - Get the first ->private from the
|
|
|
* lower neighbour list, RCU
|
|
@@ -5072,6 +5098,30 @@ void *netdev_lower_dev_get_private(struct net_device *dev,
|
|
|
}
|
|
|
EXPORT_SYMBOL(netdev_lower_dev_get_private);
|
|
|
|
|
|
+
|
|
|
+int dev_get_nest_level(struct net_device *dev,
|
|
|
+ bool (*type_check)(struct net_device *dev))
|
|
|
+{
|
|
|
+ struct net_device *lower = NULL;
|
|
|
+ struct list_head *iter;
|
|
|
+ int max_nest = -1;
|
|
|
+ int nest;
|
|
|
+
|
|
|
+ ASSERT_RTNL();
|
|
|
+
|
|
|
+ netdev_for_each_lower_dev(dev, lower, iter) {
|
|
|
+ nest = dev_get_nest_level(lower, type_check);
|
|
|
+ if (max_nest < nest)
|
|
|
+ max_nest = nest;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type_check(dev))
|
|
|
+ max_nest++;
|
|
|
+
|
|
|
+ return max_nest;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(dev_get_nest_level);
|
|
|
+
|
|
|
static void dev_change_rx_flags(struct net_device *dev, int flags)
|
|
|
{
|
|
|
const struct net_device_ops *ops = dev->netdev_ops;
|