mirror of https://gitee.com/openkylin/linux.git
net: Find the nesting level of a given device by type.
Multiple devices in the kernel can be stacked/nested and they need to know their nesting level for the purposes of lockdep. This patch provides a generic function that determines a nesting level of a particular device by its type (ex: vlan, macvlan, etc). We only care about nesting of the same type of devices. For example: eth0 <- vlan0.10 <- macvlan0 <- vlan1.20 The nesting level of vlan1.20 would be 1, since there is another vlan in the stack under it. Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
29e9824278
commit
4085ebe8c3
|
@ -3077,6 +3077,14 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
|
||||||
priv; \
|
priv; \
|
||||||
priv = netdev_lower_get_next_private_rcu(dev, &(iter)))
|
priv = netdev_lower_get_next_private_rcu(dev, &(iter)))
|
||||||
|
|
||||||
|
void *netdev_lower_get_next(struct net_device *dev,
|
||||||
|
struct list_head **iter);
|
||||||
|
#define netdev_for_each_lower_dev(dev, ldev, iter) \
|
||||||
|
for (iter = &(dev)->adj_list.lower, \
|
||||||
|
ldev = netdev_lower_get_next(dev, &(iter)); \
|
||||||
|
ldev; \
|
||||||
|
ldev = netdev_lower_get_next(dev, &(iter)))
|
||||||
|
|
||||||
void *netdev_adjacent_get_private(struct list_head *adj_list);
|
void *netdev_adjacent_get_private(struct list_head *adj_list);
|
||||||
void *netdev_lower_get_first_private_rcu(struct net_device *dev);
|
void *netdev_lower_get_first_private_rcu(struct net_device *dev);
|
||||||
struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
|
struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
|
||||||
|
@ -3092,6 +3100,8 @@ void netdev_upper_dev_unlink(struct net_device *dev,
|
||||||
void netdev_adjacent_rename_links(struct net_device *dev, char *oldname);
|
void netdev_adjacent_rename_links(struct net_device *dev, char *oldname);
|
||||||
void *netdev_lower_dev_get_private(struct net_device *dev,
|
void *netdev_lower_dev_get_private(struct net_device *dev,
|
||||||
struct net_device *lower_dev);
|
struct net_device *lower_dev);
|
||||||
|
int dev_get_nest_level(struct net_device *dev,
|
||||||
|
bool (*type_check)(struct net_device *dev));
|
||||||
int skb_checksum_help(struct sk_buff *skb);
|
int skb_checksum_help(struct sk_buff *skb);
|
||||||
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
|
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
|
||||||
netdev_features_t features, bool tx_path);
|
netdev_features_t features, bool tx_path);
|
||||||
|
|
|
@ -4622,6 +4622,32 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
|
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
|
* netdev_lower_get_first_private_rcu - Get the first ->private from the
|
||||||
* lower neighbour list, RCU
|
* 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);
|
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)
|
static void dev_change_rx_flags(struct net_device *dev, int flags)
|
||||||
{
|
{
|
||||||
const struct net_device_ops *ops = dev->netdev_ops;
|
const struct net_device_ops *ops = dev->netdev_ops;
|
||||||
|
|
Loading…
Reference in New Issue