From: Markus Pargmann <mpa@pengutronix.de>
To: ptxdist@pengutronix.de
Cc: Markus Pargmann <mpa@pengutronix.de>
Subject: [ptxdist] [PATCH 1/4] radvd: Initial commit
Date: Tue, 17 Jun 2014 10:25:15 +0200 [thread overview]
Message-ID: <1402993518-27068-1-git-send-email-mpa@pengutronix.de> (raw)
Add radvd as package to ptxdist. Version 1.12 is used. A necessary patch
for not continous time is added which is not mainline yet.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
...ime-Use-clock_gettime-and-monotonic-clock.patch | 269 +++++++++++++++++++++
patches/radvd-1.12/series | 4 +
rules/radvd.in | 8 +
rules/radvd.make | 67 +++++
4 files changed, 348 insertions(+)
create mode 100644 patches/radvd-1.12/0001-time-Use-clock_gettime-and-monotonic-clock.patch
create mode 100644 patches/radvd-1.12/series
create mode 100644 rules/radvd.in
create mode 100644 rules/radvd.make
diff --git a/patches/radvd-1.12/0001-time-Use-clock_gettime-and-monotonic-clock.patch b/patches/radvd-1.12/0001-time-Use-clock_gettime-and-monotonic-clock.patch
new file mode 100644
index 000000000000..76636ed33d93
--- /dev/null
+++ b/patches/radvd-1.12/0001-time-Use-clock_gettime-and-monotonic-clock.patch
@@ -0,0 +1,269 @@
+From b65ed3db454d35053bfe40d3216a14c8a1b33eda Mon Sep 17 00:00:00 2001
+From: Markus Pargmann <mpa@pengutronix.de>
+Date: Fri, 13 Jun 2014 16:11:32 +0200
+Subject: [PATCH for 1.12] time: Use clock_gettime and monotonic clock
+
+Currently the system time is used to calculate the timeout in
+milliseconds for the poll function. This can lead to bugs as soon as the
+time of the system changes through NTP. For example starting radvd
+before NTP can lead to a 44 year jump, resulting in a poll timeout of
+10^6 seconds.
+
+This patch replaces all gettimeofday() usage by the better clock_gettime
+call using a monotonic clock which avoids those situations.
+
+Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
+---
+
+This is the patch for 1.12, in case there is some stable release in the future.
+I will send a patch for 2.0 later.
+
+Regards,
+
+Markus
+
+
+ includes.h | 1 +
+ process.c | 12 ++++++------
+ radvd.c | 8 ++++----
+ radvd.h | 12 ++++++------
+ send.c | 24 ++++++------------------
+ timer.c | 35 +++++++++++++++++++----------------
+ 6 files changed, 42 insertions(+), 50 deletions(-)
+
+diff --git a/includes.h b/includes.h
+index 2111e6651d31..d621b5ee585e 100644
+--- a/includes.h
++++ b/includes.h
+@@ -21,6 +21,7 @@
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
++#include <stdint.h>
+ #include <time.h>
+ #include <syslog.h>
+ #include <unistd.h>
+diff --git a/process.c b/process.c
+index 53a1150c2091..91011d036528 100644
+--- a/process.c
++++ b/process.c
+@@ -119,7 +119,7 @@ static void process_rs(struct Interface *iface, unsigned char *msg, int len, str
+ {
+ double delay;
+ double next;
+- struct timeval tv;
++ struct timespec ts;
+ uint8_t *opt_str;
+
+ /* validation */
+@@ -154,22 +154,22 @@ static void process_rs(struct Interface *iface, unsigned char *msg, int len, str
+ opt_str += optlen;
+ }
+
+- gettimeofday(&tv, NULL);
++ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ delay = MAX_RA_DELAY_TIME * rand() / (RAND_MAX + 1.0);
+
+ if (iface->UnicastOnly) {
+ send_ra_forall(iface, &addr->sin6_addr);
+- } else if (timevaldiff(&tv, &iface->last_multicast) / 1000.0 < iface->MinDelayBetweenRAs) {
++ } else if (timespecdiff(&ts, &iface->last_multicast) / 1000.0 < iface->MinDelayBetweenRAs) {
+ /* last RA was sent only a few moments ago, don't send another immediately. */
+ next =
+- iface->MinDelayBetweenRAs - (tv.tv_sec + tv.tv_usec / 1000000.0) + (iface->last_multicast.tv_sec + iface->last_multicast.tv_usec / 1000000.0) + delay / 1000.0;
+- iface->next_multicast = next_timeval(next);
++ iface->MinDelayBetweenRAs - (ts.tv_sec + ts.tv_nsec / 1000000000.0) + (iface->last_multicast.tv_sec + iface->last_multicast.tv_nsec / 1000000000.0) + delay / 1000.0;
++ iface->next_multicast = next_timespec(next);
+ } else {
+ /* no RA sent in a while, send a multicast reply */
+ send_ra_forall(iface, NULL);
+ next = rand_between(iface->MinRtrAdvInterval, iface->MaxRtrAdvInterval);
+- iface->next_multicast = next_timeval(next);
++ iface->next_multicast = next_timespec(next);
+ }
+ }
+
+diff --git a/radvd.c b/radvd.c
+index ab275efee40f..fcea72a2eea0 100644
+--- a/radvd.c
++++ b/radvd.c
+@@ -470,7 +470,7 @@ void timer_handler(void *data)
+ next = min(MAX_INITIAL_RTR_ADVERT_INTERVAL, next);
+ }
+
+- iface->next_multicast = next_timeval(next);
++ iface->next_multicast = next_timespec(next);
+ }
+
+ void config_interface(void)
+@@ -499,12 +499,12 @@ void kickoff_adverts(void)
+ for (iface = IfaceList; iface; iface = iface->next) {
+ double next;
+
+- gettimeofday(&iface->last_ra_time, NULL);
++ clock_gettime(CLOCK_MONOTONIC, &iface->last_ra_time);
+
+ if (iface->UnicastOnly)
+ continue;
+
+- gettimeofday(&iface->last_multicast, NULL);
++ clock_gettime(CLOCK_MONOTONIC, &iface->last_multicast);
+
+ /* TODO: AdvSendAdvert is being checked in send_ra now so it can be removed here. */
+ if (!iface->AdvSendAdvert)
+@@ -516,7 +516,7 @@ void kickoff_adverts(void)
+ iface->init_racount++;
+
+ next = min(MAX_INITIAL_RTR_ADVERT_INTERVAL, iface->MaxRtrAdvInterval);
+- iface->next_multicast = next_timeval(next);
++ iface->next_multicast = next_timespec(next);
+ }
+ }
+ }
+diff --git a/radvd.h b/radvd.h
+index d3b6957cff24..8db4b9dbe1c6 100644
+--- a/radvd.h
++++ b/radvd.h
+@@ -50,7 +50,7 @@ struct Interface {
+
+ int cease_adv;
+
+- struct timeval last_ra_time;
++ struct timespec last_ra_time;
+
+ int IgnoreIfMissing;
+ int AdvSendAdvert;
+@@ -87,8 +87,8 @@ struct Interface {
+ struct AdvRDNSS *AdvRDNSSList;
+ struct AdvDNSSL *AdvDNSSLList;
+ struct Clients *ClientList;
+- struct timeval last_multicast;
+- struct timeval next_multicast;
++ struct timespec last_multicast;
++ struct timespec next_multicast;
+
+ /* Info whether this interface has failed in the past (and may need to be reinitialized) */
+ int HasFailed;
+@@ -212,9 +212,9 @@ void reload_config(void);
+ void reset_prefix_lifetimes(void);
+
+ /* timer.c */
+-struct timeval next_timeval(double next);
+-int timevaldiff(struct timeval const *a, struct timeval const *b);
+-int next_time_msec(struct Interface const *iface);
++struct timespec next_timespec(double next);
++int64_t timespecdiff(struct timespec const *a, struct timespec const *b);
++uint64_t next_time_msec(struct Interface const *iface);
+ int expired(struct Interface const *iface);
+
+ /* device.c */
+diff --git a/send.c b/send.c
+index fb14184d9d84..eaa9506bf6a0 100644
+--- a/send.c
++++ b/send.c
+@@ -76,18 +76,6 @@ static void send_ra_inc_len(size_t * len, int add)
+ }
+ }
+
+-static time_t time_diff_secs(const struct timeval *time_x, const struct timeval *time_y)
+-{
+- time_t secs_diff;
+-
+- secs_diff = time_x->tv_sec - time_y->tv_sec;
+- if ((time_x->tv_usec - time_y->tv_usec) >= 500000)
+- secs_diff++;
+-
+- return secs_diff;
+-
+-}
+-
+ static void decrement_lifetime(const time_t secs, uint32_t * lifetime)
+ {
+
+@@ -118,8 +106,8 @@ int send_ra(struct Interface *iface, struct in6_addr *dest)
+ struct AdvDNSSL *dnssl;
+ struct AdvLowpanCo *lowpanco;
+ struct AdvAbro *abroo;
+- struct timeval time_now;
+- time_t secs_since_last_ra;
++ struct timespec time_now;
++ int64_t secs_since_last_ra;
+ char addr_str[INET6_ADDRSTRLEN];
+
+ unsigned char buff[MSG_SIZE_SEND];
+@@ -167,14 +155,14 @@ int send_ra(struct Interface *iface, struct in6_addr *dest)
+
+ if (dest == NULL) {
+ dest = (struct in6_addr *)all_hosts_addr;
+- gettimeofday(&iface->last_multicast, NULL);
++ clock_gettime(CLOCK_MONOTONIC, &iface->last_multicast);
+ }
+
+- gettimeofday(&time_now, NULL);
+- secs_since_last_ra = time_diff_secs(&time_now, &iface->last_ra_time);
++ clock_gettime(CLOCK_MONOTONIC, &time_now);
++ secs_since_last_ra = timespecdiff(&time_now, &iface->last_ra_time) / 1000;
+ if (secs_since_last_ra < 0) {
+ secs_since_last_ra = 0;
+- flog(LOG_WARNING, "gettimeofday() went backwards!");
++ flog(LOG_WARNING, "clock_gettime(CLOCK_MONOTONIC) went backwards!");
+ }
+ iface->last_ra_time = time_now;
+
+diff --git a/timer.c b/timer.c
+index ede0c36de499..622034290601 100644
+--- a/timer.c
++++ b/timer.c
+@@ -16,29 +16,32 @@
+ #include "config.h"
+ #include "radvd.h"
+
+-struct timeval next_timeval(double next)
++struct timespec next_timespec(double next)
+ {
+- struct timeval tv;
+- gettimeofday(&tv, NULL);
+- tv.tv_sec += (int)next;
+- tv.tv_usec += 1000000 * (next - (int)next);
+- return tv;
++ struct timespec ts;
++
++ clock_gettime(CLOCK_MONOTONIC, &ts);
++ ts.tv_sec += (int)next;
++ ts.tv_nsec += 1000000000ULL * (next - (int)next);
++ return ts;
+ }
+
+-int timevaldiff(struct timeval const *a, struct timeval const *b)
++int64_t timespecdiff(struct timespec const *a, struct timespec const *b)
+ {
+- int msec;
+- msec = (a->tv_sec - b->tv_sec) * 1000;
+- msec += (a->tv_usec - b->tv_usec) / 1000;
++ int64_t msec;
++ msec = ((int64_t)a->tv_sec - b->tv_sec) * 1000;
++ msec += ((int64_t)a->tv_nsec - b->tv_nsec) / (1000 * 1000);
+ return msec;
+ }
+
+ /* Returns when the next time should expire in milliseconds. */
+-int next_time_msec(struct Interface const *iface)
++uint64_t next_time_msec(struct Interface const *iface)
+ {
+- struct timeval tv;
+- int retval;
+- gettimeofday(&tv, NULL);
+- retval = timevaldiff(&iface->next_multicast, &tv);
+- return retval >= 1 ? retval : 1;
++ struct timespec ts;
++ int64_t diff_ms;
++ clock_gettime(CLOCK_MONOTONIC, &ts);
++ diff_ms = timespecdiff(&iface->next_multicast, &ts);
++ if (diff_ms <= 0)
++ return 0;
++ return (uint64_t)diff_ms;
+ }
+--
+2.0.0.rc2
+
diff --git a/patches/radvd-1.12/series b/patches/radvd-1.12/series
new file mode 100644
index 000000000000..06b25c75bb01
--- /dev/null
+++ b/patches/radvd-1.12/series
@@ -0,0 +1,4 @@
+# generated by git-ptx-patches
+#tag:base --start-number 1
+0001-time-Use-clock_gettime-and-monotonic-clock.patch
+# 7520c46047013d8255e352f310f0e087 - git-ptx-patches magic
diff --git a/rules/radvd.in b/rules/radvd.in
new file mode 100644
index 000000000000..fc653fa79022
--- /dev/null
+++ b/rules/radvd.in
@@ -0,0 +1,8 @@
+## SECTION=networking
+
+config RADVD
+ bool
+ prompt "radvd"
+ select LIBDAEMON
+ help
+ Router Advertisement Daemon
diff --git a/rules/radvd.make b/rules/radvd.make
new file mode 100644
index 000000000000..6109130cf0a3
--- /dev/null
+++ b/rules/radvd.make
@@ -0,0 +1,67 @@
+# -*-makefile-*-
+#
+# Copyright (C) 2014 by Markus Pargmann <mpa@pengutronix.de>
+#
+# See CREDITS for details about who has contributed to this project.
+#
+# For further information about the PTXdist project and license conditions
+# see the README file.
+#
+
+#
+# We provide this package
+#
+PACKAGES-$(PTXCONF_RADVD) += radvd
+
+#
+# Paths and names
+#
+RADVD_VERSION := 1.12
+RADVD := radvd-$(RADVD_VERSION)
+RADVD_SUFFIX := tar.xz
+RADVD_MD5 := baddc38a5f26ca46a9ce7e778b59c1ae
+RADVD_URL := http://www.litech.org/radvd/dist/$(RADVD).$(RADVD_SUFFIX)
+RADVD_DIR := $(BUILDDIR)/$(RADVD)
+RADVD_BUILD_OOT := NO
+RADVD_SOURCE := $(SRCDIR)/$(RADVD).$(RADVD_SUFFIX)
+RADVD_LICENSE := BSD
+
+# ----------------------------------------------------------------------------
+# Extract
+# ----------------------------------------------------------------------------
+
+$(STATEDIR)/radvd.extract: $(STATEDIR)/autogen-tools
+
+$(STATEDIR)/radvd.extract:
+ @$(call targetinfo)
+ @$(call clean, $(RADVD_DIR))
+ @$(call extract, RADVD)
+ cd $(RADVD_DIR) && [ -f configure ] || sh autogen.sh
+ @$(call patchin, RADVD)
+ @$(call touch)
+
+#
+# autoconf
+#
+RADVD_CONF_TOOL := autoconf
+
+# ----------------------------------------------------------------------------
+# Target-Install
+# ----------------------------------------------------------------------------
+
+$(STATEDIR)/radvd.targetinstall:
+ @$(call targetinfo)
+
+ @$(call install_init, radvd)
+ @$(call install_fixup, radvd, PRIORITY, optional)
+ @$(call install_fixup, radvd, SECTION, base)
+ @$(call install_fixup, radvd, AUTHOR, "Markus Pargmann <mpa@pengutronix.de>")
+ @$(call install_fixup, radvd, DESCRIPTION, missing)
+
+ @$(call install_copy, radvd, 0, 0, 0755, -, /usr/sbin/radvd)
+
+ @$(call install_finish, radvd)
+
+ @$(call touch)
+
+# vim: syntax=make
--
2.0.0
--
ptxdist mailing list
ptxdist@pengutronix.de
next reply other threads:[~2014-06-17 8:25 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-17 8:25 Markus Pargmann [this message]
2014-06-17 8:25 ` [ptxdist] [PATCH 2/4] alfred: " Markus Pargmann
2014-06-17 8:25 ` [ptxdist] [PATCH 3/4] crda: Fix udev rule Markus Pargmann
2014-06-17 8:25 ` [ptxdist] [PATCH 4/4] cppzmq: zmq header for C++ Markus Pargmann
2014-06-17 12:26 ` Alexander Aring
2014-06-18 9:09 ` Markus Pargmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1402993518-27068-1-git-send-email-mpa@pengutronix.de \
--to=mpa@pengutronix.de \
--cc=ptxdist@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox