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.

ok?

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