Fix routing metrics
Subsystems (3)
v3 cover Fix routing metrics
At the moment we initialize the routing metrics with the, on the inetpeer cached values in rt_init_metrics(). So if we have the metrics cached on the inetpeer, we ignore the user configured fib_metrics. This leads to the fact that we can't configure the mtu, hoplimit etc. if we have learned metrics cached.
The first patch invalidates the inetpeer tree along routing cache. This is done by replacing the old tree with a fresh initialized inet_peer_base when rt_cache_invalidate() is invoked. The old tree is added to a garbage collector list and destroyed later with a delayed work queue. I use a delay of 60 seconds, so rt_check_expire() ran at least on time before on a default configuration.
The second patch removes the redirect_genid handling. We don't need this any more because we remove the whole inetpeer tree when the redirects are invalidated.
Changes from v2:
- Fix possible null pointer dereference in ip_rt_redirect()
PATCH v3 1/2 inetpeer: Invalidate the inetpeer tree along with the routing cache
We initialize the routing metrics with the values cached on the inetpeer in rt_init_metrics(). So if we have the metrics cached on the inetpeer, we ignore the user configured fib_metrics.
To fix this issue, we replace the old tree with a fresh initialized inet_peer_base. The old tree is removed later with a delayed work queue.
--- include/net/inetpeer.h | 3 ++ net/ipv4/inetpeer.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++- net/ipv4/route.c | 1 + 3 files changed, 83 insertions(+), 1 deletions(-)
include/net/inetpeer.h +3 -0
@@ -41,6 +41,7 @@ struct inet_peer {u32 pmtu_orig;u32 pmtu_learned;struct inetpeer_addr_base redirect_learned; +struct list_head gc_list;/* * Once inet_peer is queued for deletion (refcnt == -1), following fields * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp
@@ -96,6 +97,8 @@ static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr,extern void inet_putpeer (struct inet_peer *p);extern bool inet_peer_xrlim_allow (struct inet_peer *peer,int timeout); +extern void inetpeer_invalidate_tree (int family); +/* * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, * tcp_ts_stamp if no refcount is taken on inet_peer
net/ipv4/inetpeer.c +79 -1
113 lines not on this page · raw message
net/ipv4/route.c +1 -0
@@ -938,6 +938,7 @@ static void rt_cache_invalidate(struct net *net)get_random_bytes (&shuffle,sizeof (shuffle));atomic_add (shuffle +1U , &net->ipv4.rt_genid); redirect_genid++; +inetpeer_invalidate_tree (AF_INET ); }/*
Signature · 1 line
1.7.0.4
Re: [PATCH 1/2] inetpeer: Invalidate the inetpeer tree along with the routing cache
From: Steffen Klassert <[email protected]>
Date: Wed, 7 Mar 2012 08:20:26 +0100
Quoted 8 lines
We initialize the routing metrics with the values cached on the inetpeer in
rt_init_metrics(). So if we have the metrics cached on the inetpeer, we ignore the user configuredfib_metrics.To fix this issue, we replace the old tree with a fresh initialized
inet_peer_base. The old tree is removed later with a delayed work queue.Signed-off-by Steffen Klassert <[email protected]>
Applied, but I had to fixup trailing whitespace:
Review
Quoted 1 line
(quoted diff) +1
-0+ spin_lock_bh(&gc_lock);
at the end of that line.
PATCH v3 2/2 route: Remove redirect_genid
In reply to Steffen KlassertAs we invalidate the inetpeer tree along with the routing cache now, we don't need a genid to reset the redirect handling when the routing cache is flushed.
--- include/net/inetpeer.h | 1 - net/ipv4/inetpeer.c | 1 - net/ipv4/route.c | 11 ++--------- 3 files changed, 2 insertions(+), 11 deletions(-)
include/net/inetpeer.h +0 -1
@@ -35,7 +35,6 @@ struct inet_peer {u32 metrics[RTAX_MAX ];u32 rate_tokens;/* rate limiting for ICMP */ -int redirect_genid;unsigned long rate_last;unsigned long pmtu_expires;u32 pmtu_orig;
net/ipv4/inetpeer.c +0 -1
@@ -498,7 +498,6 @@ relookup: p->rate_last =0 ; p->pmtu_expires =0 ; p->pmtu_orig =0 ; - p->redirect_genid =0 ;memset (&p->redirect_learned,0 ,sizeof (p->redirect_learned));INIT_LIST_HEAD (&p->gc_list);
net/ipv4/route.c +2 -9
@@ -132,7 +132,6 @@ static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ;static int ip_rt_min_pmtu__read_mostly =512 +20 +20 ;static int ip_rt_min_advmss__read_mostly =256 ;static int rt_chain_length_max__read_mostly =20 ; -static int redirect_genid;static struct delayed_work expires_work;static unsigned long expires_ljiffies;
@@ -937,7 +936,6 @@ static void rt_cache_invalidate(struct net *net)get_random_bytes (&shuffle,sizeof (shuffle));atomic_add (shuffle +1U , &net->ipv4.rt_genid); - redirect_genid++;inetpeer_invalidate_tree (AF_INET ); }
@@ -1486,10 +1484,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, peer = rt->peer;if (peer) { -if (peer->redirect_learned.a4 != new_gw || - peer->redirect_genid != redirect_genid) { +if (peer->redirect_learned.a4 != new_gw) { peer->redirect_learned.a4 = new_gw; - peer->redirect_genid = redirect_genid;atomic_inc (&__rt_peer_genid); }check_peer_redir (&rt->dst, peer);
@@ -1794,8 +1790,6 @@ static void ipv4_validate_peer(struct rtable *rt)if (peer) {check_peer_pmtu (&rt->dst, peer); -if (peer->redirect_genid != redirect_genid) - peer->redirect_learned.a4 =0 ;if (peer->redirect_learned.a4 && peer->redirect_learned.a4 != rt->rt_gateway)check_peer_redir (&rt->dst, peer);
@@ -1959,8 +1953,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,dst_init_metrics (&rt->dst, peer->metrics, false);check_peer_pmtu (&rt->dst, peer); -if (peer->redirect_genid != redirect_genid) - peer->redirect_learned.a4 =0 ; +if (peer->redirect_learned.a4 && peer->redirect_learned.a4 != rt->rt_gateway) { rt->rt_gateway = peer->redirect_learned.a4;
Signature · 1 line
1.7.0.4
Re: [PATCH 2/2] route: Remove redirect_genid
From: Steffen Klassert <[email protected]>
Date: Wed, 7 Mar 2012 08:21:10 +0100
Quoted 5 lines
As we invalidate the inetpeer tree along with the routing cache now, we don't need a genid to reset the redirect handling when the routing cache is flushed.
Signed-off-by Steffen Klassert <[email protected]>
Applied.