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