Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Use time_uptime instead of time_second to avoid time leaps



details:   https://anonhg.NetBSD.org/src/rev/b42f74b18c86
branches:  trunk
changeset: 809878:b42f74b18c86
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Fri Aug 07 08:11:33 2015 +0000

description:
Use time_uptime instead of time_second to avoid time leaps

Some codes in sys/net* use time_second to manage time periods such as
cache expirations. However, time_second doesn't increase monotonically
and can leap by say settimeofday(2) according to time_second(9). We
should use time_uptime instead of it to avoid such time leaps.

This change replaces time_second with time_uptime. Additionally it
converts a time based on time_uptime to a time based on time_second
when the kernel passes the time to userland programs that expect
the latter, and vice versa.

Note that we shouldn't leak time_uptime to other hosts over the
netowrk. My investigation shows there is no such leak:
http://mail-index.netbsd.org/tech-net/2015/08/06/msg005332.html

Discussed on tech-kern and tech-net.

diffstat:

 sys/net/rtsock.c           |  12 ++++++++----
 sys/netinet/if_arp.c       |  35 +++++++++++++----------------------
 sys/netinet/ip_input.c     |   6 +++---
 sys/netinet/ip_output.c    |   6 +++---
 sys/netinet6/icmp6.c       |   8 ++++----
 sys/netinet6/in6.c         |  31 ++++++++++++++++++++++++-------
 sys/netinet6/in6.h         |   6 +++---
 sys/netinet6/ip6_forward.c |   8 ++++----
 sys/netinet6/ip6_id.c      |   8 ++++----
 sys/netinet6/ip6_mroute.c  |   8 ++++----
 sys/netinet6/nd6.c         |  31 ++++++++++++++++++-------------
 sys/netinet6/nd6_rtr.c     |  36 ++++++++++++++++++------------------
 sys/sys/timevar.h          |  14 +++++++++++++-
 13 files changed, 119 insertions(+), 90 deletions(-)

diffs (truncated from 727 to 300 lines):

diff -r 9c6d46f5589c -r b42f74b18c86 sys/net/rtsock.c
--- a/sys/net/rtsock.c  Fri Aug 07 07:34:56 2015 +0000
+++ b/sys/net/rtsock.c  Fri Aug 07 08:11:33 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtsock.c,v 1.172 2015/07/17 02:21:08 ozaki-r Exp $     */
+/*     $NetBSD: rtsock.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.172 2015/07/17 02:21:08 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -717,8 +717,11 @@
        metric(RTV_RTTVAR, rmx_rttvar);
        metric(RTV_HOPCOUNT, rmx_hopcount);
        metric(RTV_MTU, rmx_mtu);
-       metric(RTV_EXPIRE, rmx_expire);
 #undef metric
+       if (which & RTV_EXPIRE) {
+               out->rt_rmx.rmx_expire = in->rtm_rmx.rmx_expire ?
+                   time_wall_to_mono(in->rtm_rmx.rmx_expire) : 0;
+       }
 }
 
 static void
@@ -732,8 +735,9 @@
        metric(rmx_rttvar);
        metric(rmx_hopcount);
        metric(rmx_mtu);
-       metric(rmx_expire);
 #undef metric
+       out->rtm_rmx.rmx_expire = in->rt_rmx.rmx_expire ?
+           time_mono_to_wall(in->rt_rmx.rmx_expire) : 0;
 }
 
 static int
diff -r 9c6d46f5589c -r b42f74b18c86 sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c      Fri Aug 07 07:34:56 2015 +0000
+++ b/sys/netinet/if_arp.c      Fri Aug 07 08:11:33 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_arp.c,v 1.170 2015/07/15 08:49:15 ozaki-r Exp $     */
+/*     $NetBSD: if_arp.c,v 1.171 2015/08/07 08:11:33 ozaki-r Exp $     */
 
 /*-
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.170 2015/07/15 08:49:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.171 2015/08/07 08:11:33 ozaki-r Exp $");
 
 #include "opt_ddb.h"
 #include "opt_inet.h"
@@ -429,8 +429,8 @@
 
                if (rt->rt_expire == 0)
                        continue;
-               if ((rt->rt_expire - time_second) < arpt_refresh &&
-                   rt->rt_pksent > (time_second - arpt_keep)) {
+               if ((rt->rt_expire - time_uptime) < arpt_refresh &&
+                   rt->rt_pksent > (time_uptime - arpt_keep)) {
                        /*
                         * If the entry has been used during since last
                         * refresh, try to renew it before deleting.
@@ -439,7 +439,7 @@
                            &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
                            &satocsin(rt_getkey(rt))->sin_addr,
                            CLLADDR(rt->rt_ifp->if_sadl));
-               } else if (rt->rt_expire <= time_second)
+               } else if (rt->rt_expire <= time_uptime)
                        arptfree(la); /* timer has expired; clear */
        }
 
