summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-06-03 02:57:00 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-06-03 02:57:00 +0000
commit3a0e6a46a211c4aa0d2a9a84d401bf0e5b3f5c00 (patch)
tree47bc14a641ed4bfc6faec38b5599d7b61ee05b65
parentc4c7bdfa5d8189e7231f83b4c495821a785afe81 (diff)
set rt_expire times against time_uptime, not time_second.
time_second is unix time so it can be affected by clock changes. time_uptime is monotonic so it isnt affected by clock changes. that in turn means route expiries wont jump with clock changes if set against time_uptime. the expiry is translated into unix time for export to userland though. ok mpi@
-rw-r--r--sys/net/route.c6
-rw-r--r--sys/net/route.h6
-rw-r--r--sys/net/rtsock.c30
-rw-r--r--sys/netinet/if_ether.c23
4 files changed, 38 insertions, 27 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 38286b8f605..a23f8702311 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.303 2016/06/01 06:40:27 dlg Exp $ */
+/* $OpenBSD: route.c,v 1.304 2016/06/03 02:56:59 dlg Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -1186,7 +1186,7 @@ rt_checkgate(struct rtentry *rt, struct rtentry **rtp)
}
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;
@@ -1541,7 +1541,7 @@ rt_timer_add(struct rtentry *rt, void (*func)(struct rtentry *,
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
diff --git a/sys/net/route.h b/sys/net/route.h
index 0332c26379e..940d473577f 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.135 2016/04/27 14:47:27 mpi Exp $ */
+/* $OpenBSD: route.h,v 1.136 2016/06/03 02:56:59 dlg Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -364,8 +364,8 @@ void rt_sendaddrmsg(struct rtentry *, int);
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 *),
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 35a819b18a2..f3018d85cf6 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.189 2016/06/01 12:06:49 mpi Exp $ */
+/* $OpenBSD: rtsock.c,v 1.190 2016/06/03 02:56:59 dlg Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -931,22 +931,40 @@ route_arp_conflict(struct rt_addrinfo *info, unsigned int tableid)
}
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;
}
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index f7f418287d9..1992c3a041d 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ether.c,v 1.210 2016/05/31 07:50:34 mpi Exp $ */
+/* $OpenBSD: if_ether.c,v 1.211 2016/06/03 02:56:59 dlg Exp $ */
/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
/*
@@ -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);
@@ -133,13 +133,6 @@ arp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
arpinit_done = 1;
pool_init(&arp_pool, sizeof(struct llinfo_arp), 0, 0, 0, "arp",
NULL);
- /*
- * We generate expiration times from time.tv_sec
- * so avoid accidently creating permanent routes.
- */
- if (time_second == 0) {
- time_second++;
- }
timeout_set(&arptimer_to, arptimer, &arptimer_to);
timeout_add_sec(&arptimer_to, 1);
@@ -158,7 +151,7 @@ arp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
* 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;
}
@@ -319,7 +312,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
* 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);
return (0);
@@ -358,13 +351,13 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
/* 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,
@@ -597,7 +590,7 @@ arpcache(struct ifnet *ifp, struct ether_arp *ea, struct rtentry *rt)
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. */