From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Miller Subject: [PATCH 11/13 net-3.1-stable] inet: add a redirect generation id in inetpeer Date: Tue, 06 Dec 2011 16:33:51 -0500 (EST) Message-ID: <20111206.163351.1846331571448628501.davem@davemloft.net> Mime-Version: 1.0 Content-Type: Text/Plain; charset=iso-8859-2 Content-Transfer-Encoding: QUOTED-PRINTABLE To: netdev@vger.kernel.org Return-path: Received: from shards.monkeyblade.net ([198.137.202.13]:33999 "EHLO shards.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754431Ab1LFVdw convert rfc822-to-8bit (ORCPT ); Tue, 6 Dec 2011 16:33:52 -0500 Received: from localhost (nat-pool-rdu.redhat.com [66.187.233.202]) (authenticated bits=0) by shards.monkeyblade.net (8.14.4/8.14.4) with ESMTP id pB6LXpLU024304 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 6 Dec 2011 13:33:52 -0800 Sender: netdev-owner@vger.kernel.org List-ID: =46rom: Eric Dumazet [ Upstream commit de68dca1816660b0d3ac89fa59ffb410007a143f ] Now inetpeer is the place where we cache redirect information for ipv4 destinations, we must be able to invalidate informations when a route i= s added/removed on host. As inetpeer is not yet namespace aware, this patch adds a shared redirect_genid, and a per inetpeer redirect_genid. This might be change= d later if inetpeer becomes ns aware. Cache information for one inerpeer is valid as long as its redirect_genid has the same value than global redirect_genid. Reported-by: Arkadiusz Mi=B6kiewicz Tested-by: Arkadiusz Mi=B6kiewicz Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/inetpeer.h | 1 + net/ipv4/route.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 78c83e6..e9ff3fc 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -35,6 +35,7 @@ struct inet_peer { =20 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; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b2e9544..65d2572 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -132,6 +132,7 @@ static int ip_rt_mtu_expires __read_mostly =3D 10 *= 60 * HZ; static int ip_rt_min_pmtu __read_mostly =3D 512 + 20 + 20; static int ip_rt_min_advmss __read_mostly =3D 256; static int rt_chain_length_max __read_mostly =3D 20; +static int redirect_genid; =20 /* * Interface to generic destination cache. @@ -842,6 +843,7 @@ static void rt_cache_invalidate(struct net *net) =20 get_random_bytes(&shuffle, sizeof(shuffle)); atomic_add(shuffle + 1U, &net->ipv4.rt_genid); + redirect_genid++; } =20 /* @@ -1396,8 +1398,10 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr,= __be32 new_gw, =20 peer =3D rt->peer; if (peer) { - if (peer->redirect_learned.a4 !=3D new_gw) { + if (peer->redirect_learned.a4 !=3D new_gw || + peer->redirect_genid !=3D redirect_genid) { peer->redirect_learned.a4 =3D new_gw; + peer->redirect_genid =3D redirect_genid; atomic_inc(&__rt_peer_genid); } check_peer_redir(&rt->dst, peer); @@ -1706,6 +1710,8 @@ static struct dst_entry *ipv4_dst_check(struct ds= t_entry *dst, u32 cookie) if (peer) { check_peer_pmtu(dst, peer); =20 + if (peer->redirect_genid !=3D redirect_genid) + peer->redirect_learned.a4 =3D 0; if (peer->redirect_learned.a4 && peer->redirect_learned.a4 !=3D rt->rt_gateway) { if (check_peer_redir(dst, peer)) @@ -1857,6 +1863,8 @@ static void rt_init_metrics(struct rtable *rt, co= nst struct flowi4 *fl4, dst_init_metrics(&rt->dst, peer->metrics, false); =20 check_peer_pmtu(&rt->dst, peer); + if (peer->redirect_genid !=3D redirect_genid) + peer->redirect_learned.a4 =3D 0; if (peer->redirect_learned.a4 && peer->redirect_learned.a4 !=3D rt->rt_gateway) { rt->rt_gateway =3D peer->redirect_learned.a4; --=20 1.7.7.3