ipv4: Implement __ip_dev_find using new interface address hash.
Much quicker than going through the FIB tables. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@ -132,46 +132,6 @@ static void fib_flush(struct net *net)
|
||||
rt_cache_flush(net, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* __ip_dev_find - find the first device with a given source address.
|
||||
* @net: the net namespace
|
||||
* @addr: the source address
|
||||
* @devref: if true, take a reference on the found device
|
||||
*
|
||||
* If a caller uses devref=false, it should be protected by RCU, or RTNL
|
||||
*/
|
||||
struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
|
||||
{
|
||||
struct flowi fl = {
|
||||
.fl4_dst = addr,
|
||||
};
|
||||
struct fib_result res = { 0 };
|
||||
struct net_device *dev = NULL;
|
||||
struct fib_table *local_table;
|
||||
|
||||
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
||||
res.r = NULL;
|
||||
#endif
|
||||
|
||||
rcu_read_lock();
|
||||
local_table = fib_get_table(net, RT_TABLE_LOCAL);
|
||||
if (!local_table ||
|
||||
fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) {
|
||||
rcu_read_unlock();
|
||||
return NULL;
|
||||
}
|
||||
if (res.type != RTN_LOCAL)
|
||||
goto out;
|
||||
dev = FIB_RES_DEV(res);
|
||||
|
||||
if (dev && devref)
|
||||
dev_hold(dev);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(__ip_dev_find);
|
||||
|
||||
/*
|
||||
* Find address type as if only "dev" was present in the system. If
|
||||
* on_dev is NULL then all interfaces are taken into consideration.
|
||||
|
Reference in New Issue
Block a user