Download raw body.
dhcp6leased(8): Set pltime to 0 when upstream interface goes down.
In case of a flash-renumbering event we configure new prefixes with a
pltime > 0. Clients should form new addresses and prefer those.
Reported & fix tested by Tamas (cstamas at cstamas.hu), thanks!
OK?
(We can do better here, for example remove the old prefix when we get a
new one. That's more complicated to implement and I was short and time
and this fixes the issue for now. I also want to double check what the
current thinking in the IETF is wrt. flash renumbering.)
diff --git engine.c engine.c
index 58acebb65b7..887ef551bfc 100644
--- engine.c
+++ engine.c
@@ -135,6 +135,7 @@ void request_dhcp_discover(struct dhcp6leased_iface *);
void request_dhcp_request(struct dhcp6leased_iface *);
void configure_interfaces(struct dhcp6leased_iface *);
void deconfigure_interfaces(struct dhcp6leased_iface *);
+void deprecate_interfaces(struct dhcp6leased_iface *);
int prefixcmp(struct prefix *, struct prefix *, int);
void send_reconfigure_interface(struct iface_pd_conf *,
struct prefix *, enum reconfigure_action);
@@ -1049,8 +1050,19 @@ state_transition(struct dhcp6leased_iface *iface, enum if_state new_state)
switch (new_state) {
case IF_DOWN:
+ switch (old_state) {
+ case IF_RENEWING:
+ case IF_REBINDING:
+ case IF_REBOOTING:
+ case IF_BOUND:
+ deprecate_interfaces(iface);
+ break;
+ default:
+ break;
+ }
/*
- * Nothing to do until iface comes up. IP addresses will expire.
+ * Nothing else to do until iface comes up.
+ * IP addresses will expire.
*/
iface->timo.tv_sec = -1;
break;
@@ -1387,6 +1399,58 @@ deconfigure_interfaces(struct dhcp6leased_iface *iface)
memset(iface->pds, 0, sizeof(iface->pds));
}
+void
+deprecate_interfaces(struct dhcp6leased_iface *iface)
+{
+ struct iface_conf *iface_conf;
+ struct iface_ia_conf *ia_conf;
+ struct iface_pd_conf *pd_conf;
+ struct timespec now, diff;
+ uint32_t i;
+ char ntopbuf[INET6_ADDRSTRLEN];
+ char ifnamebuf[IF_NAMESIZE], *if_name;
+
+
+ if ((if_name = if_indextoname(iface->if_index, ifnamebuf)) == NULL) {
+ log_debug("%s: unknown interface %d", __func__,
+ iface->if_index);
+ return;
+ }
+ if ((iface_conf = find_iface_conf(&engine_conf->iface_list, if_name))
+ == NULL) {
+ log_debug("%s: no interface configuration for %d", __func__,
+ iface->if_index);
+ return;
+ }
+
+ for (i = 0; i < iface_conf->ia_count; i++) {
+ struct prefix *pd = &iface->pds[i];
+
+ log_info("%s went down, deprecating prefix delegation #%d %s/%d"
+ " from server %s", if_name, i, inet_ntop(AF_INET6,
+ &pd->prefix, ntopbuf, INET6_ADDRSTRLEN), pd->prefix_len,
+ dhcp_duid2str(iface->serverid_len, iface->serverid));
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timespecsub(&now, &iface->request_time, &diff);
+
+ SIMPLEQ_FOREACH(ia_conf, &iface_conf->iface_ia_list, entry) {
+ struct prefix *pd = &iface->pds[ia_conf->id];
+
+ if (pd->vltime > diff.tv_sec)
+ pd->vltime -= diff.tv_sec;
+ else
+ pd->vltime = 0;
+
+ pd->pltime = 0;
+
+ SIMPLEQ_FOREACH(pd_conf, &ia_conf->iface_pd_list, entry) {
+ send_reconfigure_interface(pd_conf, pd, CONFIGURE);
+ }
+ }
+}
+
int
prefixcmp(struct prefix *a, struct prefix *b, int count)
{
--
In my defence, I have been left unsupervised.
dhcp6leased(8): Set pltime to 0 when upstream interface goes down.