aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorThomas Winter <Thomas.Winter@alliedtelesis.co.nz>2017-05-15 18:14:44 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-16 12:52:17 -0400
commitbcfc7d33110b0f33069d74138eeb7ca9acbb3c85 (patch)
treecc5fc5cf89b66a4e9078164f198f75fac38a3f9b /net
parentbafbb9c73241760023d8981191ddd30bb1c6dbac (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/ipmr.c18
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);