net: Add inet_addr lookup by table

Currently inet_addr_type and inet_dev_addr_type expect local addresses
to be in the local table. With the VRF device local routes for devices
associated with a VRF will be in the table associated with the VRF.
Provide an alternate inet_addr lookup to use a specific table rather
than defaulting to the local table.

Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David Ahern 2015-08-13 14:59:04 -06:00 коммит произвёл David S. Miller
Родитель 9a24abfa42
Коммит 15be405eb2
2 изменённых файлов: 16 добавлений и 7 удалений

Просмотреть файл

@ -189,6 +189,7 @@ void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk);
void ip_rt_send_redirect(struct sk_buff *skb); void ip_rt_send_redirect(struct sk_buff *skb);
unsigned int inet_addr_type(struct net *net, __be32 addr); unsigned int inet_addr_type(struct net *net, __be32 addr);
unsigned int inet_addr_type_table(struct net *net, __be32 addr, int tb_id);
unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
__be32 addr); __be32 addr);
void ip_rt_multicast_event(struct in_device *); void ip_rt_multicast_event(struct in_device *);

Просмотреть файл

@ -212,12 +212,12 @@ void fib_flush_external(struct net *net)
*/ */
static inline unsigned int __inet_dev_addr_type(struct net *net, static inline unsigned int __inet_dev_addr_type(struct net *net,
const struct net_device *dev, const struct net_device *dev,
__be32 addr) __be32 addr, int tb_id)
{ {
struct flowi4 fl4 = { .daddr = addr }; struct flowi4 fl4 = { .daddr = addr };
struct fib_result res; struct fib_result res;
unsigned int ret = RTN_BROADCAST; unsigned int ret = RTN_BROADCAST;
struct fib_table *local_table; struct fib_table *table;
if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr)) if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr))
return RTN_BROADCAST; return RTN_BROADCAST;
@ -226,10 +226,10 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
rcu_read_lock(); rcu_read_lock();
local_table = fib_get_table(net, RT_TABLE_LOCAL); table = fib_get_table(net, tb_id);
if (local_table) { if (table) {
ret = RTN_UNICAST; ret = RTN_UNICAST;
if (!fib_table_lookup(local_table, &fl4, &res, FIB_LOOKUP_NOREF)) { if (!fib_table_lookup(table, &fl4, &res, FIB_LOOKUP_NOREF)) {
if (!dev || dev == res.fi->fib_dev) if (!dev || dev == res.fi->fib_dev)
ret = res.type; ret = res.type;
} }
@ -239,16 +239,24 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
return ret; return ret;
} }
unsigned int inet_addr_type_table(struct net *net, __be32 addr, int tb_id)
{
return __inet_dev_addr_type(net, NULL, addr, tb_id);
}
EXPORT_SYMBOL(inet_addr_type_table);
unsigned int inet_addr_type(struct net *net, __be32 addr) unsigned int inet_addr_type(struct net *net, __be32 addr)
{ {
return __inet_dev_addr_type(net, NULL, addr); return __inet_dev_addr_type(net, NULL, addr, RT_TABLE_LOCAL);
} }
EXPORT_SYMBOL(inet_addr_type); EXPORT_SYMBOL(inet_addr_type);
unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
__be32 addr) __be32 addr)
{ {
return __inet_dev_addr_type(net, dev, addr); int rt_table = vrf_dev_table(dev) ? : RT_TABLE_LOCAL;
return __inet_dev_addr_type(net, dev, addr, rt_table);
} }
EXPORT_SYMBOL(inet_dev_addr_type); EXPORT_SYMBOL(inet_dev_addr_type);