diff options
author | Thomas Winter <Thomas.Winter@alliedtelesis.co.nz> | 2017-05-15 18:14:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-16 12:52:17 -0400 |
commit | bcfc7d33110b0f33069d74138eeb7ca9acbb3c85 (patch) | |
tree | cc5fc5cf89b66a4e9078164f198f75fac38a3f9b /net | |
parent | bafbb9c73241760023d8981191ddd30bb1c6dbac (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.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); |