net: Fix up inet_addr_type checks
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. inet_addr_type_dev_table keeps the same semantics as inet_addr_type but if the passed in device is enslaved to a VRF then the table for that VRF is used for the lookup. Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
15be405eb2
commit
30bbaa1950
@@ -119,6 +119,7 @@
|
||||
#ifdef CONFIG_IP_MROUTE
|
||||
#include <linux/mroute.h>
|
||||
#endif
|
||||
#include <net/vrf.h>
|
||||
|
||||
|
||||
/* The inetsw table contains everything that inet_create needs to
|
||||
@@ -427,6 +428,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
struct net *net = sock_net(sk);
|
||||
unsigned short snum;
|
||||
int chk_addr_ret;
|
||||
int tb_id = RT_TABLE_LOCAL;
|
||||
int err;
|
||||
|
||||
/* If the socket has its own bind function then use it. (RAW) */
|
||||
@@ -448,7 +450,16 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
goto out;
|
||||
}
|
||||
|
||||
chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
|
||||
if (sk->sk_bound_dev_if) {
|
||||
struct net_device *dev;
|
||||
|
||||
rcu_read_lock();
|
||||
dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
|
||||
if (dev)
|
||||
tb_id = vrf_dev_table_rcu(dev) ? : tb_id;
|
||||
rcu_read_unlock();
|
||||
}
|
||||
chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id);
|
||||
|
||||
/* Not specified by any standard per-se, however it breaks too
|
||||
* many applications when removed. It is unfortunate since
|
||||
|
Reference in New Issue
Block a user