net: vrf: Implement get_saddr for IPv6
IPv6 source address selection needs to consider the real egress route. Similar to IPv4 implement a get_saddr6 method which is called if source address has not been set. The get_saddr6 method does a full lookup which means pulling a route from the VRF FIB table and properly considering linklocal/multicast destination addresses. Lookup failures (eg., unreachable) then cause the source address selection to fail which gets propagated back to the caller. 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
a2e2ff560f
commit
0d240e7811
@@ -162,6 +162,30 @@ int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(l3mdev_get_saddr);
|
||||
|
||||
int l3mdev_get_saddr6(struct net *net, const struct sock *sk,
|
||||
struct flowi6 *fl6)
|
||||
{
|
||||
struct net_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
if (fl6->flowi6_oif) {
|
||||
rcu_read_lock();
|
||||
|
||||
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);
|
||||
|
||||
if (dev && netif_is_l3_master(dev) &&
|
||||
dev->l3mdev_ops->l3mdev_get_saddr6)
|
||||
rc = dev->l3mdev_ops->l3mdev_get_saddr6(dev, sk, fl6);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(l3mdev_get_saddr6);
|
||||
|
||||
/**
|
||||
* l3mdev_fib_rule_match - Determine if flowi references an
|
||||
* L3 master device
|
||||
|
||||
Reference in New Issue
Block a user