aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Wang <weiwan@google.com>2018-01-26 11:40:17 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-02-12 07:07:20 +0100
commit81259f3592f8bc36f146034663a27184966c9e62 (patch)
tree88e5aeca6957979ab9d415823e6af9bd37541201
parent513f3cc3d1d344634f26c12ad3d445c962f1a85a (diff)
download96b-common-81259f3592f8bc36f146034663a27184966c9e62.tar.gz
ipv6: change route cache aging logic
[ Upstream commit 31afeb425f7fad8bcf9561aeb0b8405479f97a98 ] In current route cache aging logic, if a route has both RTF_EXPIRE and RTF_GATEWAY set, the route will only be removed if the neighbor cache has no NTF_ROUTER flag. Otherwise, even if the route has expired, it won't get deleted. Fix this logic to always check if the route has expired first and then do the gateway neighbor cache check if previous check decide to not remove the exception entry. Fixes: 1859bac04fb6 ("ipv6: remove from fib tree aged out RTF_CACHE dst") Signed-off-by: Wei Wang <weiwan@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/ipv6/route.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0458b761f3c5..a560fb1d0230 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1586,12 +1586,19 @@ static void rt6_age_examine_exception(struct rt6_exception_bucket *bucket,
* EXPIRES exceptions - e.g. pmtu-generated ones are pruned when
* expired, independently from their aging, as per RFC 8201 section 4
*/
- if (!(rt->rt6i_flags & RTF_EXPIRES) &&
- time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) {
- RT6_TRACE("aging clone %p\n", rt);
+ if (!(rt->rt6i_flags & RTF_EXPIRES)) {
+ if (time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) {
+ RT6_TRACE("aging clone %p\n", rt);
+ rt6_remove_exception(bucket, rt6_ex);
+ return;
+ }
+ } else if (time_after(jiffies, rt->dst.expires)) {
+ RT6_TRACE("purging expired route %p\n", rt);
rt6_remove_exception(bucket, rt6_ex);
return;
- } else if (rt->rt6i_flags & RTF_GATEWAY) {
+ }
+
+ if (rt->rt6i_flags & RTF_GATEWAY) {
struct neighbour *neigh;
__u8 neigh_flags = 0;
@@ -1606,11 +1613,8 @@ static void rt6_age_examine_exception(struct rt6_exception_bucket *bucket,
rt6_remove_exception(bucket, rt6_ex);
return;
}
- } else if (__rt6_check_expired(rt)) {
- RT6_TRACE("purging expired route %p\n", rt);
- rt6_remove_exception(bucket, rt6_ex);
- return;
}
+
gc_args->more++;
}