ipmr: vrf: Find VIFs using the actual device
The skb->dev that is passed into ip_mr_input is the loX device for VRFs. When we lookup a vif for this dev, none is found as we do not create vifs for loopbacks. Instead lookup a vif for the actual device that the packet was received on, eg the vlan. Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz> cc: David Ahern <dsa@cumulusnetworks.com> cc: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> cc: roopa <roopa@cumulusnetworks.com> Acked-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
bafbb9c732
commit
bcfc7d3311
|
@ -1980,6 +1980,20 @@ int ip_mr_input(struct sk_buff *skb)
|
||||||
struct net *net = dev_net(skb->dev);
|
struct net *net = dev_net(skb->dev);
|
||||||
int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
|
int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
|
||||||
struct mr_table *mrt;
|
struct mr_table *mrt;
|
||||||
|
struct net_device *dev;
|
||||||
|
|
||||||
|
/* skb->dev passed in is the loX master dev for vrfs.
|
||||||
|
* As there are no vifs associated with loopback devices,
|
||||||
|
* get the proper interface that does have a vif associated with it.
|
||||||
|
*/
|
||||||
|
dev = skb->dev;
|
||||||
|
if (netif_is_l3_master(skb->dev)) {
|
||||||
|
dev = dev_get_by_index_rcu(net, IPCB(skb)->iif);
|
||||||
|
if (!dev) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Packet is looped back after forward, it should not be
|
/* Packet is looped back after forward, it should not be
|
||||||
* forwarded second time, but still can be delivered locally.
|
* forwarded second time, but still can be delivered locally.
|
||||||
|
@ -2017,7 +2031,7 @@ int ip_mr_input(struct sk_buff *skb)
|
||||||
/* already under rcu_read_lock() */
|
/* already under rcu_read_lock() */
|
||||||
cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
|
cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
int vif = ipmr_find_vif(mrt, skb->dev);
|
int vif = ipmr_find_vif(mrt, dev);
|
||||||
|
|
||||||
if (vif >= 0)
|
if (vif >= 0)
|
||||||
cache = ipmr_cache_find_any(mrt, ip_hdr(skb)->daddr,
|
cache = ipmr_cache_find_any(mrt, ip_hdr(skb)->daddr,
|
||||||
|
@ -2037,7 +2051,7 @@ int ip_mr_input(struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
|
|
||||||
read_lock(&mrt_lock);
|
read_lock(&mrt_lock);
|
||||||
vif = ipmr_find_vif(mrt, skb->dev);
|
vif = ipmr_find_vif(mrt, dev);
|
||||||
if (vif >= 0) {
|
if (vif >= 0) {
|
||||||
int err2 = ipmr_cache_unresolved(mrt, vif, skb);
|
int err2 = ipmr_cache_unresolved(mrt, vif, skb);
|
||||||
read_unlock(&mrt_lock);
|
read_unlock(&mrt_lock);
|
||||||
|
|
Loading…
Reference in New Issue