tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pppoe, dhcpcd v6 and renew



On Tue, Nov 14, 2017 at 04:55:03PM +0000, Roy Marples wrote:
> On 14/11/2017 05:06, Roy Marples wrote:
> > dhcpcd did try and start the interface, but didn't actually do anything.
> > Can you try the attached patch please?
> > I've only compile tested it and won't be able to actually try it for a
> > while.
> 
> So that patch caused a few other problems.
> This one is more invasive but fixes a whole raft of issues related to not
> removing addresses on carrier down, which is exclusive to NetBSD-8.
> 
> Let me know how it works!

I had to fix a conflict for netbsd-8, here's the updated patch.

dhcpcd is now more verbose:
Nov 14 19:29:43 chassiron /netbsd: pppoe0: LCP keepalive timed out, going to restart the connection
Nov 14 19:29:43 chassiron dhcpcd[25536]: pppoe0: carrier lost
Nov 14 19:30:48 chassiron /netbsd: pppoe0: connected to lns-1-par-se100
Nov 14 19:30:48 chassiron dhcpcd[25536]: pppoe0: carrier acquired
Nov 14 19:30:48 chassiron dhcpcd[25536]: pppoe0: IAID 00:00:00:06
Nov 14 19:30:48 chassiron dhcpcd[25536]: pppoe0: IAID 00:00:00:00
Nov 14 19:30:50 chassiron dhcpcd[25536]: pppoe0: rebinding prior DHCPv6 lease

But it didn't send anything on the pppoe0 interface (confirmed by a tcpdump).
Here's what it prints on a fresh start:
Nov 14 19:28:27 chassiron dhcpcd[29292]: forked to background, child pid 25536
Nov 14 19:28:27 chassiron dhcpcd[25536]: DUID 00:01:00:01:21:85:aa:70:02:4a:06:41:92:71
Nov 14 19:28:27 chassiron dhcpcd[25536]: pppoe0: IAID 00:00:00:06
Nov 14 19:28:27 chassiron dhcpcd[25536]: pppoe0: IAID 00:00:00:00
Nov 14 19:28:27 chassiron dhcpcd[25536]: pppoe0: soliciting a DHCPv6 lease
Nov 14 19:28:28 chassiron dhcpcd[25536]: pppoe0: ADV 2001:41d0:fe9d:1100::/56 from fe80::230:88ff:fe04:63c9
Nov 14 19:28:28 chassiron dhcpcd[25536]: pppoe0: REPLY6 received from fe80::230:88ff:fe04:63c9
Nov 14 19:28:28 chassiron dhcpcd[25536]: pppoe0: renew in 43200, rebind in 69120, expire in 172800 seconds
Nov 14 19:28:28 chassiron dhcpcd[25536]: lo0: adding reject route to 2001:41d0:fe9d:1100::/56 via ::1
Nov 14 19:28:28 chassiron dhcpcd[25536]: pppoe0: delegated prefix 2001:41d0:fe9d:1100::/56

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: dist/src/dhcp6.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/src/dhcp6.c,v
retrieving revision 1.1.1.4
diff -u -p -u -r1.1.1.4 dhcp6.c
--- dist/src/dhcp6.c	10 May 2017 11:00:37 -0000	1.1.1.4
+++ dist/src/dhcp6.c	14 Nov 2017 18:34:36 -0000
@@ -3391,28 +3391,47 @@ dhcp6_start(struct interface *ifp, enum 
 	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))
Index: dist/src/dhcpcd.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/src/dhcpcd.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 dhcpcd.c
--- dist/src/dhcpcd.c	10 May 2017 11:03:44 -0000	1.4
+++ dist/src/dhcpcd.c	14 Nov 2017 18:34:36 -0000
@@ -863,36 +863,20 @@ dhcpcd_startinterface(void *arg)
 		if (ifo->options & DHCPCD_IPV6RS)
 			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))
-		{
-			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);
 		}
 	}
 
Index: dist/src/if-bsd.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/src/if-bsd.c,v
retrieving revision 1.1.1.3
diff -u -p -u -r1.1.1.3 if-bsd.c
--- dist/src/if-bsd.c	10 May 2017 11:00:37 -0000	1.1.1.3
+++ dist/src/if-bsd.c	14 Nov 2017 18:34:36 -0000
@@ -1185,6 +1185,12 @@ if_ifa(struct dhcpcd_ctx *ctx, const str
 		}
 #endif
 
+#ifdef __KAME__
+		if (IN6_IS_ADDR_LINKLOCAL(&addr6))
+			/* Remove the scope from the address */
+			addr6.s6_addr[2] = addr6.s6_addr[3] = '\0';
+#endif
+
 		ipv6_handleifa(ctx, ifam->ifam_type, NULL,
 		    ifp->name, &addr6, ipv6_prefixlen(&mask6), addrflags);
 		break;
Index: dist/src/ipv6nd.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/src/ipv6nd.c,v
retrieving revision 1.1.1.2
diff -u -p -u -r1.1.1.2 ipv6nd.c
--- dist/src/ipv6nd.c	14 Apr 2017 09:53:07 -0000	1.1.1.2
+++ dist/src/ipv6nd.c	14 Nov 2017 18:34:36 -0000
@@ -326,6 +326,8 @@ ipv6nd_expire(struct interface *ifp, uin
 {
 	struct ra *rap;
 	struct timespec now;
+	uint32_t vltime = seconds;
+	uint32_t pltime = seconds / 2;
 
 	if (ifp->ctx->ra_routers == NULL)
 		return;
@@ -337,13 +339,18 @@ ipv6nd_expire(struct interface *ifp, uin
 			rap->acquired = now;
 			rap->expired = seconds ? 0 : 1;
 			if (seconds) {
-				struct ipv6_addr *ap;
+				struct ipv6_addr *ia;
 
 				rap->lifetime = seconds;
-				TAILQ_FOREACH(ap, &rap->addrs, next) {
-					if (ap->prefix_vltime) {
-						ap->prefix_vltime = seconds;
-						ap->prefix_pltime = seconds / 2;
+				TAILQ_FOREACH(ia, &rap->addrs, next) {
+					if (ia->prefix_pltime > pltime ||
+					    ia->prefix_vltime > vltime)
+					{
+						ia->acquired = now;
+						if (ia->prefix_pltime != 0)
+							ia->prefix_pltime =
+							    pltime;
+						ia->prefix_vltime = vltime;
 					}
 				}
 				ipv6_addaddrs(&rap->addrs);
@@ -1103,7 +1110,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)


Home | Main Index | Thread Index | Old Index