[PATCH] odhcpd: add option to use absolute timestamps

Nick vincent at systemli.org
Tue Feb 9 04:57:04 EST 2021


Maybe I will just inject via ubus a prefix, that is not reflected by the 
config, like the
"UBUS_METHOD("add_prefix", handle_add_prefix, prefix_attrs)"

At the end that gives me the flexibility I need without the need to 
insert absolute timestamps.

Best,
Nick

On 2/6/21 9:33 PM, Nick wrote:
> 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