[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