/* netdev_master_upper_dev_get_rcu calls * list_first_or_null_rcu to walk the upper dev list. * list_first_or_null_rcu does not handle a const arg. We aren't * making changes, just want the master device from that list so * typecast to remove the const
*/
master = netdev_master_upper_dev_get_rcu(_dev); if (master)
ifindex = master->ifindex;
}
/** * l3mdev_master_upper_ifindex_by_index_rcu - get index of upper l3 master * device * @net: network namespace for device index lookup * @ifindex: targeted interface
*/ int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex)
{ struct net_device *dev;
dev = dev_get_by_index_rcu(net, ifindex); while (dev && !netif_is_l3_master(dev))
dev = netdev_master_upper_dev_get_rcu(dev);
return dev ? dev->ifindex : 0;
}
EXPORT_SYMBOL_GPL(l3mdev_master_upper_ifindex_by_index_rcu);
/** * l3mdev_fib_table_rcu - get FIB table id associated with an L3 * master interface * @dev: targeted interface
*/
if (netif_is_l3_master(dev)) { if (dev->l3mdev_ops->l3mdev_fib_table)
tb_id = dev->l3mdev_ops->l3mdev_fib_table(dev);
} elseif (netif_is_l3_slave(dev)) { /* Users of netdev_master_upper_dev_get_rcu need non-const, * but current inet_*type functions take a const
*/ struct net_device *_dev = (struct net_device *) dev; conststruct net_device *master;
/** * l3mdev_link_scope_lookup - IPv6 route lookup based on flow for link * local and multicast addresses * @net: network namespace for device index lookup * @fl6: IPv6 flow struct for lookup * This function does not hold refcnt on the returned dst. * Caller must hold rcu_read_lock().
*/
WARN_ON_ONCE(!rcu_read_lock_held()); if (fl6->flowi6_oif) {
dev = dev_get_by_index_rcu(net, fl6->flowi6_oif); if (dev && netif_is_l3_slave(dev))
dev = netdev_master_upper_dev_get_rcu(dev);
/** * l3mdev_fib_rule_match - Determine if flowi references an * L3 master device * @net: network namespace for device index lookup * @fl: flow struct * @arg: store the table the rule matched with here
*/
int l3mdev_fib_rule_match(struct net *net, struct flowi *fl, struct fib_lookup_arg *arg)
{ struct net_device *dev; int rc = 0;
/* update flow ensures flowi_l3mdev is set when relevant */ if (!fl->flowi_l3mdev) return 0;
rcu_read_lock();
dev = dev_get_by_index_rcu(net, fl->flowi_l3mdev); if (dev && netif_is_l3_master(dev) &&
dev->l3mdev_ops->l3mdev_fib_table) {
arg->table = dev->l3mdev_ops->l3mdev_fib_table(dev);
rc = 1;
}
if (fl->flowi_oif) {
dev = dev_get_by_index_rcu(net, fl->flowi_oif); if (dev) { if (!fl->flowi_l3mdev) {
fl->flowi_l3mdev = l3mdev_master_ifindex_rcu(dev);
fl->flowi_flags |= FLOWI_FLAG_L3MDEV_OIF;
}
/* oif set to L3mdev directs lookup to its table; * reset to avoid oif match in fib_lookup
*/ if (netif_is_l3_master(dev))
fl->flowi_oif = 0; goto out;
}
}
if (fl->flowi_iif > LOOPBACK_IFINDEX && !fl->flowi_l3mdev) {
dev = dev_get_by_index_rcu(net, fl->flowi_iif); if (dev)
fl->flowi_l3mdev = l3mdev_master_ifindex_rcu(dev);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.