From: Roy Marples Date: Tue, 14 Nov 2017 16:41:59 +0000 (+0000) Subject: DHCPv6: confirm lease on carrier up X-Git-Tag: v7.0.0-rc4~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=385479d24ef0db44351d13e65d766709284b07c1;p=thirdparty%2Fdhcpcd.git DHCPv6: confirm lease on carrier up On some platforms which preserve state when carrier goes down, such as NetBSD-8, the state does not enter the CONFIRM state. Add more logic to dhcp6_start so that we can better control this from the various call points. --- diff --git a/src/dhcp6.c b/src/dhcp6.c index 2910274a..7e85a455 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -3673,28 +3673,47 @@ dhcp6_start(struct interface *ifp, enum DH6S init_state) struct dhcp6_state *state; state = D6_STATE(ifp); - if (state) { - if (state->state == DH6S_INFORMED && - init_state == DH6S_INFORM) - { - dhcp6_startinform(ifp); - return 0; - } - if (init_state == DH6S_INIT && - ifp->options->options & DHCPCD_DHCP6 && - (state->state == DH6S_INFORM || - state->state == DH6S_INFORMED || - state->state == DH6S_DELEGATED)) - { - /* Change from stateless to stateful */ + if (state != NULL) { + switch (init_state) { + case DH6S_INIT: + /* This should only happen on OS's where we keep state + * on carrier down, such as NetBSD-8. */ goto gogogo; + case DH6S_INFORM: + if (state->state == DH6S_INFORMED) + dhcp6_startinform(ifp); + break; + case DH6S_REQUEST: + if (ifp->options->options & DHCPCD_DHCP6 && + (state->state == DH6S_INFORM || + state->state == DH6S_INFORMED || + state->state == DH6S_DELEGATED)) + { + /* Change from stateless to stateful */ + init_state = DH6S_INIT; + goto gogogo; + } + break; + case DH6S_CONFIRM: + /* This should only happen on OS's where we keep state + * on carrier down, such as NetBSD-8. */ + init_state = DH6S_INIT; + goto gogogo; + default: + /* Not possible, but sushes some compiler warnings. */ + break; } - /* We're already running DHCP6 */ - /* XXX: What if the managed flag vanishes from all RA? */ -#ifndef SMALL - dhcp6_activateinterfaces(ifp); -#endif return 0; + } else { + switch (init_state) { + case DH6S_CONFIRM: + /* No DHCPv6 config, no existing state + * so nothing to do. */ + return 0; + default: + init_state = DH6S_INIT; + break; + } } if (!(ifp->options->options & DHCPCD_DHCP6)) diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 8b3ac1b5..e677e4c6 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -871,37 +871,22 @@ dhcpcd_startinterface(void *arg) ipv6nd_startrs(ifp); } - if (ifo->options & DHCPCD_DHCP6) + + if (ifo->options & DHCPCD_DHCP6) { dhcp6_find_delegates(ifp); - if ((!(ifo->options & DHCPCD_IPV6RS) || - ifo->options & (DHCPCD_IA_FORCED | DHCPCD_INFORM6)) && - ifp->active == IF_ACTIVE_USER) - { - ssize_t nolease; - - if (ifo->options & DHCPCD_IA_FORCED) - nolease = dhcp6_start(ifp, DH6S_INIT); - else if (ifo->options & DHCPCD_INFORM6) - nolease = dhcp6_start(ifp, DH6S_INFORM); - else { - nolease = 0; - /* Enabling the below doesn't really make - * sense as there is currently no standard - * to push routes via DHCPv6. - * (There is an expired working draft, - * maybe abandoned?) - * You can also get it to work by forcing - * an IA as shown above. */ -#if 0 - /* With no RS or delegates we might - * as well try and solicit a DHCPv6 address */ - if (nolease == 0) - nolease = dhcp6_start(ifp, DH6S_INIT); -#endif + if (ifp->active == IF_ACTIVE_USER) { + enum DH6S d6_state; + + if (ifo->options & DHCPCD_IA_FORCED) + d6_state = DH6S_INIT; + else if (ifo->options & DHCPCD_INFORM6) + d6_state = DH6S_INFORM; + else + d6_state = DH6S_CONFIRM; + if (dhcp6_start(ifp, d6_state) == -1) + logerr("%s: dhcp6_start", ifp->name); } - if (nolease == -1) - logerr("%s: dhcp6_start", ifp->name); } } diff --git a/src/ipv6nd.c b/src/ipv6nd.c index a5b032ed..a4bae15b 100644 --- a/src/ipv6nd.c +++ b/src/ipv6nd.c @@ -1095,7 +1095,7 @@ handle_flag: #define LOG_DHCP6 logdebug #endif if (rap->flags & ND_RA_FLAG_MANAGED) { - if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1) + if (new_data && dhcp6_start(ifp, DH6S_REQUEST) == -1) LOG_DHCP6("dhcp6_start: %s", ifp->name); } else if (rap->flags & ND_RA_FLAG_OTHER) { if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1)