--- /dev/null
+From stable-bounces@linux.kernel.org Mon Dec 19 17:04:41 2005
+Date: Mon, 19 Dec 2005 17:01:49 -0800 (PST)
+Message-Id: <20051219.170149.96068621.davem@davemloft.net>
+To: stable@kernel.org
+From: "David S. Miller" <davem@davemloft.net>
+Subject: [IPV6]: Fix route lifetime.
+
+From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+
+The route expiration time is stored in rt6i_expires in jiffies.
+The argument of rt6_route_add() for adding a route is not the
+expiration time in jiffies nor in clock_t, but the lifetime
+(or time left before expiration) in clock_t.
+
+Because of the confusion, we sometimes saw several strange errors
+(FAILs) in TAHI IPv6 Ready Logo Phase-2 Self Test.
+The symptoms were analyzed by Mitsuru Chinen <CHINEN@jp.ibm.com>.
+
+Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@redhat.com>
+---
+
+ net/ipv6/addrconf.c | 16 ++++++++++++----
+ net/ipv6/route.c | 2 +-
+ 2 files changed, 13 insertions(+), 5 deletions(-)
+
+Index: linux-2.6.14.y/net/ipv6/addrconf.c
+===================================================================
+--- linux-2.6.14.y.orig/net/ipv6/addrconf.c
++++ linux-2.6.14.y/net/ipv6/addrconf.c
+@@ -1456,9 +1456,17 @@ void addrconf_prefix_rcv(struct net_devi
+ not good.
+ */
+ if (valid_lft >= 0x7FFFFFFF/HZ)
+- rt_expires = 0;
++ rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ);
+ else
+- rt_expires = jiffies + valid_lft * HZ;
++ rt_expires = valid_lft * HZ;
++
++ /*
++ * We convert this (in jiffies) to clock_t later.
++ * Avoid arithmetic overflow there as well.
++ * Overflow can happen only if HZ < USER_HZ.
++ */
++ if (HZ < USER_HZ && rt_expires > 0x7FFFFFFF / USER_HZ)
++ rt_expires = 0x7FFFFFFF / USER_HZ;
+
+ if (pinfo->onlink) {
+ struct rt6_info *rt;
+@@ -1470,12 +1478,12 @@ void addrconf_prefix_rcv(struct net_devi
+ ip6_del_rt(rt, NULL, NULL, NULL);
+ rt = NULL;
+ } else {
+- rt->rt6i_expires = rt_expires;
++ rt->rt6i_expires = jiffies + rt_expires;
+ }
+ }
+ } else if (valid_lft) {
+ addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
+- dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
++ dev, jiffies_to_clock_t(rt_expires), RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
+ }
+ if (rt)
+ dst_release(&rt->u.dst);
+Index: linux-2.6.14.y/net/ipv6/route.c
+===================================================================
+--- linux-2.6.14.y.orig/net/ipv6/route.c
++++ linux-2.6.14.y/net/ipv6/route.c
+@@ -829,7 +829,7 @@ int ip6_route_add(struct in6_rtmsg *rtms
+ }
+
+ rt->u.dst.obsolete = -1;
+- rt->rt6i_expires = clock_t_to_jiffies(rtmsg->rtmsg_info);
++ rt->rt6i_expires = jiffies + clock_t_to_jiffies(rtmsg->rtmsg_info);
+ if (nlh && (r = NLMSG_DATA(nlh))) {
+ rt->rt6i_protocol = r->rtm_protocol;
+ } else {