diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2005-12-19 17:02:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-12-19 17:02:45 -0500 |
commit | 3dd4bc68fac5df16b6d3ed6ed3c29cf05f29a47e (patch) | |
tree | 854f73bd7862354eac94b624d436b59fdd5ffecb /net/ipv6/addrconf.c | |
parent | b03664869aa6f84c3c98a06ac9d6905b195909bc (diff) |
[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: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 73a23b4130a5..4ea8cf7c0cc4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1596,9 +1596,17 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1596 | not good. | 1596 | not good. |
1597 | */ | 1597 | */ |
1598 | if (valid_lft >= 0x7FFFFFFF/HZ) | 1598 | if (valid_lft >= 0x7FFFFFFF/HZ) |
1599 | rt_expires = 0; | 1599 | rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ); |
1600 | else | 1600 | else |
1601 | rt_expires = jiffies + valid_lft * HZ; | 1601 | rt_expires = valid_lft * HZ; |
1602 | |||
1603 | /* | ||
1604 | * We convert this (in jiffies) to clock_t later. | ||
1605 | * Avoid arithmetic overflow there as well. | ||
1606 | * Overflow can happen only if HZ < USER_HZ. | ||
1607 | */ | ||
1608 | if (HZ < USER_HZ && rt_expires > 0x7FFFFFFF / USER_HZ) | ||
1609 | rt_expires = 0x7FFFFFFF / USER_HZ; | ||
1602 | 1610 | ||
1603 | if (pinfo->onlink) { | 1611 | if (pinfo->onlink) { |
1604 | struct rt6_info *rt; | 1612 | struct rt6_info *rt; |
@@ -1610,12 +1618,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1610 | ip6_del_rt(rt, NULL, NULL, NULL); | 1618 | ip6_del_rt(rt, NULL, NULL, NULL); |
1611 | rt = NULL; | 1619 | rt = NULL; |
1612 | } else { | 1620 | } else { |
1613 | rt->rt6i_expires = rt_expires; | 1621 | rt->rt6i_expires = jiffies + rt_expires; |
1614 | } | 1622 | } |
1615 | } | 1623 | } |
1616 | } else if (valid_lft) { | 1624 | } else if (valid_lft) { |
1617 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, | 1625 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, |
1618 | dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT); | 1626 | dev, jiffies_to_clock_t(rt_expires), RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT); |
1619 | } | 1627 | } |
1620 | if (rt) | 1628 | if (rt) |
1621 | dst_release(&rt->u.dst); | 1629 | dst_release(&rt->u.dst); |