diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r-- | net/ipv4/ipmr.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 3a02d52ed50e..551de4d023a8 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1980,6 +1980,20 @@ int ip_mr_input(struct sk_buff *skb) | |||
1980 | struct net *net = dev_net(skb->dev); | 1980 | struct net *net = dev_net(skb->dev); |
1981 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; | 1981 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; |
1982 | struct mr_table *mrt; | 1982 | struct mr_table *mrt; |
1983 | struct net_device *dev; | ||
1984 | |||
1985 | /* skb->dev passed in is the loX master dev for vrfs. | ||
1986 | * As there are no vifs associated with loopback devices, | ||
1987 | * get the proper interface that does have a vif associated with it. | ||
1988 | */ | ||
1989 | dev = skb->dev; | ||
1990 | if (netif_is_l3_master(skb->dev)) { | ||
1991 | dev = dev_get_by_index_rcu(net, IPCB(skb)->iif); | ||
1992 | if (!dev) { | ||
1993 | kfree_skb(skb); | ||
1994 | return -ENODEV; | ||
1995 | } | ||
1996 | } | ||
1983 | 1997 | ||
1984 | /* Packet is looped back after forward, it should not be | 1998 | /* Packet is looped back after forward, it should not be |
1985 | * forwarded second time, but still can be delivered locally. | 1999 | * forwarded second time, but still can be delivered locally. |
@@ -2017,7 +2031,7 @@ int ip_mr_input(struct sk_buff *skb) | |||
2017 | /* already under rcu_read_lock() */ | 2031 | /* already under rcu_read_lock() */ |
2018 | cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); | 2032 | cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); |
2019 | if (!cache) { | 2033 | if (!cache) { |
2020 | int vif = ipmr_find_vif(mrt, skb->dev); | 2034 | int vif = ipmr_find_vif(mrt, dev); |
2021 | 2035 | ||
2022 | if (vif >= 0) | 2036 | if (vif >= 0) |
2023 | cache = ipmr_cache_find_any(mrt, ip_hdr(skb)->daddr, | 2037 | cache = ipmr_cache_find_any(mrt, ip_hdr(skb)->daddr, |
@@ -2037,7 +2051,7 @@ int ip_mr_input(struct sk_buff *skb) | |||
2037 | } | 2051 | } |
2038 | 2052 | ||
2039 | read_lock(&mrt_lock); | 2053 | read_lock(&mrt_lock); |
2040 | vif = ipmr_find_vif(mrt, skb->dev); | 2054 | vif = ipmr_find_vif(mrt, dev); |
2041 | if (vif >= 0) { | 2055 | if (vif >= 0) { |
2042 | int err2 = ipmr_cache_unresolved(mrt, vif, skb); | 2056 | int err2 = ipmr_cache_unresolved(mrt, vif, skb); |
2043 | read_unlock(&mrt_lock); | 2057 | read_unlock(&mrt_lock); |