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))
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);
}
}
#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)