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. */
>