@@ -506,16 +506,6 @@
 
        if (!arpinit_done) {
                arpinit_done = 1;
-               /*
-                * We generate expiration times from time_second
-                * so avoid accidentally creating permanent routes.
-                */
-               if (time_second == 0) {
-                       struct timespec ts;
-                       ts.tv_sec = 1;
-                       ts.tv_nsec = 0;
-                       tc_setclock(&ts);
-               }
                callout_init(&arptimer_ch, CALLOUT_MPSAFE);
                callout_reset(&arptimer_ch, hz, arptimer, NULL);
        }
@@ -589,7 +579,8 @@
                         * it's a "permanent" route, so that routes cloned
                         * from it do not need their expiration time set.
                         */
-                       rt->rt_expire = time_second;
+                       KASSERT(time_uptime != 0);
+                       rt->rt_expire = time_uptime;
                        /*
                         * linklayers with particular link MTU limitation.
                         */
@@ -844,11 +835,11 @@
         * 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, CLLADDR(sdl),
                    min(sdl->sdl_alen, ifp->if_addrlen));
-               rt->rt_pksent = time_second; /* Time for last pkt sent */
+               rt->rt_pksent = time_uptime; /* Time for last pkt sent */
                return 1;
        }
        /*
@@ -876,13 +867,13 @@
                /* This should never happen. (Should it? -gwr) */
                printf("arpresolve: unresolved and rt_expire == 0\n");
                /* 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,
                                    &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
@@ -1234,7 +1225,7 @@
                (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, ar_sha(ah),
                    ah->ar_hln);
                if (rt->rt_expire)
-                       rt->rt_expire = time_second + arpt_keep;
+                       rt->rt_expire = time_uptime + arpt_keep;
                rt->rt_flags &= ~RTF_REJECT;
                la->la_asked = 0;
 
diff -r 9c6d46f5589c -r b42f74b18c86 sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c    Fri Aug 07 07:34:56 2015 +0000
+++ b/sys/netinet/ip_input.c    Fri Aug 07 08:11:33 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_input.c,v 1.322 2015/05/02 20:22:12 joerg Exp $     */
+/*     $NetBSD: ip_input.c,v 1.323 2015/08/07 08:11:33 ozaki-r Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.322 2015/05/02 20:22:12 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.323 2015/08/07 08:11:33 ozaki-r Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -319,7 +319,7 @@
        ip_reass_init();
 
        ip_ids = ip_id_init();
-       ip_id = time_second & 0xfffff;
+       ip_id = time_uptime & 0xfffff;
 
        ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout);
 #ifdef GATEWAY
diff -r 9c6d46f5589c -r b42f74b18c86 sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c   Fri Aug 07 07:34:56 2015 +0000
+++ b/sys/netinet/ip_output.c   Fri Aug 07 08:11:33 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_output.c,v 1.244 2015/07/17 02:21:08 ozaki-r Exp $  */
+/*     $NetBSD: ip_output.c,v 1.245 2015/08/07 08:11:33 ozaki-r Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.244 2015/07/17 02:21:08 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.245 2015/08/07 08:11:33 ozaki-r Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -274,7 +274,7 @@
        }
        if ((rt->rt_flags & RTF_REJECT) != 0) {
                if (rt->rt_rmx.rmx_expire == 0 ||
-                   time_second < rt->rt_rmx.rmx_expire) {
+                   time_uptime < rt->rt_rmx.rmx_expire) {
                        error = (rt == rt0) ? EHOSTDOWN : EHOSTUNREACH;
                        goto bad;
                }
diff -r 9c6d46f5589c -r b42f74b18c86 sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c      Fri Aug 07 07:34:56 2015 +0000
+++ b/sys/netinet6/icmp6.c      Fri Aug 07 08:11:33 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: icmp6.c,v 1.172 2015/07/24 07:36:29 ozaki-r Exp $      */
+/*     $NetBSD: icmp6.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $      */
 /*     $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.172 2015/07/24 07:36:29 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.173 2015/08/07 08:11:33 ozaki-r Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -1812,9 +1812,9 @@
                                ltime = ND6_INFINITE_LIFETIME;
                        else {
                                if (ifa6->ia6_lifetime.ia6t_expire >
-                                   time_second)
+                                   time_uptime)
                                        ltime = ifa6->ia6_lifetime.ia6t_expire -
-                                           time_second;
+                                           time_uptime;
                                else
                                        ltime = 0;
                        }
diff -r 9c6d46f5589c -r b42f74b18c86 sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Fri Aug 07 07:34:56 2015 +0000
+++ b/sys/netinet6/in6.c        Fri Aug 07 08:11:33 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.188 2015/04/22 19:46:08 roy Exp $    */
+/*     $NetBSD: in6.c,v 1.189 2015/08/07 08:11:33 ozaki-r Exp $        */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.188 2015/04/22 19:46:08 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.189 2015/08/07 08:11:33 ozaki-r Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -507,6 +507,9 @@
                            maxexpire - ia->ia6_updatetime) {
                                retlt->ia6t_expire = ia->ia6_updatetime +
                                    ia->ia6_lifetime.ia6t_vltime;
+                               retlt->ia6t_expire = retlt->ia6t_expire ?
+                                   time_mono_to_wall(retlt->ia6t_expire) :
+                                   0;
                        } else
                                retlt->ia6t_expire = maxexpire;
                }
