[PATCH] odhcpd: add option to use absolute timestamps

Nick vincent at systemli.org
Sat Feb 6 15:33:10 EST 2021


I see that more as setting a preferred lifetime with a relative time-span.
E.g. I will get a a preferred_lft of 120 from now, and I would set it like:

   date '+%d %b %Y %T' --date="@$(($(date +%s)+120))"

So it does not need to be synced, since I'm only interested in the 
timespan from now + 120s.
Setting this as abs time-span will prevent a reload or restart of the 
daemon setting the value again to now + 120.

Bests,
Nick

On 2/6/21 9:14 PM, Hans Dedecker wrote:
>
>
> On Sat, Jan 30, 2021 at 5:33 PM Nick Hainke <vincent at systemli.org 
> <mailto:vincent at systemli.org>> wrote:
>
>     Until now it is not possible to give absolute timestamps in odhcpd.
>     This means that on every new RA or request, the timestamp is renewed.
>     Further, the valid and preferred lifetimes are not synced between all
>     devices.
>
>     There are several usecases when it is needed to have absolute
>     timestamp
>     that needed to be synced across all devices, e.g. your ISP delegates
>     you a prefix for some certain time, or you want to change to another
>     prefix.
>
>     The purpose of having this as a absolute timestamp is to make it
>     easier
>     to track. An example configuration is
>
>       option absolute_lifetime '1'
>       option valid_lifetime '05 Jan 2021 23:00:00'
>       option preferred_lifetime '05 Jan 2021 23:00:00'
>
>     If the valid_lifetime is in the past, the preferred lifetime and valid
>     lifetime are set to 1 minute.
>
> I have my reservations about the patch as it requires knowledge of 
> absolute time on devices.
> This is a problem as not all devices have a RTC; or the time needs to 
> be synchronized with a wan NTP server.
> This is also the reason why netifd does not to support absolute 
> lifetimes for configured prefixes
>
> Hans
>
>
>     Signed-off-by: Nick Hainke <vincent at systemli.org
>     <mailto:vincent at systemli.org>>
>     ---
>      README          |  8 ++++--
>      src/config.c    | 69
>     ++++++++++++++++++++++++++++++++++---------------
>      src/dhcpv6-ia.c | 10 +++++++
>      src/odhcpd.h    |  1 +
>      4 files changed, 65 insertions(+), 23 deletions(-)
>
>     diff --git a/README b/README
>     index f9cbb11..0af5c75 100644
>     --- a/README
>     +++ b/README
>     @@ -107,11 +107,13 @@ dns_service               bool    1        
>                Announce the address of interface as DNS service
>                                                             if the
>     list of dns is empty
>      domain                 list    <local search domain>  Search
>     domains to announce
>
>     -leasetime              string  12h  DHCPv4 address leasetime
>     +leasetime              string  12h  DHCPv4 address leasetime. If
>     absolute_lifetime is
>     +                                                       set the
>     value can be given as a date, e.g. "10 Jan 2020 00:00:00".
>      start                  integer 100  DHCPv4 pool start
>      limit                  integer 150  DHCPv4 pool size
>      preferred_lifetime     string  12h  Value for the preferred lifetime
>     -                                                       for a prefix
>     +                                                       for a
>     prefix. If absolute_lifetime is set the value can
>     +                                                       be given
>     as a date, e.g. "10 Jan 2020 00:00:00".
>      ra_default             integer 0  Override default route
>                             0: default, 1: ignore no public address,
>     2: ignore all
>      ra_flags               list    other-config            List of RA
>     flags to be
>     @@ -145,6 +147,8 @@ ndproxy_slave               bool    0        
>                NDProxy external slave
>      prefix_filter          string  ::/0                    Only
>     advertise on-link prefixes within
>                             [IPv6 prefix]                   the
>     provided IPv6 prefix; others are
>     filtered out.
>     +absolute_lifetime              bool    0    Interpret configured
>     lifetime as
>     +  absolute timestamps. The format has to be "10 Jan 2020 00:00:00".
>
>
>      Sections of type host (static leases)
>     diff --git a/src/config.c b/src/config.c
>     index 78b5855..42f73a1 100644
>     --- a/src/config.c
>     +++ b/src/config.c
>     @@ -8,6 +8,7 @@
>      #include <string.h>
>      #include <sys/stat.h>
>      #include <syslog.h>
>     +#include <time.h>
>
>      #include <uci.h>
>      #include <uci_blob.h>
>     @@ -83,6 +84,7 @@ enum {
>             IFACE_ATTR_NDPROXY_SLAVE,
>             IFACE_ATTR_PREFIX_FILTER,
>             IFACE_ATTR_PREFERRED_LIFETIME,
>     +       IFACE_ATTR_ABSOLUTE_LIFETIME,
>             IFACE_ATTR_MAX
>      };
>
>     @@ -132,6 +134,7 @@ static const struct blobmsg_policy
>     iface_attrs[IFACE_ATTR_MAX] = {
>             [IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave",
>     .type = BLOBMSG_TYPE_BOOL },
>             [IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter",
>     .type = BLOBMSG_TYPE_STRING },
>             [IFACE_ATTR_PREFERRED_LIFETIME] = { .name =
>     "preferred_lifetime", .type = BLOBMSG_TYPE_STRING },
>     +       [IFACE_ATTR_ABSOLUTE_LIFETIME] = { .name =
>     "absolute_lifetime", .type = BLOBMSG_TYPE_BOOL },
>      };
>
>      static const struct uci_blob_param_info
>     iface_attr_info[IFACE_ATTR_MAX] = {
>     @@ -212,6 +215,7 @@ static void set_interface_defaults(struct
>     interface *iface)
>             iface->ra_mininterval = iface->ra_maxinterval/3;
>             iface->ra_lifetime = -1;
>             iface->ra_dns = true;
>     +       iface->absolute_lifetime = false;
>      }
>
>      static void clean_interface(struct interface *iface)
>     @@ -321,29 +325,48 @@ static void set_config(struct uci_section *s)
>             }
>      }
>
>     -static double parse_leasetime(struct blob_attr *c) {
>     +static double parse_leasetime(struct blob_attr *c, bool absolute) {
>             char *val = blobmsg_get_string(c), *endptr = NULL;
>     -       double time = strcmp(val, "infinite") ? strtod(val,
>     &endptr) : UINT32_MAX;
>     -
>     -       if (time && endptr && endptr[0]) {
>     -               if (endptr[0] == 's')
>     -                       time *= 1;
>     -               else if (endptr[0] == 'm')
>     -                       time *= 60;
>     -               else if (endptr[0] == 'h')
>     -                       time *= 3600;
>     -               else if (endptr[0] == 'd')
>     -                       time *= 24 * 3600;
>     -               else if (endptr[0] == 'w')
>     -                       time *= 7 * 24 * 3600;
>     -               else
>     +       double ret_time = strcmp(val, "infinite") ? strtod(val,
>     &endptr) : UINT32_MAX;
>     +
>     +       if (absolute)
>     +       {
>     +               // "10 Jan 2020 00:00:00"
>     +               // Parse absolut time
>     +               struct tm tm = {0};
>     +               char *s = strptime(val, "%d %b %Y %H:%M:%S", &tm);
>     +               if (s == NULL) {
>     +                       syslog(LOG_ERR, "Failed to Parse Date:
>     %s", val);
>                             goto err;
>     +               }
>     +
>     +               time_t now = odhcpd_time();
>     +               time_t wall_time = time(NULL);
>     +               time_t t = mktime(&tm);
>     +
>     +               double diff = difftime(t,wall_time);
>     +               ret_time += now + diff;
>     +       } else {
>     +               if (ret_time && endptr && endptr[0]) {
>     +                       if (endptr[0] == 's')
>     +                               ret_time *= 1;
>     +                       else if (endptr[0] == 'm')
>     +                               ret_time *= 60;
>     +                       else if (endptr[0] == 'h')
>     +                               ret_time *= 3600;
>     +                       else if (endptr[0] == 'd')
>     +                               ret_time *= 24 * 3600;
>     +                       else if (endptr[0] == 'w')
>     +                               ret_time *= 7 * 24 * 3600;
>     +                       else
>     +                               goto err;
>     +               }
>             }
>
>     -       if (time < 60)
>     -               time = 60;
>     +       if (ret_time < 60)
>     +               ret_time = 60;
>
>     -       return time;
>     +       return ret_time;
>
>      err:
>             return -1;
>     @@ -409,7 +432,7 @@ int set_lease_from_blobmsg(struct blob_attr *ba)
>             }
>
>             if ((c = tb[LEASE_ATTR_LEASETIME])) {
>     -               double time = parse_leasetime(c);
>     +               double time = parse_leasetime(c, false); // do not
>     support absolute timestamps for now
>                     if (time < 0)
>                             goto err;
>
>     @@ -520,8 +543,12 @@ int config_parse_interface(void *data, size_t
>     len, const char *name, bool overwr
>             if ((c = tb[IFACE_ATTR_DYNAMICDHCP]))
>                     iface->no_dynamic_dhcp = !blobmsg_get_bool(c);
>
>     +
>     +       if ((c = tb[IFACE_ATTR_ABSOLUTE_LIFETIME]))
>     +               iface->absolute_lifetime = blobmsg_get_bool(c);
>     +
>             if ((c = tb[IFACE_ATTR_LEASETIME])) {
>     -               double time = parse_leasetime(c);
>     +               double time = parse_leasetime(c,
>     iface->absolute_lifetime);
>                     if (time < 0)
>                             goto err;
>
>     @@ -529,7 +556,7 @@ int config_parse_interface(void *data, size_t
>     len, const char *name, bool overwr
>             }
>
>             if ((c = tb[IFACE_ATTR_PREFERRED_LIFETIME])) {
>     -               double time = parse_leasetime(c);
>     +               double time = parse_leasetime(c,
>     iface->absolute_lifetime);
>                     if (time < 0)
>                             goto err;
>
>     diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
>     index a59fc20..78be8b8 100644
>     --- a/src/dhcpv6-ia.c
>     +++ b/src/dhcpv6-ia.c
>     @@ -865,6 +865,16 @@ static size_t build_ia(uint8_t *buf, size_t
>     buflen, uint16_t status,
>                             if (prefix_valid > leasetime)
>                                     prefix_valid = leasetime;
>
>     +                       if (iface->absolute_lifetime) {
>     +                               if ((long int)
>     iface->dhcp_leasetime > now) {
>     +                                       prefix_valid =
>     iface->dhcp_leasetime - now;
>     +                                       prefix_pref =
>     iface->preferred_lifetime - now;
>     +                               } else { // if we have a timestamp
>     in the past set pref and valid to 60s
>     +                                       prefix_valid = 60;
>     +                                       prefix_pref = 60;
>     +                               }
>     +                       }
>     +
>                             if (a->flags & OAF_DHCPV6_PD) {
>                                     struct dhcpv6_ia_prefix o_ia_p = {
>                                             .type =
>     htons(DHCPV6_OPT_IA_PREFIX),
>     diff --git a/src/odhcpd.h b/src/odhcpd.h
>     index 45b6784..98673a8 100644
>     --- a/src/odhcpd.h
>     +++ b/src/odhcpd.h
>     @@ -288,6 +288,7 @@ struct interface {
>             uint32_t ra_hoplimit;
>             int ra_mtu;
>             uint32_t preferred_lifetime;
>     +       bool absolute_lifetime;
>
>             // DHCP
>             uint32_t dhcp_leasetime;
>     -- 
>     2.30.0
>
>
>     _______________________________________________
>     openwrt-devel mailing list
>     openwrt-devel at lists.openwrt.org
>     <mailto:openwrt-devel at lists.openwrt.org>
>     https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>     <https://lists.openwrt.org/mailman/listinfo/openwrt-devel>
>



More information about the openwrt-devel mailing list