Patch "ipv6: set dst.obsolete when a cached route has expired" has been added to the 4.12-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
ipv6: set dst.obsolete when a cached route has expired
to the 4.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ipv6-set-dst.obsolete-when-a-cached-route-has-expired.patch
and it can be found in the queue-4.12 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Sep 14 23:20:23 PDT 2017
From: Xin Long <[email protected]>
Date: Sat, 26 Aug 2017 20:10:10 +0800
Subject: ipv6: set dst.obsolete when a cached route has expired
From: Xin Long <[email protected]>
[ Upstream commit 1e2ea8ad37be25a7cdcc974945935829d534d5d3 ]
Now it doesn't check for the cached route expiration in ipv6's dst_ops->check(), because it trusts dst_gc that would clean the cached route up when it's expired.
The problem is in dst_gc, it would clean the cached route only when it's refcount is 1. If some other module (like xfrm) keeps holding it and the module only release it when dst_ops->check() fails.
But without checking for the cached route expiration, .check() may always return true. Meanwhile, without releasing the cached route, dst_gc couldn't del it. It will cause this cached route never to expire.
This patch is to set dst.obsolete with DST_OBSOLETE_KILL in .gc when it's expired, and check obsolete != DST_OBSOLETE_FORCE_CHK in .check.
Note that this is even needed when ipv6 dst_gc timer is removed one day. It would set dst.obsolete in .redirect and .update_pmtu instead, and check for cached route expiration when getting it, just like what ipv4 route does.
--- net/ipv6/ip6_fib.c | 4 +++- net/ipv6/route.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-)
net/ipv6/ip6_fib.c +3 -1
@@ -1790,8 +1790,10 @@ static int fib6_age(struct rt6_info *rt, } gc_args->more++; }else if (rt->rt6i_flags &RTF_CACHE ) { +if (time_after_eq (now, rt->dst.lastuse + gc_args->timeout)) + rt->dst.obsolete =DST_OBSOLETE_KILL ;if (atomic_read (&rt->dst.__refcnt) ==0 && -time_after_eq (now, rt->dst.lastuse + gc_args->timeout)) { + rt->dst.obsolete ==DST_OBSOLETE_KILL ) {RT6_TRACE ("aging clone %p\n" , rt);return -1 ; }else if (rt->rt6i_flags &RTF_GATEWAY ) {
net/ipv6/route.c +2 -1
@@ -444,7 +444,8 @@ static bool rt6_check_expired(const struif (time_after (jiffies, rt->dst.expires))return true; }else if (rt->dst.from) { -return rt6_check_expired ((struct rt6_info *) rt->dst.from); +return rt->dst.obsolete !=DST_OBSOLETE_FORCE_CHK || +rt6_check_expired ((struct rt6_info *)rt->dst.from); }return false; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.12/ip6_gre-update-mtu-properly-in-ip6gre_err.patch queue-4.12/ipv6-set-dst.obsolete-when-a-cached-route-has-expired.patch queue-4.12/ipv6-do-not-set-sk_destruct-in-ipv6_addrform-sockopt.patch queue-4.12/sctp-avoid-out-of-bounds-reads-from-address-storage.patch