[IPV6] ADDRCONF: Allow longer lifetime on 64bit archs.
- Allow longer lifetimes (>= 0x7fffffff/HZ) on 64bit archs
by using unsigned long.
- Shadow this arithmetic overflow workaround by introducing
helper functions: addrconf_timeout_fixup() and
addrconf_finite_timeout().
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 48534c6..220cffe 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -446,7 +446,7 @@
struct route_info *rinfo = (struct route_info *) opt;
struct in6_addr prefix_buf, *prefix;
unsigned int pref;
- u32 lifetime;
+ unsigned long lifetime;
struct rt6_info *rt;
if (len < sizeof(struct route_info)) {
@@ -472,13 +472,7 @@
if (pref == ICMPV6_ROUTER_PREF_INVALID)
pref = ICMPV6_ROUTER_PREF_MEDIUM;
- lifetime = ntohl(rinfo->lifetime);
- if (lifetime == 0xffffffff) {
- /* infinity */
- } else if (lifetime > 0x7fffffff/HZ - 1) {
- /* Avoid arithmetic overflow */
- lifetime = 0x7fffffff/HZ - 1;
- }
+ lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ);
if (rinfo->length == 3)
prefix = (struct in6_addr *)rinfo->prefix;
@@ -506,7 +500,7 @@
(rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
if (rt) {
- if (lifetime == 0xffffffff) {
+ if (!addrconf_finite_timeout(lifetime)) {
rt->rt6i_flags &= ~RTF_EXPIRES;
} else {
rt->rt6i_expires = jiffies + HZ * lifetime;