Message ID | 20180225194730.30063-11-dsahern@gmail.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Series | net/ipv6: Separate data structures for FIB and data path | expand |
On Sun, Feb 25, 2018 at 11:47 AM, David Ahern <dsahern@gmail.com> wrote: > Add expires to rt6_info for FIB entries, and add fib6 helpers to > manage it. Data path use of dst.expires remains. > > Signed-off-by: David Ahern <dsahern@gmail.com> > --- > include/net/ip6_fib.h | 26 +++++++++++++++++++++----- > net/ipv6/addrconf.c | 6 +++--- > net/ipv6/ip6_fib.c | 8 ++++---- > net/ipv6/ndisc.c | 2 +- > net/ipv6/route.c | 14 +++++++------- > 5 files changed, 36 insertions(+), 20 deletions(-) > > diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h > index da81669b9c90..3ba0bb7c7a43 100644 > --- a/include/net/ip6_fib.h > +++ b/include/net/ip6_fib.h > @@ -179,6 +179,7 @@ struct rt6_info { > should_flush:1, > unused:6; > > + unsigned long expires; > struct dst_metrics *fib6_metrics; > #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] > #define fib6_hoplimit fib6_metrics->metrics[RTAX_HOPLIMIT-1] > @@ -199,6 +200,26 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) > return ((struct rt6_info *)dst)->rt6i_idev; > } > > +static inline void fib6_clean_expires(struct rt6_info *f6i) > +{ > + f6i->rt6i_flags &= ~RTF_EXPIRES; > + f6i->expires = 0; > +} > + > +static inline void fib6_set_expires(struct rt6_info *f6i, > + unsigned long expires) > +{ > + f6i->expires = expires; > + f6i->rt6i_flags |= RTF_EXPIRES; > +} > + > +static inline bool fib6_check_expired(const struct rt6_info *f6i) > +{ > + if (f6i->rt6i_flags & RTF_EXPIRES) > + return time_after(jiffies, f6i->expires); > + return false; > +} > + > static inline void rt6_clean_expires(struct rt6_info *rt) > { > rt->rt6i_flags &= ~RTF_EXPIRES; > @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) > > static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) > { > - struct rt6_info *rt; > - > - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); > - if (rt && rt != rt0) > - rt0->dst.expires = rt->dst.expires; I was wondering if we need to retain the above logic. It makes sure dst.expires gets synced to its "parent" route. But it might be hard because after your change, we can no longer use rt->from to refer to the "parent". > dst_set_expires(&rt0->dst, timeout); > rt0->rt6i_flags |= RTF_EXPIRES; > } > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index eeecef2b83a4..478f45bf13cf 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -1202,7 +1202,7 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_r > ip6_del_rt(dev_net(ifp->idev->dev), rt); > else { > if (!(rt->rt6i_flags & RTF_EXPIRES)) > - rt6_set_expires(rt, expires); > + fib6_set_expires(rt, expires); > ip6_rt_put(rt); > } > } > @@ -2648,9 +2648,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) > rt = NULL; > } else if (addrconf_finite_timeout(rt_expires)) { > /* not infinity */ > - rt6_set_expires(rt, jiffies + rt_expires); > + fib6_set_expires(rt, jiffies + rt_expires); > } else { > - rt6_clean_expires(rt); > + fib6_clean_expires(rt); > } > } else if (valid_lft) { > clock_t expires = 0; > diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c > index faa2b46349df..7bc23b048189 100644 > --- a/net/ipv6/ip6_fib.c > +++ b/net/ipv6/ip6_fib.c > @@ -886,9 +886,9 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, > if (!(iter->rt6i_flags & RTF_EXPIRES)) > return -EEXIST; > if (!(rt->rt6i_flags & RTF_EXPIRES)) > - rt6_clean_expires(iter); > + fib6_clean_expires(iter); > else > - rt6_set_expires(iter, rt->dst.expires); > + fib6_set_expires(iter, rt->expires); > iter->fib6_pmtu = rt->fib6_pmtu; > return -EEXIST; > } > @@ -1975,8 +1975,8 @@ static int fib6_age(struct rt6_info *rt, void *arg) > * Routes are expired even if they are in use. > */ > > - if (rt->rt6i_flags & RTF_EXPIRES && rt->dst.expires) { > - if (time_after(now, rt->dst.expires)) { > + if (rt->rt6i_flags & RTF_EXPIRES && rt->expires) { > + if (time_after(now, rt->expires)) { > RT6_TRACE("expiring %p\n", rt); > return -1; > } > diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c > index 33f9e3dc526a..bd804e8cd73c 100644 > --- a/net/ipv6/ndisc.c > +++ b/net/ipv6/ndisc.c > @@ -1318,7 +1318,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) > } > > if (rt) > - rt6_set_expires(rt, jiffies + (HZ * lifetime)); > + fib6_set_expires(rt, jiffies + (HZ * lifetime)); > if (in6_dev->cnf.accept_ra_min_hop_limit < 256 && > ra_msg->icmph.icmp6_hop_limit) { > if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) { > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 1649e78b019d..b6206ec947e6 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -435,7 +435,7 @@ static bool rt6_check_expired(const struct rt6_info *rt) > return true; > } else if (rt->from) { > return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK || > - rt6_check_expired(rt->from); > + fib6_check_expired(rt->from); > } > return false; > } > @@ -685,7 +685,7 @@ static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, > !(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE)) > goto out; > > - if (rt6_check_expired(rt)) > + if (fib6_check_expired(rt)) > goto out; > > m = rt6_score_route(rt, oif, strict); > @@ -869,9 +869,9 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, > > if (rt) { > if (!addrconf_finite_timeout(lifetime)) > - rt6_clean_expires(rt); > + fib6_clean_expires(rt); > else > - rt6_set_expires(rt, jiffies + HZ * lifetime); > + fib6_set_expires(rt, jiffies + HZ * lifetime); > > ip6_rt_put(rt); > } > @@ -2266,7 +2266,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, > for_each_fib6_node_rt_rcu(fn) { > if (rt->fib6_nh.nh_flags & RTNH_F_DEAD) > continue; > - if (rt6_check_expired(rt)) > + if (fib6_check_expired(rt)) > continue; > if (rt->rt6i_flags & RTF_REJECT) > break; > @@ -2718,10 +2718,10 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, > goto out; > > if (cfg->fc_flags & RTF_EXPIRES) > - rt6_set_expires(rt, jiffies + > + fib6_set_expires(rt, jiffies + > clock_t_to_jiffies(cfg->fc_expires)); > else > - rt6_clean_expires(rt); > + fib6_clean_expires(rt); > > if (cfg->fc_protocol == RTPROT_UNSPEC) > cfg->fc_protocol = RTPROT_BOOT; > -- > 2.11.0 >
On 2/26/18 3:28 PM, Wei Wang wrote: >> @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) >> >> static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) >> { >> - struct rt6_info *rt; >> - >> - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); >> - if (rt && rt != rt0) >> - rt0->dst.expires = rt->dst.expires; > > I was wondering if we need to retain the above logic. It makes sure > dst.expires gets synced to its "parent" route. But it might be hard > because after your change, we can no longer use rt->from to refer to > the "parent". As I understand it, the FIB entries are cloned into pcpu, uncached and exception routes. We should never have an rt6_info that ever points back more than 1 level -- ie., the dst rt6_info points to a from representing the original FIB entry. After my change 'from' will still point to the FIB entry as a fib6_info which has its own expires. When I looked this code I was really confused. At best, the for loop above sets rt0->dst.expires to some value based on the 'from' but then the very next line calls dst_set_expires with the passed in timeout value. > >> dst_set_expires(&rt0->dst, timeout); >> rt0->rt6i_flags |= RTF_EXPIRES; >> }
On Mon, Feb 26, 2018 at 2:55 PM, David Ahern <dsahern@gmail.com> wrote: > On 2/26/18 3:28 PM, Wei Wang wrote: >>> @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) >>> >>> static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) >>> { >>> - struct rt6_info *rt; >>> - >>> - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); >>> - if (rt && rt != rt0) >>> - rt0->dst.expires = rt->dst.expires; >> >> I was wondering if we need to retain the above logic. It makes sure >> dst.expires gets synced to its "parent" route. But it might be hard >> because after your change, we can no longer use rt->from to refer to >> the "parent". > > As I understand it, the FIB entries are cloned into pcpu, uncached and > exception routes. We should never have an rt6_info that ever points back > more than 1 level -- ie., the dst rt6_info points to a from representing > the original FIB entry. > Yes. Agree. > After my change 'from' will still point to the FIB entry as a fib6_info > which has its own expires. > understood. And fib6_age() is using fib6_check_expired() and rt6_age_exceptions() is checking rt->dst.expires which I think is correct. > When I looked this code I was really confused. At best, the for loop > above sets rt0->dst.expires to some value based on the 'from' but then > the very next line calls dst_set_expires with the passed in timeout value. > > >> >>> dst_set_expires(&rt0->dst, timeout); >>> rt0->rt6i_flags |= RTF_EXPIRES; >>> } >
On Mon, Feb 26, 2018 at 03:55:14PM -0700, David Ahern wrote: > On 2/26/18 3:28 PM, Wei Wang wrote: > >> @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) > >> > >> static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) > >> { > >> - struct rt6_info *rt; > >> - > >> - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); > >> - if (rt && rt != rt0) > >> - rt0->dst.expires = rt->dst.expires; > > > > I was wondering if we need to retain the above logic. It makes sure > > dst.expires gets synced to its "parent" route. But it might be hard > > because after your change, we can no longer use rt->from to refer to > > the "parent". > > As I understand it, the FIB entries are cloned into pcpu, uncached and > exception routes. We should never have an rt6_info that ever points back > more than 1 level -- ie., the dst rt6_info points to a from representing > the original FIB entry. Agree on at most 1 level. > > After my change 'from' will still point to the FIB entry as a fib6_info > which has its own expires. > > When I looked this code I was really confused. At best, the for loop > above sets rt0->dst.expires to some value based on the 'from' but then > the very next line calls dst_set_expires with the passed in timeout value. My understanding is, the rt0 first inherits the expires from its rt0->from. The following dst_set_expires() set a new timeout if the new timeout is earlier than the existing expires. I think it is essentially taking a min. One question, would avoid taking the min cause the rt0 somehow have a longer expires than its parent (or f6i after this series)? > > > > > >> dst_set_expires(&rt0->dst, timeout); > >> rt0->rt6i_flags |= RTF_EXPIRES; > >> } >
On 2/28/18 12:21 PM, Martin KaFai Lau wrote: > On Mon, Feb 26, 2018 at 03:55:14PM -0700, David Ahern wrote: >> On 2/26/18 3:28 PM, Wei Wang wrote: >>>> @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) >>>> >>>> static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) >>>> { >>>> - struct rt6_info *rt; >>>> - >>>> - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); >>>> - if (rt && rt != rt0) >>>> - rt0->dst.expires = rt->dst.expires; >>> >>> I was wondering if we need to retain the above logic. It makes sure >>> dst.expires gets synced to its "parent" route. But it might be hard >>> because after your change, we can no longer use rt->from to refer to >>> the "parent". >> >> As I understand it, the FIB entries are cloned into pcpu, uncached and >> exception routes. We should never have an rt6_info that ever points back >> more than 1 level -- ie., the dst rt6_info points to a from representing >> the original FIB entry. > Agree on at most 1 level. > >> >> After my change 'from' will still point to the FIB entry as a fib6_info >> which has its own expires. >> >> When I looked this code I was really confused. At best, the for loop >> above sets rt0->dst.expires to some value based on the 'from' but then >> the very next line calls dst_set_expires with the passed in timeout value. > My understanding is, the rt0 first inherits the expires from its rt0->from. > > The following dst_set_expires() set a new timeout if the new timeout > is earlier than the existing expires. I think it is essentially > taking a min. > > One question, would avoid taking the min cause the rt0 somehow > have a longer expires than its parent (or f6i after this series)? I believe the current logic expands to: static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) { if (!(rt0->rt6i_flags & RTF_EXPIRES) && rt0->from) rt0->dst.expires = rt0->from->dst.expires; dst_set_expires(&rt0->dst, timeout); rt0->rt6i_flags |= RTF_EXPIRES; } With the fib6_info I can keep that logic with: static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) { if (!(rt0->rt6i_flags & RTF_EXPIRES) && rt0->from) rt0->dst.expires = rt0->from->expires; dst_set_expires(&rt0->dst, timeout); rt0->rt6i_flags |= RTF_EXPIRES; }
On Wed, Feb 28, 2018 at 03:25:02PM -0700, David Ahern wrote: > On 2/28/18 12:21 PM, Martin KaFai Lau wrote: > > On Mon, Feb 26, 2018 at 03:55:14PM -0700, David Ahern wrote: > >> On 2/26/18 3:28 PM, Wei Wang wrote: > >>>> @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) > >>>> > >>>> static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) > >>>> { > >>>> - struct rt6_info *rt; > >>>> - > >>>> - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); > >>>> - if (rt && rt != rt0) > >>>> - rt0->dst.expires = rt->dst.expires; > >>> > >>> I was wondering if we need to retain the above logic. It makes sure > >>> dst.expires gets synced to its "parent" route. But it might be hard > >>> because after your change, we can no longer use rt->from to refer to > >>> the "parent". > >> > >> As I understand it, the FIB entries are cloned into pcpu, uncached and > >> exception routes. We should never have an rt6_info that ever points back > >> more than 1 level -- ie., the dst rt6_info points to a from representing > >> the original FIB entry. > > Agree on at most 1 level. > > > >> > >> After my change 'from' will still point to the FIB entry as a fib6_info > >> which has its own expires. > >> > >> When I looked this code I was really confused. At best, the for loop > >> above sets rt0->dst.expires to some value based on the 'from' but then > >> the very next line calls dst_set_expires with the passed in timeout value. > > My understanding is, the rt0 first inherits the expires from its rt0->from. > > > > The following dst_set_expires() set a new timeout if the new timeout > > is earlier than the existing expires. I think it is essentially > > taking a min. > > > > One question, would avoid taking the min cause the rt0 somehow > > have a longer expires than its parent (or f6i after this series)? > > I believe the current logic expands to: > > static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) > { > if (!(rt0->rt6i_flags & RTF_EXPIRES) && rt0->from) > rt0->dst.expires = rt0->from->dst.expires; > > dst_set_expires(&rt0->dst, timeout); I think the RTF_EXPIRES check should also be skipped. Otherwise, the already-exist rt6_cache will not get a new expires after another pmtu exception. A nit. It seems rt6_update_expires() is only used by rt6_do_update_pmtu(). It could be more readable to move these codes to rt6_do_update_pmtu() such that we know it is a special handling for pmtu case. (i.e. remove rt6_update_expires()). > rt0->rt6i_flags |= RTF_EXPIRES; > } > > > With the fib6_info I can keep that logic with: > > static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) > { > if (!(rt0->rt6i_flags & RTF_EXPIRES) && rt0->from) > rt0->dst.expires = rt0->from->expires; > > dst_set_expires(&rt0->dst, timeout); > rt0->rt6i_flags |= RTF_EXPIRES; > } >
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index da81669b9c90..3ba0bb7c7a43 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -179,6 +179,7 @@ struct rt6_info { should_flush:1, unused:6; + unsigned long expires; struct dst_metrics *fib6_metrics; #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] #define fib6_hoplimit fib6_metrics->metrics[RTAX_HOPLIMIT-1] @@ -199,6 +200,26 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) return ((struct rt6_info *)dst)->rt6i_idev; } +static inline void fib6_clean_expires(struct rt6_info *f6i) +{ + f6i->rt6i_flags &= ~RTF_EXPIRES; + f6i->expires = 0; +} + +static inline void fib6_set_expires(struct rt6_info *f6i, + unsigned long expires) +{ + f6i->expires = expires; + f6i->rt6i_flags |= RTF_EXPIRES; +} + +static inline bool fib6_check_expired(const struct rt6_info *f6i) +{ + if (f6i->rt6i_flags & RTF_EXPIRES) + return time_after(jiffies, f6i->expires); + return false; +} + static inline void rt6_clean_expires(struct rt6_info *rt) { rt->rt6i_flags &= ~RTF_EXPIRES; @@ -213,11 +234,6 @@ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) { - struct rt6_info *rt; - - for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from); - if (rt && rt != rt0) - rt0->dst.expires = rt->dst.expires; dst_set_expires(&rt0->dst, timeout); rt0->rt6i_flags |= RTF_EXPIRES; } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index eeecef2b83a4..478f45bf13cf 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1202,7 +1202,7 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_r ip6_del_rt(dev_net(ifp->idev->dev), rt); else { if (!(rt->rt6i_flags & RTF_EXPIRES)) - rt6_set_expires(rt, expires); + fib6_set_expires(rt, expires); ip6_rt_put(rt); } } @@ -2648,9 +2648,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) rt = NULL; } else if (addrconf_finite_timeout(rt_expires)) { /* not infinity */ - rt6_set_expires(rt, jiffies + rt_expires); + fib6_set_expires(rt, jiffies + rt_expires); } else { - rt6_clean_expires(rt); + fib6_clean_expires(rt); } } else if (valid_lft) { clock_t expires = 0; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index faa2b46349df..7bc23b048189 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -886,9 +886,9 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, if (!(iter->rt6i_flags & RTF_EXPIRES)) return -EEXIST; if (!(rt->rt6i_flags & RTF_EXPIRES)) - rt6_clean_expires(iter); + fib6_clean_expires(iter); else - rt6_set_expires(iter, rt->dst.expires); + fib6_set_expires(iter, rt->expires); iter->fib6_pmtu = rt->fib6_pmtu; return -EEXIST; } @@ -1975,8 +1975,8 @@ static int fib6_age(struct rt6_info *rt, void *arg) * Routes are expired even if they are in use. */ - if (rt->rt6i_flags & RTF_EXPIRES && rt->dst.expires) { - if (time_after(now, rt->dst.expires)) { + if (rt->rt6i_flags & RTF_EXPIRES && rt->expires) { + if (time_after(now, rt->expires)) { RT6_TRACE("expiring %p\n", rt); return -1; } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 33f9e3dc526a..bd804e8cd73c 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1318,7 +1318,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) } if (rt) - rt6_set_expires(rt, jiffies + (HZ * lifetime)); + fib6_set_expires(rt, jiffies + (HZ * lifetime)); if (in6_dev->cnf.accept_ra_min_hop_limit < 256 && ra_msg->icmph.icmp6_hop_limit) { if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1649e78b019d..b6206ec947e6 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -435,7 +435,7 @@ static bool rt6_check_expired(const struct rt6_info *rt) return true; } else if (rt->from) { return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK || - rt6_check_expired(rt->from); + fib6_check_expired(rt->from); } return false; } @@ -685,7 +685,7 @@ static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, !(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE)) goto out; - if (rt6_check_expired(rt)) + if (fib6_check_expired(rt)) goto out; m = rt6_score_route(rt, oif, strict); @@ -869,9 +869,9 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, if (rt) { if (!addrconf_finite_timeout(lifetime)) - rt6_clean_expires(rt); + fib6_clean_expires(rt); else - rt6_set_expires(rt, jiffies + HZ * lifetime); + fib6_set_expires(rt, jiffies + HZ * lifetime); ip6_rt_put(rt); } @@ -2266,7 +2266,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, for_each_fib6_node_rt_rcu(fn) { if (rt->fib6_nh.nh_flags & RTNH_F_DEAD) continue; - if (rt6_check_expired(rt)) + if (fib6_check_expired(rt)) continue; if (rt->rt6i_flags & RTF_REJECT) break; @@ -2718,10 +2718,10 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, goto out; if (cfg->fc_flags & RTF_EXPIRES) - rt6_set_expires(rt, jiffies + + fib6_set_expires(rt, jiffies + clock_t_to_jiffies(cfg->fc_expires)); else - rt6_clean_expires(rt); + fib6_clean_expires(rt); if (cfg->fc_protocol == RTPROT_UNSPEC) cfg->fc_protocol = RTPROT_BOOT;
Add expires to rt6_info for FIB entries, and add fib6 helpers to manage it. Data path use of dst.expires remains. Signed-off-by: David Ahern <dsahern@gmail.com> --- include/net/ip6_fib.h | 26 +++++++++++++++++++++----- net/ipv6/addrconf.c | 6 +++--- net/ipv6/ip6_fib.c | 8 ++++---- net/ipv6/ndisc.c | 2 +- net/ipv6/route.c | 14 +++++++------- 5 files changed, 36 insertions(+), 20 deletions(-)