summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtadvd
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2013-08-05 20:13:02 +0000
committerhrs <hrs@FreeBSD.org>2013-08-05 20:13:02 +0000
commit13c1bcf2c1d5fbdca99cdddec726f822b68dddbc (patch)
treec3af796aa3d9d6e1a9fa48bdec823e34beac7892 /usr.sbin/rtadvd
parent103825c951713677489b0556d7cd86852ec2969c (diff)
downloadFreeBSD-src-13c1bcf2c1d5fbdca99cdddec726f822b68dddbc.zip
FreeBSD-src-13c1bcf2c1d5fbdca99cdddec726f822b68dddbc.tar.gz
- Use time_uptime instead of time_second in data structures for
PF_INET6 in kernel. This fixes various malfunction when the wall time clock is changed. Bump __FreeBSD_version to 1000041. - Use clock_gettime(CLOCK_MONOTONIC_FAST) in userland utilities. MFC after: 1 month
Diffstat (limited to 'usr.sbin/rtadvd')
-rw-r--r--usr.sbin/rtadvd/config.c20
-rw-r--r--usr.sbin/rtadvd/rrenum.c9
-rw-r--r--usr.sbin/rtadvd/rtadvd.c41
-rw-r--r--usr.sbin/rtadvd/rtadvd.h4
-rw-r--r--usr.sbin/rtadvd/timer.c45
-rw-r--r--usr.sbin/rtadvd/timer.h10
-rw-r--r--usr.sbin/rtadvd/timer_subr.c49
-rw-r--r--usr.sbin/rtadvd/timer_subr.h44
8 files changed, 99 insertions, 123 deletions
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c
index d10829a..bb4aaec 100644
--- a/usr.sbin/rtadvd/config.c
+++ b/usr.sbin/rtadvd/config.c
@@ -34,7 +34,6 @@
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -58,6 +57,7 @@
#include <string.h>
#include <search.h>
#include <stdlib.h>
+#include <time.h>
#include <unistd.h>
#include <ifaddrs.h>
@@ -563,8 +563,9 @@ getconfig(struct ifinfo *ifi)
makeentry(entbuf, sizeof(entbuf), i, "vltimedecr");
if (agetflag(entbuf)) {
- struct timeval now;
- gettimeofday(&now, 0);
+ struct timespec now;
+
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
pfx->pfx_vltimeexpire =
now.tv_sec + pfx->pfx_validlifetime;
}
@@ -583,8 +584,9 @@ getconfig(struct ifinfo *ifi)
makeentry(entbuf, sizeof(entbuf), i, "pltimedecr");
if (agetflag(entbuf)) {
- struct timeval now;
- gettimeofday(&now, 0);
+ struct timespec now;
+
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
pfx->pfx_pltimeexpire =
now.tv_sec + pfx->pfx_preflifetime;
}
@@ -1164,7 +1166,7 @@ delete_prefix(struct prefix *pfx)
void
invalidate_prefix(struct prefix *pfx)
{
- struct timeval timo;
+ struct timespec timo;
struct rainfo *rai;
struct ifinfo *ifi;
char ntopbuf[INET6_ADDRSTRLEN];
@@ -1191,7 +1193,7 @@ invalidate_prefix(struct prefix *pfx)
delete_prefix(pfx);
}
timo.tv_sec = prefix_timo;
- timo.tv_usec = 0;
+ timo.tv_nsec = 0;
rtadvd_set_timer(&timo, pfx->pfx_timer);
}
@@ -1415,7 +1417,7 @@ make_packet(struct rainfo *rai)
TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
uint32_t vltime, pltime;
- struct timeval now;
+ struct timespec now;
ndopt_pi = (struct nd_opt_prefix_info *)buf;
ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
@@ -1432,7 +1434,7 @@ make_packet(struct rainfo *rai)
vltime = 0;
else {
if (pfx->pfx_vltimeexpire || pfx->pfx_pltimeexpire)
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
if (pfx->pfx_vltimeexpire == 0)
vltime = pfx->pfx_validlifetime;
else
diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c
index a8fbbf2..0c97d98 100644
--- a/usr.sbin/rtadvd/rrenum.c
+++ b/usr.sbin/rtadvd/rrenum.c
@@ -49,6 +49,7 @@
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
+#include <time.h>
#include <syslog.h>
#include "rtadvd.h"
#include "rrenum.h"
@@ -215,7 +216,7 @@ do_use_prefix(int len, struct rr_pco_match *rpm,
rai = ifi->ifi_rainfo;
TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
- struct timeval now;
+ struct timespec now;
if (prefix_match(&pfx->pfx_prefix,
pfx->pfx_prefixlen, &rpm->rpm_prefix,
@@ -226,14 +227,16 @@ do_use_prefix(int len, struct rr_pco_match *rpm,
pfx->pfx_preflifetime =
ntohl(rpu->rpu_pltime);
if (irr->irr_rrf_decrvalid) {
- gettimeofday(&now, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST,
+ &now);
pfx->pfx_vltimeexpire =
now.tv_sec +
pfx->pfx_validlifetime;
} else
pfx->pfx_vltimeexpire = 0;
if (irr->irr_rrf_decrprefd) {
- gettimeofday(&now, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST,
+ &now);
pfx->pfx_pltimeexpire =
now.tv_sec +
pfx->pfx_preflifetime;
diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c
index c3420ef..ba71954 100644
--- a/usr.sbin/rtadvd/rtadvd.c
+++ b/usr.sbin/rtadvd/rtadvd.c
@@ -35,7 +35,6 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
-#include <sys/time.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
@@ -179,7 +178,7 @@ int
main(int argc, char *argv[])
{
struct pollfd set[PFD_MAX];
- struct timeval *timeout;
+ struct timespec *timeout;
int i, ch;
int fflag = 0, logopt;
int error;
@@ -331,7 +330,7 @@ main(int argc, char *argv[])
"<%s> set timer to %ld:%ld. waiting for "
"inputs or timeout", __func__,
(long int)timeout->tv_sec,
- (long int)timeout->tv_usec);
+ (long int)timeout->tv_nsec / 1000);
} else {
syslog(LOG_DEBUG,
"<%s> there's no timer. waiting for inputs",
@@ -339,7 +338,7 @@ main(int argc, char *argv[])
}
if ((i = poll(set, sizeof(set)/sizeof(set[0]),
timeout ? (timeout->tv_sec * 1000 +
- timeout->tv_usec / 1000) : INFTIM)) < 0) {
+ timeout->tv_nsec / 1000 / 1000) : INFTIM)) < 0) {
/* EINTR would occur if a signal was delivered */
if (errno != EINTR)
@@ -432,7 +431,7 @@ rtadvd_shutdown(void)
if (ifi->ifi_ra_timer == NULL)
continue;
if (ifi->ifi_ra_lastsent.tv_sec == 0 &&
- ifi->ifi_ra_lastsent.tv_usec == 0 &&
+ ifi->ifi_ra_lastsent.tv_nsec == 0 &&
ifi->ifi_ra_timer != NULL) {
/*
* When RA configured but never sent,
@@ -1006,7 +1005,7 @@ static void
set_short_delay(struct ifinfo *ifi)
{
long delay; /* must not be greater than 1000000 */
- struct timeval interval, now, min_delay, tm_tmp, *rest;
+ struct timespec interval, now, min_delay, tm_tmp, *rest;
if (ifi->ifi_ra_timer == NULL)
return;
@@ -1023,9 +1022,9 @@ set_short_delay(struct ifinfo *ifi)
delay = random() % MAX_RA_DELAY_TIME;
#endif
interval.tv_sec = 0;
- interval.tv_usec = delay;
+ interval.tv_nsec = delay * 1000;
rest = rtadvd_timer_rest(ifi->ifi_ra_timer);
- if (TIMEVAL_LT(rest, &interval)) {
+ if (TS_CMP(rest, &interval, <)) {
syslog(LOG_DEBUG, "<%s> random delay is larger than "
"the rest of the current timer", __func__);
interval = *rest;
@@ -1038,13 +1037,13 @@ set_short_delay(struct ifinfo *ifi)
* MIN_DELAY_BETWEEN_RAS plus the random value after the
* previous advertisement was sent.
*/
- gettimeofday(&now, NULL);
- TIMEVAL_SUB(&now, &ifi->ifi_ra_lastsent, &tm_tmp);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+ TS_SUB(&now, &ifi->ifi_ra_lastsent, &tm_tmp);
min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
- min_delay.tv_usec = 0;
- if (TIMEVAL_LT(&tm_tmp, &min_delay)) {
- TIMEVAL_SUB(&min_delay, &tm_tmp, &min_delay);
- TIMEVAL_ADD(&min_delay, &interval, &interval);
+ min_delay.tv_nsec = 0;
+ if (TS_CMP(&tm_tmp, &min_delay, <)) {
+ TS_SUB(&min_delay, &tm_tmp, &min_delay);
+ TS_ADD(&min_delay, &interval, &interval);
}
rtadvd_set_timer(&interval, ifi->ifi_ra_timer);
}
@@ -1242,7 +1241,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
int inconsistent = 0;
char ntopbuf[INET6_ADDRSTRLEN];
char prefixbuf[INET6_ADDRSTRLEN];
- struct timeval now;
+ struct timespec now;
#if 0 /* impossible */
if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION)
@@ -1285,7 +1284,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
* XXX: can we really expect that all routers on the link
* have synchronized clocks?
*/
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
preferred_time += now.tv_sec;
if (!pfx->pfx_timer && rai->rai_clockskew &&
@@ -1318,7 +1317,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
valid_time = ntohl(pinfo->nd_opt_pi_valid_time);
if (pfx->pfx_vltimeexpire) {
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
valid_time += now.tv_sec;
if (!pfx->pfx_timer && rai->rai_clockskew &&
@@ -1784,7 +1783,7 @@ ra_output(struct ifinfo *ifi)
}
/* update timestamp */
- gettimeofday(&ifi->ifi_ra_lastsent, NULL);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &ifi->ifi_ra_lastsent);
/* update counter */
ifi->ifi_rs_waitcount = 0;
@@ -1866,7 +1865,7 @@ ra_timeout(void *arg)
/* update RA timer */
void
-ra_timer_update(void *arg, struct timeval *tm)
+ra_timer_update(void *arg, struct timespec *tm)
{
uint16_t interval;
struct rainfo *rai;
@@ -1916,12 +1915,12 @@ ra_timer_update(void *arg, struct timeval *tm)
}
tm->tv_sec = interval;
- tm->tv_usec = 0;
+ tm->tv_nsec = 0;
syslog(LOG_DEBUG,
"<%s> RA timer on %s is set to %ld:%ld",
__func__, ifi->ifi_ifname,
- (long int)tm->tv_sec, (long int)tm->tv_usec);
+ (long int)tm->tv_sec, (long int)tm->tv_nsec / 1000);
return;
}
diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h
index ac8ce99..e7ed87f 100644
--- a/usr.sbin/rtadvd/rtadvd.h
+++ b/usr.sbin/rtadvd/rtadvd.h
@@ -270,7 +270,7 @@ struct ifinfo {
uint32_t ifi_burstinterval;
struct rtadvd_timer *ifi_ra_timer;
/* timestamp when the latest RA was sent */
- struct timeval ifi_ra_lastsent;
+ struct timespec ifi_ra_lastsent;
uint16_t ifi_rs_waitcount;
/* statistics */
@@ -286,7 +286,7 @@ extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
extern char *mcastif;
struct rtadvd_timer *ra_timeout(void *);
-void ra_timer_update(void *, struct timeval *);
+void ra_timer_update(void *, struct timespec *);
void ra_output(struct ifinfo *);
int prefix_match(struct in6_addr *, int,
diff --git a/usr.sbin/rtadvd/timer.c b/usr.sbin/rtadvd/timer.c
index 2ea77b5..faa541d 100644
--- a/usr.sbin/rtadvd/timer.c
+++ b/usr.sbin/rtadvd/timer.c
@@ -31,7 +31,6 @@
* SUCH DAMAGE.
*/
-#include <sys/time.h>
#include <sys/queue.h>
#include <sys/socket.h>
@@ -44,6 +43,7 @@
#include <stdlib.h>
#include <string.h>
#include <search.h>
+#include <time.h>
#include <netdb.h>
#include "rtadvd.h"
@@ -52,12 +52,17 @@
struct rtadvd_timer_head_t ra_timer =
TAILQ_HEAD_INITIALIZER(ra_timer);
-static struct timeval tm_limit = {0x7fffffff, 0x7fffffff};
-static struct timeval tm_max;
+static struct timespec tm_limit;
+static struct timespec tm_max;
void
rtadvd_timer_init(void)
{
+ /* Generate maximum time in timespec. */
+ memset(&tm_limit.tv_sec, 0xff, sizeof(tm_limit.tv_sec));
+ memset(&tm_limit.tv_nsec, 0xff, sizeof(tm_limit.tv_nsec));
+ tm_limit.tv_sec &= ~(1UL << (sizeof(tm_limit.tv_sec) * 8 - 1));
+ tm_limit.tv_nsec &= ~(1UL << (sizeof(tm_limit.tv_nsec) * 8 - 1));
tm_max = tm_limit;
TAILQ_INIT(&ra_timer);
@@ -102,7 +107,7 @@ rtadvd_update_timeout_handler(void)
struct rtadvd_timer *
rtadvd_add_timer(struct rtadvd_timer *(*timeout)(void *),
- void (*update)(void *, struct timeval *),
+ void (*update)(void *, struct timespec *),
void *timeodata, void *updatedata)
{
struct rtadvd_timer *rat;
@@ -149,48 +154,48 @@ rtadvd_remove_timer(struct rtadvd_timer *rat)
* call the expire function for the timer and update the timer.
* Return the next interval for select() call.
*/
-struct timeval *
+struct timespec *
rtadvd_check_timer(void)
{
- static struct timeval returnval;
- struct timeval now;
+ static struct timespec returnval;
+ struct timespec now;
struct rtadvd_timer *rat;
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
tm_max = tm_limit;
TAILQ_FOREACH(rat, &ra_timer, rat_next) {
- if (TIMEVAL_LEQ(&rat->rat_tm, &now)) {
+ if (TS_CMP(&rat->rat_tm, &now, <=)) {
if (((*rat->rat_expire)(rat->rat_expire_data) == NULL))
continue; /* the timer was removed */
if (rat->rat_update)
(*rat->rat_update)(rat->rat_update_data, &rat->rat_tm);
- TIMEVAL_ADD(&rat->rat_tm, &now, &rat->rat_tm);
+ TS_ADD(&rat->rat_tm, &now, &rat->rat_tm);
}
- if (TIMEVAL_LT(&rat->rat_tm, &tm_max))
+ if (TS_CMP(&rat->rat_tm, &tm_max, <))
tm_max = rat->rat_tm;
}
- if (TIMEVAL_EQUAL(&tm_max, &tm_limit)) {
+ if (TS_CMP(&tm_max, &tm_limit, ==)) {
/* no need to timeout */
return (NULL);
- } else if (TIMEVAL_LT(&tm_max, &now)) {
+ } else if (TS_CMP(&tm_max, &now, <)) {
/* this may occur when the interval is too small */
- returnval.tv_sec = returnval.tv_usec = 0;
+ returnval.tv_sec = returnval.tv_nsec = 0;
} else
- TIMEVAL_SUB(&tm_max, &now, &returnval);
+ TS_SUB(&tm_max, &now, &returnval);
return (&returnval);
}
void
-rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *rat)
+rtadvd_set_timer(struct timespec *tm, struct rtadvd_timer *rat)
{
- struct timeval now;
+ struct timespec now;
/* reset the timer */
- gettimeofday(&now, NULL);
- TIMEVAL_ADD(&now, tm, &rat->rat_tm);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+ TS_ADD(&now, tm, &rat->rat_tm);
/* update the next expiration time */
- if (TIMEVAL_LT(&rat->rat_tm, &tm_max))
+ if (TS_CMP(&rat->rat_tm, &tm_max, <))
tm_max = rat->rat_tm;
return;
diff --git a/usr.sbin/rtadvd/timer.h b/usr.sbin/rtadvd/timer.h
index f70e0d1..4498aaf 100644
--- a/usr.sbin/rtadvd/timer.h
+++ b/usr.sbin/rtadvd/timer.h
@@ -35,18 +35,18 @@ struct rtadvd_timer {
TAILQ_ENTRY(rtadvd_timer) rat_next;
struct rainfo *rat_rai;
- struct timeval rat_tm;
+ struct timespec rat_tm;
struct rtadvd_timer *(*rat_expire)(void *);
void *rat_expire_data;
- void (*rat_update)(void *, struct timeval *);
+ void (*rat_update)(void *, struct timespec *);
void *rat_update_data;
};
void rtadvd_timer_init(void);
void rtadvd_update_timeout_handler(void);
struct rtadvd_timer *rtadvd_add_timer(struct rtadvd_timer *(*)(void *),
- void (*)(void *, struct timeval *), void *, void *);
-void rtadvd_set_timer(struct timeval *,
+ void (*)(void *, struct timespec *), void *, void *);
+void rtadvd_set_timer(struct timespec *,
struct rtadvd_timer *);
void rtadvd_remove_timer(struct rtadvd_timer *);
-struct timeval *rtadvd_check_timer(void);
+struct timespec *rtadvd_check_timer(void);
diff --git a/usr.sbin/rtadvd/timer_subr.c b/usr.sbin/rtadvd/timer_subr.c
index 2bebdd3..0ddf0a4 100644
--- a/usr.sbin/rtadvd/timer_subr.c
+++ b/usr.sbin/rtadvd/timer_subr.c
@@ -30,69 +30,34 @@
* SUCH DAMAGE.
*/
-#include <sys/time.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <syslog.h>
#include <stdio.h>
#include <inttypes.h>
+#include <time.h>
#include "timer.h"
#include "timer_subr.h"
-struct timeval *
+struct timespec *
rtadvd_timer_rest(struct rtadvd_timer *rat)
{
- static struct timeval returnval, now;
+ static struct timespec returnval, now;
- gettimeofday(&now, NULL);
- if (TIMEVAL_LEQ(&rat->rat_tm, &now)) {
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+ if (TS_CMP(&rat->rat_tm, &now, <=)) {
syslog(LOG_DEBUG,
"<%s> a timer must be expired, but not yet",
__func__);
- returnval.tv_sec = returnval.tv_usec = 0;
+ returnval.tv_sec = returnval.tv_nsec = 0;
}
else
- TIMEVAL_SUB(&rat->rat_tm, &now, &returnval);
+ TS_SUB(&rat->rat_tm, &now, &returnval);
return (&returnval);
}
-/* result = a + b */
-void
-TIMEVAL_ADD(struct timeval *a, struct timeval *b, struct timeval *result)
-{
- long l;
-
- if ((l = a->tv_usec + b->tv_usec) < MILLION) {
- result->tv_usec = l;
- result->tv_sec = a->tv_sec + b->tv_sec;
- }
- else {
- result->tv_usec = l - MILLION;
- result->tv_sec = a->tv_sec + b->tv_sec + 1;
- }
-}
-
-/*
- * result = a - b
- * XXX: this function assumes that a >= b.
- */
-void
-TIMEVAL_SUB(struct timeval *a, struct timeval *b, struct timeval *result)
-{
- long l;
-
- if ((l = a->tv_usec - b->tv_usec) >= 0) {
- result->tv_usec = l;
- result->tv_sec = a->tv_sec - b->tv_sec;
- }
- else {
- result->tv_usec = MILLION + l;
- result->tv_sec = a->tv_sec - b->tv_sec - 1;
- }
-}
-
char *
sec2str(uint32_t s, char *buf)
{
diff --git a/usr.sbin/rtadvd/timer_subr.h b/usr.sbin/rtadvd/timer_subr.h
index 9ceddad..32e1bb1 100644
--- a/usr.sbin/rtadvd/timer_subr.h
+++ b/usr.sbin/rtadvd/timer_subr.h
@@ -31,27 +31,29 @@
*/
#define SSBUFLEN 1024
-#define MILLION 1000000
-/* a < b */
-#define TIMEVAL_LT(a, b) \
- (((a)->tv_sec < (b)->tv_sec) || \
- (((a)->tv_sec == (b)->tv_sec) && \
- ((a)->tv_usec < (b)->tv_usec)))
+#define TS_CMP(tsp, usp, cmp) \
+ (((tsp)->tv_sec == (usp)->tv_sec) ? \
+ ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
+ ((tsp)->tv_sec cmp (usp)->tv_sec))
+#define TS_ADD(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec >= 1000000000L) { \
+ (vsp)->tv_sec++; \
+ (vsp)->tv_nsec -= 1000000000L; \
+ } \
+ } while (0)
+#define TS_SUB(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec < 0) { \
+ (vsp)->tv_sec--; \
+ (vsp)->tv_nsec += 1000000000L; \
+ } \
+ } while (0)
-/* a <= b */
-#define TIMEVAL_LEQ(a, b) \
- (((a)->tv_sec < (b)->tv_sec) || \
- (((a)->tv_sec == (b)->tv_sec) && \
- ((a)->tv_usec <= (b)->tv_usec)))
-
-#define TIMEVAL_EQUAL(a,b) \
- (((a)->tv_sec == (b)->tv_sec) && \
- ((a)->tv_usec == (b)->tv_usec))
-
-struct timeval *rtadvd_timer_rest(struct rtadvd_timer *);
-void TIMEVAL_ADD(struct timeval *, struct timeval *,
- struct timeval *);
-void TIMEVAL_SUB(struct timeval *, struct timeval *,
- struct timeval *);
+struct timespec *rtadvd_timer_rest(struct rtadvd_timer *);
char *sec2str(uint32_t, char *buf);
OpenPOWER on IntegriCloud