On 27/05/16(Fri) 17:06, David Gwynne wrote:
> time_second is unix time, can jump with clock changes. time_uptime
> is better cos it is monotonic.
> 
> userland expects the expiry to be in unix time though, so it's
> translated before it appears in route messages.

Could you at least keep ND in sync and use time_second for ln_expire
as well?  I don't think it makes sense to introduce more differences
than we already have.

> Index: net/route.c
> ===================================================================
> RCS file: /cvs/src/sys/net/route.c,v
> retrieving revision 1.300
> diff -u -p -r1.300 route.c
> --- net/route.c       2 May 2016 22:15:49 -0000       1.300
> +++ net/route.c       27 May 2016 07:03:47 -0000
> @@ -1187,7 +1187,7 @@ rt_checkgate(struct rtentry *rt, struct 
>       }
>  
>       if (rt->rt_flags & RTF_REJECT)
> -             if (rt->rt_expire == 0 || time_second < rt->rt_expire)
> +             if (rt->rt_expire == 0 || time_uptime < rt->rt_expire)
>                       return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
>  
>       *rtp = rt;
> @@ -1542,7 +1542,7 @@ rt_timer_add(struct rtentry *rt, void (*
>       long             current_time;
>  
>       current_time = time_uptime;
> -     rt->rt_rmx.rmx_expire = time_second + queue->rtq_timeout;
> +     rt->rt_rmx.rmx_expire = time_uptime + queue->rtq_timeout;
>  
>       /*
>        * If there's already a timer with this action, destroy it before
> Index: net/route.h
> ===================================================================
> RCS file: /cvs/src/sys/net/route.h,v
> retrieving revision 1.135
> diff -u -p -r1.135 route.h
> --- net/route.h       27 Apr 2016 14:47:27 -0000      1.135
> +++ net/route.h       27 May 2016 07:03:47 -0000
> @@ -364,8 +364,8 @@ void       rt_sendaddrmsg(struct rtentry *, i
>  void  rt_missmsg(int, struct rt_addrinfo *, int, uint8_t, u_int, int, u_int);
>  int   rt_setgate(struct rtentry *, struct sockaddr *);
>  int   rt_checkgate(struct rtentry *, struct rtentry **);
> -void  rt_setmetrics(u_long, struct rt_metrics *, struct rt_kmetrics *);
> -void  rt_getmetrics(struct rt_kmetrics *, struct rt_metrics *);
> +void  rt_setmetrics(u_long, const struct rt_metrics *, struct rt_kmetrics *);
> +void  rt_getmetrics(const struct rt_kmetrics *, struct rt_metrics *);
>  
>  int                   rt_timer_add(struct rtentry *,
>                            void(*)(struct rtentry *, struct rttimer *),
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.188
> diff -u -p -r1.188 rtsock.c
> --- net/rtsock.c      30 Mar 2016 10:13:14 -0000      1.188
> +++ net/rtsock.c      27 May 2016 07:03:47 -0000
> @@ -931,22 +931,40 @@ route_arp_conflict(struct rt_addrinfo *i
>  }
>  
>  void
> -rt_setmetrics(u_long which, struct rt_metrics *in, struct rt_kmetrics *out)
> +rt_setmetrics(u_long which, const struct rt_metrics *in,
> +    struct rt_kmetrics *out)
>  {
> +     int64_t expire;
> +
>       if (which & RTV_MTU)
>               out->rmx_mtu = in->rmx_mtu;
> -     if (which & RTV_EXPIRE)
> -             out->rmx_expire = in->rmx_expire;
> +     if (which & RTV_EXPIRE) {
> +             expire = in->rmx_expire;
> +             if (expire != 0) {
> +                     expire -= time_second;
> +                     expire += time_uptime;
> +             }
> +
> +             out->rmx_expire = expire;
> +     }
>       /* RTV_PRIORITY handled before */
>  }
>  
>  void
> -rt_getmetrics(struct rt_kmetrics *in, struct rt_metrics *out)
> +rt_getmetrics(const struct rt_kmetrics *in, struct rt_metrics *out)
>  {
> +     int64_t expire;
> +
> +     expire = in->rmx_expire;
> +     if (expire != 0) {
> +             expire -= time_uptime;
> +             expire += time_second;
> +     }
> +
>       bzero(out, sizeof(*out));
>       out->rmx_locks = in->rmx_locks;
>       out->rmx_mtu = in->rmx_mtu;
> -     out->rmx_expire = in->rmx_expire;
> +     out->rmx_expire = expire;
>       out->rmx_pksent = in->rmx_pksent;
>  }
>  
> Index: netinet/if_ether.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/if_ether.c,v
> retrieving revision 1.209
> diff -u -p -r1.209 if_ether.c
> --- netinet/if_ether.c        23 May 2016 09:23:43 -0000      1.209
> +++ netinet/if_ether.c        27 May 2016 07:03:47 -0000
> @@ -114,7 +114,7 @@ arptimer(void *arg)
>       LIST_FOREACH_SAFE(la, &arp_list, la_list, nla) {
>               struct rtentry *rt = la->la_rt;
>  
> -             if (rt->rt_expire && rt->rt_expire <= time_second)
> +             if (rt->rt_expire && rt->rt_expire <= time_uptime)
>                       arptfree(rt); /* timer has expired; clear */
>       }
>       splx(s);
> @@ -158,7 +158,7 @@ arp_rtrequest(struct ifnet *ifp, int req
>                        * it's a "permanent" route, so that routes cloned
>                        * from it do not need their expiration time set.
>                        */
> -                     rt->rt_expire = time_second;
> +                     rt->rt_expire = time_uptime;
>                       if ((rt->rt_flags & RTF_CLONING) != 0)
>                               break;
>               }
> @@ -340,7 +340,7 @@ arpresolve(struct ifnet *ifp, struct rte
>        * Check the address family and length is valid, the address
>        * is resolved; otherwise, try to resolve.
>        */
> -     if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
> +     if ((rt->rt_expire == 0 || rt->rt_expire > time_uptime) &&
>           sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
>               memcpy(desten, LLADDR(sdl), sdl->sdl_alen);
>               if (created)
> @@ -376,13 +376,13 @@ arpresolve(struct ifnet *ifp, struct rte
>               /* This should never happen. (Should it? -gwr) */
>               printf("%s: unresolved and rt_expire == 0\n", __func__);
>               /* Set expiration time to now (expired). */
> -             rt->rt_expire = time_second;
> +             rt->rt_expire = time_uptime;
>       }
>  #endif
>       if (rt->rt_expire) {
>               rt->rt_flags &= ~RTF_REJECT;
> -             if (la->la_asked == 0 || rt->rt_expire != time_second) {
> -                     rt->rt_expire = time_second;
> +             if (la->la_asked == 0 || rt->rt_expire != time_uptime) {
> +                     rt->rt_expire = time_uptime;
>                       if (la->la_asked++ < arp_maxtries)
>                               arprequest(ifp,
>                                   
> &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr,
> @@ -618,7 +618,7 @@ arpcache(struct ifnet *ifp, struct ether
>       sdl->sdl_alen = sizeof(ea->arp_sha);
>       memcpy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
>       if (rt->rt_expire)
> -             rt->rt_expire = time_second + arpt_keep;
> +             rt->rt_expire = time_uptime + arpt_keep;
>       rt->rt_flags &= ~RTF_REJECT;
>  
>       /* Notify userland that an ARP resolution has been done. */
> 

Reply via email to