changeset 5044:f51d310db3b7 draft

inet6: Swap between DISCOVER and INFORM better Most of the time this will be dictated by the RA, but let our config decide as well.
author Roy Marples <roy@marples.name>
date Thu, 06 Feb 2020 14:59:24 +0000
parents dac9291f82f0
children 91d05626f72d
files src/dhcp6.c src/ipv6nd.c
diffstat 2 files changed, 44 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/dhcp6.c	Thu Feb 06 12:58:43 2020 +0000
+++ b/src/dhcp6.c	Thu Feb 06 14:59:24 2020 +0000
@@ -1642,6 +1642,20 @@
 	    INF_MAX_RD, dhcp6_failinform, ifp);
 }
 
+static bool
+dhcp6_startdiscoinform(struct interface *ifp)
+{
+	unsigned long long opts = ifp->options->options;
+
+	if (opts & DHCPCD_IA_FORCED || ipv6nd_hasradhcp(ifp, true))
+		dhcp6_startdiscover(ifp);
+	else if (opts & DHCPCD_INFORM6 || ipv6nd_hasradhcp(ifp, false))
+		dhcp6_startinform(ifp);
+	else
+		return false;
+	return true;
+}
+
 static void
 dhcp6_leaseextend(struct interface *ifp)
 {
@@ -1689,13 +1703,7 @@
 		unlink(state->leasefile);
 	}
 
-	if (ifp->options->options & DHCPCD_IA_FORCED ||
-	    ipv6nd_hasradhcp(ifp, true))
-		dhcp6_startdiscover(ifp);
-	else if (ifp->options->options & DHCPCD_INFORM6 ||
-	    ipv6nd_hasradhcp(ifp, false))
-		dhcp6_startinform(ifp);
-	else {
+	if (!dhcp6_startdiscoinform(ifp)) {
 		logwarnx("%s: no advertising IPv6 router wants DHCP",ifp->name);
 		state->state = DH6S_INIT;
 		eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
@@ -2640,7 +2648,7 @@
 	{
 		r = dhcp6_readlease(ifp, 1);
 		if (r == -1) {
-			if (errno != ENOENT)
+			if (errno != ENOENT && errno != ESRCH)
 				logerr("%s: %s", __func__, state->leasefile);
 		} else if (r != 0 &&
 		    !(ifp->options->options & DHCPCD_ANONYMOUS))
@@ -2655,7 +2663,7 @@
 			return;
 		}
 	}
-	dhcp6_startdiscover(ifp);
+	dhcp6_startdiscoinform(ifp);
 }
 
 #ifndef SMALL
@@ -3261,7 +3269,7 @@
 		case DH6S_CONFIRM:
 			if (dhcp6_validatelease(ifp, r, len, sfrom, NULL) == -1)
 			{
-				dhcp6_startdiscover(ifp);
+				dhcp6_startdiscoinform(ifp);
 				return;
 			}
 			break;
@@ -3300,7 +3308,7 @@
 				 * until a new one is found.
 				 */
 				if (state->state != DH6S_DISCOVER)
-					dhcp6_startdiscover(ifp);
+					dhcp6_startdiscoinform(ifp);
 				return;
 			}
 			/* RFC8415 18.2.10.1 */
@@ -3786,12 +3794,17 @@
 		case DH6S_INIT:
 			goto gogogo;
 		case DH6S_INFORM:
-			if (state->state == DH6S_INFORMED)
+			if (state->state == DH6S_INIT ||
+			    state->state == DH6S_INFORMED ||
+			    (state->state == DH6S_DISCOVER &&
+			    !(ifp->options->options & DHCPCD_IA_FORCED) &&
+			    !ipv6nd_hasradhcp(ifp, true)))
 				dhcp6_startinform(ifp);
 			break;
 		case DH6S_REQUEST:
 			if (ifp->options->options & DHCPCD_DHCP6 &&
-			    (state->state == DH6S_INFORM ||
+			    (state->state == DH6S_INIT ||
+			     state->state == DH6S_INFORM ||
 			     state->state == DH6S_INFORMED ||
 			     state->state == DH6S_DELEGATED))
 			{
@@ -3840,8 +3853,7 @@
 	dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
 	    AF_INET6, ifp);
 	if (ipv6_linklocal(ifp) == NULL) {
-		logdebugx("%s: delaying DHCPv6 soliciation for LL address",
-		    ifp->name);
+		logdebugx("%s: delaying DHCPv6 for LL address", ifp->name);
 		ipv6_addlinklocalcallback(ifp, dhcp6_start1, ifp);
 		return 0;
 	}
@@ -3864,11 +3876,8 @@
 	case DH6S_BOUND:
 		dhcp6_startrebind(ifp);
 		break;
-	case DH6S_INFORMED:
-		dhcp6_startinform(ifp);
-		break;
 	default:
-		dhcp6_startdiscover(ifp);
+		dhcp6_startdiscoinform(ifp);
 		break;
 	}
 }
@@ -3984,6 +3993,20 @@
 		ipv6nd_advertise(ia);
 	}
 #endif
+
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startdiscover, ifp);
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_senddiscover, ifp);
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startinform, ifp);
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendinform, ifp);
+	switch (state->state) {
+	case DH6S_DISCOVER:	/* FALLTHROUGH */
+	case DH6S_REQUEST:
+	case DH6S_INFORM:
+		state->state = DH6S_INIT;
+		break;
+	default:
+		break;
+	}
 }
 
 void
--- a/src/ipv6nd.c	Thu Feb 06 12:58:43 2020 +0000
+++ b/src/ipv6nd.c	Thu Feb 06 14:59:24 2020 +0000
@@ -1115,6 +1115,8 @@
 	 * routers like to decrease the advertised valid and preferred times
 	 * in accordance with the own prefix times which would result in too
 	 * much needless log spam. */
+	if (rap->willexpire)
+		new_data = true;
 	logfunc = new_data || !rap->isreachable ? loginfox : logdebugx,
 	logfunc("%s: Router Advertisement from %s", ifp->name, rap->sfrom);