diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2016-06-03 02:57:00 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2016-06-03 02:57:00 +0000 |
commit | 3a0e6a46a211c4aa0d2a9a84d401bf0e5b3f5c00 (patch) | |
tree | 47bc14a641ed4bfc6faec38b5599d7b61ee05b65 | |
parent | c4c7bdfa5d8189e7231f83b4c495821a785afe81 (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.c | 6 | ||||
-rw-r--r-- | sys/net/route.h | 6 | ||||
-rw-r--r-- | sys/net/rtsock.c | 30 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 23 |
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. */ |