aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 48534c6c0735..7ff687020fa9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
240static inline struct rt6_info *rt6_device_match(struct net *net, 240static inline struct rt6_info *rt6_device_match(struct net *net,
241 struct rt6_info *rt, 241 struct rt6_info *rt,
242 int oif, 242 int oif,
243 int strict) 243 int flags)
244{ 244{
245 struct rt6_info *local = NULL; 245 struct rt6_info *local = NULL;
246 struct rt6_info *sprt; 246 struct rt6_info *sprt;
@@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
253 if (dev->flags & IFF_LOOPBACK) { 253 if (dev->flags & IFF_LOOPBACK) {
254 if (sprt->rt6i_idev == NULL || 254 if (sprt->rt6i_idev == NULL ||
255 sprt->rt6i_idev->dev->ifindex != oif) { 255 sprt->rt6i_idev->dev->ifindex != oif) {
256 if (strict && oif) 256 if (flags & RT6_LOOKUP_F_IFACE && oif)
257 continue; 257 continue;
258 if (local && (!oif || 258 if (local && (!oif ||
259 local->rt6i_idev->dev->ifindex == oif)) 259 local->rt6i_idev->dev->ifindex == oif))
@@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
266 if (local) 266 if (local)
267 return local; 267 return local;
268 268
269 if (strict) 269 if (flags & RT6_LOOKUP_F_IFACE)
270 return net->ipv6.ip6_null_entry; 270 return net->ipv6.ip6_null_entry;
271 } 271 }
272 return rt; 272 return rt;
@@ -446,7 +446,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
446 struct route_info *rinfo = (struct route_info *) opt; 446 struct route_info *rinfo = (struct route_info *) opt;
447 struct in6_addr prefix_buf, *prefix; 447 struct in6_addr prefix_buf, *prefix;
448 unsigned int pref; 448 unsigned int pref;
449 u32 lifetime; 449 unsigned long lifetime;
450 struct rt6_info *rt; 450 struct rt6_info *rt;
451 451
452 if (len < sizeof(struct route_info)) { 452 if (len < sizeof(struct route_info)) {
@@ -472,13 +472,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
472 if (pref == ICMPV6_ROUTER_PREF_INVALID) 472 if (pref == ICMPV6_ROUTER_PREF_INVALID)
473 pref = ICMPV6_ROUTER_PREF_MEDIUM; 473 pref = ICMPV6_ROUTER_PREF_MEDIUM;
474 474
475 lifetime = ntohl(rinfo->lifetime); 475 lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ);
476 if (lifetime == 0xffffffff) {
477 /* infinity */
478 } else if (lifetime > 0x7fffffff/HZ - 1) {
479 /* Avoid arithmetic overflow */
480 lifetime = 0x7fffffff/HZ - 1;
481 }
482 476
483 if (rinfo->length == 3) 477 if (rinfo->length == 3)
484 prefix = (struct in6_addr *)rinfo->prefix; 478 prefix = (struct in6_addr *)rinfo->prefix;
@@ -506,7 +500,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
506 (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); 500 (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
507 501
508 if (rt) { 502 if (rt) {
509 if (lifetime == 0xffffffff) { 503 if (!addrconf_finite_timeout(lifetime)) {
510 rt->rt6i_flags &= ~RTF_EXPIRES; 504 rt->rt6i_flags &= ~RTF_EXPIRES;
511 } else { 505 } else {
512 rt->rt6i_expires = jiffies + HZ * lifetime; 506 rt->rt6i_expires = jiffies + HZ * lifetime;
@@ -2202,8 +2196,12 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2202 2196
2203 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); 2197 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
2204 2198
2205 expires = (rt->rt6i_flags & RTF_EXPIRES) ? 2199 if (!(rt->rt6i_flags & RTF_EXPIRES))
2206 rt->rt6i_expires - jiffies : 0; 2200 expires = 0;
2201 else if (rt->rt6i_expires - jiffies < INT_MAX)
2202 expires = rt->rt6i_expires - jiffies;
2203 else
2204 expires = INT_MAX;
2207 2205
2208 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, 2206 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0,
2209 expires, rt->u.dst.error) < 0) 2207 expires, rt->u.dst.error) < 0)