@@ -525,6 +528,9 @@
                            maxexpire - ia->ia6_updatetime) {
                                retlt->ia6t_preferred = ia->ia6_updatetime +
                                    ia->ia6_lifetime.ia6t_pltime;
+                               retlt->ia6t_preferred = retlt->ia6t_preferred ?
+                                   time_mono_to_wall(retlt->ia6t_preferred) :
+                                   0;
                        } else
                                retlt->ia6t_preferred = maxexpire;
                }
@@ -545,6 +551,7 @@
                int i;
                struct nd_prefixctl prc0;
                struct nd_prefix *pr;
+               struct in6_addrlifetime *lt;
 
                /* reject read-only flags */
                if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
@@ -555,6 +562,16 @@
                        return EINVAL;
                }
                /*
+                * ia6t_expire and ia6t_preferred won't be used for now,
+                * so just in case.
+                */
+               lt = &ifra->ifra_lifetime;
+               if (lt->ia6t_expire != 0)
+                       lt->ia6t_expire = time_wall_to_mono(lt->ia6t_expire);
+               if (lt->ia6t_preferred != 0)
+                       lt->ia6t_preferred =
+                           time_wall_to_mono(lt->ia6t_preferred);
+               /*
                 * first, make or update the interface address structure,
                 * and link it to the list.
                 */
@@ -878,7 +895,7 @@
                ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
                ia->ia_addr.sin6_family = AF_INET6;
                ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
-               ia->ia6_createtime = time_second;
+               ia->ia6_createtime = time_uptime;



Home | Main Index | Thread Index | Old Index