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);
|
||||
int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
|
||||
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
|
||||
* 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() */
|
||||
cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
|
||||
if (!cache) {
|
||||
int vif = ipmr_find_vif(mrt, skb->dev);
|
||||
int vif = ipmr_find_vif(mrt, dev);
|
||||
|
||||
if (vif >= 0)
|
||||
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);
|
||||
vif = ipmr_find_vif(mrt, skb->dev);
|
||||
vif = ipmr_find_vif(mrt, dev);
|
||||
if (vif >= 0) {
|
||||
int err2 = ipmr_cache_unresolved(mrt, vif, skb);
|
||||
read_unlock(&mrt_lock);
|
||||
|
|
Loading…
Reference in New Issue