Mercurial > hg > dhcpcd
changeset 4183:115cbfa711e2 draft
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.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Tue, 14 Nov 2017 16:41:59 +0000 |
| parents | 4d1dbe479752 |
| children | 548f1baa118d |
| files | src/dhcp6.c src/dhcpcd.c src/ipv6nd.c |
| diffstat | 3 files changed, 52 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/src/dhcp6.c Tue Nov 14 15:37:23 2017 +0000 +++ b/src/dhcp6.c Tue Nov 14 16:41:59 2017 +0000 @@ -3673,28 +3673,47 @@ 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 (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; } - 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 */ - goto gogogo; + 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; } - /* We're already running DHCP6 */ - /* XXX: What if the managed flag vanishes from all RA? */ -#ifndef SMALL - dhcp6_activateinterfaces(ifp); -#endif - return 0; } if (!(ifp->options->options & DHCPCD_DHCP6))
--- a/src/dhcpcd.c Tue Nov 14 15:37:23 2017 +0000 +++ b/src/dhcpcd.c Tue Nov 14 16:41:59 2017 +0000 @@ -871,37 +871,22 @@ 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 (ifp->active == IF_ACTIVE_USER) { + enum DH6S d6_state; - 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 (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); } }
--- a/src/ipv6nd.c Tue Nov 14 15:37:23 2017 +0000 +++ b/src/ipv6nd.c Tue Nov 14 16:41:59 2017 +0000 @@ -1095,7 +1095,7 @@ #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)
