diff options
Diffstat (limited to 'include/net/ip6_fib.h')
-rw-r--r-- | include/net/ip6_fib.h | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 28d27a6..fdc48a9 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -166,35 +166,50 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) static inline void rt6_clean_expires(struct rt6_info *rt) { + if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) + dst_release(rt->dst.from); + rt->rt6i_flags &= ~RTF_EXPIRES; + rt->dst.from = NULL; } static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) { - rt->dst.expires = expires; + if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) + dst_release(rt->dst.from); + rt->rt6i_flags |= RTF_EXPIRES; + rt->dst.expires = expires; } -static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) +static inline void rt6_update_expires(struct rt6_info *rt, int timeout) { - struct rt6_info *rt; - - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); - rt = (struct rt6_info *)rt->dst.from); - if (rt && rt != rt0) - rt0->dst.expires = rt->dst.expires; - - dst_set_expires(&rt0->dst, timeout); - rt0->rt6i_flags |= RTF_EXPIRES; + if (!(rt->rt6i_flags & RTF_EXPIRES)) { + if (rt->dst.from) + dst_release(rt->dst.from); + /* dst_set_expires relies on expires == 0 + * if it has not been set previously. + */ + rt->dst.expires = 0; + } + + dst_set_expires(&rt->dst, timeout); + rt->rt6i_flags |= RTF_EXPIRES; } static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) { struct dst_entry *new = (struct dst_entry *) from; + if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) { + if (new == rt->dst.from) + return; + dst_release(rt->dst.from); + } + rt->rt6i_flags &= ~RTF_EXPIRES; - dst_hold(new); rt->dst.from = new; + dst_hold(new); } static inline void ip6_rt_put(struct rt6_info *rt) |