diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2016-04-07 11:10:06 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-10 10:26:22 +0200 |
commit | 77ef57530f1140ce60b31125359819a185a68c58 (patch) | |
tree | 6318a79135268864fa4643cb9a07fbcc9558f6a5 /net/ipv4/route.c | |
parent | 396250c2041a9190e1d8199dfb2598c461de4343 (diff) |
net: vrf: Fix dst reference counting
commit 9ab179d83b4e31ea277a123492e419067c2f129a upstream.
Vivek reported a kernel exception deleting a VRF with an active
connection through it. The root cause is that the socket has a cached
reference to a dst that is destroyed. Converting the dst_destroy to
dst_release and letting proper reference counting kick in does not
work as the dst has a reference to the device which needs to be released
as well.
I talked to Hannes about this at netdev and he pointed out the ipv4 and
ipv6 dst handling has dst_ifdown for just this scenario. Rather than
continuing with the reinvented dst wheel in VRF just remove it and
leverage the ipv4 and ipv6 versions.
Fixes: 193125dbd8eb2 ("net: Introduce VRF device driver")
Fixes: 35402e3136634 ("net: Add IPv6 support to VRF device")
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d76752a28bfa..29a87fadf01b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1500,9 +1500,9 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, #endif } -static struct rtable *rt_dst_alloc(struct net_device *dev, - unsigned int flags, u16 type, - bool nopolicy, bool noxfrm, bool will_cache) +struct rtable *rt_dst_alloc(struct net_device *dev, + unsigned int flags, u16 type, + bool nopolicy, bool noxfrm, bool will_cache) { struct rtable *rt; @@ -1531,6 +1531,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev, return rt; } +EXPORT_SYMBOL(rt_dst_alloc); /* called in rcu_read_lock() section */ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, |