"valid_lft" and "preferred_lft" are different. If the "preferred_lft"
is expired the prefix should be avoided in source prefix selection.
However, the interface is allowed to still receive downstream traffic.
preferred_lfetime:
Limit for preferred lifetime of a prefix
If you want the old behavior, you have to set preferred_lifetime to
the same value as leasetime.
Signed-off-by: Nick Hainke <vincent@systemli.org>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
leasetime string 12h DHCPv4 address leasetime
start integer 100 DHCPv4 pool start
limit integer 150 DHCPv4 pool size
leasetime string 12h DHCPv4 address leasetime
start integer 100 DHCPv4 pool start
limit integer 150 DHCPv4 pool size
+preferred_lifetime string 12h Value for the preferred lifetime
+ for a prefix
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
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
IFACE_ATTR_NDPROXY_ROUTING,
IFACE_ATTR_NDPROXY_SLAVE,
IFACE_ATTR_PREFIX_FILTER,
IFACE_ATTR_NDPROXY_ROUTING,
IFACE_ATTR_NDPROXY_SLAVE,
IFACE_ATTR_PREFIX_FILTER,
+ IFACE_ATTR_PREFERRED_LIFETIME,
[IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = BLOBMSG_TYPE_BOOL },
[IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = BLOBMSG_TYPE_STRING },
[IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = BLOBMSG_TYPE_BOOL },
[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 },
};
static const struct uci_blob_param_info iface_attr_info[IFACE_ATTR_MAX] = {
};
static const struct uci_blob_param_info iface_attr_info[IFACE_ATTR_MAX] = {
iface->ndp = MODE_DISABLED;
iface->learn_routes = 1;
iface->dhcp_leasetime = 43200;
iface->ndp = MODE_DISABLED;
iface->learn_routes = 1;
iface->dhcp_leasetime = 43200;
+ iface->preferred_lifetime = 43200;
iface->dhcpv4_start.s_addr = htonl(START_DEFAULT);
iface->dhcpv4_end.s_addr = htonl(START_DEFAULT + LIMIT_DEFAULT - 1);
iface->dhcpv6_assignall = true;
iface->dhcpv4_start.s_addr = htonl(START_DEFAULT);
iface->dhcpv4_end.s_addr = htonl(START_DEFAULT + LIMIT_DEFAULT - 1);
iface->dhcpv6_assignall = true;
iface->dhcp_leasetime = time;
}
iface->dhcp_leasetime = time;
}
+ if ((c = tb[IFACE_ATTR_PREFERRED_LIFETIME])) {
+ double time = parse_leasetime(c);
+ if (time < 0)
+ goto err;
+
+ iface->preferred_lifetime = time;
+ }
+
if ((c = tb[IFACE_ATTR_START])) {
iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c));
iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) +
if ((c = tb[IFACE_ATTR_START])) {
iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c));
iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) +
addr.s6_addr32[2] = addr.s6_addr32[3] = 0;
}
addr.s6_addr32[2] = addr.s6_addr32[3] = 0;
}
+ if (pref > (uint32_t)c->preferred_until)
+ pref = c->preferred_until;
+
if (pref > (uint32_t)c->valid_until)
pref = c->valid_until;
if (pref > (uint32_t)c->valid_until)
pref = c->valid_until;
+ uint32_t leasetime, pref;
leasetime = a->leasetime;
leasetime = a->leasetime;
+ pref = a->leasetime;
+ } else {
leasetime = iface->dhcp_leasetime;
leasetime = iface->dhcp_leasetime;
+ pref = iface->preferred_lifetime;
+ }
- uint32_t pref = leasetime;
uint32_t valid = leasetime;
struct odhcpd_ipaddr *addrs = (a->managed) ? a->managed : iface->addr6;
uint32_t valid = leasetime;
struct odhcpd_ipaddr *addrs = (a->managed) ? a->managed : iface->addr6;
if (prefix_pref != UINT32_MAX)
prefix_pref -= now;
if (prefix_pref != UINT32_MAX)
prefix_pref -= now;
- if (prefix_pref > leasetime)
- prefix_pref = leasetime;
+ if (prefix_pref > pref)
+ prefix_pref = pref;
if (prefix_valid != UINT32_MAX)
prefix_valid -= now;
if (prefix_valid != UINT32_MAX)
prefix_valid -= now;
/* UINT32_MAX is considered as infinite leasetime */
a->valid_until = (valid == UINT32_MAX) ? 0 : valid + now;
/* UINT32_MAX is considered as infinite leasetime */
a->valid_until = (valid == UINT32_MAX) ? 0 : valid + now;
+ if (!INFINITE_VALID(a->preferred_until))
+ /* UINT32_MAX is considered as infinite leasetime */
+ a->preferred_until = (pref == UINT32_MAX) ? 0 : pref + now;
+
o_ia.t1 = htonl((pref == UINT32_MAX) ? pref : pref * 5 / 10);
o_ia.t2 = htonl((pref == UINT32_MAX) ? pref : pref * 8 / 10);
o_ia.t1 = htonl((pref == UINT32_MAX) ? pref : pref * 5 / 10);
o_ia.t2 = htonl((pref == UINT32_MAX) ? pref : pref * 8 / 10);
a->peer = *addr;
a->assigned = is_na && l ? l->hostid : reqhint;
a->valid_until = now;
a->peer = *addr;
a->assigned = is_na && l ? l->hostid : reqhint;
a->valid_until = now;
+ a->preferred_until = now;
a->dhcp_free_cb = dhcpv6_ia_free_assignment;
a->iface = iface;
a->flags = (is_pd ? OAF_DHCPV6_PD : OAF_DHCPV6_NA);
a->dhcp_free_cb = dhcpv6_ia_free_assignment;
a->iface = iface;
a->flags = (is_pd ? OAF_DHCPV6_PD : OAF_DHCPV6_NA);
struct sockaddr_in6 peer;
time_t valid_until;
struct sockaddr_in6 peer;
time_t valid_until;
+ time_t preferred_until;
#define fr_timer reconf_timer
struct uloop_timeout reconf_timer;
#define fr_timer reconf_timer
struct uloop_timeout reconf_timer;
uint32_t ra_retranstime;
uint32_t ra_hoplimit;
int ra_mtu;
uint32_t ra_retranstime;
uint32_t ra_hoplimit;
int ra_mtu;
+ uint32_t preferred_lifetime;
// DHCP
uint32_t dhcp_leasetime;
// DHCP
uint32_t dhcp_leasetime;
preferred = TIME_LEFT(addr->preferred, now);
if (iface->ra_useleasetime &&
preferred = TIME_LEFT(addr->preferred, now);
if (iface->ra_useleasetime &&
- preferred > iface->dhcp_leasetime)
- preferred = iface->dhcp_leasetime;
+ preferred > iface->preferred_lifetime)
+ preferred = iface->preferred_lifetime;
}
valid = TIME_LEFT(addr->valid, now);
}
valid = TIME_LEFT(addr->valid, now);