Commit 3dd4bc68 authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki Committed by David S. Miller

[IPV6]: Fix route lifetime.

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: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b0366486
...@@ -1596,9 +1596,17 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -1596,9 +1596,17 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
not good. not good.
*/ */
if (valid_lft >= 0x7FFFFFFF/HZ) if (valid_lft >= 0x7FFFFFFF/HZ)
rt_expires = 0; rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ);
else 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) { if (pinfo->onlink) {
struct rt6_info *rt; struct rt6_info *rt;
...@@ -1610,12 +1618,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -1610,12 +1618,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
ip6_del_rt(rt, NULL, NULL, NULL); ip6_del_rt(rt, NULL, NULL, NULL);
rt = NULL; rt = NULL;
} else { } else {
rt->rt6i_expires = rt_expires; rt->rt6i_expires = jiffies + rt_expires;
} }
} }
} else if (valid_lft) { } else if (valid_lft) {
addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, 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) if (rt)
dst_release(&rt->u.dst); dst_release(&rt->u.dst);
......
...@@ -829,7 +829,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, ...@@ -829,7 +829,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
} }
rt->u.dst.obsolete = -1; 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))) { if (nlh && (r = NLMSG_DATA(nlh))) {
rt->rt6i_protocol = r->rtm_protocol; rt->rt6i_protocol = r->rtm_protocol;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment